Browse Source

Vue3 重构:REVIEW 租户管理

YunaiV 2 năm trước cách đây
mục cha
commit
7c92735aff

+ 6 - 6
src/api/system/tenant/index.ts

@@ -32,31 +32,31 @@ export interface TenantExportReqVO {
 }
 
 // 查询租户列表
-export const getTenantPageApi = (params: TenantPageReqVO) => {
+export const getTenantPage = (params: TenantPageReqVO) => {
   return request.get({ url: '/system/tenant/page', params })
 }
 
 // 查询租户详情
-export const getTenantApi = (id: number) => {
+export const getTenant = (id: number) => {
   return request.get({ url: '/system/tenant/get?id=' + id })
 }
 
 // 新增租户
-export const createTenantApi = (data: TenantVO) => {
+export const createTenant = (data: TenantVO) => {
   return request.post({ url: '/system/tenant/create', data })
 }
 
 // 修改租户
-export const updateTenantApi = (data: TenantVO) => {
+export const updateTenant = (data: TenantVO) => {
   return request.put({ url: '/system/tenant/update', data })
 }
 
 // 删除租户
-export const deleteTenantApi = (id: number) => {
+export const deleteTenant = (id: number) => {
   return request.delete({ url: '/system/tenant/delete?id=' + id })
 }
 
 // 导出租户
-export const exportTenantApi = (params: TenantExportReqVO) => {
+export const exportTenant = (params: TenantExportReqVO) => {
   return request.download({ url: '/system/tenant/export-excel', params })
 }

+ 69 - 97
src/views/system/tenant/form.vue

@@ -7,96 +7,67 @@
       label-width="80px"
       v-loading="formLoading"
     >
-      <el-row>
-        <el-col :span="10">
-          <el-form-item label="租户名" prop="name">
-            <el-input v-model="formData.name" placeholder="请输入租户名" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="10" :offset="2">
-          <el-form-item label="租户套餐" prop="packageId">
-            <el-select v-model="formData.packageId" placeholder="请选择租户套餐" clearable>
-              <el-option
-                v-for="item in packageList"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col :span="10">
-          <el-form-item label="联系人" prop="contactName">
-            <el-input v-model="formData.contactName" placeholder="请输入联系人" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="10" :offset="2">
-          <el-form-item label="联系手机" prop="contactMobile">
-            <el-input v-model="formData.contactMobile" placeholder="请输入联系手机" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col :span="10">
-          <el-form-item v-if="formData.id === undefined" label="用户名称" prop="username">
-            <el-input v-model="formData.username" placeholder="请输入用户名称" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="10" :offset="2">
-          <el-form-item v-if="formData.id === undefined" label="用户密码" prop="password">
-            <el-input
-              v-model="formData.password"
-              placeholder="请输入用户密码"
-              type="password"
-              show-password
-            />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col :span="10">
-          <el-form-item label="账号额度" prop="accountCount">
-            <el-input-number
-              v-model="formData.accountCount"
-              placeholder="请输入账号额度"
-              controls-position="right"
-              :min="0"
-            />
-          </el-form-item>
-        </el-col>
-        <el-col :span="10" :offset="2">
-          <el-form-item label="过期时间" prop="expireTime">
-            <el-date-picker
-              clearable
-              v-model="formData.expireTime"
-              type="date"
-              value-format="x"
-              placeholder="请选择过期时间"
-            />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col :span="10">
-          <el-form-item label="绑定域名" prop="domain">
-            <el-input v-model="formData.domain" placeholder="请输入绑定域名" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="10" :offset="2">
-          <el-form-item label="租户状态" prop="status">
-            <el-radio-group v-model="formData.status">
-              <el-radio
-                v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
-                :key="dict.value"
-                :label="dict.value"
-                >{{ dict.label }}
-              </el-radio>
-            </el-radio-group>
-          </el-form-item>
-        </el-col>
-      </el-row>
+      <el-form-item label="租户名" prop="name">
+        <el-input v-model="formData.name" placeholder="请输入租户名" />
+      </el-form-item>
+      <el-form-item label="租户套餐" prop="packageId">
+        <el-select v-model="formData.packageId" placeholder="请选择租户套餐" clearable>
+          <el-option
+            v-for="item in packageList"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="联系人" prop="contactName">
+        <el-input v-model="formData.contactName" placeholder="请输入联系人" />
+      </el-form-item>
+      <el-form-item label="联系手机" prop="contactMobile">
+        <el-input v-model="formData.contactMobile" placeholder="请输入联系手机" />
+      </el-form-item>
+      <el-form-item v-if="formData.id === undefined" label="用户名称" prop="username">
+        <el-input v-model="formData.username" placeholder="请输入用户名称" />
+      </el-form-item>
+      <el-form-item v-if="formData.id === undefined" label="用户密码" prop="password">
+        <el-input
+          v-model="formData.password"
+          placeholder="请输入用户密码"
+          type="password"
+          show-password
+        />
+      </el-form-item>
+      <el-form-item label="账号额度" prop="accountCount">
+        <el-input-number
+          v-model="formData.accountCount"
+          placeholder="请输入账号额度"
+          controls-position="right"
+          :min="0"
+        />
+      </el-form-item>
+      <el-form-item label="过期时间" prop="expireTime">
+        <el-date-picker
+          clearable
+          v-model="formData.expireTime"
+          type="date"
+          value-format="x"
+          placeholder="请选择过期时间"
+        />
+      </el-form-item>
+      <el-form-item label="绑定域名" prop="domain">
+        <el-input v-model="formData.domain" placeholder="请输入绑定域名" />
+      </el-form-item>
+      <el-form-item label="租户状态" prop="status">
+        <el-radio-group v-model="formData.status">
+          <el-radio
+            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
+            :key="dict.value"
+            :label="dict.value"
+          >
+            {{ dict.label }}
+          </el-radio>
+        </el-radio-group>
+      </el-form-item>
     </el-form>
     <template #footer>
       <div class="dialog-footer">
@@ -110,7 +81,7 @@
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import * as TenantApi from '@/api/system/tenant'
 import { CommonStatusEnum } from '@/utils/constants'
-import { getTenantPackageList as getTenantPackageListApi } from '@/api/system/tenantPackage'
+import * as TenantPackageApi from '@/api/system/tenantPackage'
 
 const { t } = useI18n() // 国际化
 const message = useMessage() // 消息弹窗
@@ -142,7 +113,7 @@ const formRef = ref() // 表单 Ref
 const packageList = ref([]) // 租户套餐
 
 /** 打开弹窗 */
-const openModal = async (type: string, id?: number) => {
+const open = async (type: string, id?: number) => {
   modelVisible.value = true
   modelTitle.value = t('action.' + type)
   formType.value = type
@@ -151,14 +122,15 @@ const openModal = async (type: string, id?: number) => {
   if (id) {
     formLoading.value = true
     try {
-      formData.value = await TenantApi.getTenantApi(id)
+      formData.value = await TenantApi.getTenant(id)
     } finally {
       formLoading.value = false
     }
   }
-  packageList.value = await getTenantPackageListApi()
+  // 加载套餐列表
+  packageList.value = await TenantPackageApi.getTenantPackageList()
 }
-defineExpose({ openModal }) // 提供 openModal 方法,用于打开弹窗
+defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 
 /** 提交表单 */
 const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
@@ -172,10 +144,10 @@ const submitForm = async () => {
   try {
     const data = formData.value as unknown as TenantApi.TenantVO
     if (formType.value === 'create') {
-      await TenantApi.createTenantApi(data)
+      await TenantApi.createTenant(data)
       message.success(t('common.createSuccess'))
     } else {
-      await TenantApi.updateTenantApi(data)
+      await TenantApi.updateTenant(data)
       message.success(t('common.updateSuccess'))
     }
     modelVisible.value = false

+ 39 - 37
src/views/system/tenant/index.vue

@@ -1,13 +1,20 @@
 <template>
   <!-- 搜索 -->
-  <content-wrap>
-    <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true">
+  <ContentWrap>
+    <el-form
+      class="-mb-15px"
+      :model="queryParams"
+      ref="queryFormRef"
+      :inline="true"
+      label-width="68px"
+    >
       <el-form-item label="租户名" prop="name">
         <el-input
           v-model="queryParams.name"
           placeholder="请输入租户名"
           clearable
           @keyup.enter="handleQuery"
+          class="!w-240px"
         />
       </el-form-item>
       <el-form-item label="联系人" prop="contactName">
@@ -16,6 +23,7 @@
           placeholder="请输入联系人"
           clearable
           @keyup.enter="handleQuery"
+          class="!w-240px"
         />
       </el-form-item>
       <el-form-item label="联系手机" prop="contactMobile">
@@ -24,12 +32,18 @@
           placeholder="请输入联系手机"
           clearable
           @keyup.enter="handleQuery"
+          class="!w-240px"
         />
       </el-form-item>
       <el-form-item label="租户状态" prop="status">
-        <el-select v-model="queryParams.status" placeholder="请选择租户状态" clearable>
+        <el-select
+          v-model="queryParams.status"
+          placeholder="请选择租户状态"
+          clearable
+          class="!w-240px"
+        >
           <el-option
-            v-for="dict in getDictOptions(DICT_TYPE.COMMON_STATUS)"
+            v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
             :key="dict.value"
             :label="dict.label"
             :value="dict.value"
@@ -41,10 +55,10 @@
           v-model="queryParams.createTime"
           value-format="YYYY-MM-DD HH:mm:ss"
           type="daterange"
-          range-separator="-"
           start-placeholder="开始日期"
           end-placeholder="结束日期"
           :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
+          class="!w-240px"
         />
       </el-form-item>
 
@@ -57,11 +71,7 @@
           <Icon icon="ep:refresh" class="mr-5px" />
           重置
         </el-button>
-        <el-button
-          type="primary"
-          @click="openModal('create')"
-          v-hasPermi="['system:tenant:create']"
-        >
+        <el-button type="primary" @click="openForm('create')" v-hasPermi="['system:tenant:create']">
           <Icon icon="ep:plus" class="mr-5px" />
           新增
         </el-button>
@@ -77,10 +87,10 @@
         </el-button>
       </el-form-item>
     </el-form>
-  </content-wrap>
+  </ContentWrap>
 
   <!-- 列表 -->
-  <content-wrap>
+  <ContentWrap>
     <el-table v-loading="loading" :data="list" align="center">
       <el-table-column label="租户编号" align="center" prop="id" />
       <el-table-column label="租户名" align="center" prop="name" />
@@ -126,7 +136,7 @@
           <el-button
             link
             type="primary"
-            @click="openModal('update', scope.row.id)"
+            @click="openForm('update', scope.row.id)"
             v-hasPermi="['system:tenant:update']"
           >
             编辑
@@ -149,20 +159,18 @@
       v-model:limit="queryParams.pageSize"
       @pagination="getList"
     />
-  </content-wrap>
+  </ContentWrap>
 
   <!-- 表单弹窗:添加/修改 -->
-  <tenant-form ref="modalRef" @success="getList" />
+  <TenantForm ref="formRef" @success="getList" />
 </template>
 <script setup lang="ts" name="Tenant">
-import { DICT_TYPE, getDictOptions } from '@/utils/dict'
+import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
 import download from '@/utils/download'
 import * as TenantApi from '@/api/system/tenant'
-import { getTenantPackageList as getTenantPackageListApi } from '@/api/system/tenantPackage'
+import * as TenantPackageApi from '@/api/system/tenantPackage'
 import TenantForm from './form.vue'
-import ContentWrap from '@/components/ContentWrap/src/ContentWrap.vue'
-import DictTag from '@/components/DictTag/src/DictTag.vue'
 
 const message = useMessage() // 消息弹窗
 const { t } = useI18n() // 国际化
@@ -170,7 +178,6 @@ const { t } = useI18n() // 国际化
 const loading = ref(true) // 列表的加载中
 const total = ref(0) // 列表的总页数
 const list = ref([]) // 列表的数据
-const packageList = ref([]) //租户套餐列表
 const queryParams = reactive({
   pageNo: 1,
   pageSize: 10,
@@ -179,15 +186,16 @@ const queryParams = reactive({
   contactMobile: undefined,
   status: undefined,
   createTime: []
-}) //查询参数对象
+})
 const queryFormRef = ref() // 搜索的表单
 const exportLoading = ref(false) // 导出的加载中
+const packageList = ref([]) //租户套餐列表
 
 /** 查询参数列表 */
 const getList = async () => {
   loading.value = true
   try {
-    const data = await TenantApi.getTenantPageApi(queryParams)
+    const data = await TenantApi.getTenantPage(queryParams)
     list.value = data.list
     total.value = data.total
   } finally {
@@ -208,9 +216,9 @@ const resetQuery = () => {
 }
 
 /** 添加/修改操作 */
-const modalRef = ref()
-const openModal = (type: string, id?: number) => {
-  modalRef.value.openModal(type, id)
+const formRef = ref()
+const openForm = (type: string, id?: number) => {
+  formRef.value.open(type, id)
 }
 
 /** 删除按钮操作 */
@@ -219,7 +227,7 @@ const handleDelete = async (id: number) => {
     // 删除的二次确认
     await message.delConfirm()
     // 发起删除
-    await TenantApi.deleteTenantApi(id)
+    await TenantApi.deleteTenant(id)
     message.success(t('common.delSuccess'))
     // 刷新列表
     await getList()
@@ -233,23 +241,17 @@ const handleExport = async () => {
     await message.exportConfirm()
     // 发起导出
     exportLoading.value = true
-    const data = await TenantApi.exportTenantApi(queryParams)
-    download.excel(data, '参数配置.xls')
+    const data = await TenantApi.exportTenant(queryParams)
+    download.excel(data, '租户列表.xls')
   } catch {
   } finally {
     exportLoading.value = false
   }
 }
 
-/**获取租户套餐**/
-const getTenantPackageList = async () => {
-  const data = await getTenantPackageListApi()
-  packageList.value = data
-}
-
 /** 初始化 **/
-onMounted(() => {
-  getList()
-  getTenantPackageList()
+onMounted(async () => {
+  await getList()
+  packageList.value = await TenantPackageApi.getTenantPackageList()
 })
 </script>

+ 0 - 186
src/views/system/tenant/tenant.data.ts

@@ -1,186 +0,0 @@
-import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas'
-import { getTenantPackageList, TenantPackageVO } from '@/api/system/tenantPackage'
-import { ComponentOptions } from '@/types/components'
-
-const { t } = useI18n() // 国际化
-
-export const tenantPackageOption: ComponentOptions[] = []
-const getTenantPackageOptions = async () => {
-  const res = await getTenantPackageList()
-  res.forEach((tenantPackage: TenantPackageVO) => {
-    tenantPackageOption.push({
-      key: tenantPackage.id,
-      value: tenantPackage.id,
-      label: tenantPackage.name
-    })
-  })
-
-  return tenantPackageOption
-}
-getTenantPackageOptions()
-
-const validateName = (rule: any, value: any, callback: any) => {
-  const reg = /^[a-zA-Z0-9]{4,30}$/
-  if (value === '') {
-    callback(new Error('请输入用户名称'))
-  } else {
-    console.log(reg.test(rule), 'reg.test(rule)')
-    if (!reg.test(value)) {
-      callback(new Error('用户名称由 数字、字母 组成'))
-    } else {
-      callback()
-    }
-  }
-}
-const validateMobile = (rule: any, value: any, callback: any) => {
-  const reg = /^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/
-  if (value === '') {
-    callback(new Error('请输入联系手机'))
-  } else {
-    if (!reg.test(value)) {
-      callback(new Error('请输入正确的手机号'))
-    } else {
-      callback()
-    }
-  }
-}
-
-// 表单校验
-export const rules = reactive({
-  name: [required],
-  packageId: [required],
-  contactName: [required],
-  contactMobile: [
-    required,
-    {
-      validator: validateMobile,
-      trigger: 'blur'
-    }
-  ],
-  accountCount: [required],
-  expireTime: [required],
-  username: [
-    required,
-    {
-      min: 4,
-      max: 30,
-      trigger: 'blur',
-      message: '用户名称长度为 4-30 个字符'
-    },
-    { validator: validateName, trigger: 'blur' }
-  ],
-  password: [
-    required,
-    {
-      min: 4,
-      max: 16,
-      trigger: 'blur',
-      message: '密码长度为 4-16 位'
-    }
-  ],
-  domain: [required],
-  status: [required]
-})
-
-// CrudSchema.
-const crudSchemas = reactive<VxeCrudSchema>({
-  primaryKey: 'id',
-  primaryTitle: '租户编号',
-  primaryType: 'id',
-  action: true,
-  columns: [
-    {
-      title: '租户名称',
-      field: 'name',
-      isSearch: true
-    },
-    {
-      title: '租户套餐',
-      field: 'packageId',
-      table: {
-        slots: {
-          default: 'packageId_default'
-        }
-      },
-      form: {
-        component: 'Select',
-        componentProps: {
-          options: tenantPackageOption
-        }
-      }
-    },
-    {
-      title: '联系人',
-      field: 'contactName',
-      isSearch: true
-    },
-    {
-      title: '联系手机',
-      field: 'contactMobile',
-      isSearch: true
-    },
-    {
-      title: '用户名称',
-      field: 'username',
-      isTable: false,
-      isDetail: false
-    },
-    {
-      title: '用户密码',
-      field: 'password',
-      isTable: false,
-      isDetail: false,
-      form: {
-        component: 'InputPassword'
-      }
-    },
-    {
-      title: '账号额度',
-      field: 'accountCount',
-      table: {
-        slots: {
-          default: 'accountCount_default'
-        }
-      },
-      form: {
-        component: 'InputNumber'
-      }
-    },
-    {
-      title: '过期时间',
-      field: 'expireTime',
-      formatter: 'formatDate',
-      form: {
-        component: 'DatePicker',
-        componentProps: {
-          type: 'datetime',
-          valueFormat: 'x'
-        }
-      }
-    },
-    {
-      title: '绑定域名',
-      field: 'domain'
-    },
-    {
-      title: '租户状态',
-      field: 'status',
-      dictType: DICT_TYPE.COMMON_STATUS,
-      dictClass: 'number',
-      isSearch: true
-    },
-    {
-      title: t('table.createTime'),
-      field: 'createTime',
-      formatter: 'formatDate',
-      isForm: false,
-      search: {
-        show: true,
-        itemRender: {
-          name: 'XDataTimePicker'
-        }
-      }
-    }
-  ]
-})
-export const { allSchemas } = useVxeCrudSchemas(crudSchemas)