Pārlūkot izejas kodu

perf: (emit) 优化emits事件

gemercheung 3 gadi atpakaļ
vecāks
revīzija
4cd3a51a6c

+ 131 - 130
src/views/advertisement/list.vue

@@ -1,130 +1,131 @@
-<template>
-  <div class="p-4">
-    <BasicTable @register="registerTable">
-      <template #toolbar>
-        <a-button type="primary" @click="handleCreate">新增</a-button>
-      </template>
-      <template #time="{ record }">
-        <Time v-if="record.createTime" :value="record.createTime" mode="date" />
-      </template>
-      <template #img="{ record }">
-        <TableImg :size="200" :simpleShow="true" :imgList="[record.image]" />
-      </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              label: '编辑',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              color: 'error',
-              label: '删除',
-              popConfirm: {
-                title: '是否确认删除',
-                confirm: deleteConfirm.bind(null, record),
-              },
-            },
-          ]"
-        />
-      </template>
-    </BasicTable>
-    <listDrawer @register="registerDrawer" @reload="reload" />
-  </div>
-</template>
-<script lang="ts">
-  import { defineComponent } from 'vue';
-  import { BasicTable, useTable, BasicColumn, TableAction, TableImg } from '/@/components/Table';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { useDrawer } from '/@/components/Drawer';
-  import { Time } from '/@/components/Time';
-  import listDrawer from './listDrawer.vue';
-  import { ListApi, itemDeletelApi } from '/@/api/advertisement/list';
-  // param type 2
-  export default defineComponent({
-    components: { BasicTable, TableAction, TableImg, listDrawer, Time },
-    setup() {
-      const { createMessage } = useMessage();
-      const [registerDrawer, { openDrawer }] = useDrawer();
-      const columns: BasicColumn[] = [
-        {
-          title: '序号',
-          dataIndex: 'id',
-          fixed: 'left',
-          width: 100,
-        },
-        {
-          title: '封面',
-          dataIndex: 'image',
-          ellipsis: true,
-          slots: { customRender: 'img' },
-          width: 230,
-        },
-        {
-          title: '标题',
-          dataIndex: 'title',
-          width: 230,
-        },
-        {
-          title: '排序',
-          dataIndex: 'orderNum',
-          width: 100,
-        },
-        {
-          title: '编辑时间',
-          dataIndex: 'createTime',
-          slots: { customRender: 'time' },
-          width: 150,
-        },
-
-        {
-          title: '操作',
-          dataIndex: '',
-          fixed: 'right',
-          slots: { customRender: 'action' },
-          width: 130,
-        },
-      ];
-
-      // { getForm }
-      const [registerTable, { reload }] = useTable({
-        title: '轮播图',
-        api: ListApi,
-        columns: columns,
-        useSearchForm: false,
-
-        showTableSetting: true,
-        tableSetting: { fullScreen: true },
-        showIndexColumn: false,
-        rowKey: 'id',
-      });
-
-      function handleCreate() {
-        openDrawer(true, {
-          isUpdate: false,
-        });
-      }
-      function handleEdit(record: Recordable) {
-        openDrawer(true, {
-          record,
-          isUpdate: true,
-        });
-      }
-      function deleteConfirm(val) {
-        itemDeletelApi({ id: val.id }).then((res) => {
-          createMessage.success(res);
-          reload();
-        });
-      }
-      return {
-        deleteConfirm,
-        reload,
-        registerTable,
-        createMessage,
-        registerDrawer,
-        handleCreate,
-        handleEdit,
-      };
-    },
-  });
-</script>
+<template>
+  <div class="p-4">
+    <BasicTable @register="registerTable">
+      <template #toolbar>
+        <a-button type="primary" @click="handleCreate">新增</a-button>
+      </template>
+      <template #time="{ record }">
+        <Time v-if="record.createTime" :value="record.createTime" mode="date" />
+      </template>
+      <template #img="{ record }">
+        <TableImg :size="200" :simpleShow="true" :imgList="[record.image]" />
+      </template>
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '编辑',
+              onClick: handleEdit.bind(null, record),
+            },
+            {
+              color: 'error',
+              label: '删除',
+              popConfirm: {
+                title: '是否确认删除',
+                confirm: deleteConfirm.bind(null, record),
+              },
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <listDrawer @register="registerDrawer" @reload="reload" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTable, useTable, BasicColumn, TableAction, TableImg } from '/@/components/Table';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useDrawer } from '/@/components/Drawer';
+  import { Time } from '/@/components/Time';
+  import listDrawer from './listDrawer.vue';
+  import { ListApi, itemDeletelApi } from '/@/api/advertisement/list';
+  // param type 2
+  export default defineComponent({
+    components: { BasicTable, TableAction, TableImg, listDrawer, Time },
+    emits: ['register', 'reload'],
+    setup() {
+      const { createMessage } = useMessage();
+      const [registerDrawer, { openDrawer }] = useDrawer();
+      const columns: BasicColumn[] = [
+        {
+          title: '序号',
+          dataIndex: 'id',
+          fixed: 'left',
+          width: 100,
+        },
+        {
+          title: '封面',
+          dataIndex: 'image',
+          ellipsis: true,
+          slots: { customRender: 'img' },
+          width: 230,
+        },
+        {
+          title: '标题',
+          dataIndex: 'title',
+          width: 230,
+        },
+        {
+          title: '排序',
+          dataIndex: 'orderNum',
+          width: 100,
+        },
+        {
+          title: '编辑时间',
+          dataIndex: 'createTime',
+          slots: { customRender: 'time' },
+          width: 150,
+        },
+
+        {
+          title: '操作',
+          dataIndex: '',
+          fixed: 'right',
+          slots: { customRender: 'action' },
+          width: 130,
+        },
+      ];
+
+      // { getForm }
+      const [registerTable, { reload }] = useTable({
+        title: '轮播图',
+        api: ListApi,
+        columns: columns,
+        useSearchForm: false,
+
+        showTableSetting: true,
+        tableSetting: { fullScreen: true },
+        showIndexColumn: false,
+        rowKey: 'id',
+      });
+
+      function handleCreate() {
+        openDrawer(true, {
+          isUpdate: false,
+        });
+      }
+      function handleEdit(record: Recordable) {
+        openDrawer(true, {
+          record,
+          isUpdate: true,
+        });
+      }
+      function deleteConfirm(val) {
+        itemDeletelApi({ id: val.id }).then((res) => {
+          createMessage.success(res);
+          reload();
+        });
+      }
+      return {
+        deleteConfirm,
+        reload,
+        registerTable,
+        createMessage,
+        registerDrawer,
+        handleCreate,
+        handleEdit,
+      };
+    },
+  });
+</script>

+ 98 - 97
src/views/advertisement/listDrawer.vue

@@ -1,97 +1,98 @@
-<template>
-  <BasicDrawer
-    v-bind="$attrs"
-    width="50%"
-    :showDetailBack="false"
-    :title="getTitle"
-    @register="registerDrawer"
-  >
-    <BasicForm @register="registerForm" />
-  </BasicDrawer>
-</template>
-<script lang="ts">
-  import { defineComponent, ref, unref, computed } from 'vue';
-  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
-  import { BasicForm, useForm } from '/@/components/Form';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { schemas } from './schemas';
-  import { itemUpdateApi, itemSaveApi } from '/@/api/advertisement/list';
-  export default defineComponent({
-    components: { BasicDrawer, BasicForm },
-    setup(_, { emit }) {
-      const { createMessage } = useMessage();
-      const modelRef = ref({});
-      const isUpdate = ref(true);
-      const [registerForm, { validate, setProps, resetFields, setFieldsValue }] = useForm({
-        labelCol: {
-          span: 4,
-        },
-        wrapperCol: {
-          span: 18,
-        },
-        schemas: schemas,
-        actionColOptions: {
-          offset: 8,
-          span: 8,
-        },
-        submitButtonOptions: {
-          text: '提交',
-        },
-        submitFunc: summitAddDrawer,
-      });
-      const getTitle = computed(() => (!unref(isUpdate) ? '新增轮播资讯' : '编辑轮播资讯'));
-      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
-        resetFields();
-        setDrawerProps({ confirmLoading: false });
-        isUpdate.value = !!data?.isUpdate;
-        modelRef.value = data.record;
-        if (unref(isUpdate)) {
-          console.log('data.record', data.record);
-          setFieldsValue({
-            ...data.record,
-            image: [data.record.image],
-          });
-        }
-      });
-
-      async function summitAddDrawer() {
-        try {
-          let data = await validate();
-          let httpApi = unref(isUpdate) ? itemUpdateApi : itemSaveApi;
-          setProps({
-            submitButtonOptions: {
-              loading: true,
-            },
-          });
-          console.log('data', data, modelRef.value);
-          httpApi({
-            ...modelRef.value,
-            ...data,
-            image: data.image[0],
-          }).then((res) => {
-            console.log('itemUpdateApi', res);
-            setProps({
-              submitButtonOptions: {
-                loading: false,
-              },
-            });
-            createMessage.success('提交成功!');
-            emit('reload');
-            closeDrawer();
-          });
-
-          // setTimeout(() => {
-
-          // }, 2000);
-        } catch (error) {}
-      }
-
-      return {
-        registerForm,
-        getTitle,
-        registerDrawer,
-        closeDrawer,
-      };
-    },
-  });
-</script>
+<template>
+  <BasicDrawer
+    v-bind="$attrs"
+    width="50%"
+    :showDetailBack="false"
+    :title="getTitle"
+    @register="registerDrawer"
+  >
+    <BasicForm @register="registerForm" />
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref, computed } from 'vue';
+  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+  import { BasicForm, useForm } from '/@/components/Form';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { schemas } from './schemas';
+  import { itemUpdateApi, itemSaveApi } from '/@/api/advertisement/list';
+  export default defineComponent({
+    components: { BasicDrawer, BasicForm },
+    emits: ['register', 'reload'],
+    setup(_, { emit }) {
+      const { createMessage } = useMessage();
+      const modelRef = ref({});
+      const isUpdate = ref(true);
+      const [registerForm, { validate, setProps, resetFields, setFieldsValue }] = useForm({
+        labelCol: {
+          span: 4,
+        },
+        wrapperCol: {
+          span: 18,
+        },
+        schemas: schemas,
+        actionColOptions: {
+          offset: 8,
+          span: 8,
+        },
+        submitButtonOptions: {
+          text: '提交',
+        },
+        submitFunc: summitAddDrawer,
+      });
+      const getTitle = computed(() => (!unref(isUpdate) ? '新增轮播资讯' : '编辑轮播资讯'));
+      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+        resetFields();
+        setDrawerProps({ confirmLoading: false });
+        isUpdate.value = !!data?.isUpdate;
+        modelRef.value = data.record;
+        if (unref(isUpdate)) {
+          console.log('data.record', data.record);
+          setFieldsValue({
+            ...data.record,
+            image: [data.record.image],
+          });
+        }
+      });
+
+      async function summitAddDrawer() {
+        try {
+          let data = await validate();
+          let httpApi = unref(isUpdate) ? itemUpdateApi : itemSaveApi;
+          setProps({
+            submitButtonOptions: {
+              loading: true,
+            },
+          });
+          console.log('data', data, modelRef.value);
+          httpApi({
+            ...modelRef.value,
+            ...data,
+            image: data.image[0],
+          }).then((res) => {
+            console.log('itemUpdateApi', res);
+            setProps({
+              submitButtonOptions: {
+                loading: false,
+              },
+            });
+            createMessage.success('提交成功!');
+            emit('reload');
+            closeDrawer();
+          });
+
+          // setTimeout(() => {
+
+          // }, 2000);
+        } catch (error) {}
+      }
+
+      return {
+        registerForm,
+        getTitle,
+        registerDrawer,
+        closeDrawer,
+      };
+    },
+  });
+</script>

