Эх сурвалжийг харах

fix(系统模块-国际化): 优化国际化分组功能

shizhongming 2 жил өмнө
parent
commit
467075a2ee

+ 39 - 0
src/api/sys/sysI18nApi.ts

@@ -0,0 +1,39 @@
+import { ApiServiceEnum, defHttp } from '@/utils/http/axios';
+import { isNull } from '@/utils/is';
+
+enum Api {
+  listFront = 'sys/i18n/listFront',
+}
+
+export const listFrontApi = async (locale: string) => {
+  const i18nData: Recordable<string> = await defHttp.post({
+    service: ApiServiceEnum.SMART_SYSTEM,
+    url: Api.listFront,
+    data: {
+      value: locale,
+    },
+  });
+  const result: Recordable = {};
+  if (isNull(i18nData)) {
+    return result;
+  }
+  Object.keys(i18nData).forEach((key) => {
+    const value = i18nData[key];
+    convertObject(result, key.split('.'), value);
+  });
+  return result;
+};
+
+const convertObject = (data: any, keyList: string[], value: string) => {
+  if (keyList.length > 0) {
+    if (keyList.length === 1) {
+      data[keyList[0]] = value;
+    } else {
+      const firstKey = keyList[0];
+      if (!data[firstKey]) {
+        data[firstKey] = {};
+      }
+      convertObject(data[firstKey], keyList.slice(1), value);
+    }
+  }
+};

+ 6 - 20
src/modules/system/views/i18n/I18nMainView.vue

@@ -3,10 +3,10 @@
     <a-layout class="full-height i18n-main-container">
       <a-layout-sider theme="light" width="300px" class="full-height i18n-group-container">
         <!--    国际化分组    -->
-        <I18nGroupList @current-change="({ row }) => (groupId = row.groupId)" />
+        <I18nGroupList @change="(id) => (groupId = id)" />
       </a-layout-sider>
       <a-layout>
-        <a-layout-content class="i18n-container" style=" margin-bottom: 2px;background: #f0f2f5">
+        <a-layout-content class="i18n-container" style="margin-bottom: 2px; background: #f0f2f5">
           <I18nList :group-id="groupId" @change="(id) => (i18nId = id)" />
         </a-layout-content>
         <a-layout-content class="i18n-item-container">
@@ -17,29 +17,15 @@
   </div>
 </template>
 
-<script lang="ts">
-  import { defineComponent, ref } from 'vue';
+<script lang="ts" setup>
+  import { ref } from 'vue';
 
   import I18nGroupList from './components/I18nGroupList.vue';
   import I18nList from './components/i18nList.vue';
   import I18nItemList from './components/I18nItemList.vue';
 
-  export default defineComponent({
-    name: 'I18nMainView',
-    components: {
-      I18nGroupList,
-      I18nList,
-      I18nItemList,
-    },
-    setup() {
-      const groupId = ref<number>();
-      const i18nId = ref<number>();
-      return {
-        groupId,
-        i18nId,
-      };
-    },
-  });
+  const groupId = ref<number | null>();
+  const i18nId = ref<number>();
 </script>
 
 <style lang="less" scoped>

+ 112 - 55
src/modules/system/views/i18n/components/I18nGroupList.vue

@@ -1,9 +1,9 @@
 <template>
   <div class="full-height" :class="prefixCls">
     <div class="table-container">
-      <SmartTable @register="registerTable" v-bind="$attrs">
+      <SmartTable @register="registerTable" v-bind="$attrs" @cell-click="handleCellClick">
         <template #table-groupName="{ row }">
-          <span @contextmenu="(e) => handleContext(e, row)">{{ row.groupName }}</span>
+          <div @contextmenu="(e) => handleContext(e, row)">{{ row.text }}</div>
         </template>
       </SmartTable>
     </div>
@@ -13,9 +13,9 @@
         class="button"
         block
         type="primary"
-        @click="() => showAddModal()"
+        @click="handleAdd"
       >
