index.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <template>
  2. <!-- 搜索工作区 -->
  3. <ContentWrap>
  4. <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
  5. </ContentWrap>
  6. <ContentWrap>
  7. <!-- 操作工具栏 -->
  8. <div class="mb-10px">
  9. <XButton
  10. type="primary"
  11. preIcon="ep:zoom-in"
  12. :title="t('action.add')"
  13. v-hasPermi="['system:tenant:create']"
  14. @click="handleCreate()"
  15. />
  16. <XButton
  17. type="warning"
  18. preIcon="ep:download"
  19. :title="t('action.export')"
  20. v-hasPermi="['system:tenant:export']"
  21. @click="exportList('租户数据.xls')"
  22. />
  23. </div>
  24. <!-- 列表 -->
  25. <Table
  26. :columns="allSchemas.tableColumns"
  27. :selection="false"
  28. :data="tableObject.tableList"
  29. :loading="tableObject.loading"
  30. :pagination="{
  31. total: tableObject.total
  32. }"
  33. v-model:pageSize="tableObject.pageSize"
  34. v-model:currentPage="tableObject.currentPage"
  35. @register="register"
  36. >
  37. <template #accountCount="{ row }">
  38. <el-tag> {{ row.accountCount }} </el-tag>
  39. </template>
  40. <template #status="{ row }">
  41. <DictTag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
  42. </template>
  43. <template #packageId="{ row }">
  44. <el-tag v-if="row.packageId === 0" type="danger">系统租户</el-tag>
  45. <el-tag v-else type="success"> {{ getPackageName(row.packageId) }} </el-tag>
  46. </template>
  47. <template #expireTime="{ row }">
  48. <span>{{ dayjs(row.expireTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  49. </template>
  50. <template #createTime="{ row }">
  51. <span>{{ dayjs(row.createTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
  52. </template>
  53. <template #action="{ row }">
  54. <!-- 操作:修改 -->
  55. <XTextButton
  56. preIcon="ep:edit"
  57. :title="t('action.edit')"
  58. v-hasPermi="['system:tenant:update']"
  59. @click="handleUpdate(row)"
  60. />
  61. <!-- 操作:详情 -->
  62. <XTextButton
  63. preIcon="ep:view"
  64. :title="t('action.detail')"
  65. v-hasPermi="['system:tenant:update']"
  66. @click="handleDetail(row)"
  67. />
  68. <!-- 操作:删除 -->
  69. <XTextButton
  70. preIcon="ep:delete"
  71. :title="t('action.del')"
  72. v-hasPermi="['system:tenant:delete']"
  73. @click="delList(row.id, false)"
  74. />
  75. </template>
  76. </Table>
  77. </ContentWrap>
  78. <XModal v-model="dialogVisible" :title="dialogTitle">
  79. <!-- 对话框(添加 / 修改) -->
  80. <Form
  81. v-if="['create', 'update'].includes(actionType)"
  82. :schema="allSchemas.formSchema"
  83. :rules="rules"
  84. ref="formRef"
  85. >
  86. <template #packageId>
  87. <el-select v-model="tenantPackageId">
  88. <el-option
  89. v-for="item in tenantPackageOptions"
  90. :key="item.id"
  91. :label="item.name"
  92. :value="item.id"
  93. />
  94. </el-select>
  95. </template>
  96. </Form>
  97. <!-- 对话框(详情) -->
  98. <Descriptions
  99. v-if="actionType === 'detail'"
  100. :schema="allSchemas.detailSchema"
  101. :data="detailRef"
  102. >
  103. <template #packageId="{ row }">
  104. <el-tag v-if="row.packageId === 0" type="danger">系统租户</el-tag>
  105. <el-tag v-else type="success"> {{ getPackageName(row.packageId) }} </el-tag>
  106. </template>
  107. </Descriptions>
  108. <!-- 操作按钮 -->
  109. <template #footer>
  110. <!-- 按钮:保存 -->
  111. <XButton
  112. v-if="['create', 'update'].includes(actionType)"
  113. type="primary"
  114. :title="t('action.save')"
  115. :loading="actionLoading"
  116. @click="submitForm()"
  117. />
  118. <!-- 按钮:关闭 -->
  119. <XButton :loading="actionLoading" :title="t('dialog.close')" @click="dialogVisible = false" />
  120. </template>
  121. </XModal>
  122. </template>
  123. <script setup lang="ts">
  124. import { ref, unref, onMounted } from 'vue'
  125. import dayjs from 'dayjs'
  126. import { ElMessage, ElTag, ElSelect, ElOption } from 'element-plus'
  127. import { DICT_TYPE } from '@/utils/dict'
  128. import { useTable } from '@/hooks/web/useTable'
  129. import { useI18n } from '@/hooks/web/useI18n'
  130. import { FormExpose } from '@/components/Form'
  131. import type { TenantVO } from '@/api/system/tenant/types'
  132. import { rules, allSchemas } from './tenant.data'
  133. import * as TenantApi from '@/api/system/tenant'
  134. import { getTenantPackageList } from '@/api/system/tenantPackage'
  135. import { TenantPackageVO } from '@/api/system/tenantPackage/types'
  136. const { t } = useI18n() // 国际化
  137. // ========== 列表相关 ==========
  138. const { register, tableObject, methods } = useTable<TenantVO>({
  139. getListApi: TenantApi.getTenantPageApi,
  140. delListApi: TenantApi.deleteTenantApi,
  141. exportListApi: TenantApi.exportTenantApi
  142. })
  143. const { getList, setSearchParams, delList, exportList } = methods
  144. // ========== 套餐 ==========
  145. const tenantPackageId = ref() // 套餐
  146. const tenantPackageOptions = ref<TenantPackageVO[]>([]) //套餐列表
  147. const getTenantPackageOptions = async () => {
  148. const res = await getTenantPackageList()
  149. tenantPackageOptions.value.push(...res)
  150. }
  151. const getPackageName = (packageId: number) => {
  152. for (let item of tenantPackageOptions.value) {
  153. if (item.id === packageId) {
  154. return item.name
  155. }
  156. }
  157. return '未知套餐'
  158. }
  159. // ========== CRUD 相关 ==========
  160. const actionLoading = ref(false) // 遮罩层
  161. const actionType = ref('') // 操作按钮的类型
  162. const dialogVisible = ref(false) // 是否显示弹出层
  163. const dialogTitle = ref('edit') // 弹出层标题
  164. const formRef = ref<FormExpose>() // 表单 Ref
  165. // 设置标题
  166. const setDialogTile = (type: string) => {
  167. dialogTitle.value = t('action.' + type)
  168. actionType.value = type
  169. dialogVisible.value = true
  170. }
  171. // 新增操作
  172. const handleCreate = () => {
  173. // 重置表单
  174. tenantPackageId.value = ''
  175. setDialogTile('create')
  176. }
  177. // 修改操作
  178. const handleUpdate = async (row: any) => {
  179. setDialogTile('update')
  180. // 设置数据
  181. const res = await TenantApi.getTenantApi(row.id)
  182. tenantPackageId.value = res.packageId
  183. res.expireTime = dayjs(res.expireTime).format('YYYY-MM-DD HH:mm:ss')
  184. unref(formRef)?.setValues(res)
  185. }
  186. // 提交按钮
  187. const submitForm = async () => {
  188. const elForm = unref(formRef)?.getElFormRef()
  189. if (!elForm) return
  190. elForm.validate(async (valid) => {
  191. if (valid) {
  192. actionLoading.value = true
  193. // 提交请求
  194. try {
  195. const data = unref(formRef)?.formModel as TenantVO
  196. data.packageId = tenantPackageId.value
  197. if (actionType.value === 'create') {
  198. data.expireTime = dayjs(data.expireTime).valueOf().toString()
  199. await TenantApi.createTenantApi(data)
  200. ElMessage.success(t('common.createSuccess'))
  201. } else {
  202. data.expireTime = dayjs(data.expireTime).valueOf().toString()
  203. await TenantApi.updateTenantApi(data)
  204. ElMessage.success(t('common.updateSuccess'))
  205. }
  206. // 操作成功,重新加载列表
  207. dialogVisible.value = false
  208. await getList()
  209. } finally {
  210. actionLoading.value = false
  211. }
  212. }
  213. })
  214. }
  215. // ========== 详情相关 ==========
  216. const detailRef = ref() // 详情 Ref
  217. // 详情操作
  218. const handleDetail = async (row: any) => {
  219. // 设置数据
  220. detailRef.value = row
  221. setDialogTile('detail')
  222. }
  223. // ========== 初始化 ==========
  224. onMounted(async () => {
  225. await getList()
  226. await getTenantPackageOptions()
  227. })
  228. </script>