+ 147 - 146
src/views/advertisement/pads.vue

@@ -1,146 +1,147 @@
-<template>
-  <div class="p-4">
-    <BasicTable @register="registerTable">
-      <template #toolbar>
-        <a-button type="primary" @click="handleCreate">新增</a-button>
-      </template>
-      <template #img="{ record }">
-        <TableImg :size="90" :simpleShow="true" :imgList="[record.image]" />
-      </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              label: '编辑',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              color: 'error',
-              label: '删除',
-              popConfirm: {
-                title: '是否确认删除',
-                confirm: handleDelete.bind(null, record),
-              },
-            },
-          ]"
-        />
-      </template>
-    </BasicTable>
-    <PadsDrawer :type="type" @register="registerDrawer" @reload="reload" />
-  </div>
-</template>
-<script lang="ts">
-  import { defineComponent, h } from 'vue';
-  import { BasicTable, useTable, BasicColumn, TableAction, TableImg } from '/@/components/Table';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  // import { Tag } from 'ant-design-vue';
-  import PadsDrawer from './padsDrawer.vue';
-  import { RecommendListApi, RecommendDeleteApi } from '/@/api/advertisement/list';
-  import { useDrawer } from '/@/components/Drawer';
-  import { Time } from '/@/components/Time';
-  import { useRoute } from 'vue-router';
-  import { useI18n } from '/@/hooks/web/useI18n';
-  // param type 2
-  export default defineComponent({
-    components: { BasicTable, TableAction, TableImg, PadsDrawer },
-    setup() {
-      const { t } = useI18n();
-      const { createMessage } = useMessage();
-      const [registerDrawer, { openDrawer }] = useDrawer();
-      const route = useRoute();
-      console.log('searchForm', route, route.fullPath);
-      const type = route.fullPath.split('/').pop(); //charAt(route.fullPath.length - 2) || '1';
-      const columns: BasicColumn[] = [
-        {
-          title: '排序',
-          dataIndex: 'orderNum',
-          fixed: 'left',
-          width: 100,
-        },
-        {
-          title: '封面',
-          dataIndex: 'image',
-          ellipsis: true,
-          slots: { customRender: 'img' },
-          width: 230,
-        },
-        {
-          title: '标题',
-          dataIndex: 'title',
-          width: 230,
-        },
-        {
-          title: '直播间链接',
-          dataIndex: 'sceneUrl',
-          width: 300,
-        },
-        {
-          title: '编辑时间',
-          dataIndex: 'createTime',
-          width: 150,
-          customRender: ({ record }) => {
-            return (
-              record.createTime &&
-              h(Time, {
-                value: record.createTime,
-                mode: 'datetime',
-              })
-            );
-          },
-        },
-
-        {
-          title: '操作',
-          dataIndex: '',
-          fixed: 'right',
-          slots: { customRender: 'action' },
-          width: 130,
-        },
-      ];
-
-      const [registerTable, { getForm, reload }] = useTable({
-        title: '推荐位',
-        api: RecommendListApi,
-        columns: columns,
-        // useSearchForm: true,
-        // formConfig: searchForm,
-        showTableSetting: true,
-        tableSetting: { fullScreen: true },
-        showIndexColumn: false,
-        rowKey: 'id',
-        searchInfo: {
-          type,
-        },
-      });
-      function handleCreate() {
-        openDrawer(true, {
-          isUpdate: false,
-          ...getForm().getFieldsValue(),
-        });
-      }
-      async function handleDelete(record: Recordable) {
-        let res = await RecommendDeleteApi({ id: record.id });
-        console.log(res);
-        createMessage.success(t('common.optSuccess'));
-        reload();
-      }
-      function handleEdit(record: Recordable) {
-        openDrawer(true, {
-          record,
-          ...getForm().getFieldsValue(),
-          isUpdate: true,
-        });
-      }
-      return {
-        registerTable,
-        createMessage,
-        registerDrawer,
-        handleCreate,
-        handleEdit,
-        reload,
-        type,
-        handleDelete,
-      };
-    },
-  });
-</script>
+<template>
+  <div class="p-4">
+    <BasicTable @register="registerTable">
+      <template #toolbar>
+        <a-button type="primary" @click="handleCreate">新增</a-button>
+      </template>
+      <template #img="{ record }">
+        <TableImg :size="90" :simpleShow="true" :imgList="[record.image]" />
+      </template>
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '编辑',
+              onClick: handleEdit.bind(null, record),
+            },
+            {
+              color: 'error',
+              label: '删除',
+              popConfirm: {
+                title: '是否确认删除',
+                confirm: handleDelete.bind(null, record),
+              },
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <PadsDrawer :type="type" @register="registerDrawer" @reload="reload" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, h } from 'vue';
+  import { BasicTable, useTable, BasicColumn, TableAction, TableImg } from '/@/components/Table';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  // import { Tag } from 'ant-design-vue';
+  import PadsDrawer from './padsDrawer.vue';
+  import { RecommendListApi, RecommendDeleteApi } from '/@/api/advertisement/list';
+  import { useDrawer } from '/@/components/Drawer';
+  import { Time } from '/@/components/Time';
+  import { useRoute } from 'vue-router';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  // param type 2
+  export default defineComponent({
+    components: { BasicTable, TableAction, TableImg, PadsDrawer },
+    emits: ['register'],
+    setup() {
+      const { t } = useI18n();
+      const { createMessage } = useMessage();
+      const [registerDrawer, { openDrawer }] = useDrawer();
+      const route = useRoute();
+      console.log('searchForm', route, route.fullPath);
+      const type = route.fullPath.split('/').pop(); //charAt(route.fullPath.length - 2) || '1';
+      const columns: BasicColumn[] = [
+        {
+          title: '排序',
+          dataIndex: 'orderNum',
+          fixed: 'left',
+          width: 100,
+        },
+        {
+          title: '封面',
+          dataIndex: 'image',
+          ellipsis: true,
+          slots: { customRender: 'img' },
+          width: 230,
+        },
+        {
+          title: '标题',
+          dataIndex: 'title',
+          width: 230,
+        },
+        {
+          title: '直播间链接',
+          dataIndex: 'sceneUrl',
+          width: 300,
+        },
+        {
+          title: '编辑时间',
+          dataIndex: 'createTime',
+          width: 150,
+          customRender: ({ record }) => {
+            return (
+              record.createTime &&
+              h(Time, {
+                value: record.createTime,
+                mode: 'datetime',
+              })
+            );
+          },
+        },
+
+        {
+          title: '操作',
+          dataIndex: '',
+          fixed: 'right',
+          slots: { customRender: 'action' },
+          width: 130,
+        },
+      ];
+
+      const [registerTable, { getForm, reload }] = useTable({
+        title: '推荐位',
+        api: RecommendListApi,
+        columns: columns,
+        // useSearchForm: true,
+        // formConfig: searchForm,
+        showTableSetting: true,
+        tableSetting: { fullScreen: true },
+        showIndexColumn: false,
+        rowKey: 'id',
+        searchInfo: {
+          type,
+        },
+      });
+      function handleCreate() {
+        openDrawer(true, {
+          isUpdate: false,
+          ...getForm().getFieldsValue(),
+        });
+      }
+      async function handleDelete(record: Recordable) {
+        let res = await RecommendDeleteApi({ id: record.id });
+        console.log(res);
+        createMessage.success(t('common.optSuccess'));
+        reload();
+      }
+      function handleEdit(record: Recordable) {
+        openDrawer(true, {
+          record,
+          ...getForm().getFieldsValue(),
+          isUpdate: true,
+        });
+      }
+      return {
+        registerTable,
+        createMessage,
+        registerDrawer,
+        handleCreate,
+        handleEdit,
+        reload,
+        type,
+        handleDelete,
+      };
+    },
+  });
+</script>

+ 106 - 106
src/views/advertisement/padsDrawer.vue

@@ -1,106 +1,106 @@
-<template>
-  <BasicDrawer
-    v-bind="$attrs"
-    width="50%"
-    :showDetailBack="false"
-    :title="getTitle"
-    @register="registerDrawer"
-  >
-    <BasicForm @register="registerForm" />
-  </BasicDrawer>
-</template>
-<script lang="ts">
-  import { defineComponent, computed, ref, unref } from 'vue';
-  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
-  import { BasicForm, useForm } from '/@/components/Form';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { padsSchemas } from './schemas';
-  import { padsSaveApi, padsUpdateApi } from '/@/api/advertisement/list';
-
-  export default defineComponent({
-    components: { BasicDrawer, BasicForm },
-    props: {
-      type: {
-        type: String,
-        default: '0',
-      },
-    },
-    emits: ['reload'],
-    setup(props, { emit }) {
-      const { createMessage } = useMessage();
-      const modelRef = ref({
-        type: props.type,
-      });
-      const isUpdate = ref(true);
-      const [registerForm, { validate, setProps, resetFields, setFieldsValue }] = useForm({
-        labelCol: {
-          span: 4,
-        },
-        wrapperCol: {
-          span: 18,
-        },
-        schemas: padsSchemas,
-        actionColOptions: {
-          offset: 8,
-          span: 8,
-        },
-        submitButtonOptions: {
-          text: '提交',
-        },
-        submitFunc: summitAddDrawer,
-      });
-
-      async function summitAddDrawer() {
-        try {
-          let data = await validate();
-          let httpApi = unref(isUpdate) ? padsUpdateApi : padsSaveApi;
-          setProps({
-            submitButtonOptions: {
-              loading: true,
-            },
-          });
-          httpApi({
-            ...modelRef.value,
-            ...data,
-            image: data.image[0],
-          }).then((_) => {
-            setProps({
-              submitButtonOptions: {
-                loading: false,
-              },
-            });
-            createMessage.success('提交成功!');
-            emit('reload');
-            closeDrawer();
-          });
-        } catch (error) {
-          console.log('error', error);
-        }
-      }
-      const getTitle = computed(() => (!unref(isUpdate) ? '新增推荐位' : '编辑推荐位'));
-      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
-        resetFields();
-        setDrawerProps({ confirmLoading: false });
-        isUpdate.value = !!data?.isUpdate;
-        modelRef.value = {
-          ...data.record,
-          type: props.type,
-        };
-
-        if (unref(isUpdate)) {
-          console.log('data.record', data.record);
-          setFieldsValue({
-            ...data.record,
-            image: [data.record.image],
-          });
-        }
-      });
-      return {
-        registerForm,
-        getTitle,
-        registerDrawer,
-        closeDrawer,
-      };
-    },
-  });
-</script>
+<template>
+  <BasicDrawer
+    v-bind="$attrs"
+    width="50%"
+    :showDetailBack="false"
+    :title="getTitle"
+    @register="registerDrawer"
+  >
+    <BasicForm @register="registerForm" />
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent, computed, ref, unref } from 'vue';
+  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+  import { BasicForm, useForm } from '/@/components/Form';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { padsSchemas } from './schemas';
+  import { padsSaveApi, padsUpdateApi } from '/@/api/advertisement/list';
+
+  export default defineComponent({
+    components: { BasicDrawer, BasicForm },
+    props: {
+      type: {
+        type: String,
+        default: '0',
+      },
+    },
+    emits: ['register', 'reload'],
+    setup(props, { emit }) {
+      const { createMessage } = useMessage();
+      const modelRef = ref({
+        type: props.type,
+      });
+      const isUpdate = ref(true);
+      const [registerForm, { validate, setProps, resetFields, setFieldsValue }] = useForm({
+        labelCol: {
+          span: 4,
+        },
+        wrapperCol: {
+          span: 18,
+        },
+        schemas: padsSchemas,
+        actionColOptions: {
+          offset: 8,
+          span: 8,
+        },
+        submitButtonOptions: {
+          text: '提交',
+        },
+        submitFunc: summitAddDrawer,
+      });
+
+      async function summitAddDrawer() {
+        try {
+          let data = await validate();
+          let httpApi = unref(isUpdate) ? padsUpdateApi : padsSaveApi;
+          setProps({
+            submitButtonOptions: {
+              loading: true,
+            },
+          });
+          httpApi({
+            ...modelRef.value,
+            ...data,
+            image: data.image[0],
+          }).then((_) => {
+            setProps({
+              submitButtonOptions: {
+                loading: false,
+              },
+            });
+            createMessage.success('提交成功!');
+            emit('reload');
+            closeDrawer();
+          });
+        } catch (error) {
+          console.log('error', error);
+        }
+      }
+      const getTitle = computed(() => (!unref(isUpdate) ? '新增推荐位' : '编辑推荐位'));
+      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+        resetFields();
+        setDrawerProps({ confirmLoading: false });
+        isUpdate.value = !!data?.isUpdate;
+        modelRef.value = {
+          ...data.record,
+          type: props.type,
+        };
+
+        if (unref(isUpdate)) {
+          console.log('data.record', data.record);
+          setFieldsValue({
+            ...data.record,
+            image: [data.record.image],
+          });
+        }
+      });
+      return {
+        registerForm,
+        getTitle,
+        registerDrawer,
+        closeDrawer,
+      };
+    },
+  });
+</script>