-        {{ $t('common.button.add') }}
+        {{ t('common.button.add') }}
       </a-button>
     </div>
   </div>
@@ -26,8 +26,16 @@
   import { useDesign } from '@/hooks/web/useDesign';
   import { useContextMenu } from '@/hooks/web/useContextMenu';
   import { useI18n } from '@/hooks/web/useI18n';
-  import { listGroupApi, getGroupByIdApi, saveUpdateGroupApi, deleteGroupApi } from './i18n.api';
+  import {
+    listGroupTreeApi,
+    getGroupByIdApi,
+    saveUpdateGroupApi,
+    deleteGroupApi,
+  } from './i18n.api';
   import { SystemPermissions } from '@/modules/system/constants/SystemConstants';
+  import { nextTick, ref, unref, watch } from 'vue';
+
+  const emit = defineEmits(['change']);
 
   const { t } = useI18n();
 
@@ -42,73 +50,122 @@
           label: t('common.button.edit'),
           icon: 'ant-design:edit-outlined',
           handler: () => {
-            editByRowModal(row);
+            editByRowModal(row.data);
           },
         },
         {
           label: t('common.button.delete'),
           icon: 'ant-design:delete-outlined',
           handler: () => {
-            deleteByRow(row);
+            deleteByRow(row.data);
           },
         },
       ],
     });
   };
 
