Bläddra i källkod

feat(系统模块-租户管理): 租户管理添加绑定用户和订阅套餐功能

shizhongming 2 år sedan
förälder
incheckning
5e198de9c6

+ 59 - 0
src/modules/smart-system/views/tenant/tenantManager/SysTenantListView.api.ts

@@ -11,6 +11,12 @@ enum Api {
   listNoBindUser = '/sys/tenant/manager/listNoBindUser',
   bindTenantUser = '/sys/tenant/manager/bindTenantUser',
   removeBindUser = '/sys/tenant/manager/removeBindUser',
+
+  listSubscribe = '/sys/tenant/subscribe/listWithPackage',
+  setSubscribeUseYn = '/sys/tenant/subscribe/setUseYn',
+  getSubscribeById = '/sys/tenant/subscribe/getById',
+  batchSaveUpdateSubscribe = '/sys/tenant/subscribe/saveUpdateBatch',
+  listNoBindPackageByTenantId = '/sys/tenant/manager/listNoBindPackageByTenantId',
 }
 
 export const listApi = (params) => {
@@ -104,3 +110,56 @@ export const removeBindUserApi = (data) => {
     data,
   });
 };
+
+export const listSubscribeApi = (params) => {
+  return defHttp.post({
+    service: ApiServiceEnum.SMART_SYSTEM,
+    url: Api.listSubscribe,
+    data: {
+      ...params,
+    },
+  });
+};
+
+export const setSubscribeUseYnApi = (rows: any[], useYn: boolean) => {
+  return defHttp.post({
+    service: ApiServiceEnum.SMART_SYSTEM,
+    url: Api.setSubscribeUseYn,
+    data: {
+      idList: rows.map((item) => item.id),
+      useYn,
+    },
+  });
+};
+
+export const getSubscribeByIdApi = (id: number) => {
+  return defHttp.post({
+    service: ApiServiceEnum.SMART_SYSTEM,
+    url: Api.getSubscribeById,
+    data: id,
+  });
+};
+
+/**
+ * 根据租户ID查询没有绑定的套餐
+ * @param data
+ */
+export const listNoBindPackageByTenantIdApi = (data) => {
+  return defHttp.post({
+    service: ApiServiceEnum.SMART_SYSTEM,
+    url: Api.listNoBindPackageByTenantId,
+    data,
+  });
+};
+
+/**
+ * 根据租户ID查询没有绑定的套餐
+ * @param data
+ */
+export const batchSaveUpdateSubscribeApi = (data: Recordable) => {
+  return defHttp.post({
+    service: ApiServiceEnum.SMART_SYSTEM,
+    url: Api.batchSaveUpdateSubscribe,
+    data,
+  });
+};

+ 190 - 0
src/modules/smart-system/views/tenant/tenantManager/SysTenantListView.config.ts

@@ -3,11 +3,17 @@ import type { FormSchema } from '@/components/Form';
 import { tableUseYnClass } from '@/components/SmartTable';
 import { Ref, unref } from 'vue';
 
+import { listNoBindPackageByTenantIdApi } from './SysTenantListView.api';
+
 export enum Permission {
   save = 'sys:tenant:manager:save',
   update = 'sys:tenant:manager:update',
   delete = 'sys:tenant:manager:delete',
   useYn = 'sys:tenant:manager:setUseYn',
+  bindUser = 'sys:tenant:manager:bindUser',
+  subscribeAddUpdate = 'sys:tenant:manager:subscribe:addUpdate',
+  subscribeDelete = 'sys:tenant:manager:subscribe:delete',
+  subscribeSetUseYn = 'sys:tenant:manager:subscribe:setUseYn',
 }
 
 export const SYSTEM_TENANT_TYPE_DICT = 'SYSTEM_TENANT_TYPE';
@@ -433,3 +439,187 @@ export const getBindUserModalListColumns = (): SmartColumn[] => {
     },
   ];
 };