+ 116 - 116
src/views/product/addModal.vue

@@ -1,116 +1,116 @@
-<template>
-  <BasicModal
-    v-bind="$attrs"
-    @register="register"
-    @cancel="resetFields"
-    title="新 增"
-    @ok="handleOk"
-  >
-    <div class="pt-3px pr-3px">
-      <BasicForm @register="registerForm" :model="model" />
-    </div>
-  </BasicModal>
-</template>
-<script lang="ts">
-  import { defineComponent, ref } from 'vue';
-  import { saveItemApi } from '/@/api/product/category';
-  import { BasicModal, useModalInner } from '/@/components/Modal';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { useI18n } from '/@/hooks/web/useI18n';
-  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
-  const schemas: FormSchema[] = [
-    {
-      field: 'name',
-      component: 'Input',
-      label: '商品属性',
-      colProps: {
-        span: 18,
-      },
-      required: true,
-      componentProps: {
-        maxLength: 15,
-      },
-    },
-    {
-      field: 'sortOrder',
-      component: 'InputNumber',
-      label: '排序',
-      defaultValue: 1,
-      rules: [
-        {
-          required: false,
-          // @ts-ignore
-          validator: async (rule, value) => {
-            if (value && (value < 0 || value > 1000)) {
-              return Promise.reject('请输入正确的排序');
-            }
-            return Promise.resolve();
-          },
-          trigger: 'change',
-        },
-      ],
-      colProps: {
-        span: 24,
-      },
-    },
-  ];
-  export default defineComponent({
-    components: { BasicModal, BasicForm },
-    props: {
-      userData: { type: Object },
-    },
-    emits: ['saveadd'],
-    setup(_, context) {
-      const modelRef = ref({});
-      const { createMessage } = useMessage();
-      const { t } = useI18n();
-      const [
-        registerForm,
-        {
-          // setFieldsValue,
-          validate,
-          resetFields,
-          // getFieldsValue,
-        },
-      ] = useForm({
-        labelWidth: 120,
-        schemas,
-        showActionButtonGroup: false,
-        actionColOptions: {
-          span: 24,
-        },
-      });
-
-      const [register, { closeModal }] = useModalInner((data) => {
-        data && onDataReceive(data);
-      });
-
-      function onDataReceive(data) {
-        console.log('Data Received', data);
-        // 方式1;
-        // setFieldsValue({
-        //   field2: data.data,
-        //   field1: data.info,
-        // });
-
-        // // 方式2
-        modelRef.value = { field2: data.data, field1: data.info };
-
-        // setProps({
-        //   model:{ field2: data.data, field1: data.info }
-        // })
-      }
-
-      async function handleOk() {
-        let data = await validate();
-        let res = await saveItemApi(data);
-        context && context.emit('saveadd', res);
-        createMessage.success(t('common.optSuccess'));
-        closeModal();
-        resetFields();
-      }
-
-      return { register, resetFields, schemas, registerForm, model: modelRef, handleOk, t };
-    },
-  });
-</script>
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    @cancel="resetFields"
+    title="新 增"
+    @ok="handleOk"
+  >
+    <div class="pt-3px pr-3px">
+      <BasicForm @register="registerForm" :model="model" />
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref } from 'vue';
+  import { saveItemApi } from '/@/api/product/category';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  const schemas: FormSchema[] = [
+    {
+      field: 'name',
+      component: 'Input',
+      label: '商品属性',
+      colProps: {
+        span: 18,
+      },
+      required: true,
+      componentProps: {
+        maxLength: 15,
+      },
+    },
+    {
+      field: 'sortOrder',
+      component: 'InputNumber',
+      label: '排序',
+      defaultValue: 1,
+      rules: [
+        {
+          required: false,
+          // @ts-ignore
+          validator: async (rule, value) => {
+            if (value && (value < 0 || value > 1000)) {
+              return Promise.reject('请输入正确的排序');
+            }
+            return Promise.resolve();
+          },
+          trigger: 'change',
+        },
+      ],
+      colProps: {
+        span: 24,
+      },
+    },
+  ];
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['register', 'saveadd'],
+    setup(_, context) {
+      const modelRef = ref({});
+      const { createMessage } = useMessage();
+      const { t } = useI18n();
+      const [
+        registerForm,
+        {
+          // setFieldsValue,
+          validate,
+          resetFields,
+          // getFieldsValue,
+        },
+      ] = useForm({
+        labelWidth: 120,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+
+      function onDataReceive(data) {
+        console.log('Data Received', data);
+        // 方式1;
+        // setFieldsValue({
+        //   field2: data.data,
+        //   field1: data.info,
+        // });
+
+        // // 方式2
+        modelRef.value = { field2: data.data, field1: data.info };
+
+        // setProps({
+        //   model:{ field2: data.data, field1: data.info }
+        // })
+      }
+
+      async function handleOk() {
+        let data = await validate();
+        let res = await saveItemApi(data);
+        context && context.emit('saveadd', res);
+        createMessage.success(t('common.optSuccess'));
+        closeModal();
+        resetFields();
+      }
+
+      return { register, resetFields, schemas, registerForm, model: modelRef, handleOk, t };
+    },
+  });
+</script>

+ 171 - 170
src/views/product/category.vue

