fanfan 2 лет назад
Родитель
Сommit
34a7a482ec

+ 1 - 1
package.json

@@ -32,7 +32,7 @@
   "dependencies": {
     "@ant-design/icons-vue": "^6.1.0",
     "@codemirror/commands": "^6.2.2",
-    "@codemirror/history": "^0.19.2",
+    "@codemirror/lang-java": "^6.0.1",
     "@codemirror/lang-json": "^6.0.1",
     "@codemirror/state": "^6.2.0",
     "@codemirror/view": "^6.9.2",

+ 13 - 35
pnpm-lock.yaml

@@ -3,7 +3,7 @@ lockfileVersion: 5.4
 specifiers:
   '@ant-design/icons-vue': ^6.1.0
   '@codemirror/commands': ^6.2.2
-  '@codemirror/history': ^0.19.2
+  '@codemirror/lang-java': ^6.0.1
   '@codemirror/lang-json': ^6.0.1
   '@codemirror/state': ^6.2.0
   '@codemirror/view': ^6.9.2
@@ -101,7 +101,7 @@ specifiers:
 dependencies:
   '@ant-design/icons-vue': 6.1.0_vue@3.2.47
   '@codemirror/commands': 6.2.2
-  '@codemirror/history': 0.19.2
+  '@codemirror/lang-java': 6.0.1
   '@codemirror/lang-json': 6.0.1
   '@codemirror/state': 6.2.0
   '@codemirror/view': 6.9.2
@@ -1445,12 +1445,11 @@ packages:
       '@lezer/common': 1.0.2
     dev: false
 
-  /@codemirror/history/0.19.2:
-    resolution: {integrity: sha512-unhP4t3N2smzmHoo/Yio6ueWi+il8gm9VKrvi6wlcdGH5fOfVDNkmjHQ495SiR+EdOG35+3iNebSPYww0vN7ow==}
-    deprecated: As of 0.20.0, this package has been merged into @codemirror/commands
+  /@codemirror/lang-java/6.0.1:
+    resolution: {integrity: sha512-OOnmhH67h97jHzCuFaIEspbmsT98fNdhVhmA3zCxW0cn7l8rChDhZtwiwJ/JOKXgfm4J+ELxQihxaI7bj7mJRg==}
     dependencies:
-      '@codemirror/state': 0.19.9
-      '@codemirror/view': 0.19.48
+      '@codemirror/language': 6.6.0
+      '@lezer/java': 1.0.3
     dev: false
 
   /@codemirror/lang-json/6.0.1:
@@ -1479,13 +1478,6 @@ packages:
       crelt: 1.0.5
     dev: false
 
-  /@codemirror/rangeset/0.19.9:
-    resolution: {integrity: sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ==}
-    deprecated: As of 0.20.0, this package has been merged into @codemirror/state
-    dependencies:
-      '@codemirror/state': 0.19.9
-    dev: false
-
   /@codemirror/search/6.2.3:
     resolution: {integrity: sha512-V9n9233lopQhB1dyjsBK2Wc1i+8hcCqxl1wQ46c5HWWLePoe4FluV3TGHoZ04rBRlGjNyz9DTmpJErig8UE4jw==}
     dependencies:
@@ -1494,31 +1486,10 @@ packages:
       crelt: 1.0.5
     dev: false
 
-  /@codemirror/state/0.19.9:
-    resolution: {integrity: sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==}
-    dependencies:
-      '@codemirror/text': 0.19.6
-    dev: false
-
   /@codemirror/state/6.2.0:
     resolution: {integrity: sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==}
     dev: false
 
-  /@codemirror/text/0.19.6:
-    resolution: {integrity: sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA==}
-    deprecated: As of 0.20.0, this package has been merged into @codemirror/state
-    dev: false
-
-  /@codemirror/view/0.19.48:
-    resolution: {integrity: sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==}
-    dependencies:
-      '@codemirror/rangeset': 0.19.9
-      '@codemirror/state': 0.19.9
-      '@codemirror/text': 0.19.6
-      style-mod: 4.0.2
-      w3c-keyname: 2.2.6
-    dev: false
-
   /@codemirror/view/6.9.2:
     resolution: {integrity: sha512-ci0r/v6aKOSlzOs7/STMTYP3jX/+YMq2dAfAJcLIB6uom4ThtrUlzeuS7GTRGNqJJ+qAJR1vGWfXgu4CO/0myQ==}
     dependencies:
@@ -2030,6 +2001,13 @@ packages:
       '@lezer/common': 1.0.2
     dev: false
 
+  /@lezer/java/1.0.3:
+    resolution: {integrity: sha512-kKN17wmgP1cgHb8juR4pwVSPMKkDMzY/lAPbBsZ1fpXwbk2sg3N1kIrf0q+LefxgrANaQb/eNO7+m2QPruTFng==}
+    dependencies:
+      '@lezer/highlight': 1.1.3
+      '@lezer/lr': 1.3.3
+    dev: false
+
   /@lezer/json/1.0.0:
     resolution: {integrity: sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==}
     dependencies:

+ 2 - 2
src/api/sys/sysOrgApi.ts

@@ -8,11 +8,11 @@ enum Api {
   sysOrgQueryTreeAbbr = '/sys/org/query/tree/abbr',
   sysOrgQueryTreeDetail = '/sys/org/query/tree/detail',
   sysOrgRemove = '/sys/org/remove',
-  sysOrgQueryList = '/sys/org/list',
+  sysOrgQueryList = '/sys/org/query/list',
 }
 
 /**
- * @description: 新增组织机构,权限 - sys:org:add
+ * @description: 查询组织机构分页列表,权限 - sys:org:add
  * @method: POST
  */
 export const sysOrgQueryList = (params?: object) => {

+ 3 - 3
src/api/sys/sysUserApi.ts

@@ -19,10 +19,10 @@ export const sysUserAdd = (params?: object) => {
 };
 /**
  * @description: 获取用户详细信息,权限 - sys:user:query
- * @method: POST
+ * @method: GET
  */
-export const sysUserDetail = (params?: object) => {
-  return defHttp.post({ url: Api.sysUserDetail, params: params });
+export const sysUserDetail = (userId?: string) => {
+  return defHttp.get({ url: Api.sysUserDetail + '/' + userId });
 };
 /**
  * @description: 通过主键id修改用户,权限 - sys:user:edit

+ 34 - 78
src/components/CodeEditor/src/codemirror/CodeMirror.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="relative !h-full w-full overflow-hidden" ref="el" />
+  <div class="relative !h-full w-full" ref="el" />
 </template>
 
 <script lang="ts" setup>
@@ -11,8 +11,7 @@
   import { basicSetup, EditorView } from 'codemirror';
   import { EditorState, Compartment } from '@codemirror/state';
   import { json } from '@codemirror/lang-json';
-  import { lineNumbers } from '@codemirror/view';
-  import { history } from '@codemirror/history';
+  import { java } from '@codemirror/lang-java';
 
   const props = defineProps({
     mode: {
@@ -30,15 +29,18 @@
   let timer;
 
   const debounceRefresh = useDebounceFn(refresh, 100);
-  const appStore = useAppStore();
+  // const appStore = useAppStore();
 
   watch(
     () => props.value,
     async value => {
       await nextTick();
-      const oldValue = editor?.getValue();
+      const oldValue = editor?.state.doc.toString();
       if (value !== oldValue) {
-        editor?.setValue(value ? value : '');
+        // editor?.setValue(value ? value : '');
+        editor.dispatch({
+          changes: { from: 0, insert: props.value },
+        });
       }
     },
     { flush: 'post' },
@@ -48,22 +50,22 @@
     editor?.setOption('mode', props.mode);
   });
 
-  watch(
-    () => appStore.getDarkMode,
-    async () => {
-      setTheme();
-    },
-    {
-      immediate: true,
-    },
-  );
+  // watch(
+  //   () => appStore.getDarkMode,
+  //   async () => {
+  //     setTheme();
+  //   },
+  //   {
+  //     immediate: true,
+  //   },
+  // );
 
-  function setTheme() {
-    unref(editor)?.setOption(
-      'theme',
-      appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight',
-    );
-  }
+  // function setTheme() {
+  //   unref(editor)?.setOption(
+  //     'theme',
+  //     appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight',
+  //   );
+  // }
 
   function refresh() {
     editor?.refresh();
@@ -76,78 +78,32 @@
       doc: '',
       extensions: [
         basicSetup,
-        language.of(json()),
+        language.of(props.mode == 'javascript' ? json() : java()),
         tabSize.of(EditorState.tabSize.of(4)),
         EditorView.updateListener.of(v => {
           if (v.docChanged) {
             if (timer) clearTimeout(timer);
             timer = setTimeout(() => {
-              const doc = v.state.toJSON()?.doc;
-              const removeLine = doc.replace(/\n/g, '');
-              const json = JSON.parse(removeLine || '{}');
-              emit('change', json);
+              try {
+                const doc = v.state.toJSON()?.doc;
+                const removeLine = doc.replace(/\n/g, '');
+                const json = JSON.parse(removeLine || '{}');
+                emit('change', json);
+              } catch (error) {
+                emit('change', v.state.toString());
+              }
             }, 500);
           }
         }),
       ],
     });
-    const editor = new EditorView({
+    editor = new EditorView({
       state,
       parent: el.value!,
     });
-    const jsonData = [
-      {
-        field: 'field1',
-        component: 'Input',
-        label: '字段1',
-        colProps: {
-          span: 8,
-        },
-        componentProps: {
-          onChange: 'console.log(e)',
-        },
-      },
-      {
-        field: 'sex',
-        label: '性别',
-        component: 'ApiRadioGroup',
-        required: true,
-        componentProps: {
-          api: 'listDictModel',
-          params: {
-            dictCode: 'sys_sex',
-          },
-          labelField: 'dictItemName',
-          valueField: 'dictItemCode',
-        },
-        defaultValue: '1',
-      },
-    ];
     editor.dispatch({
-      changes: { from: 0, insert: JSON.stringify(jsonData) + '\n' },
+      changes: { from: 0, insert: props.value },
     });
-    // const addonOptions = {
-    //   autoCloseBrackets: true,
-    //   autoCloseTags: true,
-    //   foldGutter: true,
-    //   gutters: ['CodeMirror-linenumbers'],
-    // };
-
-    // editor = CodeMirror(el.value!, {
-    //   value: '',
-    //   mode: props.mode,
-    //   readOnly: props.readonly,
-    //   tabSize: 2,
-    //   theme: 'material-palenight',
-    //   lineWrapping: true,
-    //   lineNumbers: true,
-    //   ...addonOptions,
-    // });
-    // editor?.setValue(props.value);
-    // setTheme();
-    // editor?.on('change', () => {
-    //   emit('change', editor?.getValue());
-    // });
   }
 
   onMounted(async () => {

+ 124 - 241
src/views/sys/sysConfig/bak.vue

@@ -1,261 +1,144 @@
 <template>
-  <div>
-    <BasicTable @register="registerTable" @resizeColumn="resizeColumn">
-      <template #bodyCell="{ column, record }">
-        <template v-if="column.key === 'disable'">
-          <Tag :color="record.disable ? 'error' : 'success'">
-            {{ commonDict(record.disable, 1) }}
-          </Tag>
-        </template>
-        <template v-if="column.key === 'sysInner'">
-          <Tag :color="record.sysInner ? 'success' : 'error'">
-            {{ commonDict(record.sysInner, 1) }}
-          </Tag>
-        </template>
-        <template v-if="column.key === 'action'">
-          <TableAction
-            :actions="[
-              {
-                icon: 'icon-edit|iconfont',
-                tooltip: '编辑',
-                onClick: handleEdit.bind(null, record),
-              },
-              {
-                icon: 'icon-delete|iconfont',
-                tooltip: '删除',
-                color: 'error',
-                popConfirm: {
-                  title: '是否确认删除',
-                  placement: 'left',
-                  confirm: handleDelete.bind(null, record),
-                },
-              },
-            ]"
-          />
-        </template>
-      </template>
-      <template #search="{ onSearch }">
-        <div class="search">
-          <a-input-search
-            class="table-search-item"
-            v-model:value="tableSearch.value1"
-            placeholder="请输入姓名"
-            @search="onSearch"
-          />
-          <a-select
-            ref="select"
-            placeholder="选择病区"
-            v-model:value="tableSearch.value2"
-            style="width: 120px"
-            @change="onSearch"
-            class="table-search-item"
-          >
-            <a-select-option value="1"> <span class="mr-1">病区</span>全部 </a-select-option>
-            <a-select-option value="jack"> <span class="mr-1">病区</span>Jack </a-select-option>
-            <a-select-option value="lucy"><span class="mr-1">病区</span>Lucy</a-select-option>
-            <a-select-option value="Yiminghe"
-              ><span class="mr-1">病区</span>yiminghe</a-select-option
-            >
-          </a-select>
-          <a-select
-            ref="select"
-            placeholder="选择设备"
-            v-model:value="tableSearch.value3"
-            style="width: 120px"
-            @change="onSearch"
-            class="table-search-item"
-          >
-            <a-select-option value="1"> <span class="mr-1">设备</span>全部 </a-select-option>
-            <a-select-option value="jack"> <span class="mr-1">设备</span>111 </a-select-option>
-            <a-select-option value="lucy"><span class="mr-1">设备</span>222</a-select-option>
-            <a-select-option value="Yiminghe"><span class="mr-1">设备</span>333</a-select-option>
-          </a-select>
-        </div>
-      </template>
-      <template #toolbar>
-        <a-button
-          v-auth="['system:sysConfig:add']"
-          preIcon="icon-plus|iconfont"
-          type="primary"
-          @click="handleCreate"
-          >新增
-        </a-button>
-        <!-- <a-button
-          v-auth="['system:sysConfig:export']"
-          color="warning"
-          preIcon="ant-design:download-outlined"
-          @click="handleExport"
-          >导出
-        </a-button> -->
-        <a-button
-          v-auth="['system:sysConfig:refresh']"
-          color="success"
-          preIcon="icon-redo|iconfont"
-          @click="handleRefresh"
-          >刷新缓存
-        </a-button>
-      </template>
-    </BasicTable>
-    <FormModal @register="registerModal" @success="handleSuccess" />
+  <div class="flex mt-6">
+    <div class="w-1/2 -enter-x">
+      <BasicForm @register="register" @submit="handleSubmit" />
+    </div>
+    <div class="w-1/2 -enter-x">
+      <Textarea
+        v-model:value="textSchemas"
+        :rows="10"
+        placeholder="请输入 schemas"
+        @change="onChange"
+        wrap="soft"
+      />
+      <CodeEditor v-model:value="codeValue" :mode="modeValue" @change="handleChange" />
+      {{ data111 }}
+    </div>
   </div>
 </template>
-<script lang="ts" setup>
-  import { ref, onBeforeMount, reactive } from 'vue';
-  import { Tag } from 'ant-design-vue';
-  import { BasicTable, TableAction, useTable } from '/@/components/Table';
-  import { useModal } from '/@/components/Modal';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import FormModal from './FormModal.vue';
-  import { columns, searchBasicFormSchema, searchFormSchema } from './data';
 
-  // import { exportList, fetchList, refresh, removeObj } from '/@/api/modules/system/sysConfigApi';
-  import { sysConfigQueryList, sysConfigRemove } from '/@/api/sys/sysConfigApi';
-  // import { downloadFile, listDictModel } from '/@/api/common';
-  // import { listDictModel } from '/@/api/common';
-  import { commonDict } from '/@/utils';
-  import { templateRef } from '@vueuse/core';
-  import { useDebounceFn } from '@vueuse/shared';
+<script setup lang="ts">
+  import { BasicForm, useForm } from '/@/components/Form';
+  import { Textarea } from 'ant-design-vue';
+  import { useDebounceFn } from '@vueuse/core';
+  import { ref, onMounted, watch, computed } from 'vue';
+  import { CodeEditor } from '/@/components/CodeEditor';
+  import { listDictModel } from '/@/api/common';
 
-  defineOptions({
-    name: 'sysConfig',
-  });
+  const codeValue = ref(null);
+  const modeValue = ref('application/json');
 
-  // const sysStatusOptions = ref([]);
-  onBeforeMount(async () => {
-    // sysStatusOptions.value = await listDictModel({ dictCode: 'sys_status' });
-  });
-  const tableSearch = reactive({
-    value1: '',
-    value2: '1',
-    value3: '1',
+  onMounted(() => {
+    console.log('1231231');
   });
-  const { createMessage, createConfirm } = useMessage();
-  const [registerTable, { reload, getCacheColumns, setColumns }] = useTable({
-    id: 'sys_config',
-    storage: true,
-    title: '参数列表',
-    api: sysConfigQueryList,
-    rowKey: 'id',
-    columns,
-    formConfig: {
-      formId: 'sys_config',
-      layout: 'vertical',
-      labelWidth: 100,
-      schemas: searchFormSchema,
-      actionColOptions: {
-        span: 23,
+
+  const schemas = ref([
+    {
+      field: 'field1',
+      component: 'Input',
+      label: '字段1',
+      colProps: {
+        span: 8,
+      },
+      componentProps: {
+        placeholder: '自定义placeholder',
+        onChange: (e: any) => {
+          console.log(e);
+        },
       },
-      showActionButtonGroup: false,
-      // autoSubmitOnEnter: true,
-      // baseColProps: { xs: 24, sm: 12, md: 12, lg: 8 },
-      // resetButtonOptions: {
-      //   preIcon: 'ant-design:delete-outlined',
-      // },
-      // submitButtonOptions: {
-      //   preIcon: 'ant-design:search-outlined',
-      // },
     },
-    basicSearch: {
-      schemas: searchBasicFormSchema,
-      fields: tableSearch,
+    {
+      field: 'field2',
+      component: 'Input',
+      label: '字段2',
+      colProps: {
+        span: 8,
+      },
+      componentProps: {
+        placeholder: '自定义placeholder222222222',
+        onChange: (e: any) => {
+          console.log(e);
+        },
+      },
     },
-    showIndexColumn: true,
-    useSearchForm: true,
-    showTableSetting: true,
-    bordered: true,
-    actionColumn: {
-      auth: ['system:sysConfig:edit', 'system:sysConfig:remove'],
-      width: 80,
-      title: '操作',
-      dataIndex: 'action',
+  ]) as any;
+
+  watch(
+    () => schemas.value,
+    (newVal, oldVal) => {
+      console.log('🚀 ~ file: index.vue:67 ~ oldVal:', oldVal);
+      console.log('🚀 ~ file: index.vue:67 ~ newVal:', newVal);
     },
+  );
+  const count = ref(1);
+  const data111 = computed(() => {
+    return count.value + 1;
   });
-  const [registerModal, { openModal }] = useModal();
-
-  // 新增按钮事件
-  function handleCreate() {
-    openModal(true, {
-      isUpdate: false,
-    });
-  }
-
-  // 编辑按钮事件
-  function handleEdit(record: Recordable) {
-    console.log(record);
-    openModal(true, {
-      record,
-      isUpdate: true,
-    });
-  }
 
-  // 删除按钮事件
-  async function handleDelete(record: Recordable) {
-    console.log(record);
-    await sysConfigRemove([record.id]);
-    createMessage.success('删除成功!');
-    await reload();
-  }
-
-  // 导出按钮事件
-  // async function handleExport() {
-  //   createConfirm({
-  //     iconType: 'warning',
-  //     title: '提示',
-  //     content: '确认导出?',
-  //     onOk: async () => {
-  //       const params = getForm().getFieldsValue();
-  //       const filepath = await exportList(params);
-  //       downloadFile(filepath);
-  //     },
-  //   });
-  // }
+  const [register, { resetSchema }] = useForm({
+    labelWidth: 120,
+    schemas,
+    actionColOptions: {
+      span: 24,
+    },
+    showActionButtonGroup: false,
+  });
+  const textSchemas = ref(null);
 
-  // 刷新缓存按钮事件
-  async function handleRefresh() {
-    createConfirm({
-      iconType: 'warning',
-      title: '提示',
-      content: '确认刷新所有参数缓存?',
-      onOk: async () => {
-        await sysConfigQueryList({});
-        createMessage.success('刷新成功!');
+  const debounceFn = useDebounceFn(data => {
+    const span = Math.round(Math.random() * 20 + 5);
+    schemas.value = [
+      {
+        field: 'field1',
+        component: 'Input',
+        label: '字段' + span,
+        colProps: {
+          span,
+        },
+        componentProps: {
+          placeholder: '自定义placeholder',
+          onChange: e => {
+            console.log(e);
+          },
+        },
       },
-    });
-  }
-
-  // 弹窗回调事件
-  async function handleSuccess({ isUpdate, values }) {
-    console.log(isUpdate);
-    console.log(values);
-    await reload();
-  }
-
-  const debounceFn = useDebounceFn(async (w, col) => {
-    const cacheColumns = await getCacheColumns();
-    const columns = cacheColumns.map(ele => {
-      if (ele.dataIndex == col.dataIndex) {
-        ele.width = w;
-      }
-      return ele;
-    }) as any;
-    setColumns(columns);
+    ];
+    resetSchema(data);
+    console.log('🚀 ~ file: index.vue:107 ~ debounceFn ~ data:', data);
+    console.log('🚀 ~ file: index.vue:89 ~ debounceFn ~ schemas.value:', schemas.value);
+    // console.log('🚀 ~ file: index.vue:91 ~ debounceFn ~ data:', data);
+    // resetSchema([data]);
   }, 1000 * 3);
 
-  // 动态设置宽度
-  async function resizeColumn(w, col) {
-    col.width = w;
-    debounceFn(w, col);
+  function onChange(e) {
+    // const str = "[{field: 'field1',component: 'Input',label: '字段1',colProps: {span: 24,},}]";
+    // const val = JSON.parse(str);
+    // const val = JSON.stringify(e.target.value, null, 4).replace(/\n/g, '');
+    // console.log(val);
+    // console.log('🚀 ~ file: index.vue:71 ~ onChange ~ val:', val);
+    // debounceFn();
+    count.value = Math.round(Math.random() * 100);
   }
+  function handleChange(val) {
+    console.log('🚀 ~ file: index.vue:100 ~ handleChange ~ val:', val);
+    if (Array.isArray(val)) {
+      const arr = val.map(ele => {
+        if (ele?.componentProps) {
+          if (ele.componentProps?.api) {
+            ele.componentProps.api = listDictModel;
+          }
+          if (ele.componentProps?.onChange) {
+            ele.componentProps.onChange = new Function('e', ele.componentProps.onChange);
+          }
+        }
+        return ele;
+      });
+      console.log('🚀 ~ file: index.vue:126 ~ arr ~ arr:', arr);
+      debounceFn(arr);
+    }
+    textSchemas.value = JSON.stringify(val);
+  }
+  function handleSubmit() {}
 </script>
 
-<sytle scoped lang="less">
-.table-search {
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  &-item {
-    margin-right: 10px;
-    max-width: 180px;
-  }
-}
-</sytle>
+<style scoped></style>

+ 242 - 123
src/views/sys/sysConfig/index.vue

@@ -1,144 +1,263 @@
 <template>
-  <div class="flex mt-6">
-    <div class="w-1/2 -enter-x">
-      <BasicForm @register="register" @submit="handleSubmit" />
-    </div>
-    <div class="w-1/2 -enter-x">
-      <Textarea
-        v-model:value="textSchemas"
-        :rows="10"
-        placeholder="请输入 schemas"
-        @change="onChange"
-        wrap="soft"
-      />
-      <CodeEditor v-model:value="codeValue" :mode="modeValue" @change="handleChange" />
-      {{ data111 }}
-    </div>
+  <div>
+    <BasicTable @register="registerTable" @resizeColumn="resizeColumn">
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'disable'">
+          <Tag :color="record.disable ? 'error' : 'success'">
+            {{ commonDict(record.disable, 1) }}
+          </Tag>
+        </template>
+        <template v-if="column.key === 'sysInner'">
+          <Tag :color="record.sysInner ? 'success' : 'error'">
+            {{ commonDict(record.sysInner, 1) }}
+          </Tag>
+        </template>
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                icon: 'icon-edit|iconfont',
+                tooltip: '编辑',
+                onClick: handleEdit.bind(null, record),
+              },
+              {
+                icon: 'icon-delete|iconfont',
+                tooltip: '删除',
+                color: 'error',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
+      </template>
+      <template #search="{ onSearch }">
+        <div class="search">
+          <a-input-search
+            class="table-search-item"
+            v-model:value="tableSearch.value1"
+            placeholder="请输入姓名"
+            @search="onSearch"
+          />
+          <a-select
+            ref="select"
+            placeholder="选择病区"
+            v-model:value="tableSearch.value2"
+            style="width: 120px"
+            @change="onSearch"
+            class="table-search-item"
+          >
+            <a-select-option value="1"> <span class="mr-1">病区</span>全部 </a-select-option>
+            <a-select-option value="jack"> <span class="mr-1">病区</span>Jack </a-select-option>
+            <a-select-option value="lucy"><span class="mr-1">病区</span>Lucy</a-select-option>
+            <a-select-option value="Yiminghe"
+              ><span class="mr-1">病区</span>yiminghe</a-select-option
+            >
+          </a-select>
+          <a-select
+            ref="select"
+            placeholder="选择设备"
+            v-model:value="tableSearch.value3"
+            style="width: 120px"
+            @change="onSearch"
+            class="table-search-item"
+          >
+            <a-select-option value="1"> <span class="mr-1">设备</span>全部 </a-select-option>
+            <a-select-option value="jack"> <span class="mr-1">设备</span>111 </a-select-option>
+            <a-select-option value="lucy"><span class="mr-1">设备</span>222</a-select-option>
+            <a-select-option value="Yiminghe"><span class="mr-1">设备</span>333</a-select-option>
+          </a-select>
+        </div>
+      </template>
+      <template #toolbar>
+        <a-button
+          v-auth="['system:sysConfig:add']"
+          preIcon="icon-plus|iconfont"
+          type="primary"
+          @click="handleCreate"
+          >新增
+        </a-button>
+        <!-- <a-button
+          v-auth="['system:sysConfig:export']"
+          color="warning"
+          preIcon="ant-design:download-outlined"
+          @click="handleExport"
+          >导出
+        </a-button> -->
+        <a-button
+          v-auth="['system:sysConfig:refresh']"
+          color="success"
+          preIcon="icon-redo|iconfont"
+          @click="handleRefresh"
+          >刷新缓存
+        </a-button>
+      </template>
+    </BasicTable>
+    <FormModal @register="registerModal" @success="handleSuccess" />
   </div>
 </template>
+<script lang="ts" setup>
+  import { ref, onBeforeMount, reactive } from 'vue';
+  import { Tag } from 'ant-design-vue';
+  import { BasicTable, TableAction, useTable } from '/@/components/Table';
+  import { useModal } from '/@/components/Modal';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import FormModal from './FormModal.vue';
+  import { columns, searchBasicFormSchema, searchFormSchema } from './data';
 
-<script setup lang="ts">
-  import { BasicForm, useForm } from '/@/components/Form';
-  import { Textarea } from 'ant-design-vue';
-  import { useDebounceFn } from '@vueuse/core';
-  import { ref, onMounted, watch, computed } from 'vue';
-  import { CodeEditor } from '/@/components/CodeEditor';
-  import { listDictModel } from '/@/api/common';
+  // import { exportList, fetchList, refresh, removeObj } from '/@/api/modules/system/sysConfigApi';
+  import { sysConfigQueryList, sysConfigRemove } from '/@/api/sys/sysConfigApi';
+  // import { downloadFile, listDictModel } from '/@/api/common';
+  // import { listDictModel } from '/@/api/common';
+  import { commonDict } from '/@/utils';
+  import { templateRef } from '@vueuse/core';
+  import { useDebounceFn } from '@vueuse/shared';
 
-  const codeValue = ref(null);
-  const modeValue = ref('application/json');
-
-  onMounted(() => {
-    console.log('1231231');
+  defineOptions({
+    name: 'sysConfig',
   });
 
-  const schemas = ref([
-    {
-      field: 'field1',
-      component: 'Input',
-      label: '字段1',
-      colProps: {
-        span: 8,
-      },
-      componentProps: {
-        placeholder: '自定义placeholder',
-        onChange: (e: any) => {
-          console.log(e);
-        },
+  // const sysStatusOptions = ref([]);
+  onBeforeMount(async () => {
+    // sysStatusOptions.value = await listDictModel({ dictCode: 'sys_status' });
+  });
+  const tableSearch = reactive({
+    value1: '',
+    value2: '1',
+    value3: '1',
+  });
+  const { createMessage, createConfirm } = useMessage();
+  const [registerTable, { reload, getCacheColumns, setColumns }] = useTable({
+    // 存储需要设置 id 和 storage
+    id: 'sys_config',
+    storage: true,
+    title: '参数列表',
+    api: sysConfigQueryList,
+    rowKey: 'id',
+    columns,
+    formConfig: {
+      formId: 'sys_config',
+      labelWidth: 100,
+      schemas: searchFormSchema,
+      actionColOptions: {
+        xs: 24,
+        sm: 12,
+        md: 12,
+        lg: 8,
       },
-    },
-    {
-      field: 'field2',
-      component: 'Input',
-      label: '字段2',
-      colProps: {
-        span: 8,
+      autoSubmitOnEnter: true,
+      baseColProps: { xs: 24, sm: 12, md: 12, lg: 8 },
+      resetButtonOptions: {
+        preIcon: 'icon-delete|iconfont',
       },
-      componentProps: {
-        placeholder: '自定义placeholder222222222',
-        onChange: (e: any) => {
-          console.log(e);
-        },
+      submitButtonOptions: {
+        preIcon: 'icon-search|iconfont',
       },
     },
-  ]) as any;
-
-  watch(
-    () => schemas.value,
-    (newVal, oldVal) => {
-      console.log('🚀 ~ file: index.vue:67 ~ oldVal:', oldVal);
-      console.log('🚀 ~ file: index.vue:67 ~ newVal:', newVal);
+    basicSearch: {
+      schemas: searchBasicFormSchema,
+      fields: tableSearch,
     },
-  );
-  const count = ref(1);
-  const data111 = computed(() => {
-    return count.value + 1;
-  });
-
-  const [register, { resetSchema }] = useForm({
-    labelWidth: 120,
-    schemas,
-    actionColOptions: {
-      span: 24,
+    showIndexColumn: true,
+    useSearchForm: true,
+    showTableSetting: true,
+    bordered: true,
+    actionColumn: {
+      auth: ['system:sysConfig:edit', 'system:sysConfig:remove'],
+      width: 80,
+      title: '操作',
+      dataIndex: 'action',
     },
-    showActionButtonGroup: false,
   });
-  const textSchemas = ref(null);
+  const [registerModal, { openModal }] = useModal();
 
-  const debounceFn = useDebounceFn(data => {
-    const span = Math.round(Math.random() * 20 + 5);
-    schemas.value = [
-      {
-        field: 'field1',
-        component: 'Input',
-        label: '字段' + span,
-        colProps: {
-          span,
-        },
-        componentProps: {
-          placeholder: '自定义placeholder',
-          onChange: e => {
-            console.log(e);
-          },
-        },
+  // 新增按钮事件
+  function handleCreate() {
+    openModal(true, {
+      isUpdate: false,
+    });
+  }
+
+  // 编辑按钮事件
+  function handleEdit(record: Recordable) {
+    console.log(record);
+    openModal(true, {
+      record,
+      isUpdate: true,
+    });
+  }
+
+  // 删除按钮事件
+  async function handleDelete(record: Recordable) {
+    console.log(record);
+    await sysConfigRemove([record.id]);
+    createMessage.success('删除成功!');
+    await reload();
+  }
+
+  // 导出按钮事件
+  // async function handleExport() {
+  //   createConfirm({
+  //     iconType: 'warning',
+  //     title: '提示',
+  //     content: '确认导出?',
+  //     onOk: async () => {
+  //       const params = getForm().getFieldsValue();
+  //       const filepath = await exportList(params);
+  //       downloadFile(filepath);
+  //     },
+  //   });
+  // }
+
+  // 刷新缓存按钮事件
+  async function handleRefresh() {
+    createConfirm({
+      iconType: 'warning',
+      title: '提示',
+      content: '确认刷新所有参数缓存?',
+      onOk: async () => {
+        await sysConfigQueryList({});
+        createMessage.success('刷新成功!');
       },
-    ];
-    resetSchema(data);
-    console.log('🚀 ~ file: index.vue:107 ~ debounceFn ~ data:', data);
-    console.log('🚀 ~ file: index.vue:89 ~ debounceFn ~ schemas.value:', schemas.value);
-    // console.log('🚀 ~ file: index.vue:91 ~ debounceFn ~ data:', data);
-    // resetSchema([data]);
-  }, 1000 * 3);
+    });
+  }
 
-  function onChange(e) {
-    // const str = "[{field: 'field1',component: 'Input',label: '字段1',colProps: {span: 24,},}]";
-    // const val = JSON.parse(str);
-    // const val = JSON.stringify(e.target.value, null, 4).replace(/\n/g, '');
-    // console.log(val);
-    // console.log('🚀 ~ file: index.vue:71 ~ onChange ~ val:', val);
-    // debounceFn();
-    count.value = Math.round(Math.random() * 100);
+  // 弹窗回调事件
+  async function handleSuccess({ isUpdate, values }) {
+    console.log(isUpdate);
+    console.log(values);
+    await reload();
   }
-  function handleChange(val) {
-    console.log('🚀 ~ file: index.vue:100 ~ handleChange ~ val:', val);
-    if (Array.isArray(val)) {
-      const arr = val.map(ele => {
-        if (ele?.componentProps) {
-          if (ele.componentProps?.api) {
-            ele.componentProps.api = listDictModel;
-          }
-          if (ele.componentProps?.onChange) {
-            ele.componentProps.onChange = new Function('e', ele.componentProps.onChange);
-          }
-        }
-        return ele;
-      });
-      console.log('🚀 ~ file: index.vue:126 ~ arr ~ arr:', arr);
-      debounceFn(arr);
-    }
-    textSchemas.value = JSON.stringify(val);
+
+  const debounceFn = useDebounceFn(async (w, col) => {
+    const cacheColumns = await getCacheColumns();
+    const columns = cacheColumns.map(ele => {
+      if (ele.dataIndex == col.dataIndex) {
+        ele.width = w;
+      }
+      return ele;
+    }) as any;
+    setColumns(columns);
+  }, 1000 * 3);
+
+  // 动态设置宽度
+  async function resizeColumn(w, col) {
+    col.width = w;
+    debounceFn(w, col);
   }
-  function handleSubmit() {}
 </script>
 
-<style scoped></style>
+<sytle scoped lang="less">
+.table-search {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  &-item {
+    margin-right: 10px;
+    max-width: 180px;
+  }
+}
+</sytle>

+ 1 - 1
src/views/sys/sysDept/DeptTree.vue

@@ -53,7 +53,7 @@
 
   // 格式化图标
   function createIcon() {
-    return 'ant-design:apartment-outlined';
+    return 'icon-apartment|iconfont';
   }
 
   // 暴露内部方法

+ 36 - 31
src/views/sys/sysDept/sysDeptTable/index.vue

@@ -1,39 +1,45 @@
 <template>
   <div>
     <BasicTable @register="registerTable">
-      <template #disable="{ record }">
-        <Tag :color="record.disable ? 'error' : 'success'">
-          {{ commonDict(record.disable, 1) }}
-        </Tag>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'disable'">
+          <Tag :color="record.disable ? 'error' : 'success'">
+            {{ commonDict(record.disable, 1) }}
+          </Tag>
+        </template>
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                auth: ['sys:org:edit'],
+                icon: 'icon-edit|iconfont',
+                tooltip: '编辑',
+                onClick: handleEdit.bind(null, record),
+              },
+              {
+                auth: ['sys:org:remove'],
+                icon: 'icon-delete|iconfont',
+                tooltip: '删除',
+                color: 'error',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
       </template>
       <template #toolbar>
-        <a-button v-auth="['system:sysDept:add']" type="primary" @click="handleCreate" preIcon="icon-plus|iconfont"
+        <a-button
+          v-auth="['sys:org:add']"
+          type="primary"
+          @click="handleCreate"
+          preIcon="icon-plus|iconfont"
           >新增</a-button
         >
       </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              auth: ['system:sysDept:edit'],
-              icon: 'clarity:note-edit-line',
-              tooltip: '编辑',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              auth: ['system:sysDept:remove'],
-              icon: 'ant-design:delete-outlined',
-              tooltip: '删除',
-              color: 'error',
-              popConfirm: {
-                title: '是否确认删除',
-                placement: 'left',
-                confirm: handleDelete.bind(null, record),
-              },
-            },
-          ]"
-        />
-      </template>
     </BasicTable>
     <FormModal @register="registerModal" @success="handleSuccess" />
   </div>
@@ -77,10 +83,10 @@
       autoSubmitOnEnter: true,
       baseColProps: { xs: 24, sm: 12, md: 12, lg: 12, xl: 8 },
       resetButtonOptions: {
-        preIcon: 'ant-design:delete-outlined',
+        preIcon: 'icon-delete|iconfont',
       },
       submitButtonOptions: {
-        preIcon: 'ant-design:search-outlined',
+        preIcon: 'icon-search|iconfont',
       },
     },
     showIndexColumn: false,
@@ -92,7 +98,6 @@
       width: 80,
       title: '操作',
       dataIndex: 'action',
-      slots: { customRender: 'action' },
     },
     beforeFetch: handleBeforeFetch,
     afterFetch: handleAfterFetch,

+ 2 - 2
src/views/sys/sysDict/index.vue

@@ -5,7 +5,7 @@
   </PageWrapper>
 </template>
 <script lang="ts" setup>
-  import { isRef, ref, watch, isReactive } from 'vue';
+  import { ref, watch } from 'vue';
   import { PageWrapper } from '/@/components/Page';
   import SysDictTable from './sysDictTable/index.vue';
   import SysDictItemTable from './sysDictItemTable/index.vue';
@@ -21,7 +21,7 @@
     if (!value) return;
     dictId.value = value;
   }
-  const isGetSub = isReactive(getSub());
+  const isGetSub = getSub();
   console.log('🚀 ~ file: index.vue ~ line 20 ~ isGetSub', isGetSub);
   // 监听数据
   watch(

+ 6 - 14
src/views/sys/sysGen/PreviewModal.vue

@@ -1,4 +1,4 @@
-<!-- <template>
+<template>
   <BasicModal
     v-bind="$attrs"
     destroyOnClose
@@ -33,15 +33,15 @@
   const activeKey = ref('index.vue.vm');
   const codeTypeData = ref([]) as any;
   const { createMessage } = useMessage();
-  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async data => {
     setModalProps({ confirmLoading: false });
     codeTypeData.value = [];
     getTitle.value = `代码预览  - ${data.record.tableComment}`;
     rowId.value = data.record.tableId;
     const resData = await genPreviewTableId(data.record.tableId);
-    for (let i in resData) {
-      let key = i.split('/')[2];
-      let nameData = key.split('.');
+    for (const i in resData) {
+      const key = i.split('/')[2];
+      const nameData = key.split('.');
       let mode = '';
       if (nameData.length == 2) {
         mode = nameData[0];
@@ -84,12 +84,4 @@
     overflow-x: hidden;
     overflow-y: auto;
   }
-</style> -->
-
-<template>
-  <div />
-</template>
-
-<script setup lang="ts"></script>
-
-<style scoped></style>
+</style>

+ 125 - 0
src/views/sys/sysGen/TableModal.vue

@@ -0,0 +1,125 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    destroyOnClose
+    @register="registerModal"
+    :title="getTitle"
+    @ok="handleSubmit"
+    :defaultFullscreen="true"
+    ok-text="关闭"
+  >
+    <Tabs v-model:activeKey="activeKey">
+      <template v-for="item in settingData" :key="item.key">
+        <TabPane :tab="item.tab" :tabKey="item.key">
+          <div v-if="item.key == 'field'">
+            <BasicTable @register="registerTable">
+              <template #toolbar>
+                <a-button type="primary" @click="genSubmit">保存配置</a-button>
+              </template>
+            </BasicTable>
+          </div>
+          <div v-else>
+            <BasicForm @register="registerForm" />
+          </div>
+        </TabPane>
+      </template>
+    </Tabs>
+  </BasicModal>
+</template>
+<script lang="ts" setup>
+  import { ref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { Tabs, TabPane } from 'ant-design-vue';
+  import { BasicTable, useTable } from '/@/components/Table';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { columnsEdit, genFormSchema } from './data';
+  import { genColumnTableId, genEdit } from '/@/api/sys/sysGenApi';
+  defineEmits(['register']);
+  const getTitle = ref('生成配置');
+  const rowId = ref();
+  const activeKey = ref('field');
+  const settingData = [
+    {
+      key: 'field',
+      tab: '字段配置',
+    },
+    {
+      key: 'info',
+      tab: '生成配置',
+    },
+  ];
+  const { createMessage } = useMessage();
+  const [registerTable, { setTableData, getDataSource }] = useTable({
+    dataSource: [] as any,
+    columns: columnsEdit,
+    showIndexColumn: true,
+    pagination: false,
+    indexColumnProps: {
+      fixed: 'left',
+    },
+    bordered: true,
+  });
+  const [registerForm, { resetFields, validate }] = useForm({
+    labelWidth: 100,
+    schemas: genFormSchema,
+    baseColProps: { xs: 24, md: 12, xl: 8, xxl: 8 },
+    actionColOptions: {
+      span: 24,
+    },
+    resetButtonOptions: {
+      preIcon: 'ant-design:delete-outlined',
+      text: '重置',
+    },
+    submitButtonOptions: {
+      preIcon: 'ant-design:check-outlined',
+      text: '保存',
+    },
+    submitFunc: handleGenInfo,
+  });
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async data => {
+    setModalProps({ confirmLoading: false });
+    await resetFields();
+    getTitle.value = `生成配置  - ${data.record.tableComment}`;
+    rowId.value = data.record.tableId;
+    const resData = await genColumnTableId(data.record.tableId);
+    setTableData(resData);
+  });
+
+  // 提交按钮事件
+  async function handleSubmit() {
+    createMessage.success('关闭');
+    closeModal();
+    setModalProps({ confirmLoading: false });
+  }
+
+  async function handleGenInfo() {
+    try {
+      const values = await validate();
+      console.log('🚀 ~ file: EditModal.vue ~ line 92 ~ handleGenInfo ~ values', values);
+      setModalProps({ confirmLoading: true });
+      // !unref(isUpdate)
+      //   ? await addObj([{ ...values }])
+      //   : await editObj({ ...values, id: rowId.value });
+      // !unref(isUpdate) ? createMessage.success('新增成功!') : createMessage.success('编辑成功!');
+      // emit('success');
+      closeModal();
+    } finally {
+      setModalProps({ confirmLoading: false });
+    }
+  }
+  async function genSubmit() {
+    console.log('生成');
+    const tableData = getDataSource();
+    const res = await genEdit(tableData);
+    console.log('🚀 ~ file: EditModal.vue ~ line 80 ~ genSubmit ~ res', res);
+  }
+</script>
+<style lang="less" scoped>
+  .code-content {
+    height: calc(100vh - 176px);
+    width: 100%;
+    overflow-x: hidden;
+    overflow-y: auto;
+  }
+</style>

+ 0 - 174
src/views/sys/sysGen/bak.vue

@@ -1,174 +0,0 @@
-<!-- <template>
-  <div>
-    <BasicTable @register="registerTable">
-      <template #toolbar>
-        <a-button type="warning" @click="handleImportTable">导入</a-button>
-        <a-button type="success" @click="handleGenTable">生成</a-button>
-        <a-button type="danger" @click="handleDelete">删除</a-button>
-      </template>
-      <template #bodyCell="{ column, record }">
-        <template v-if="column.key == 'action'">
-          <TableAction
-            :actions="[
-              {
-                tooltip: '预览',
-                label: '预览',
-                onClick: handlePreview.bind(null, record),
-              },
-              {
-                tooltip: '编辑',
-                label: '编辑',
-                onClick: handleEditTable.bind(null, record),
-              },
-              {
-                tooltip: '删除',
-                label: '删除',
-                onClick: handleDelete.bind(null, record),
-              },
-              {
-                tooltip: '同步',
-                label: '同步',
-                onClick: handleSynchDb.bind(null, record),
-              },
-              {
-                tooltip: '生成代码',
-                label: '生成代码',
-                onClick: handleGenTable.bind(null, record),
-              },
-            ]"
-          />
-        </template>
-      </template>
-    </BasicTable>
-    <PreviewModal @register="registerModal" @success="handleSuccess" />
-    <EditModal @register="registerModalEdit" @success="handleSuccess" />
-    <TableModal @register="registerModalTable" @success="handleSuccess" />
-  </div>
-</template>
-<script lang="ts" setup>
-  import { BasicTable, useTable, TableAction } from '/@/components/Table';
-  import { columns, searchFormSchema } from './data';
-  import { genList, genSynchDb, genRemove, genBatchGenCode } from '/@/api/sys/sysGenApi';
-  import { useModal } from '/@/components/Modal';
-  import PreviewModal from './PreviewModal.vue';
-  import EditModal from './EditModal.vue';
-  import TableModal from './TableModal.vue';
-  import { downloadByData } from '/@/utils/file/download';
-  import { useMessage } from '/@/hooks/web/useMessage';
-
-  const { createMessage } = useMessage();
-  const [registerModal, { openModal }] = useModal();
-  const [registerModalTable, { openModal: openModalTable }] = useModal();
-  const [registerModalEdit, { openModal: openModalEdit }] = useModal();
-  const [registerTable, { getSelectRowKeys, getSelectRows, reload }] = useTable({
-    title: '代码生成列表',
-    api: genList,
-    rowKey: 'tableId',
-    rowSelection: { type: 'checkbox' },
-    clickToRowSelect: false,
-    columns,
-    formConfig: {
-      labelWidth: 120,
-      schemas: searchFormSchema,
-      autoSubmitOnEnter: true,
-      baseColProps: { xs: 24, sm: 12, md: 12, lg: 8 },
-      resetButtonOptions: {
-        preIcon: 'ant-design:delete-outlined',
-      },
-      submitButtonOptions: {
-        preIcon: 'ant-design:search-outlined',
-      },
-    },
-    showIndexColumn: true,
-    indexColumnProps: {
-      fixed: 'left',
-    },
-    useSearchForm: true,
-    showTableSetting: true,
-    bordered: true,
-    actionColumn: {
-      width: 300,
-      title: '操作',
-      dataIndex: 'action',
-    },
-  });
-
-  // 预览按钮事件
-  function handlePreview(record: Recordable) {
-    console.log(record);
-    openModal(true, {
-      record,
-    });
-  }
-  // 编辑按钮事件
-  function handleEditTable(record: Recordable) {
-    console.log(record);
-    openModalEdit(true, {
-      record,
-    });
-  }
-  // 删除按钮事件
-  async function handleDelete(record: Recordable) {
-    const isGen = getSelectRowKeys().length ? true : false;
-    if (isGen) {
-      await genRemove(getSelectRowKeys());
-    } else {
-      await genRemove([record.tableId]);
-    }
-    await reload();
-  }
-  // 同步按钮事件
-  async function handleSynchDb(record: Recordable) {
-    console.log(record);
-    const res = await genSynchDb({ tableName: record.tableName });
-    createMessage.success('同步成功');
-    console.log('🚀 ~ file: index.vue ~ line 106 ~ handleSynchDb ~ res', res);
-  }
-
-  // 导入
-  function handleImportTable(record) {
-    openModalTable(true, {
-      record,
-    });
-  }
-
-  // 生成按钮事件
-  async function handleGenTable(record: Recordable) {
-    const isGen = getSelectRows().length ? true : false;
-    console.log(
-      '🚀 ~ file: index.vue:123 ~ handleGenTable ~ getSelectRows().length ',
-      getSelectRows().length,
-    );
-    let streamData = '';
-    let fileName = '';
-    if (isGen) {
-      const tables = getSelectRows()
-        .map(ele => {
-          return ele.tableName;
-        })
-        .join(',');
-      streamData = await genBatchGenCode(tables);
-      fileName = tables;
-    } else {
-      streamData = await genBatchGenCode(record.tableName);
-      fileName = record.tableName;
-    }
-    console.log('🚀 ~ file: index.vue:139 ~ handleGenTable ~ streamData', streamData);
-    downloadByData(streamData, `${fileName}.zip`);
-    console.log(record);
-    // let url = GenBatchGenCode();
-  }
-  // 详情按钮事件
-  async function handleSuccess(record: Recordable) {
-    console.log(record);
-    await reload();
-  }
-</script> -->
-
-<template>
-  <div />
-</template>
-
-<script setup lang="ts"></script>
-
-<style scoped></style>

+ 156 - 139
src/views/sys/sysGen/index.vue

@@ -1,149 +1,166 @@
 <template>
-  <!-- 样式完全自定义 -->
   <div>
-    <div class="flex">
-      <div class="flex-row justify-center flex-wrap">
-        <div class="title">基础元素</div>
-        <!-- tid 与 defaultElementTypeProvider 中对应 -->
-        <!-- 包含 class="ep-draggable-item" -->
-        <div class="ep-draggable-item item" tid="defaultModule.text">
-          <i class="iconfont sv-text" />
-          <span>文本</span>
-        </div>
-        <div class="ep-draggable-item item" tid="defaultModule.image">
-          <i class="iconfont sv-image" />
-          <span>图片</span>
-        </div>
-        <div class="ep-draggable-item item" tid="defaultModule.table">
-          <i class="iconfont sv-table" />
-          <span>表格</span>
-        </div>
-      </div>
-      <div class="flex-5 center">
-        <!-- 设计器的 容器 -->
-        <div id="hiprint-printTemplate" />
-      </div>
-      <div class="flex-2 right">
-        <!-- 元素参数的 容器 -->
-        <div id="PrintElementOptionSetting" />
-      </div>
-    </div>
-    <div>
-      <a-button class="api circle-10 ml-10" @click.stop="exportJson">
-        <i class="iconfont sv-export" />
-        导出模板 json
-      </a-button>
-      <a-button class="api circle-10 ml-10" @click.stop="exportJsonTid">
-        导出模板 json tid
-        <i class="iconfont sv-export" />
-      </a-button>
-      <a-button class="secondary circle-10 ml-10" @click.stop="print">
-        <i class="iconfont sv-printer" />
-        浏览器打印
-      </a-button>
-    </div>
-    <div class="container hidden" />
+    <BasicTable @register="registerTable">
+      <template #toolbar>
+        <a-button type="warning" @click="handleImportTable">导入</a-button>
+        <a-button type="success" @click="handleGenTable">生成</a-button>
+        <a-button type="danger" @click="handleDelete">删除</a-button>
+      </template>
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key == 'action'">
+          <TableAction
+            :actions="[
+              {
+                tooltip: '预览',
+                label: '预览',
+                onClick: handlePreview.bind(null, record),
+              },
+              {
+                tooltip: '编辑',
+                label: '编辑',
+                onClick: handleEditTable.bind(null, record),
+              },
+              {
+                tooltip: '删除',
+                label: '删除',
+                onClick: handleDelete.bind(null, record),
+              },
+              {
+                tooltip: '同步',
+                label: '同步',
+                onClick: handleSynchDb.bind(null, record),
+              },
+              {
+                tooltip: '生成代码',
+                label: '生成代码',
+                onClick: handleGenTable.bind(null, record),
+              },
+            ]"
+          />
+        </template>
+      </template>
+    </BasicTable>
+    <PreviewModal @register="registerModal" @success="handleSuccess" />
+    <EditModal @register="registerModalEdit" @success="handleSuccess" />
+    <TableModal @register="registerModalTable" @success="handleSuccess" />
   </div>
 </template>
+<script lang="ts" setup>
+  import { BasicTable, useTable, TableAction } from '/@/components/Table';
+  import { columns, searchFormSchema } from './data';
+  import { genList, genSynchDb, genRemove, genBatchGenCode } from '/@/api/sys/sysGenApi';
+  import { useModal } from '/@/components/Modal';
+  import PreviewModal from './PreviewModal.vue';
+  import EditModal from './EditModal.vue';
+  import TableModal from './TableModal.vue';
+  import { downloadByData } from '/@/utils/file/download';
+  import { useMessage } from '/@/hooks/web/useMessage';
 
-<script setup lang="ts">
-  import { onMounted, ref } from 'vue';
-  import printData from './printData';
-  import { disAutoConnect, hiprint, defaultElementTypeProvider } from 'vue-plugin-hiprint';
-  console.log('🚀 ~ file: index.vue:30 ~ hiprint:', hiprint);
-  // autoConnect(); // 默认 自动连接直接打印客户端
-  disAutoConnect(); // 取消自动连接直接打印客户端
-  hiprint.init({
-    providers: [defaultElementTypeProvider()],
+  const { createMessage } = useMessage();
+  const [registerModal, { openModal }] = useModal();
+  const [registerModalTable, { openModal: openModalTable }] = useModal();
+  const [registerModalEdit, { openModal: openModalEdit }] = useModal();
+  const [registerTable, { getSelectRowKeys, getSelectRows, reload }] = useTable({
+    title: '代码生成列表',
+    api: genList,
+    rowKey: 'tableId',
+    rowSelection: { type: 'checkbox' },
+    clickToRowSelect: false,
+    columns,
+    formConfig: {
+      labelWidth: 120,
+      schemas: searchFormSchema,
+      autoSubmitOnEnter: true,
+      baseColProps: { xs: 24, sm: 12, md: 12, lg: 8 },
+      resetButtonOptions: {
+        preIcon: 'ant-design:delete-outlined',
+      },
+      submitButtonOptions: {
+        preIcon: 'ant-design:search-outlined',
+      },
+    },
+    showIndexColumn: true,
+    indexColumnProps: {
+      fixed: 'left',
+    },
+    useSearchForm: true,
+    showTableSetting: true,
+    bordered: true,
+    actionColumn: {
+      width: 300,
+      title: '操作',
+      dataIndex: 'action',
+    },
   });
-  let hiprintTemplate;
-  // 判断是否已成功连接
-  if (hiprint.hiwebSocket.opened) {
-    // 注意:连接是异步的
-    // 已连接
-    const list = hiprint.hiwebSocket.getPrinterList();
-    console.log('🚀 ~ file: index.vue:43 ~ list:', list);
-    console.log('hiprintTemplate', hiprint.PrintTemplate({}));
-  } else {
-    hiprint.hiwebSocket.setHost('http://localhost:17521');
+
+  // 预览按钮事件
+  function handlePreview(record: Recordable) {
+    console.log(record);
+    openModal(true, {
+      record,
+    });
+  }
+  // 编辑按钮事件
+  function handleEditTable(record: Recordable) {
+    console.log(record);
+    openModalEdit(true, {
+      record,
+    });
+  }
+  // 删除按钮事件
+  async function handleDelete(record: Recordable) {
+    const isGen = getSelectRowKeys().length ? true : false;
+    if (isGen) {
+      await genRemove(getSelectRowKeys());
+    } else {
+      await genRemove([record.tableId]);
+    }
+    await reload();
+  }
+  // 同步按钮事件
+  async function handleSynchDb(record: Recordable) {
+    console.log(record);
+    const res = await genSynchDb({ tableName: record.tableName });
+    createMessage.success('同步成功');
+    console.log('🚀 ~ file: index.vue ~ line 106 ~ handleSynchDb ~ res', res);
   }
-  /**
-   * 这里必须要在 onMounted 中去构建 左侧可拖拽元素 或者 设计器
-   * 因为都是把元素挂载到对应容器中, 必须要先找到该容器
-   */
-  onMounted(() => {
-    buildLeftElement();
-    buildDesigner();
-  });
-  /**
-   * 构建左侧可拖拽元素
-   * 注意: 可拖拽元素必须在 hiprint.init() 之后调用
-   * 而且 必须包含 class="ep-draggable-item" 否则无法拖拽进设计器
-   */
-  const buildLeftElement = () => {
-    // eslint-disable-next-line no-undef
-    hiprint.PrintElementTypeManager.buildByHtml($('.ep-draggable-item'));
-  };
 
-  const buildDesigner = () => {
-    // eslint-disable-next-line no-undef
-    $('#hiprint-printTemplate').empty(); // 先清空, 避免重复构建
-    hiprintTemplate = new hiprint.PrintTemplate({
-      settingContainer: '#PrintElementOptionSetting', // 元素参数容器
+  // 导入
+  function handleImportTable(record) {
+    openModalTable(true, {
+      record,
     });
-    // 构建 并填充到 容器中
-    hiprintTemplate.design('#hiprint-printTemplate');
-  };
-  /**
-   * 导出模板 json
-   * 必须确保 hiprintTemplate 已成功创建
-   */
-  const exportJson = () => {
-    const json = hiprintTemplate.getJson();
-    console.log(json);
-    console.log('hiprintTemplate', hiprintTemplate);
-    const html = hiprintTemplate.getHtml(printData);
-    console.log('🚀 ~ file: index.vue:106 ~ exportJson ~ html:', html);
-    // alert('导出成功! 请查看控制台输出');
-    hiprintTemplate.print(printData);
-    setTimeout(() => {
-      const container = document.querySelector('.container');
-      container.innerHTML = '';
-      container.innerHTML = html[0].innerHTML;
-      const len = document.querySelectorAll('.container .hiprint-printPaper').length;
-      console.log('🚀 ~ file: index.vue:115 ~ exportJson ~ len:', len);
-      console.info(`共有${len}页`);
-    }, 10);
-  };
-  /**
-   * 导出模板 json tid
-   * 仅导出 options, 不导出 printElementType
-   * 必须确保 hiprintTemplate 已成功创建
-   */
-  const exportJsonTid = () => {
-    const json = hiprintTemplate.getJsonTid();
-    console.log(json);
-    alert('导出成功! 请查看控制台输出');
-  };
-  /**
-   * 浏览器打印
-   */
-  const print = () => {
-    // 参数: 打印时设置 左偏移量,上偏移量
-    const options = { leftOffset: -1, topOffset: -1 };
-    // 扩展
-    const ext = {
-      callback: () => {
-        console.log('浏览器打印窗口已打开');
-      },
-      styleHandler: () => {
-        // 重写 文本 打印样式
-        return '<style>.hiprint-printElement-text{color:red !important;}</style>';
-      },
-    };
-    // 调用浏览器打印
-    hiprintTemplate.print(printData, options, ext);
-  };
-</script>
+  }
 
-<style scoped></style>
+  // 生成按钮事件
+  async function handleGenTable(record: Recordable) {
+    const isGen = getSelectRows().length ? true : false;
+    console.log(
+      '🚀 ~ file: index.vue:123 ~ handleGenTable ~ getSelectRows().length ',
+      getSelectRows().length,
+    );
+    let streamData = '';
+    let fileName = '';
+    if (isGen) {
+      const tables = getSelectRows()
+        .map(ele => {
+          return ele.tableName;
+        })
+        .join(',');
+      streamData = await genBatchGenCode(tables);
+      fileName = tables;
+    } else {
+      streamData = await genBatchGenCode(record.tableName);
+      fileName = record.tableName;
+    }
+    console.log('🚀 ~ file: index.vue:139 ~ handleGenTable ~ streamData', streamData);
+    downloadByData(streamData, `${fileName}.zip`);
+    console.log(record);
+    // let url = GenBatchGenCode();
+  }
+  // 详情按钮事件
+  async function handleSuccess(record: Recordable) {
+    console.log(record);
+    await reload();
+  }
+</script>

+ 0 - 7
src/views/sys/sysGen/preview.vue

@@ -1,7 +0,0 @@
-<script setup lang="ts"></script>
-
-<template>
-  <div />
-</template>
-
-<style scoped></style>

+ 5 - 5
src/views/sys/sysMenu/sysMenuTable/FormModal.vue

@@ -61,11 +61,11 @@
         ...resData,
         // 设置默认值
         parentId: resData.parentId === '0' ? null : resData.parentId,
-        visible: resData.visible ? '1' : '0',
-        disable: resData.disable ? '1' : '0',
-        keepalive: resData.keepalive ? '0' : '1',
-        linkExternal: resData.linkExternal ? '1' : '0',
-        frame: resData.frame ? '1' : '0',
+        visible: resData.visible,
+        disable: resData.disable,
+        keepalive: resData.keepalive ? 0 : 1,
+        linkExternal: resData.linkExternal,
+        frame: resData.frame,
         tenantMenu: !resData.tenantMenu ? '0' : resData.tenantMenu.toString(),
       });
     } else {

+ 14 - 11
src/views/sys/sysUser/sysUserTable/FormModal.vue

@@ -6,7 +6,7 @@
     :title="getTitle"
     @ok="handleSubmit"
     width="900px"
-    ><!-- :maskClosable="false" -->
+  >
     <BasicForm @register="registerForm" />
   </BasicModal>
 </template>
@@ -27,15 +27,16 @@
   const rowId = ref();
 
   const { createMessage } = useMessage();
-  const [registerForm, { setFieldsValue, resetFields, validate, updateSchema, getFieldsValue }] = useForm({
-    labelWidth: 100,
-    schemas: dataFormSchema,
-    showActionButtonGroup: false,
-    actionColOptions: {
-      span: 23,
-    },
-    baseColProps: { lg: 12, md: 24 },
-  });
+  const [registerForm, { setFieldsValue, resetFields, validate, updateSchema, getFieldsValue }] =
+    useForm({
+      labelWidth: 100,
+      schemas: dataFormSchema,
+      showActionButtonGroup: false,
+      actionColOptions: {
+        span: 23,
+      },
+      baseColProps: { lg: 12, md: 24 },
+    });
   const [registerModal, { setModalProps, closeModal }] = useModalInner(async data => {
     await resetFields();
     setModalProps({ confirmLoading: false });
@@ -73,7 +74,9 @@
       setModalProps({ confirmLoading: true });
       console.log('values', values);
       console.log('values::::::::', values);
-      !unref(isUpdate) ? await sysUserAdd({ ...values }) : await sysUserEdit({ ...values, id: rowId.value });
+      !unref(isUpdate)
+        ? await sysUserAdd({ ...values })
+        : await sysUserEdit({ ...values, id: rowId.value });
       !unref(isUpdate) ? createMessage.success('新增成功!') : createMessage.success('编辑成功!');
       closeModal();
       emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });

+ 5 - 30
src/views/sys/sysUser/sysUserTable/data.ts

@@ -19,20 +19,15 @@ export const columns: BasicColumn[] = [
     dataIndex: 'sex',
     width: 120,
   },
-  {
-    title: '姓名',
-    dataIndex: 'realname',
-    width: 120,
-  },
   {
     title: '手机号',
     dataIndex: 'phone',
     width: 140,
   },
   {
-    title: '排序',
-    dataIndex: 'sort',
-    width: 80,
+    title: '邮箱',
+    dataIndex: 'email',
+    width: 140,
   },
   {
     title: '状态',
@@ -41,7 +36,7 @@ export const columns: BasicColumn[] = [
   },
   {
     title: '备注',
-    dataIndex: 'remarks',
+    dataIndex: 'remark',
   },
 ];
 
@@ -62,14 +57,6 @@ export const searchFormSchema: FormSchema[] = [
       placeholder: '请输入昵称',
     },
   },
-  {
-    field: 'realname',
-    label: '姓名',
-    component: 'Input',
-    componentProps: {
-      placeholder: '请输入姓名',
-    },
-  },
   {
     field: 'phone',
     label: '手机号',
@@ -152,7 +139,7 @@ export const dataFormSchema: FormSchema[] = [
     label: '角色',
     component: 'ApiSelect',
     // rules: [{ required: true, message: '请选择角色', trigger: 'change' }],
-    required: true,
+    // required: true,
     itemProps: {
       validateTrigger: 'blur',
     },
@@ -167,18 +154,6 @@ export const dataFormSchema: FormSchema[] = [
       };
     },
   },
-  {
-    field: 'sort',
-    label: '排序',
-    component: 'InputNumber',
-    required: true,
-    defaultValue: '1',
-    componentProps: {
-      placeholder: '请输入排序',
-      style: 'width: 100%',
-      min: 1,
-    },
-  },
   {
     field: 'disable',
     label: '状态',

+ 3 - 0
vite.config.ts

@@ -120,6 +120,9 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
         '@ant-design/icons-vue',
         '@vue/runtime-core',
         '@vue/shared',
+        '@codemirror/lang-java',
+        '@codemirror/lang-json',
+        'codemirror',
         'ant-design-vue/es/locale/zh_CN',
       ],
     },