+
+export const getSubscribeTableColumns = (): SmartColumn[] => {
+  return [
+    {
+      type: 'checkbox',
+      width: 60,
+      align: 'center',
+      fixed: 'left',
+      field: 'checkbox',
+    },
+    {
+      field: 'packageId',
+      title: '{system.views.tenant.manager.title.subscribe.packageId}',
+      width: 200,
+      formatter({ row }) {
+        const tenantPackage = row.tenantPackage;
+        if (!tenantPackage) {
+          return '';
+        }
+        return `${tenantPackage.packageCode || ''} - ${tenantPackage.packageName || ''}`;
+      },
+    },
+    {
+      field: 'effectTime',
+      sortable: true,
+      title: '{system.views.tenant.manager.title.subscribe.effectTime}',
+      width: 165,
+    },
+    {
+      field: 'expireTime',
+      sortable: true,
+      title: '{system.views.tenant.manager.title.subscribe.expireTime}',
+      width: 165,
+    },
+    {
+      field: 'remark',
+      title: '{common.table.remark}',
+      minWidth: 200,
+    },
+    {
+      field: 'userNumber',
+      sortable: true,
+      title: '{system.views.tenant.manager.title.subscribe.userNumber}',
+      width: 120,
+    },
+    {
+      ...tableUseYnClass(),
+      width: 120,
+    },
+    {
+      field: 'createTime',
+      title: '{common.table.createTime}',
+      width: 165,
+    },
+    {
+      field: 'createBy',
+      title: '{common.table.createUser}',
+      width: 120,
+    },
+    {
+      field: 'updateTime',
+      title: '{common.table.updateTime}',
+      width: 165,
+    },
+    {
+      field: 'updateBy',
+      title: '{common.table.updateUser}',
+      width: 120,
+    },
+  ];
+};
+
+/**
+ * 添加修改表单
+ */
+export const getSubscribeFormSchemas = (t: Function, tenantIdRef: Ref): FormSchema[] => {
+  return [
+    {
+      field: 'id',
+      label: t('system.views.tenant.manager.title.subscribe.id'),
+      component: 'Input',
+      show: false,
+      componentProps: {},
+    },
+    {
+      field: 'isAdd',
+      label: '',
+      component: 'Switch',
+      show: false,
+    },
+    {
+      field: 'packageId',
+      label: t('system.views.tenant.manager.title.subscribe.packageId'),
+      component: 'SmartPulldownTable',
+      dynamicDisabled({ model }) {
+        const isAdd = model.isAdd;
+        return isAdd === false;
+      },
+      componentProps: () => {
+        return {
+          alwaysLoad: true,
+          transfer: true,
+          showFunction: (row) => `${row.packageCode}-${row.packageName}`,
+          valueField: 'id',
+          tableProps: {
+            border: true,
+            columns: [
+              {
+                field: 'packageCode',
+                sortable: true,
+                title: '{system.views.tenant.package.title.packageCode}',
+                width: 120,
+              },
+              {
+                field: 'packageName',
+                title: '{system.views.tenant.package.title.packageName}',
+                width: 120,
+              },
+              {
+                field: 'effectTime',
+                sortable: true,
+                title: '{system.views.tenant.package.title.effectTime}',
+                width: 165,
+              },
+              {
+                field: 'expireTime',
+                sortable: true,
+                title: '{system.views.tenant.package.title.expireTime}',
+                width: 165,
+              },
+              {
+                field: 'remark',
+                title: '{common.table.remark}',
+                minWidth: 120,
+              },
+              {
+                ...tableUseYnClass(),
+                width: 120,
+              },
+            ],
+            proxyConfig: {
+              ajax: {
+                async query({ ajaxParameter }) {
+                  const tenantId = unref(tenantIdRef);
+                  if (!tenantId) {
+                    return [];
+                  }
+                  return listNoBindPackageByTenantIdApi({
+                    ...ajaxParameter,
+                    id: tenantId,
+                  });
+                },
+              },
+            },
+          },
+        };
+      },
+    },
+    {
+      field: 'times',
+      label: t('system.views.tenant.manager.title.subscribe.effectTime'),
+      component: 'RangePicker',
+      componentProps: {
+        showTime: true,
+      },
+      required: true,
+    },
+
+    {
+      field: 'userNumber',
+      label: t('system.views.tenant.manager.title.subscribe.userNumber'),
+      component: 'InputNumber',
+      componentProps: {},
+      required: true,
+      defaultValue: 1000,
+    },
+    {
+      field: 'remark',
+      label: t('common.table.remark'),
+      component: 'InputTextArea',
+      componentProps: {},
+    },
+  ];
+};

+ 6 - 25
src/modules/smart-system/views/tenant/tenantManager/SysTenantListView.vue

@@ -20,11 +20,12 @@
           <a-tab-pane key="user" :tab="t('system.views.tenant.manager.title.tabUser')">
             <TenantUserList :tenant-id="currentTenantRef?.id" />
           </a-tab-pane>
-          <a-tab-pane key="subscribe" :tab="t('system.views.tenant.manager.title.tabSubscribe')" />
+          <a-tab-pane key="subscribe" :tab="t('system.views.tenant.manager.title.tabSubscribe')">
+            <TenantSubscribeList :tenant-id="currentTenantRef?.id" />
+          </a-tab-pane>
         </a-tabs>
       </template>
     </SmartLayoutSeparate>
-    <TenantSetPackageModal @register="registerSetPackageModal" />
   </div>
 </template>
 
@@ -34,7 +35,6 @@
   import { useSizeSetting } from '@/hooks/setting/UseSizeSetting';
 
   import { SmartTable, useSmartTable } from '@/components/SmartTable';