@@ -1,170 +1,171 @@
-<template>
-  <div>
-    <BasicTable @register="registerTable">
-      <template #toolbar v-if="!getCheckRole('tourist')">
-        <a-button primary color="error" @click="handleCreate"> 新增商品分类</a-button>
-        <!-- <a-button ghost color="warning" @click="expandAll">展开全部</a-button>
-        <a-button type="primary" @click="collapseAll">折叠全部</a-button> -->
-      </template>
-      <template #action="{ record }">
-        <TableAction
-          :actions="[
-            {
-              label: '编辑',
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              color: 'error',
-              label: '删除',
-              popConfirm: {
-                title: '是否确认删除',
-                confirm: handleDelete.bind(null, record),
-              },
-            },
-          ]"
-        />
-      </template>
-    </BasicTable>
-    <AddCategoryModal @register="registeraddCategoryModal" @update="reload" />
-    <EditCategoryModal @register="registerEditCategoryModal" @update="reload" />
-  </div>
-</template>
-
-<script lang="ts">
-  import { defineComponent, h, nextTick } from 'vue';
-  import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
-  import { categoryApi, deleteCategoryApi } from '/@/api/product/category';
-  import { Tag } from 'ant-design-vue';
-
-  import { useI18n } from '/@/hooks/web/useI18n';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { makeTree } from '/@/utils/treeUtils';
-  import { useUserStore } from '/@/store/modules/user';
-
-  import AddCategoryModal from './addCategoryModal.vue';
-  import EditCategoryModal from './editCategoryModal.vue';
-  import { useModal } from '/@/components/Modal';
-
-  export default defineComponent({
-    components: { BasicTable, TableAction, AddCategoryModal, EditCategoryModal },
-    setup() {
-      const { createMessage } = useMessage();
-      const userStore = useUserStore();
-      const { getCheckRole } = userStore;
-      const { t } = useI18n();
-
-      const columns: BasicColumn[] = [
-        {
-          title: 'ID',
-          dataIndex: 'id',
-          fixed: 'left',
-          width: 100,
-        },
-        {
-          title: '分类名称',
-          dataIndex: 'name',
-          width: 200,
-          align: 'left',
-        },
-        {
-          title: '排序',
-          dataIndex: 'sortOrder',
-          width: 50,
-        },
-        {
-          title: '级数',
-          dataIndex: 'level',
-          width: 50,
-        },
-        {
-          title: '状态',
-          dataIndex: 'isShow',
-          width: 80,
-          customRender: ({ record }) => {
-            const status = record.isShow;
-            const enable = status === 1;
-            const color = enable ? 'green' : 'red';
-            const text = enable ? '显示' : '不显示';
-            return h(Tag, { color: color }, () => text);
-          },
-        },
-        // {
-        //   title: '创建时间',
-        //   dataIndex: 'createTime',
-        //   width: 180,
-        // },
-      ];
-      const [registeraddCategoryModal, { openModal: openAddCategoryModal }] = useModal();
-      const [registerEditCategoryModal, { openModal: openEditategoryModal }] = useModal();
-      const [registerTable, { reload, expandAll, collapseAll }] = useTable({
-        title: '商品分类',
-        api: categoryApi,
-        columns: columns,
-        isTreeTable: true,
-        useSearchForm: true,
-        formConfig: {
-          labelWidth: 100,
-          schemas: [
-            {
-              field: 'name',
-              label: '分类名称',
-              component: 'Input',
-              componentProps: {
-                placeholder: '请输入分类名称',
-                maxLength: 100,
-              },
-              colProps: {
-                xl: 6,
-                xxl: 6,
-              },
-            },
-          ],
-        },
-        showTableSetting: true,
-        tableSetting: { fullScreen: true },
-        showIndexColumn: true,
-        pagination: false,
-        rowKey: 'id',
-        bordered: true,
-        actionColumn: {
-          ifShow: !getCheckRole('tourist'),
-          width: 100,
-          title: '操作',
-          dataIndex: 'action',
-          slots: { customRender: 'action' },
-          fixed: undefined,
-        },
-        afterFetch(data) {
-          const treeData = makeTree(data);
-          return treeData;
-        },
-      });
-
-      function handleCreate(record: Recordable) {
-        openAddCategoryModal(true, record);
-      }
-      function handleEdit(record: Recordable) {
-        openEditategoryModal(true, record);
-      }
-      async function handleDelete(record: Recordable) {
-        await deleteCategoryApi([record.id]);
-        createMessage.success(t('common.optSuccess'));
-        nextTick(reload);
-      }
-      return {
-        registerTable,
-        createMessage,
-        t,
-        handleCreate,
-        handleEdit,
-        handleDelete,
-        expandAll,
-        collapseAll,
-        registeraddCategoryModal,
-        registerEditCategoryModal,
-        reload,
-        getCheckRole,
-      };
-    },
-  });
-</script>
+<template>
+  <div>
+    <BasicTable @register="registerTable">
+      <template #toolbar v-if="!getCheckRole('tourist')">
+        <a-button primary color="error" @click="handleCreate"> 新增商品分类</a-button>
+        <!-- <a-button ghost color="warning" @click="expandAll">展开全部</a-button>
+        <a-button type="primary" @click="collapseAll">折叠全部</a-button> -->
+      </template>
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '编辑',
+              onClick: handleEdit.bind(null, record),
+            },
+            {
+              color: 'error',
+              label: '删除',
+              popConfirm: {
+                title: '是否确认删除',
+                confirm: handleDelete.bind(null, record),
+              },
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <AddCategoryModal @register="registeraddCategoryModal" @update="reload" />
+    <EditCategoryModal @register="registerEditCategoryModal" @update="reload" />
+  </div>
+</template>
+
+<script lang="ts">
+  import { defineComponent, h, nextTick } from 'vue';
+  import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
+  import { categoryApi, deleteCategoryApi } from '/@/api/product/category';
+  import { Tag } from 'ant-design-vue';
+
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { makeTree } from '/@/utils/treeUtils';
+  import { useUserStore } from '/@/store/modules/user';
+
+  import AddCategoryModal from './addCategoryModal.vue';
+  import EditCategoryModal from './editCategoryModal.vue';
+  import { useModal } from '/@/components/Modal';
+
+  export default defineComponent({
+    components: { BasicTable, TableAction, AddCategoryModal, EditCategoryModal },
+    emits: ['register'],
+    setup() {
+      const { createMessage } = useMessage();
+      const userStore = useUserStore();
+      const { getCheckRole } = userStore;
+      const { t } = useI18n();
+
+      const columns: BasicColumn[] = [
+        {
+          title: 'ID',
+          dataIndex: 'id',
+          fixed: 'left',
+          width: 100,
+        },
+        {
+          title: '分类名称',
+          dataIndex: 'name',
+          width: 200,
+          align: 'left',
+        },
+        {
+          title: '排序',
+          dataIndex: 'sortOrder',
+          width: 50,
+        },
+        {
+          title: '级数',
+          dataIndex: 'level',
+          width: 50,
+        },
+        {
+          title: '状态',
+          dataIndex: 'isShow',
+          width: 80,
+          customRender: ({ record }) => {
+            const status = record.isShow;
+            const enable = status === 1;
+            const color = enable ? 'green' : 'red';
+            const text = enable ? '显示' : '不显示';
+            return h(Tag, { color: color }, () => text);
+          },
+        },
+        // {
+        //   title: '创建时间',
+        //   dataIndex: 'createTime',
+        //   width: 180,
+        // },
+      ];
+      const [registeraddCategoryModal, { openModal: openAddCategoryModal }] = useModal();
+      const [registerEditCategoryModal, { openModal: openEditategoryModal }] = useModal();
+      const [registerTable, { reload, expandAll, collapseAll }] = useTable({
+        title: '商品分类',
+        api: categoryApi,
+        columns: columns,
+        isTreeTable: true,
+        useSearchForm: true,
+        formConfig: {
+          labelWidth: 100,
+          schemas: [
+            {
+              field: 'name',
+              label: '分类名称',
+              component: 'Input',
+              componentProps: {
+                placeholder: '请输入分类名称',
+                maxLength: 100,
+              },
+              colProps: {
+                xl: 6,
+                xxl: 6,
+              },
+            },
+          ],
+        },
+        showTableSetting: true,
+        tableSetting: { fullScreen: true },
+        showIndexColumn: true,
+        pagination: false,
+        rowKey: 'id',
+        bordered: true,
+        actionColumn: {
+          ifShow: !getCheckRole('tourist'),
+          width: 100,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          fixed: undefined,
+        },
+        afterFetch(data) {
+          const treeData = makeTree(data);
+          return treeData;
+        },
+      });
+
+      function handleCreate(record: Recordable) {
+        openAddCategoryModal(true, record);
+      }
+      function handleEdit(record: Recordable) {
+        openEditategoryModal(true, record);
+      }
+      async function handleDelete(record: Recordable) {
+        await deleteCategoryApi([record.id]);
+        createMessage.success(t('common.optSuccess'));
+        nextTick(reload);
+      }
+      return {
+        registerTable,
+        createMessage,
+        t,
+        handleCreate,
+        handleEdit,
+        handleDelete,
+        expandAll,
+        collapseAll,
+        registeraddCategoryModal,
+        registerEditCategoryModal,
+        reload,
+        getCheckRole,
+      };
+    },
+  });
+</script>

+ 1 - 1
src/views/product/goodsSpecs.vue

@@ -73,7 +73,7 @@
         default: () => {},
       },
     },