-  const [registerTable, { editByRowModal, deleteByRow, showAddModal }] = useSmartTable({
-    size: 'small',
-    stripe: true,
-    rowConfig: { isCurrent: true },
-    height: 'auto',
-    cellClassName: 'cursor-pointer',
-    columns: [
-      {
-        title: '{system.views.i18n.group.groupName}',
-        field: 'groupName',
-        slots: {
-          default: 'table-groupName',
-        },
+  const currentRowRef = ref<any | null>(null);
+  const handleCellClick = ({ row }) => {
+    if (unref(currentRowRef)?.id === row.id) {
+      currentRowRef.value = null;
+    } else {
+      currentRowRef.value = row;
+    }
+    nextTick(() => {
+      if (unref(currentRowRef) == null) {
+        getTableInstance().clearCurrentRow();
+      } else {
+        getTableInstance().setCurrentRow(row);
+      }
+    });
+  };
+  watch(currentRowRef, () => emit('change', unref(currentRowRef)?.id));
+
+  /**
+   * 添加时间
+   */
+  const handleAdd = () => {
+    const currentRow = unref(currentRowRef);
+    const parentData =
+      currentRow == null
+        ? { parentId: 0, parentName: '根节点' }
+        : { parentId: currentRow.id, parentName: currentRow.text };
+    showAddModal(parentData);
+  };
+
+  const [registerTable, { editByRowModal, deleteByRow, showAddModal, getTableInstance }] =
+    useSmartTable({
+      size: 'small',
+      stripe: true,
+      rowConfig: { keyField: 'id', isCurrent: true },
+      height: 'auto',
+      treeConfig: {
+        reserve: true,
+        expandAll: true,
       },
-    ],
-    addEditConfig: {
-      formConfig: {
-        colon: true,
-        schemas: [
-          {
-            label: '',
-            component: 'Input',
-            field: 'groupId',
-            show: false,
-          },
-          {
-            label: t('system.views.i18n.group.groupName'),
-            component: 'Input',
-            field: 'groupName',
-            required: true,
-          },
-          {
-            label: t('system.views.i18n.group.seq'),
-            component: 'InputNumber',
-            field: 'seq',
-            defaultValue: 1,
-            required: true,
+      cellClassName: 'cursor-pointer',
+      columns: [
+        {
+          title: '{system.views.i18n.group.groupName}',
+          field: 'text',
+          treeNode: true,
+          slots: {
+            default: 'table-groupName',
           },
-        ],
+        },
+      ],
+      addEditConfig: {
+        formConfig: {
+          autoSubmitOnEnter: true,
+          baseColProps: { span: 24 },
+          colon: true,
+          schemas: [
+            {
+              label: '',
+              component: 'Input',
+              field: 'parentId',
+              show: false,
+            },
+            {
+              label: '上级',
+              component: 'Input',
+              field: 'parentName',
+              dynamicDisabled: true,
+            },
+            {
+              label: '',
+              component: 'Input',
+              field: 'groupId',
+              show: false,
+            },
+            {
+              label: t('system.views.i18n.group.groupName'),
+              component: 'Input',
+              field: 'groupName',
+              required: true,
+            },
+            {
+              label: t('system.views.i18n.group.seq'),
+              component: 'InputNumber',
+              field: 'seq',
+              defaultValue: 1,
+              required: true,
+            },
+          ],
+        },
       },
-    },
-    proxyConfig: {
-      ajax: {
-        query: listGroupApi,
-        getById: (row) => getGroupByIdApi(row.groupId),
-        save: ({ body: { insertRecords, updateRecords } }) =>
-          saveUpdateGroupApi([...insertRecords, ...updateRecords][0]),
-        delete: ({ body: { removeRecords } }) => {
-          return deleteGroupApi(removeRecords.map((item) => item.groupId));
+      proxyConfig: {
+        ajax: {
+          query: listGroupTreeApi,
+          getById: (row) => getGroupByIdApi(row.groupId),
+          save: ({ body: { insertRecords, updateRecords } }) =>
+            saveUpdateGroupApi([...insertRecords, ...updateRecords][0]),
+          delete: ({ body: { removeRecords } }) => {
+            return deleteGroupApi(removeRecords.map((item) => item.groupId));
+          },
         },
       },
-    },
-  });
+    });
 </script>
 
 <style lang="less">

+ 3 - 3
src/modules/system/views/i18n/components/i18n.api.ts

@@ -6,7 +6,7 @@ enum Api {
   i18nSaveUpdate = 'sys/i18n/saveUpdate',
   i18nDelete = 'sys/i18n/batchDeleteById',
   getGroupById = 'sys/i18n/getGroupById',
-  listGroup = 'sys/i18n/listGroup',
+  listGroupTree = 'sys/i18n/listGroupTree',
   saveUpdateGroup = 'sys/i18n/saveOrUpdateGroup',
   deleteGroup = 'sys/i18n/deleteGroup',
   getI18nItemById = 'sys/i18nItem/getById',
@@ -55,10 +55,10 @@ export const getGroupByIdApi = (groupId: number) => {
   });
 };
 
-export const listGroupApi = () => {
+export const listGroupTreeApi = () => {
   return defHttp.post({
     service: ApiServiceEnum.SMART_SYSTEM,
-    url: Api.listGroup,
+    url: Api.listGroupTree,
   });
 };
 

+ 4 - 0
src/modules/system/views/i18n/components/i18n.config.ts

@@ -93,6 +93,10 @@ export const getI18nAddEditSchemas = (t: Function): FormSchema[] => {
             label: 'backstage',
             value: 'backstage',
           },
+          {
+            label: 'front',
+            value: 'front',
+          },
         ],
       },
     },

+ 6 - 2
src/modules/system/views/i18n/components/i18nList.vue

@@ -27,7 +27,7 @@
   import { SystemPermissions } from '@/modules/system/constants/SystemConstants';
 
   const props = defineProps({
-    groupId: propTypes.number,
+    groupId: propTypes.oneOfType([propTypes.nullable, propTypes.number]),
   });
   const emit = defineEmits(['change']);
 
@@ -131,11 +131,15 @@
     proxyConfig: {
       ajax: {
         query: ({ ajaxParameter }) => {
+          let groupId = props.groupId;
+          if (groupId == null) {
+            groupId = undefined;
+          }
           const parameter = {
             ...ajaxParameter,
             parameter: {
               ...ajaxParameter?.parameter,
-              'groupId@=': props.groupId,
+              'groupId@=': groupId,
             },
           };
           return listI18nApi(parameter);