-  import { useModal } from '@/components/Modal';
 
   import {
     getFormSchemas,
@@ -53,20 +53,17 @@
   } from './SysTenantListView.api';
   import { useInjectPageDict } from '@/components/SmartPageProvider';
   import { computed, onMounted, ref, unref } from 'vue';
-  import { warnMessage } from '@/utils/message/SystemNotice';
   import { SmartLayoutSeparate } from '@/components/SmartLayoutSeparate';
   import { useDesign } from '@/hooks/web/useDesign';
 
-  import TenantSetPackageModal from './components/TenantSetPackageModal.vue';
   import TenantUserList from './components/TenantUserList.vue';
+  import TenantSubscribeList from './components/TenantSubscribeList.vue';
 
   const { prefixCls } = useDesign('system-tenant-manager');
 
   const { t } = useI18n();
   const { getTableSize } = useSizeSetting();
 
-  const [registerSetPackageModal, { openModal }] = useModal();
-
   const isolationStrategyListRef = ref<any[]>([]);
   const computedIsolationStrategyMap = computed(() => {
     return mapValues(keyBy(unref(isolationStrategyListRef), 'value'), 'label');
@@ -81,12 +78,12 @@
   });
   onMounted(() => pageDictRegister(SYSTEM_TENANT_TYPE_DICT));
 
-  const currentTenantRef = ref(null);
+  const currentTenantRef = ref<Recordable | null>(null);
   const handleCurrentChange = ({ row }) => {
     currentTenantRef.value = row;
   };
 
-  const [registerTable, { getCheckboxRecords }] = useSmartTable({
+  const [registerTable] = useSmartTable({
     id: 'system-tenant-manager',
     columns: getTableColumns(),
     height: 'auto',
@@ -170,22 +167,6 @@
           code: 'useYnFalse',
           auth: Permission.useYn,
         },
-        {
-          name: t('system.views.tenant.manager.title.setPackage'),
-          customRender: 'ant',
-          props: {
-            preIcon: 'ant-design:setting-outlined',
-            type: 'primary',
-            onClick: () => {
-              const selectRows = getCheckboxRecords();
-              if (!selectRows || selectRows.length !== 1) {
-                warnMessage(t('system.views.tenant.manager.message.selectOneRow'));
-                return false;
-              }
-              openModal(true, { tenantId: selectRows[0].id });
-            },
-          },
-        },
       ],
     },
   });

+ 0 - 21
src/modules/smart-system/views/tenant/tenantManager/components/TenantSetPackageModal.vue

@@ -1,21 +0,0 @@
-<template>
-  <BasicModal @register="registerModal" :title="t('system.views.tenant.manager.title.setPackage')">
-    <div></div>
-  </BasicModal>
-</template>
-
-<script setup lang="ts">
-  import { BasicModal, useModalInner } from '@/components/Modal';
-  import { ref } from 'vue';
-  import { useI18n } from '@/hooks/web/useI18n';
-
-  const { t } = useI18n();
-
-  const tenantIdRef = ref<number | null>(null);
-
-  const [registerModal] = useModalInner(({ tenantId }) => {
-    tenantIdRef.value = tenantId;
-  });
-</script>
-
-<style lang="less"></style>

+ 136 - 0
src/modules/smart-system/views/tenant/tenantManager/components/TenantSubscribeList.vue