-    emits: ['update', 'editdata'],
+    emits: ['update', 'editdata', 'register'],
     setup(props, { emit }) {
       let ggList = reactive({
         goodsNumber: 1,

+ 1 - 0
src/views/product/list.vue

@@ -84,6 +84,7 @@
 
   export default defineComponent({
     components: { BasicTable, TableAction, ProductDrawer, Time, PopConfirmButton },
+    emits: ['register'],
     setup() {
       const { createMessage } = useMessage();
       const go = useGo();

+ 347 - 347
src/views/product/productDrawer.vue

@@ -1,347 +1,347 @@
-<template>
-  <BasicDrawer
-    v-bind="$attrs"
-    @register="registerDrawer"
-    :isDetail="true"
-    :showDetailBack="false"
-    showFooter
-    :title="getTitle"
-    @ok="handleSubmit"
-  >
-    <BasicForm @register="registerForm">
-      <template #goodsgg>
-        <goodsSpecs :key="editData.id" :editdata="editData" @update="setEditData" ref="goodsRef" />
-      </template>
-      <template #detailed>
-        <table class="detailed">
-          <thead>
-            <tr style="" v-show="editData.productList.length > 0">
-              <th style="min-width: 60px">{{ editData.categoryName }}</th>
-              <th>库存</th>
-              <th>规格编码</th>
-              <th>市场价</th>
-              <th>销售价</th>
-            </tr>
-          </thead>
-          <tbody>
-            <tr v-for="item in editData.productList" :key="item.uuidLink">
-              <template v-if="editData.productList">
-                <td
-                  :title="item.name"
-                  style="
-                    max-width: 120px;
-                    overflow: hidden;
-                    white-space: nowrap;
-                    text-overflow: ellipsis;
-                  "
-                  >{{ item.name }}</td
-                >
-                <td
-                  ><InputNumber
-                    type="number"
-                    :maxlength="8"
-                    :max="100000000"
-                    :min="0"
-                    v-model:value="item.goodsNumber"
-                /></td>
-                <td
-                  ><Input
-                    type="text"
-                    :maxlength="8"
-                    :max="100000000"
-                    :min="0"
-                    v-model:value="item.goodsSn"
-                /></td>
-                <td
-                  ><InputNumber
-                    type="number"
-                    :maxlength="8"
-                    :max="100000000"
-                    :min="0"
-                    v-model:value="item.marketPrice"
-                /></td>
-                <td
-                  ><InputNumber
-                    type="number"
-                    :maxlength="8"
-                    :max="100000000"
-                    :min="0"
-                    v-model:value="item.retailPrice"
-                /></td>
-              </template>
-            </tr>
-          </tbody>
-        </table>
-      </template>
-      <!-- <template #formItem>
-        <BasicForm @register="itemRegister" @submit="handleSubmit">
-          <template #add="{ field }">
-            <a-button v-if="Number(field) === 0" @click="add">+</a-button>
-            <a-button v-if="field > 0" @click="del.bind(null, field)">-</a-button>
-          </template>
-        </BasicForm>
-      </template> -->
-    </BasicForm>
-  </BasicDrawer>
-</template>
-<script lang="ts">
-  import { defineComponent, ref, computed, unref } from 'vue';
-  import { BasicForm, useForm } from '/@/components/Form/index';
-  import { Input, InputNumber } from 'ant-design-vue';
-  import { formSchema } from './drawer.data';
-  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
-  import goodsSpecs from './goodsSpecs.vue';
-  import { InfoApi, UpdateSaleApi, SaveSaleApi } from '/@/api/product/list';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { useI18n } from '/@/hooks/web/useI18n';
-  import { useUserStore } from '/@/store/modules/user';
-  // import { getMenuList } from '/@/api/system/system';
-  import { makeTree, TreeNode } from '/@/utils/treeUtils';
-  import { categoryApi } from '/@/api/product/category';
-
-  interface EditDataType {
-    categoryName: string;
-    productList: ProductListItem[];
-    goodsSpecificationList?: goodsSpecificationList[];
-    id: number;
-  }
-  interface goodsSpecificationList {
-    brandName: string;
-    goodsId?: number;
-    goodsName: string;
-    id?: number;
-    picUrl: string;
-    specificationId?: number;
-    specificationName: string;
-    uuid: string;
-    val?: string | number | [];
-    value: string;
-  }
-  interface ProductListItem {
-    uuidLink: string;
-    goodsNumber?: string;
-    goodsSn: string;
-    retailPrice: string;
-    marketPrice: string;
-    name?: string;
-  }
-
-  export default defineComponent({
-    name: 'ProductDrawer',
-    components: { BasicDrawer, BasicForm, goodsSpecs, Input, InputNumber },
-    emits: ['reload', 'register'],
-    setup(_, { emit }) {
-      const isUpdate = ref(true);
-      const goodsRef = ref();
-      const { createMessage } = useMessage();
-      const userStore = useUserStore();
-      const userinfo = computed(() => userStore.getUserInfo);
-      const { t } = useI18n();
-
-      let editData = ref<EditDataType>({
-        categoryName: '',
-        productList: [],
-        id: 0,
-      });
-
-      const [registerForm, { resetFields, updateSchema, setFieldsValue, validate }] = useForm({
-        labelWidth: 120,
-        schemas: formSchema,
-        showActionButtonGroup: false,
-        baseColProps: { lg: 18, md: 18, offset: 1 },
-      });
-      const [itemRegister, {}] = useForm({
-        // formItemValue :validate appendSchemaByField, removeSchemaByFiled,
-        schemas: [
-          {
-            field: 'goodsId',
-            label: '规格名',
-            component: 'ApiTreeSelect',
-            componentProps: {
-              api: async (params) => {
-                const res = (await categoryApi(params)) as any as TreeNode[];
-                const treeData = makeTree(res);
-                return treeData;
-              },
-              maxLength: 15,
-              fieldNames: {
-                label: 'name',
-                key: 'id',
-                value: 'id',
-              },
-            },
-          },
-          {
-            field: 'goodsSn',
-            component: 'Input',
-            label: '字段0',
-            colProps: {
-              span: 8,
-            },
-            required: true,
-          },
-          {
-            field: '0',
-            component: 'Input',
-            label: ' ',
-            colProps: {
-              span: 8,
-            },
-            slot: 'add',
-          },
-        ],
-        labelWidth: 100,
-        actionColOptions: { span: 24 },
-      });
-      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
-        resetFields();
-        setDrawerProps({ confirmLoading: false });
-        isUpdate.value = !!data?.isUpdate;
-        editData.value = {
-          categoryName: '',
-          productList: [],
-          id: 0,
-        };
-        updateSchema({
-          field: 'brandId',
-          componentProps: {
-            disabled: unref(isUpdate) ? true : false,
-          },
-        });
-        if (unref(isUpdate)) {
-          let res = await InfoApi(data.record.id);
-          editData.value = {
-            ...res,
-            productList: res.productList.map((ele) => {
-              console.log('editData', ele, res.goodsSpecificationList);
-              ele.name = res.goodsSpecificationList.find(
-                (element) => element.uuid == ele.uuidLink,
-              )?.specificationName;
-              return ele;
-            }),
-          };
-          setFieldsValue({
-            ...res,
-            isOnSale: res.isOnSale === 1,
-            listPicUrl:
-              res.listPicUrl && res.listPicUrl.split('#$#').map((ele) => ele.split('?')[0]),
-            primaryPicUrl:
-              res.primaryPicUrl && res.primaryPicUrl.split('#$#').map((ele) => ele.split('?')[0]),
-            // primaryPicUrl: res.primaryPicUrl && [encodeURI(res.primaryPicUrl.split('?')[0])],
-            steamRoom: data.record?.steamRoom?.name,
-          });
-        }
-      });
-      function setEditData(value) {
-        let productList = editData.value.productList || [];
-        value.productList.map((ele) => {
-          if (!productList.some((element) => ele.uuidLink == element.uuidLink)) {
-            //判断新增
-            productList.push({
-              uuidLink: ele.uuidLink,
-              name: ele.name,
-              goodsNumber: '',
-              goodsSn: '',
-              marketPrice: '',
-              retailPrice: '',
-            });
-          } else {
-            //本来就有的 修改赋值
-            productList.forEach((setEle) => {
-              if (ele.uuidLink == setEle.uuidLink) {
-                setEle.name = ele.name;
-              }
-            });
-          }
-        });
-        productList = productList.filter((ele) =>
-          value.productList.some((element) => element.uuidLink == ele.uuidLink),
-        );
-        console.log('setEditData', productList);
-        editData.value = {
-          ...editData.value,
-          ...value,
-          productList,
-        };
-        setFieldsValue({
-          productList: productList,
-        });
-      }
-      const getTitle = computed(() => (!unref(isUpdate) ? '新增商品' : '编辑商品'));
-
-      async function handleSubmit() {
-        const { companyId, id } = userinfo.value;
-        try {
-          const values = await validate();
-          console.log('values', values);
-          let apiData = {
-            ...editData.value,
-            ...values,
-            retailPrice:
-              editData.value.productList &&
-              Math.min(...editData.value.productList.map((ele) => Number(ele.retailPrice))),
-            marketPrice:
-              editData.value.productList &&
-              Math.min(...editData.value.productList.map((ele) => Number(ele.marketPrice))),
-            isOnSale: values.isOnSale ? 1 : 0,
-          };
-
-          let requresApi = isUpdate.value ? UpdateSaleApi : SaveSaleApi;
-          if (!isUpdate.value) {
-            apiData.createUserDeptId = companyId;
-            apiData.createUserId = id;
-          }
-          let subData = await requresApi({
-            ...apiData,
-            primaryPicUrl: apiData.primaryPicUrl.join('#$#'),
-            listPicUrl: apiData.listPicUrl.join('#$#'),
-          });
-          console.log('setFieldsValue', subData);
-          setDrawerProps({ confirmLoading: true });
-          // TODO custom api
-          console.log(values);
-          createMessage.success(t('common.optSuccess'));
-          closeDrawer();
-          emit('reload');
-        } finally {
-          setDrawerProps({ confirmLoading: false });
-        }
-      }
-
-      return {
-        goodsRef,
-        registerDrawer,
-        registerForm,
-        itemRegister,
-        getTitle,
-        editData,
-        handleSubmit,
-        setEditData,
-      };
-    },
-  });
-</script>
-
-<style scoped lang="less">
-  :deep(.detailed) {
-    .title {
-      display: flex;
-      span,
-      input,
-      div {
-        flex-grow: 1;
-      }
-      input {
-        display: inline-block;
-      }
-      .name {
-        flex-grow: 2;
-      }
-    }
-    tr {
-      th {
-        font-weight: 500;
-      }
-    }
-  }
-</style>
+<template>
+  <BasicDrawer
+    v-bind="$attrs"
+    @register="registerDrawer"
+    :isDetail="true"
+    :showDetailBack="false"
+    showFooter
+    :title="getTitle"
+    @ok="handleSubmit"
+  >
+    <BasicForm @register="registerForm">
+      <template #goodsgg>
+        <goodsSpecs :key="editData.id" :editdata="editData" @update="setEditData" ref="goodsRef" />
+      </template>
+      <template #detailed>
+        <table class="detailed">
+          <thead>
+            <tr style="" v-show="editData.productList.length > 0">
+              <th style="min-width: 60px">{{ editData.categoryName }}</th>
+              <th>库存</th>
+              <th>规格编码</th>
+              <th>市场价</th>
+              <th>销售价</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr v-for="item in editData.productList" :key="item.uuidLink">
+              <template v-if="editData.productList">
+                <td
+                  :title="item.name"
+                  style="
+                    max-width: 120px;
+                    overflow: hidden;
+                    white-space: nowrap;
+                    text-overflow: ellipsis;
+                  "
+                  >{{ item.name }}</td
+                >
+                <td
+                  ><InputNumber
+                    type="number"
+                    :maxlength="8"
+                    :max="100000000"
+                    :min="0"
+                    v-model:value="item.goodsNumber"
+                /></td>
+                <td
+                  ><Input
+                    type="text"
+                    :maxlength="8"
+                    :max="100000000"
+                    :min="0"
+                    v-model:value="item.goodsSn"
+                /></td>
+                <td
+                  ><InputNumber
+                    type="number"
+                    :maxlength="8"
+                    :max="100000000"
+                    :min="0"
+                    v-model:value="item.marketPrice"
+                /></td>
+                <td
+                  ><InputNumber
+                    type="number"
+                    :maxlength="8"
+                    :max="100000000"
+                    :min="0"
+                    v-model:value="item.retailPrice"
+                /></td>
+              </template>
+            </tr>
+          </tbody>
+        </table>
+      </template>
+      <!-- <template #formItem>
+        <BasicForm @register="itemRegister" @submit="handleSubmit">
+          <template #add="{ field }">
+            <a-button v-if="Number(field) === 0" @click="add">+</a-button>
+            <a-button v-if="field > 0" @click="del.bind(null, field)">-</a-button>
+          </template>
+        </BasicForm>
+      </template> -->
+    </BasicForm>
+  </BasicDrawer>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, computed, unref } from 'vue';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { Input, InputNumber } from 'ant-design-vue';
+  import { formSchema } from './drawer.data';
+  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
+  import goodsSpecs from './goodsSpecs.vue';
+  import { InfoApi, UpdateSaleApi, SaveSaleApi } from '/@/api/product/list';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useUserStore } from '/@/store/modules/user';
+  // import { getMenuList } from '/@/api/system/system';
+  import { makeTree, TreeNode } from '/@/utils/treeUtils';
+  import { categoryApi } from '/@/api/product/category';
+
+  interface EditDataType {
+    categoryName: string;
+    productList: ProductListItem[];
+    goodsSpecificationList?: goodsSpecificationList[];
+    id: number;
+  }
+  interface goodsSpecificationList {
+    brandName: string;
+    goodsId?: number;
+    goodsName: string;
+    id?: number;
+    picUrl: string;
+    specificationId?: number;
+    specificationName: string;
+    uuid: string;
+    val?: string | number | [];
+    value: string;
+  }
+  interface ProductListItem {
+    uuidLink: string;
+    goodsNumber?: string;
+    goodsSn: string;
+    retailPrice: string;
+    marketPrice: string;
+    name?: string;
+  }
+
+  export default defineComponent({
+    name: 'ProductDrawer',
+    components: { BasicDrawer, BasicForm, goodsSpecs, Input, InputNumber },
+    emits: ['reload', 'register'],
+    setup(_, { emit }) {
+      const isUpdate = ref(true);
+      const goodsRef = ref();
+      const { createMessage } = useMessage();
+      const userStore = useUserStore();
+      const userinfo = computed(() => userStore.getUserInfo);
+      const { t } = useI18n();
+
+      let editData = ref<EditDataType>({
+        categoryName: '',
+        productList: [],
+        id: 0,
+      });
+
+      const [registerForm, { resetFields, updateSchema, setFieldsValue, validate }] = useForm({
+        labelWidth: 120,
+        schemas: formSchema,
+        showActionButtonGroup: false,
+        baseColProps: { lg: 18, md: 18, offset: 1 },
+      });
+      const [itemRegister, {}] = useForm({
+        // formItemValue :validate appendSchemaByField, removeSchemaByFiled,
+        schemas: [
+          {
+            field: 'goodsId',
+            label: '规格名',
+            component: 'ApiTreeSelect',
+            componentProps: {
+              api: async (params) => {
+                const res = (await categoryApi(params)) as any as TreeNode[];
+                const treeData = makeTree(res);
+                return treeData;
+              },
+              maxLength: 15,
+              fieldNames: {
+                label: 'name',
+                key: 'id',
+                value: 'id',
+              },
+            },
+          },
+          {
+            field: 'goodsSn',
+            component: 'Input',
+            label: '字段0',
+            colProps: {
+              span: 8,
+            },
+            required: true,
+          },
+          {
+            field: '0',
+            component: 'Input',
+            label: ' ',
+            colProps: {
+              span: 8,
+            },
+            slot: 'add',
+          },
+        ],
+        labelWidth: 100,
+        actionColOptions: { span: 24 },
+      });
+      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
+        resetFields();
+        setDrawerProps({ confirmLoading: false });
+        isUpdate.value = !!data?.isUpdate;
+        editData.value = {
+          categoryName: '',
+          productList: [],
+          id: 0,
+        };
+        updateSchema({
+          field: 'brandId',
+          componentProps: {
+            disabled: unref(isUpdate) ? true : false,
+          },
+        });
+        if (unref(isUpdate)) {
+          let res = await InfoApi(data.record.id);
+          editData.value = {
+            ...res,
+            productList: res.productList.map((ele) => {
+              console.log('editData', ele, res.goodsSpecificationList);
+              ele.name = res.goodsSpecificationList.find(
+                (element) => element.uuid == ele.uuidLink,
+              )?.specificationName;
+              return ele;
+            }),
+          };
+          setFieldsValue({
+            ...res,
+            isOnSale: res.isOnSale === 1,
+            listPicUrl:
+              res.listPicUrl && res.listPicUrl.split('#$#').map((ele) => ele.split('?')[0]),
+            primaryPicUrl:
+              res.primaryPicUrl && res.primaryPicUrl.split('#$#').map((ele) => ele.split('?')[0]),
+            // primaryPicUrl: res.primaryPicUrl && [encodeURI(res.primaryPicUrl.split('?')[0])],
+            steamRoom: data.record?.steamRoom?.name,
+          });
+        }
+      });
+      function setEditData(value) {
+        let productList = editData.value.productList || [];
+        value.productList.map((ele) => {
+          if (!productList.some((element) => ele.uuidLink == element.uuidLink)) {
+            //判断新增
+            productList.push({
+              uuidLink: ele.uuidLink,
+              name: ele.name,
+              goodsNumber: '',
+              goodsSn: '',
+              marketPrice: '',
+              retailPrice: '',
+            });
+          } else {
+            //本来就有的 修改赋值
+            productList.forEach((setEle) => {
+              if (ele.uuidLink == setEle.uuidLink) {
+                setEle.name = ele.name;
+              }
+            });
+          }
+        });
+        productList = productList.filter((ele) =>
+          value.productList.some((element) => element.uuidLink == ele.uuidLink),
+        );
+        console.log('setEditData', productList);
+        editData.value = {
+          ...editData.value,
+          ...value,
+          productList,
+        };
+        setFieldsValue({
+          productList: productList,
+        });
+      }
+      const getTitle = computed(() => (!unref(isUpdate) ? '新增商品' : '编辑商品'));
+
+      async function handleSubmit() {
+        const { companyId, id } = userinfo.value;
+        try {
+          const values = await validate();
+          console.log('values', values);
+          let apiData = {
+            ...editData.value,
+            ...values,
+            retailPrice:
+              editData.value.productList &&
+              Math.min(...editData.value.productList.map((ele) => Number(ele.retailPrice))),
+            marketPrice:
+              editData.value.productList &&
+              Math.min(...editData.value.productList.map((ele) => Number(ele.marketPrice))),
+            isOnSale: values.isOnSale ? 1 : 0,
+          };
+
+          let requresApi = isUpdate.value ? UpdateSaleApi : SaveSaleApi;
+          if (!isUpdate.value) {
+            apiData.createUserDeptId = companyId;
+            apiData.createUserId = id;
+          }
+          let subData = await requresApi({
+            ...apiData,
+            primaryPicUrl: apiData.primaryPicUrl.join('#$#'),
+            listPicUrl: apiData.listPicUrl.join('#$#'),
+          });
+          console.log('setFieldsValue', subData);
+          setDrawerProps({ confirmLoading: true });
+          // TODO custom api
+          console.log(values);
+          createMessage.success(t('common.optSuccess'));
+          closeDrawer();
+          emit('reload');
+        } finally {
+          setDrawerProps({ confirmLoading: false });
+        }
+      }
+
+      return {
+        goodsRef,
+        registerDrawer,
+        registerForm,
+        itemRegister,
+        getTitle,
+        editData,
+        handleSubmit,
+        setEditData,
+      };
+    },
+  });
+</script>
+
+<style scoped lang="less">
+  :deep(.detailed) {
+    .title {
+      display: flex;
+      span,
+      input,
+      div {
+        flex-grow: 1;
+      }
+      input {
+        display: inline-block;
+      }
+      .name {
+        flex-grow: 2;
+      }
+    }
+    tr {
+      th {
+        font-weight: 500;
+      }
+    }
+  }
+</style>

+ 225 - 224
src/views/product/ref.vue

@@ -1,224 +1,225 @@
-<template>
-  <div>
-    <BasicTable @register="registerTable">
-      <template #toolbar>
-        <a-button v-show="!getCheckRole('tourist')" type="primary" @click="handleCreate">
-          新增商品属性</a-button
-        >
-      </template>
-      <template #action="{ record, column }">
-        <TableAction :actions="createActions(record, column)" />
-      </template>
-    </BasicTable>
-    <addModal @register="registerModal" @saveadd="handleSaveAdd" />
-  </div>
-</template>
-
-<script lang="ts">
-  import { defineComponent, ref } from 'vue'; // h
-  import {
-    BasicTable,
-    useTable,
-    BasicColumn,
-    TableAction,
-    EditRecordRow,
-    ActionItem,
-  } from '/@/components/Table';
-  import { attributeListApi, attributeDeleteApi, updateItemApi } from '/@/api/product/category';
-  import { cloneDeep } from 'lodash-es';
-  // import { Tag } from 'ant-design-vue';
-  import { useI18n } from '/@/hooks/web/useI18n';
-  import { useModal } from '/@/components/Modal';
-  import addModal from './addModal.vue';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  import { useUserStore } from '/@/store/modules/user';
-
-  export default defineComponent({
-    components: { BasicTable, TableAction, addModal },
-    setup() {
-      const { createConfirm, createMessage: msg } = useMessage();
-      const [registerModal, { openModal }] = useModal();
-      const currentEditKeyRef = ref('');
-      const userStore = useUserStore();
-      const { getCheckRole } = userStore;
-      const { t } = useI18n();
-      console.log('registerModal', registerModal);
-      const columns: BasicColumn[] = [
-        {
-          title: '商品属性',
-          editRow: true,
-          editRule: async (text) => {
-            if (!text) {
-              return '请输入商品属性';
-            }
-            if (text && text.length > 15) {
-              return t('routes.corporation.maxlength');
-            }
-            return '';
-          },
-          dataIndex: 'name',
-          fixed: 'left',
-          width: 100,
-        },
-        {
-          title: '排序',
-          dataIndex: 'sortOrder',
-          editComponent: 'InputNumber',
-          editRule: async (text) => {
-            if (text == null || text < 0) {
-              return '请输入正确排序';
-            }
-            return '';
-          },
-          editRow: true,
-          width: 50,
-        },
-      ];
-
-      const [registerTable, { expandAll, reload, collapseAll }] = useTable({
-        title: '商品属性',
-        api: attributeListApi,
-        columns: columns,
-        useSearchForm: true,
-        showIndexColumn: false,
-        // rowSelection: { type: 'checkbox' },
-        rowKey: 'id',
-        bordered: true,
-        showIndexColumn: true,
-        fetchSetting: {
-          pageField: 'page',
-          sizeField: 'limit',
-          listField: 'list',
-          totalField: 'totalCount',
-        },
-        formConfig: {
-          labelWidth: 66,
-          schemas: [
-            {
-              field: `name`,
-              label: `商品属性`,
-              component: 'Input',
-              colProps: {
-                xl: 6,
-                xxl: 6,
-              },
-              componentProps: {
-                maxLength: 15,
-              },
-            },
-          ],
-        },
-        actionColumn: {
-          ifShow: !getCheckRole('tourist'),
-          width: 160,
-          title: '操作',
-          dataIndex: 'action',
-          slots: { customRender: 'action' },
-        },
-      });
-      async function handleCreate() {
-        openModal(true);
-      }
-      function handleEdit(record: EditRecordRow) {
-        currentEditKeyRef.value = record.key;
-        record.onEdit?.(true);
-      }
-      function handleDelete(record) {
-        createConfirm({
-          iconType: 'warning',
-          title: '警告',
-          content: `此操作将对${record.name}进行删除, 是否继续?`,
-          onOk: async () => {
-            let res = await attributeDeleteApi(record.id);
-            console.log('res', res);
-            reload();
-          },
-        });
-      }
-      function handleCancel(record: EditRecordRow) {
-        currentEditKeyRef.value = '';
-        record.onEdit?.(false, false);
-      }
-      async function handleSaveAdd() {
-        console.log('handleSaveAdd');
-        reload();
-      }
-
-      async function handleSave(record: EditRecordRow) {
-        // 校验
-        msg.loading({ content: '正在保存...', duration: 0, key: 'saving' });
-        const valid = await record.onValid?.();
-        console.log('ref', valid);
-        if (valid) {
-          try {
-            const data = cloneDeep(record.editValueRefs);
-            console.log(data);
-            //TODO 此处将数据提交给服务器保存
-            // ...
-            updateItemApi({
-              id: record.id,
-              ...data,
-            });
-
-            // 保存之后提交编辑状态
-            const pass = await record.onEdit?.(false, true);
-            if (pass) {
-              currentEditKeyRef.value = '';
-            }
-            msg.success({ content: '数据已保存', key: 'saving' });
-            reload();
-          } catch (error) {
-            msg.error({ content: '保存失败', key: 'saving' });
-          }
-        } else {
-          msg.error({ content: '请填写正确的数据', key: 'saving' });
-        }
-      }
-      function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
-        // console.log('editable', record);
-        if (!record.editable) {
-          return [
-            {
-              label: '编辑',
-              disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-              onClick: handleEdit.bind(null, record),
-            },
-            {
-              label: '删除',
-              color: 'error',
-              disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
-              onClick: handleDelete.bind(null, record),
-            },
-          ];
-        }
-        return [
-          {
-            label: '保存',
-            onClick: handleSave.bind(null, record, column),
-          },
-          {
-            label: '取消',
-            popConfirm: {
-              title: '是否取消编辑',
-              confirm: handleCancel.bind(null, record, column),
-            },
-          },
-        ];
-      }
-      return {
-        registerTable,
-        createActions,
-        t,
-        registerModal,
-        handleSaveAdd,
-        handleCreate,
-        handleEdit,
-        handleDelete,
-        expandAll,
-        collapseAll,
-        getCheckRole,
-        reload,
-      };
-    },
-  });
-</script>
+<template>
+  <div>
+    <BasicTable @register="registerTable">
+      <template #toolbar>
+        <a-button v-show="!getCheckRole('tourist')" type="primary" @click="handleCreate">
+          新增商品属性</a-button
+        >
+      </template>
+      <template #action="{ record, column }">
+        <TableAction :actions="createActions(record, column)" />
+      </template>
+    </BasicTable>
+    <addModal @register="registerModal" @saveadd="handleSaveAdd" />
+  </div>
+</template>
+
+<script lang="ts">
+  import { defineComponent, ref } from 'vue'; // h
+  import {
+    BasicTable,
+    useTable,
+    BasicColumn,
+    TableAction,
+    EditRecordRow,
+    ActionItem,
+  } from '/@/components/Table';
+  import { attributeListApi, attributeDeleteApi, updateItemApi } from '/@/api/product/category';
+  import { cloneDeep } from 'lodash-es';
+  // import { Tag } from 'ant-design-vue';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useModal } from '/@/components/Modal';
+  import addModal from './addModal.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useUserStore } from '/@/store/modules/user';
+
+  export default defineComponent({
+    components: { BasicTable, TableAction, addModal },
+    emits: ['register'],
+    setup() {
+      const { createConfirm, createMessage: msg } = useMessage();
+      const [registerModal, { openModal }] = useModal();
+      const currentEditKeyRef = ref('');
+      const userStore = useUserStore();
+      const { getCheckRole } = userStore;
+      const { t } = useI18n();
+      // console.log('registerModal', registerModal);
+      const columns: BasicColumn[] = [
+        {
+          title: '商品属性',
+          editRow: true,
+          editRule: async (text) => {
+            if (!text) {
+              return '请输入商品属性';
+            }
+            if (text && text.length > 15) {
+              return t('routes.corporation.maxlength');
+            }
+            return '';
+          },
+          dataIndex: 'name',
+          fixed: 'left',
+          width: 100,
+        },
+        {
+          title: '排序',
+          dataIndex: 'sortOrder',
+          editComponent: 'InputNumber',
+          editRule: async (text) => {
+            if (text == null || text < 0) {
+              return '请输入正确排序';
+            }
+            return '';
+          },
+          editRow: true,
+          width: 50,
+        },
+      ];
+
+      const [registerTable, { expandAll, reload, collapseAll }] = useTable({
+        title: '商品属性',
+        api: attributeListApi,
+        columns: columns,
+        useSearchForm: true,
+        showIndexColumn: false,
+        // rowSelection: { type: 'checkbox' },
+        rowKey: 'id',
+        bordered: true,
+        showIndexColumn: true,
+        fetchSetting: {
+          pageField: 'page',
+          sizeField: 'limit',
+          listField: 'list',
+          totalField: 'totalCount',
+        },
+        formConfig: {
+          labelWidth: 66,
+          schemas: [
+            {
+              field: `name`,
+              label: `商品属性`,
+              component: 'Input',
+              colProps: {
+                xl: 6,
+                xxl: 6,
+              },
+              componentProps: {
+                maxLength: 15,
+              },
+            },
+          ],
+        },
+        actionColumn: {
+          ifShow: !getCheckRole('tourist'),
+          width: 160,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
+      });
+      async function handleCreate() {
+        openModal(true);
+      }
+      function handleEdit(record: EditRecordRow) {
+        currentEditKeyRef.value = record.key;
+        record.onEdit?.(true);
+      }
+      function handleDelete(record) {
+        createConfirm({
+          iconType: 'warning',
+          title: '警告',
+          content: `此操作将对${record.name}进行删除, 是否继续?`,
+          onOk: async () => {
+            let res = await attributeDeleteApi(record.id);
+            console.log('res', res);
+            reload();
+          },
+        });
+      }
+      function handleCancel(record: EditRecordRow) {
+        currentEditKeyRef.value = '';
+        record.onEdit?.(false, false);
+      }
+      async function handleSaveAdd() {
+        console.log('handleSaveAdd');
+        reload();
+      }
+
+      async function handleSave(record: EditRecordRow) {
+        // 校验
+        msg.loading({ content: '正在保存...', duration: 0, key: 'saving' });
+        const valid = await record.onValid?.();
+        console.log('ref', valid);
+        if (valid) {
+          try {
+            const data = cloneDeep(record.editValueRefs);
+            console.log(data);
+            //TODO 此处将数据提交给服务器保存
+            // ...
+            updateItemApi({
+              id: record.id,
+              ...data,
+            });
+
+            // 保存之后提交编辑状态
+            const pass = await record.onEdit?.(false, true);
+            if (pass) {
+              currentEditKeyRef.value = '';
+            }
+            msg.success({ content: '数据已保存', key: 'saving' });
+            reload();
+          } catch (error) {
+            msg.error({ content: '保存失败', key: 'saving' });
+          }
+        } else {
+          msg.error({ content: '请填写正确的数据', key: 'saving' });
+        }
+      }
+      function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
+        // console.log('editable', record);
+        if (!record.editable) {
+          return [
+            {
+              label: '编辑',
+              disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
+              onClick: handleEdit.bind(null, record),
+            },
+            {
+              label: '删除',
+              color: 'error',
+              disabled: currentEditKeyRef.value ? currentEditKeyRef.value !== record.key : false,
+              onClick: handleDelete.bind(null, record),
+            },
+          ];
+        }
+        return [
+          {
+            label: '保存',
+            onClick: handleSave.bind(null, record, column),
+          },
+          {
+            label: '取消',
+            popConfirm: {
+              title: '是否取消编辑',
+              confirm: handleCancel.bind(null, record, column),
+            },
+          },
+        ];
+      }
+      return {
+        registerTable,
+        createActions,
+        t,
+        registerModal,
+        handleSaveAdd,
+        handleCreate,
+        handleEdit,
+        handleDelete,
+        expandAll,
+        collapseAll,
+        getCheckRole,
+        reload,
+      };
+    },
+  });
+</script>