@@ -0,0 +1,136 @@
+<template>
+  <div class="full-height">
+    <SmartTable @register="registerTable" :size="getTableSize" />
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { useSizeSetting } from '@/hooks/setting/UseSizeSetting';
+  import { useI18n } from '@/hooks/web/useI18n';
+  import { SmartTable, useSmartTable } from '@/components/SmartTable';
+
+  import {
+    getSubscribeTableColumns,
+    Permission,
+    getSubscribeFormSchemas,
+  } from '../SysTenantListView.config';
+  import {
+    listSubscribeApi,
+    setSubscribeUseYnApi,
+    getSubscribeByIdApi,
+    batchSaveUpdateSubscribeApi,
+  } from '../SysTenantListView.api';
+  import { propTypes } from '@/utils/propTypes';
+  import { computed, toRefs, unref, watch } from 'vue';
+  import { hasPermission } from '@/utils/auth';
+
+  const props = defineProps({
+    tenantId: propTypes.number,
+  });
+  const { tenantId: tenantIdRef } = toRefs(props);
+  watch(tenantIdRef, () => query());
+  const computedChoseTenant = computed(() => props.tenantId !== undefined);
+
+  const { t } = useI18n();
+  const { getTableSize } = useSizeSetting();
+
+  const [registerTable, { query }] = useSmartTable({
+    id: 'system-tenant-manager-subscribeList',
+    columns: getSubscribeTableColumns(),
+    height: 'auto',
+    customConfig: { storage: true },
+    stripe: true,
+    border: true,
+    sortConfig: {
+      remote: true,
+    },
+    showOverflow: 'tooltip',
+    rowConfig: {
+      isHover: true,
+      isCurrent: true,
+    },
+    columnConfig: {
+      resizable: true,
+    },
+    pagerConfig: false,
+    addEditConfig: {
+      formConfig: {
+        schemas: getSubscribeFormSchemas(t, tenantIdRef),
+        colon: true,
+        baseColProps: { span: 24 },
+        labelCol: { span: 6 },
+        wrapperCol: { span: 17 },
+      },
+    },
+    proxyConfig: {
+      ajax: {
+        query: async (params) => {
+          const tenantId = props.tenantId;
+          if (!tenantId) {
+            return [];
+          }
+          return listSubscribeApi({
+            ...params.ajaxParameter,
+            tenantId,
+          });
+        },
+        save: ({ body: { insertRecords, updateRecords } }) => {
+          const dataList = [...insertRecords, ...updateRecords];
+          dataList.forEach((item) => {
+            const times = item.times as Array<Date> | undefined;
+            if (times && times.length > 0) {
+              item.effectTime = times[0];
+              item.expireTime = times[1];
+            }
+            item.tenantId = props.tenantId;
+          });
+          return batchSaveUpdateSubscribeApi(dataList);
+        },
+        getById: async (params) => {
+          const data = await getSubscribeByIdApi(params.id);
+          if (data && data.effectTime && data.expireTime) {
+            data.times = [data.effectTime, data.expireTime];
+          }
+          return data;
+        },
+        useYn: setSubscribeUseYnApi,
+      },
+    },
+    toolbarConfig: {
+      zoom: true,
+      refresh: true,
+      column: {
+        columnOrder: true,
+      },
+      buttons: [
+        {
+          code: 'ModalAdd',
+          props: computed(() => {
+            return {
+              disabled:
+                !unref(computedChoseTenant) || !hasPermission(Permission.subscribeAddUpdate),
+            };
+          }),
+        },
+        {
+          code: 'ModalEdit',
+          auth: Permission.subscribeAddUpdate,
+        },
+        {
+          code: 'delete',
+          auth: Permission.subscribeDelete,
+        },
+        {
+          code: 'useYnTrue',
+          auth: Permission.subscribeSetUseYn,
+        },
+        {
+          code: 'useYnFalse',
+          auth: Permission.subscribeSetUseYn,
+        },
+      ],
+    },
+  });
+</script>
+
+<style scoped lang="less"></style>

+ 8 - 3
src/modules/smart-system/views/tenant/tenantManager/components/TenantUserList.vue

@@ -12,11 +12,16 @@
   import { useSizeSetting } from '@/hooks/setting/UseSizeSetting';
   import { useModal } from '@/components/Modal';
 
-  import { getTabUserListColumns, getTabUserListSearchSchemas } from '../SysTenantListView.config';
+  import {
+    getTabUserListColumns,
+    getTabUserListSearchSchemas,
+    Permission,
+  } from '../SysTenantListView.config';
   import { listTenantUserApi, removeBindUserApi } from '../SysTenantListView.api';
   import { useDesign } from '@/hooks/web/useDesign';
   import { useI18n } from '@/hooks/web/useI18n';
   import TenantAddUserModal from './TenantAddUserModal.vue';
+  import { hasPermission } from '@/utils/auth';
 
   const props = defineProps({
     tenantId: propTypes.number,
@@ -98,7 +103,7 @@
           props: computed(() => {
             return {
               onClick: () => openAddUserModal(true, { tenantId: props.tenantId }),
-              disabled: !unref(computedChoseTenant),
+              disabled: !unref(computedChoseTenant) || !hasPermission(Permission.bindUser),
             };
           }),
         },
@@ -106,7 +111,7 @@
           code: 'delete',
           props: computed(() => {
             return {
-              disabled: !unref(computedChoseTenant),
+              disabled: !unref(computedChoseTenant) || !hasPermission(Permission.bindUser),
             };
           }),
         },

+ 7 - 0
src/modules/smart-system/views/tenant/tenantManager/lang/zh_CN.ts

@@ -33,6 +33,13 @@ export default {
         bindTime: '绑定时间',
         bindBy: '绑定人',
       },
+      subscribe: {
+        tenantId: '租户',
+        packageId: '套餐包',
+        effectTime: '生效日期',
+        expireTime: '失效日期',
+        userNumber: '用户数',
+      },
     },
     validate: {
       tenantCode: '请输入租户编号',

+ 1 - 0
src/modules/smart-system/views/tenant/tenantPackage/SysTenantPackageListView.config.ts

@@ -117,6 +117,7 @@ export const getFormSchemas = (t: Function): FormSchema[] => {
       componentProps: {
         showTime: true,
       },
+      required: true,
     },
     {
       field: 'seq',