+ 1 - 1
src/views/rightsEnterprises/BindModal.vue

@@ -37,7 +37,7 @@
     props: {
       userData: { type: Object },
     },
-    emits: ['ok'],
+    emits: ['ok', 'register'],
     setup(_, context) {
       const modelRef = ref({
         isSee: false,

+ 1 - 1
src/views/rightsEnterprises/addCameraModal.vue

@@ -31,7 +31,7 @@
     props: {
       userData: { type: Object },
     },
-    emits: ['ok'],
+    emits: ['ok', 'register'],
     setup(_, context) {
       const modelRef = ref({
         isSee: false,

+ 1 - 0
src/views/rightsEnterprises/camera.vue

@@ -73,6 +73,7 @@
         },
       },
     },
+    emits: ['register'],
     setup(props) {
       const [register, { openModal }] = useModal();
       const surplusSubNum = ref({

+ 1 - 1
src/views/rightsEnterprises/cameraBind.vue

@@ -23,7 +23,7 @@
     props: {
       userData: { type: Object },
     },
-    emits: ['update'],
+    emits: ['register', 'update'],
     setup(_, context) {
       const { t } = useI18n();
       const modelRef = ref({

+ 1 - 0
src/views/rightsEnterprises/cameraList.vue

@@ -74,6 +74,7 @@
       ProductDrawer,
       addCameraModal,
     },
+    emits: ['register', 'update'],
     setup() {
       const router = useRouter();
       const [register, { openModal }] = useModal();

+ 1 - 0
src/views/rightsEnterprises/enterprises.vue

@@ -65,6 +65,7 @@
       Alert,
       addModal,
     },
+    emits: ['register'],
     setup() {
       const [register, { openModal }] = useModal();
       const surplusSubNum = ref({

+ 1 - 0
src/views/rightsEnterprises/list.vue

@@ -88,6 +88,7 @@
         },
       },
     },
+    emits: ['register', 'reload'],
     setup(props) {
       const [register, { openModal }] = useModal();
       const surplusSubNum = ref({

+ 1 - 0
src/views/rightsEnterprises/rightsList.vue

@@ -71,6 +71,7 @@
       addModal,
       ProductDrawer,
     },
+    emits: ['register'],
     setup() {
       const router = useRouter();
       const [register, { openModal }] = useModal();

+ 1 - 0
src/views/rightsEnterprises/staff.vue

@@ -68,6 +68,7 @@
       addModal,
       // DelListModal,
     },
+    emits: ['register'],
     setup() {
       const [register, { openModal }] = useModal();
       const surplusSubNum = ref({

+ 161 - 161
src/views/scenes/downloadModal.vue

@@ -1,161 +1,161 @@
-<template>
-  <BasicModal
-    v-bind="$attrs"
-    @register="register"
-    :title="t('routes.scenes.downloadScene')"
-    :showCancelBtn="false"
-    :okText="downloadInfo.isDownloaded ? t('common.okText') : t('routes.scenes.cancelDownload')"
-    @ok="handleSubmit"
-    @cancel="cancelDownload"
-  >
-    <div class="pt-20px">
-      <BasicForm @register="registerForm">
-        <template #label="{ model, field }">
-          {{ model[field] }}
-        </template>
-        <template #process> {{ downloadInfo.process }} % </template>
-        <template #status> {{ downloadInfo.status }} </template>
-      </BasicForm>
-    </div>
-    <template #centerFooter>
-      <!-- <a-button>xxxx</a-button> -->
-    </template>
-  </BasicModal>
-</template>
-<script lang="ts">
-  import { defineComponent, reactive, ref, watch } from 'vue';
-  import { BasicModal, useModalInner } from '/@/components/Modal';
-  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
-  // import { BasicTable, useTable, BasicColumn, FormSchema } from '/@/components/Table';
-  // import { useMessage } from '/@/hooks/web/useMessage';
-  // import { checkUserAddAble } from '/@/api/corporation/modal';
-  import { useI18n } from '/@/hooks/web/useI18n';
-  import { getDownloadProcessApi } from '/@/api/scene/list';
-  // import { bindAnchorListParam } from '/@/api/scene/model';
-  // import { Time } from '/@/components/Time';
-  // import { useUserStore } from '/@/store/modules/user';
-  import {
-    downloadByUrl,
-    // downloadByData,
-    // downloadByBase64,
-    // downloadByOnlineUrl,
-  } from '/@/utils/file/download';
-
-  const schemas: FormSchema[] = [
-    {
-      field: 'sceneName',
-      label: '场景名称:',
-      component: 'Input',
-      slot: 'label',
-    },
-    {
-      field: 'process',
-      label: '下载进度:',
-      component: 'Input',
-      slot: 'process',
-    },
-    {
-      field: 'status',
-      label: '状态:',
-      component: 'Input',
-      slot: 'status',
-    },
-  ];
-
-  export default defineComponent({
-    components: { BasicModal, BasicForm },
-    props: {
-      userData: { type: Object },
-    },
-    emits: ['register', 'success'],
-    setup() {
-      const { t } = useI18n();
-      // const { createMessage } = useMessage();
-      const sceneNum = ref('');
-      const finishDowloadUrl = ref('');
-      const downloadInfo = reactive<Recordable>({});
-      downloadInfo.timer = null;
-      downloadInfo.process = 0;
-      downloadInfo.status = '下载中';
-      downloadInfo.isDownloaded = false;
-
-      const [registerForm, { setFieldsValue }] = useForm({
-        schemas: schemas,
-        labelWidth: 120,
-        showActionButtonGroup: false,
-
-        actionColOptions: {
-          span: 24,
-        },
-        // submitFunc: handleSubmit,
-      });
-      const [register, { closeModal }] = useModalInner((data) => {
-        data && onDataReceive(data);
-      });
-
-      function onDataReceive(data) {
-        console.log('Data Received', data, data.num);
-
-        setFieldsValue({
-          ...data,
-        });
-
-        sceneNum.value = data.num;
-      }
-      const handleSubmit = async () => {
-        try {
-          cancelDownload();
-          closeModal();
-          if (downloadInfo.isDownloaded) {
-            downloadByUrl({
-              url: finishDowloadUrl.value as any as string,
-              target: '_self',
-            });
-          }
-        } catch (error) {}
-      };
-      async function getDownloadInfo(sceneNum: string) {
-        downloadInfo.timer = setInterval(async () => {
-          const res = await getDownloadProcessApi({ sceneNum });
-          console.log('res', res);
-          const percent = res.percent && Math.round(res.percent);
-          downloadInfo.process = percent;
-          if (res.status === 1000) {
-            downloadInfo.status = '获取中';
-          }
-          if (res.status === 1002 && res.url) {
-            cancelDownload();
-            finishDowloadUrl.value = res.url;
-            downloadInfo.isDownloaded = true;
-            downloadInfo.status = '获取成功';
-            handleSubmit();
-          }
-        }, 2000);
-      }
-      function cancelDownload() {
-        clearInterval(downloadInfo.timer);
-        sceneNum.value = '';
-      }
-      watch(
-        () => sceneNum.value,
-        () => {
-          console.log('sceneNum', sceneNum.value);
-          if (sceneNum.value) {
-            getDownloadInfo(sceneNum.value);
-          }
-        },
-      );
-
-      return {
-        t,
-        register,
-        schemas,
-        handleSubmit,
-        closeModal,
-        registerForm,
-        downloadInfo,
-        cancelDownload,
-      };
-    },
-  });
-</script>
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    :title="t('routes.scenes.downloadScene')"
+    :showCancelBtn="false"
+    :okText="downloadInfo.isDownloaded ? t('common.okText') : t('routes.scenes.cancelDownload')"
+    @ok="handleSubmit"
+    @cancel="cancelDownload"
+  >
+    <div class="pt-20px">
+      <BasicForm @register="registerForm">
+        <template #label="{ model, field }">
+          {{ model[field] }}
+        </template>
+        <template #process> {{ downloadInfo.process }} % </template>
+        <template #status> {{ downloadInfo.status }} </template>
+      </BasicForm>
+    </div>
+    <template #centerFooter>
+      <!-- <a-button>xxxx</a-button> -->
+    </template>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, ref, watch } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  // import { BasicTable, useTable, BasicColumn, FormSchema } from '/@/components/Table';
+  // import { useMessage } from '/@/hooks/web/useMessage';
+  // import { checkUserAddAble } from '/@/api/corporation/modal';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { getDownloadProcessApi } from '/@/api/scene/list';
+  // import { bindAnchorListParam } from '/@/api/scene/model';
+  // import { Time } from '/@/components/Time';
+  // import { useUserStore } from '/@/store/modules/user';
+  import {
+    downloadByUrl,
+    // downloadByData,
+    // downloadByBase64,
+    // downloadByOnlineUrl,
+  } from '/@/utils/file/download';
+
+  const schemas: FormSchema[] = [
+    {
+      field: 'sceneName',
+      label: '场景名称:',
+      component: 'Input',
+      slot: 'label',
+    },
+    {
+      field: 'process',
+      label: '下载进度:',
+      component: 'Input',
+      slot: 'process',
+    },
+    {
+      field: 'status',
+      label: '状态:',
+      component: 'Input',
+      slot: 'status',
+    },
+  ];
+
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['register', 'success'],
+    setup() {
+      const { t } = useI18n();
+      // const { createMessage } = useMessage();
+      const sceneNum = ref('');
+      const finishDowloadUrl = ref('');
+      const downloadInfo = reactive<Recordable>({});
+      downloadInfo.timer = null;
+      downloadInfo.process = 0;
+      downloadInfo.status = '下载中';
+      downloadInfo.isDownloaded = false;
+
+      const [registerForm, { setFieldsValue }] = useForm({
+        schemas: schemas,
+        labelWidth: 120,
+        showActionButtonGroup: false,
+
+        actionColOptions: {
+          span: 24,
+        },
+        // submitFunc: handleSubmit,
+      });
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+
+      function onDataReceive(data) {
+        console.log('Data Received', data, data.num);
+
+        setFieldsValue({
+          ...data,
+        });
+
+        sceneNum.value = data.num;
+      }
+      const handleSubmit = async () => {
+        try {
+          cancelDownload();
+          closeModal();
+          if (downloadInfo.isDownloaded) {
+            downloadByUrl({
+              url: finishDowloadUrl.value as any as string,
+              target: '_self',
+            });
+          }
+        } catch (error) {}
+      };
+      async function getDownloadInfo(sceneNum: string) {
+        downloadInfo.timer = setInterval(async () => {
+          const res = await getDownloadProcessApi({ sceneNum });
+          console.log('res', res);
+          const percent = res.percent && Math.round(res.percent);
+          downloadInfo.process = percent;
+          if (res.status === 1000) {
+            downloadInfo.status = '获取中';
+          }
+          if (res.status === 1002 && res.url) {
+            cancelDownload();
+            finishDowloadUrl.value = res.url;
+            downloadInfo.isDownloaded = true;
+            downloadInfo.status = '获取成功';
+            handleSubmit();
+          }
+        }, 2000);
+      }
+      function cancelDownload() {
+        clearInterval(downloadInfo.timer);
+        sceneNum.value = '';
+      }
+      watch(
+        () => sceneNum.value,
+        () => {
+          console.log('sceneNum', sceneNum.value);
+          if (sceneNum.value) {
+            getDownloadInfo(sceneNum.value);
+          }
+        },
+      );
+
+      return {
+        t,
+        register,
+        schemas,
+        handleSubmit,
+        closeModal,
+        registerForm,
+        downloadInfo,
+        cancelDownload,
+      };
+    },
+  });
+</script>

+ 142 - 142
src/views/scenes/editorModal.vue

@@ -1,142 +1,142 @@
-<template>
-  <BasicModal
-    v-bind="$attrs"
-    @cancel="resetFields"
-    @register="register"
-    title="编辑场景"
-    @ok="handleOk"
-  >
-    <div class="pt-3px pr-3px">
-      <BasicForm @register="registerForm">
-        <template #text="{ model, field }">
-          {{ model[field] }}
-        </template>
-      </BasicForm>
-    </div>
-  </BasicModal>
-</template>
-<script lang="ts">
-  import { defineComponent, ref, unref } from 'vue';
-  import { UpdateApi } from '/@/api/scene/list';
-  import { uploadLiveApi } from '/@/api/scene/live';
-  import { BasicModal, useModalInner } from '/@/components/Modal';
-  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
-  import { useI18n } from '/@/hooks/web/useI18n';
-  import { useMessage } from '/@/hooks/web/useMessage';
-  const { t } = useI18n();
-
-  export default defineComponent({
-    components: { BasicModal, BasicForm },
-    props: {
-      userData: { type: Object },
-    },
-    emits: ['reload'],
-    setup(_, context) {
-      const modelRef = ref({
-        toUserId: 0,
-        userId: 0,
-      });
-      const options = ref([]);
-      const { createMessage } = useMessage();
-      const schemas: FormSchema[] = [
-        {
-          field: 'sceneNum',
-          component: 'Input',
-          label: 'sceneNum',
-          show: false,
-        },
-        {
-          field: 'sceneName',
-          component: 'Input',
-          label: '场景名称',
-          slot: 'text',
-          colProps: {
-            span: 22,
-          },
-        },
-        {
-          field: 'picList',
-          label: '场景封面',
-          component: 'Upload',
-          required: true,
-          itemProps: {
-            validateTrigger: 'blur',
-          },
-          componentProps: {
-            api: uploadLiveApi,
-            maxSize: 5,
-            emptyHidePreview: true,
-            maxNumber: 1,
-            accept: ['jpg', 'jpeg', 'gif', 'png'],
-            afterFetch: function (data) {
-              Reflect.set(data, 'url', data.message.url);
-              return data;
-            },
-          },
-
-          colProps: {
-            span: 20,
-          },
-        },
-        {
-          field: 'isShow',
-          component: 'RadioGroup',
-          label: '是否显示在小程序',
-          required: true,
-          defaultValue: 0,
-          componentProps: {
-            options: [
-              {
-                label: '是',
-                value: 1,
-                key: 1,
-              },
-              {
-                label: '否',
-                value: 0,
-                key: 0,
-              },
-            ],
-          },
-        },
-      ];
-      const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({
-        labelWidth: 150,
-        schemas,
-        showActionButtonGroup: false,
-        actionColOptions: {
-          span: 20,
-        },
-      });
-
-      const [register, { closeModal }] = useModalInner((data) => {
-        data && onDataReceive(data);
-      });
-      function onDataReceive(data) {
-        data = unref(data);
-        console.log('onDataReceive', data);
-        setFieldsValue({
-          ...data,
-          sceneNum: data.num,
-          picList: [data.appListPicUrl],
-        });
-        // 方式1;
-      }
-
-      async function handleOk() {
-        let data = await validate();
-        console.log('data', data);
-        let res = await UpdateApi({
-          ...data,
-          appListPicUrl: data.picList[0],
-        });
-        context && context.emit('reload', res);
-        createMessage.success(t('common.optSuccess'));
-        closeModal();
-        resetFields();
-      }
-
-      return { options, register, registerForm, model: modelRef, handleOk, resetFields };
-    },
-  });
-</script>
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @cancel="resetFields"
+    @register="register"
+    title="编辑场景"
+    @ok="handleOk"
+  >
+    <div class="pt-3px pr-3px">
+      <BasicForm @register="registerForm">
+        <template #text="{ model, field }">
+          {{ model[field] }}
+        </template>
+      </BasicForm>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, unref } from 'vue';
+  import { UpdateApi } from '/@/api/scene/list';
+  import { uploadLiveApi } from '/@/api/scene/live';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  const { t } = useI18n();
+
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['reload', 'register'],
+    setup(_, context) {
+      const modelRef = ref({
+        toUserId: 0,
+        userId: 0,
+      });
+      const options = ref([]);
+      const { createMessage } = useMessage();
+      const schemas: FormSchema[] = [
+        {
+          field: 'sceneNum',
+          component: 'Input',
+          label: 'sceneNum',
+          show: false,
+        },
+        {
+          field: 'sceneName',
+          component: 'Input',
+          label: '场景名称',
+          slot: 'text',
+          colProps: {
+            span: 22,
+          },
+        },
+        {
+          field: 'picList',
+          label: '场景封面',
+          component: 'Upload',
+          required: true,
+          itemProps: {
+            validateTrigger: 'blur',
+          },
+          componentProps: {
+            api: uploadLiveApi,
+            maxSize: 5,
+            emptyHidePreview: true,
+            maxNumber: 1,
+            accept: ['jpg', 'jpeg', 'gif', 'png'],
+            afterFetch: function (data) {
+              Reflect.set(data, 'url', data.message.url);
+              return data;
+            },
+          },
+
+          colProps: {
+            span: 20,
+          },
+        },
+        {
+          field: 'isShow',
+          component: 'RadioGroup',
+          label: '是否显示在小程序',
+          required: true,
+          defaultValue: 0,
+          componentProps: {
+            options: [
+              {
+                label: '是',
+                value: 1,
+                key: 1,
+              },
+              {
+                label: '否',
+                value: 0,
+                key: 0,
+              },
+            ],
+          },
+        },
+      ];
+      const [registerForm, { validate, resetFields, setFieldsValue }] = useForm({
+        labelWidth: 150,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 20,
+        },
+      });
+
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        data = unref(data);
+        console.log('onDataReceive', data);
+        setFieldsValue({
+          ...data,
+          sceneNum: data.num,
+          picList: [data.appListPicUrl],
+        });
+        // 方式1;
+      }
+
+      async function handleOk() {
+        let data = await validate();
+        console.log('data', data);
+        let res = await UpdateApi({
+          ...data,
+          appListPicUrl: data.picList[0],
+        });
+        context && context.emit('reload', res);
+        createMessage.success(t('common.optSuccess'));
+        closeModal();
+        resetFields();
+      }
+
+      return { options, register, registerForm, model: modelRef, handleOk, resetFields };
+    },
+  });
+</script>

+ 1 - 0
src/views/scenes/list.vue

@@ -92,6 +92,7 @@
 
   export default defineComponent({
     components: { BasicTable, TableAction, TableImg, DownloadModal, EditorModal },
+    emits: ['register'],
     setup() {
       const { createMessage } = useMessage();
       const [registerDownloadModal, { openModal: openDownloadModal }] = useModal();

+ 2 - 1
src/views/scenes/live.vue

@@ -52,7 +52,7 @@
       </template>
     </BasicTable>
     <bindModal @register="registerBindModal" @success="reload" />
-    <addLiveModal @register="registeraddLiveModal" />
+    <!-- <addLiveModal @register="registeraddLiveModal" /> -->
     <LiveDrawer @register="registerLiveDrawer" @success="reload" />
   </div>
 </template>
@@ -81,6 +81,7 @@
   import LiveDrawer from './liveDrawer.vue';
   export default defineComponent({
     components: { BasicTable, TableAction, TableImg, bindModal, LiveDrawer },
+    emits: ['register'],
     setup() {
       const { createMessage } = useMessage();
       const userStore = useUserStore();

+ 4 - 3
src/views/scenes/room.vue

@@ -42,7 +42,7 @@
         <TableAction :actions="renderActions(record)" />
       </template>
     </BasicTable>
-    <roomDeital @success="reload" @register="registerModal" @submit="handleAddUser" />
+    <roomDetail @success="reload" @register="registerModal" />
   </div>
 </template>
 <script lang="ts">
@@ -62,11 +62,12 @@
   import { useI18n } from '/@/hooks/web/useI18n';
   import { useUserStore } from '/@/store/modules/user';
   import { useModal } from '/@/components/Modal';
-  import roomDeital from './roomDeital.vue';
+  import roomDetail from './roomDetail.vue';
   import { listRoomsApi, dismissRoom, deleteRoom } from '/@/api/scene/list';
 
   export default defineComponent({
-    components: { BasicTable, TableAction, TableImg, roomDeital, Time },
+    components: { BasicTable, TableAction, TableImg, roomDetail, Time },
+    emits: ['register'],
     setup() {
       const { createMessage, createConfirm } = useMessage();
       const userStore = useUserStore();

src/views/scenes/roomDeital.vue → src/views/scenes/roomDetail.vue