Browse Source

feat(order): 添加订单管理功能

- 新增订单列表页面和查看弹窗
- 实现订单数据的获取和展示
- 添加地图定位功能
- 优化省市区选择组件
zhangtao 1 day ago
parent
commit
43228870de

+ 4 - 4
.env.development

@@ -7,16 +7,16 @@ VITE_PUBLIC_PATH = /
 
 
 # 跨域代理,您可以配置多个 ,请注意,没有换行符
-# VITE_PROXY = [["/jeecgboot","http://192.168.1.34:8080/jeecg-boot"],["/upload","http://192.168.1.34:8080/jeecg-boot"]]
+VITE_PROXY = [["/jeecgboot","http://192.168.1.34:8080/jeecg-boot"],["/upload","http://192.168.1.34:8080/jeecg-boot"]]
 # VITE_PROXY = [["/jeecgboot","http://192.168.0.11:8080/jeecg-boot"],["/upload","http://192.168.0.11:8080/upload"]]
 # VITE_PROXY = [["/jeecgboot","http://192.168.1.253:8080/jeecg-boot"],["/upload","http://192.168.1.253:8080/upload"]]
-VITE_PROXY = [["/jeecgboot","http://192.168.1.166:8080/jeecg-boot"],["/upload","http://192.168.1.166:8080/upload"]]
+# VITE_PROXY = [["/jeecgboot","http://192.168.1.166:8080/jeecg-boot"],["/upload","http://192.168.1.166:8080/upload"]]
 
 #后台接口全路径地址(必填)
-# VITE_GLOB_DOMAIN_URL=http://192.168.1.34:8080/jeecg-boot #//黄、
+VITE_GLOB_DOMAIN_URL=http://192.168.1.34:8080/jeecg-boot #//黄、
 # VITE_GLOB_DOMAIN_URL=http://192.168.0.11:8080/jeecg-boot  #李
 # VITE_GLOB_DOMAIN_URL=http://192.168.1.253:8080/jeecg-boot  #张
-VITE_GLOB_DOMAIN_URL=http://192.168.1.166:8080/jeecg-boot  #张
+# VITE_GLOB_DOMAIN_URL=http://192.168.1.166:8080/jeecg-boot  #张
 
 
 #后台接口父地址(必填)

+ 15 - 0
src/api/common/api.ts

@@ -19,6 +19,8 @@ enum Api {
   siteAdd = '/appSite/add',
   siteList = '/appSite/list',
   getDepList = '/sys/sysDepart/findByDeptList',
+  getInsure = '/app/appInsure/findList',
+  getBaiduAdd = '/findByAddress',
 }
 
 /**
@@ -184,3 +186,16 @@ export function getSiteList(params) {
 export function getDepListData(params) {
   return defHttp.get({ url: Api.getDepList, params });
 }
+
+/**
+ * 查询合同列表
+ * @param params
+ * @returns
+ */
+export function getInsureList(params) {
+  return defHttp.get({ url: Api.getInsure, params });
+}
+
+export function getBaiduAdd(params) {
+  return defHttp.get({ url: Api.getBaiduAdd, params });
+}

+ 20 - 11
src/components/Form/src/jeecg/components/JAreaSelect.vue

@@ -4,19 +4,19 @@
       <!--省份-->
       <a-select v-model:value="province" @change="proChange" allowClear :disabled="disabled">
         <template v-for="item in provinceOptions" :key="`${item.value}`">
-          <a-select-option :value="item.value">{{ item.label }}</a-select-option>
+          <a-select-option :value="item.label">{{ item.label }}</a-select-option>
         </template>
       </a-select>
       <!--城市-->
       <a-select v-if="level >= 2" v-model:value="city" @change="cityChange" :disabled="disabled">
         <template v-for="item in cityOptions" :key="`${item.value}`">
-          <a-select-option :value="item.value">{{ item.label }}</a-select-option>
+          <a-select-option :value="item.label">{{ item.label }}</a-select-option>
         </template>
       </a-select>
       <!--地区-->
       <a-select v-if="level >= 3" v-model:value="area" @change="areaChange" :disabled="disabled">
         <template v-for="item in areaOptions" :key="`${item.value}`">
-          <a-select-option :value="item.value">{{ item.label }}</a-select-option>
+          <a-select-option :value="item.label">{{ item.label }}</a-select-option>
         </template>
       </a-select>
     </div>
@@ -26,7 +26,7 @@
   import { defineComponent, PropType, ref, reactive, watchEffect, computed, unref, watch, onMounted, onUnmounted, toRefs } from 'vue';
   import { propTypes } from '/@/utils/propTypes';
   import { useRuleFormItem } from '/@/hooks/component/useFormItem';
-  import { provinceOptions, getDataByCode, getRealCode } from '../../utils/areaDataUtil';
+  import { provinceOptions, getDataByCode, getRealCode, getTextData } from '../../utils/areaDataUtil';
 
   export default defineComponent({
     name: 'JAreaSelect',
@@ -60,11 +60,19 @@
       const [state] = useRuleFormItem(props, 'value', 'change', emitData);
       //城市下拉框的选项
       const cityOptions = computed(() => {
-        return pca.province ? getDataByCode(pca.province) : [];
+        if (pca.province) {
+          const code = getTextData(pca.province);
+          return code ? getDataByCode(code) : [];
+        }
+        return [];
       });
       //地区下拉框的选项
       const areaOptions = computed(() => {
-        return pca.city ? getDataByCode(pca.city) : [];
+        if (pca.city) {
+          const code = getTextData(pca.province, pca.city);
+          return code ? getDataByCode(code) : [];
+        }
+        return [];
       });
       /**
        * 监听props值
@@ -114,10 +122,10 @@
        * 省份change事件
        */
       function proChange(val) {
-        console.log(val, '设置');
-
-        pca.city = val && getDataByCode(val)[0]?.value;
-        pca.area = pca.city && getDataByCode(pca.city)[0]?.value;
+        const pro = getTextData(val);
+        pca.city = getDataByCode(pro)[0]?.value;
+        const cityCode = getTextData(val, pca.city);
+        pca.area = getDataByCode(cityCode)[0]?.value;
         state.value = props.level <= 1 ? val : props.level <= 2 ? pca.city : pca.area;
         emit('update:value', unref(state));
       }
@@ -126,7 +134,8 @@
        * 城市change事件
        */
       function cityChange(val) {
-        pca.area = val && getDataByCode(val)[0]?.value;
+        const cityCode = getTextData(pca.province, val);
+        pca.area = val && getDataByCode(cityCode)[0]?.value;
         state.value = props.level <= 2 ? val : pca.area;
         emit('update:value', unref(state));
       }

+ 25 - 3
src/components/Form/src/utils/areaDataUtil.js

@@ -1,4 +1,4 @@
-import { pcaa as REGION_DATA } from "@/utils/areaData/pcaUtils";
+import { pcaa as REGION_DATA } from '@/utils/areaData/pcaUtils';
 import { cloneDeep } from 'lodash-es';
 
 // code转汉字大对象
@@ -142,7 +142,8 @@ function getDataByCode(code) {
   let data = [];
   for (const prop in REGION_DATA[code]) {
     data.push({
-      value: prop, // 省份code值
+      // value: prop, // 省份code值
+      value: REGION_DATA[code][prop], // 省份code值
       label: REGION_DATA[code][prop], // 省份汉字
     });
   }
@@ -189,5 +190,26 @@ function getPcode(id, arr, index) {
     }
   }
 }
+
+/**
+ * 通过省市区中文获取code
+ *
+ * @param {*} pro;
+ * @param {*} city;
+ * @param {*} area;
+ * @returns
+ */
+function getTextData(pro, city, area) {
+  if (pro && city && area) {
+    return TextToCode[pro][city][area].code;
+  }
+  if (pro && city) {
+    return TextToCode[pro][city].code;
+  }
+  if (pro) {
+    return TextToCode[pro].code;
+  }
+}
+
 //--end--@updateBy:liusq----date:20210922---for:省市区三级联动需求方法-----
-export { provinceAndCityData, regionData, provinceAndCityDataPlus, regionDataPlus, getDataByCode, provinceOptions, getRealCode };
+export { provinceAndCityData, regionData, provinceAndCityDataPlus, regionDataPlus, getDataByCode, provinceOptions, getRealCode, getTextData };

+ 40 - 10
src/views/businessManagement/competition/competition.data.ts

@@ -1,9 +1,9 @@
 import { options } from '../../monitor/mynews/XssWhiteList';
-import { getSprotProject } from '/@/api/common/api';
+import { getBaiduAdd, getInsureList, getSprotProject } from '/@/api/common/api';
 import { FormSchema } from '/@/components/Table';
 import { BasicColumn } from '/@/components/Table';
 import { getAddress } from '../courses/courses.api';
-import { Image, RadioChangeEvent } from 'ant-design-vue';
+import { Button, Image, Input, InputGroup, message, RadioChangeEvent } from 'ant-design-vue';
 import { h, VNode } from 'vue';
 import dayjs from 'dayjs';
 /**
@@ -217,13 +217,42 @@ export const formSchema: FormSchema[] = [
   },
   {
     field: 'address',
-    label: '输入地址',
+    label: '详细地址',
     component: 'Input',
     required: true,
     labelWidth: 200,
     ifShow(model) {
       return model.model.siteType == 1;
     },
+    render: ({ model }) => {
+      return h(
+        InputGroup,
+        {
+          compact: true,
+        },
+        () => [
+          h(Input, {
+            value: model['address'],
+            style: 'width: calc(100% - 70px)',
+            onChange: (e) => {
+              model['address'] = e.target.value;
+            },
+          }),
+          h(
+            Button,
+            {
+              onClick: async () => {
+                if (!model['address'] || !model['provinceCode']) return message.warning('请输入地址');
+                const res = await getBaiduAdd({ address: `${model['provinceCode']}${model['cityCode']}${model['areaCode']}${model['address']}` });
+                model['latitude'] = res.latitude;
+                model['longitude'] = res.longitude;
+              },
+            },
+            () => '定位'
+          ),
+        ]
+      );
+    },
   },
   {
     field: 'cityCode',
@@ -243,7 +272,7 @@ export const formSchema: FormSchema[] = [
     component: 'Input',
     labelWidth: 200,
     required: true,
-
+    colProps: { sm: 8 },
     ifShow(model) {
       return model.model.siteType == 1;
     },
@@ -254,7 +283,7 @@ export const formSchema: FormSchema[] = [
     component: 'Input',
     labelWidth: 200,
     required: true,
-
+    colProps: { sm: 8 },
     ifShow(model) {
       return model.model.siteType == 1;
     },
@@ -292,14 +321,15 @@ export const formSchema: FormSchema[] = [
   {
     field: 'insureIds',
     label: '配套保险',
-    component: 'RadioGroup',
+    component: 'ApiSelect',
     required: true,
     labelWidth: 200,
     componentProps: {
-      options: [
-        { label: '意外伤害险1', value: '1' },
-        { label: '大额意外伤害险', value: '0' },
-      ],
+      api: getInsureList,
+      resultField: 'data',
+      labelField: 'name',
+      valueField: 'id',
+      mode: 'multiple',
     },
   },
   {

+ 9 - 6
src/views/businessManagement/competition/competitionCommon.vue

@@ -50,7 +50,7 @@
           </div>
         </template>
         <template #formFooter>
-          <div style="margin: 0 auto">
+          <div style="margin: 0 auto" v-if="Number(route.query.type) != 2">
             <a-button type="primary" @click="save" class="mr-2" :loading="isSubmit"> 保存 </a-button>
             <a-button type="error" @click="back" class="mr-2"> 关闭 </a-button>
           </div>
@@ -82,6 +82,7 @@
   const [registerForm, { setProps, resetFields, setFieldsValue, updateSchema, validate, clearValidate, getFieldsValue }] = useForm({
     schemas: formSchema,
     showActionButtonGroup: false,
+    disabled: Boolean(Number(route.query.type) == 2),
   });
   const isSubmit = ref(false);
   async function back() {
@@ -220,11 +221,13 @@
           time: [it.startTime, it.endTime],
         };
       }),
-      aptitudes: res.game.aptitudes.split(',').map((it) => {
-        return {
-          name: it,
-        };
-      }),
+      aptitudes: res.game.aptitudes
+        ? res.game.aptitudes.split(',').map((it) => {
+            return {
+              name: it,
+            };
+          })
+        : [],
     });
   }
 

+ 7 - 12
src/views/businessManagement/courses/courses.data.ts

@@ -3,7 +3,7 @@ import { FormSchema } from '/@/components/Table';
 import { rules } from '/@/utils/helper/validator';
 import { render } from '/@/utils/common/renderUtils';
 import { getWeekMonthQuarterYear } from '/@/utils';
-import { getSprotProject } from '/@/api/common/api';
+import { getInsureList, getSprotProject } from '/@/api/common/api';
 import { defHttp } from '/@/utils/http/axios';
 import { getAddress, getCoachList } from './courses.api';
 import { useUserStore } from '/@/store/modules/user';
@@ -232,19 +232,14 @@ export const formSchema: FormSchema[] = [
   {
     label: '配套保险',
     field: 'insureIds',
-    component: 'RadioGroup',
+    component: 'ApiSelect',
     required: true,
     componentProps: {
-      options: [
-        {
-          label: '意外伤害险',
-          value: 0,
-        },
-        {
-          label: '大额意外伤害险',
-          value: 1,
-        },
-      ],
+      api: getInsureList,
+      resultField: 'data',
+      labelField: 'name',
+      valueField: 'id',
+      mode: 'multiple',
     },
   },
   {

+ 7 - 5
src/views/businessManagement/schoolOpen/schoolOpen.data.ts

@@ -2,6 +2,7 @@ import { storeToRefs } from 'pinia';
 import { ZtTableColumnProps } from '/#/utils';
 import { BasicColumn, FormSchema } from '/@/components/Table';
 import { useShopInfoStore } from '/@/store/modules/shopInfo';
+import { getInsureList } from '/@/api/common/api';
 const { deptList } = storeToRefs(useShopInfoStore());
 export const formSchema: FormSchema[] = [
   {
@@ -77,12 +78,13 @@ export const formSchema: FormSchema[] = [
   {
     field: 'insurance',
     label: '配套保险',
-    component: 'RadioGroup',
+    component: 'ApiSelect',
     componentProps: {
-      options: [
-        { label: '意外伤害险1', value: 0 },
-        { label: '大额意外伤害险', value: 1 },
-      ],
+      api: getInsureList,
+      resultField: 'data',
+      labelField: 'name',
+      valueField: 'id',
+      mode: 'multiple',
     },
     required: true,
     labelWidth: 120,

+ 3 - 2
src/views/informationManagement/shopInfo/index.vue

@@ -6,14 +6,14 @@
           <TypographyTitle :level="4">基础信息</TypographyTitle>
           <Divider></Divider>
         </template>
-        <template #address="{ model, field }">
+        <!-- <template #address="{ model, field }">
           <FormItem label="营业地址" required>
             <JAreaSelect v-model:province="model['province']" v-model:city="model['city']" v-model:area="model['area']"></JAreaSelect>
             <div class="mt-4">
               <Textarea v-model:value="model[field]"></Textarea>
             </div>
           </FormItem>
-        </template>
+        </template> -->
         <template #phone="{ model, field }">
           <Input v-model:value="model[field]"></Input>
           <span class="text-gray">用户拨打商家电话时,拨打的号码为该号码。</span>
@@ -60,6 +60,7 @@
   const [registerForm, { setProps, resetFields, setFieldsValue, updateSchema, validate, clearValidate, getSchemaByField }] = useForm({
     schemas: formSchema,
     showActionButtonGroup: false,
+    labelWidth: 200,
     labelCol: { span: 4 },
     wrapperCol: { span: 18 },
   });

+ 65 - 3
src/views/informationManagement/shopInfo/shopInfo.data.ts

@@ -1,5 +1,8 @@
 import { FormSchema } from '/@/components/Table';
-import { getSprotProject } from '/@/api/common/api';
+import { getBaiduAdd, getSprotProject } from '/@/api/common/api';
+import { h } from 'vue';
+import { JAreaSelect } from '/@/components/Form';
+import { InputGroup, Input, Button, message } from 'ant-design-vue';
 const sportList = await getSprotProject({ pageSize: 20 });
 export const formSchema: FormSchema[] = [
   {
@@ -25,10 +28,45 @@ export const formSchema: FormSchema[] = [
     label: '营业地址',
     component: 'JAreaSelect',
     required: true,
-    colSlot: 'address',
+    render: ({ model }) => {
+      return h(JAreaSelect, {
+        province: model['provinceCode'],
+        area: model['area'],
+        city: model['city'],
+      });
+    },
+  },
+  {
+    field: 'provinceCode',
+    label: '详细地址',
+    component: 'Input',
+    required: true,
+    render: ({ model }) => {
+      return h(
+        InputGroup,
+        {
+          compact: true,
+        },
+        () => [
+          h(Input, { value: model['address'], style: 'width: calc(100% - 70px)' }),
+          h(
+            Button,
+            {
+              onClick: async () => {
+                if (!model['address'] || !model['provinceCode']) return message.warning('请输入地址');
+                const res = await getBaiduAdd({ address: `${model['provinceCode']}${model['cityCode']}${model['areaCode']}${model['address']}` });
+                model['latitude'] = res.latitude;
+                model['longitude'] = res.longitude;
+              },
+            },
+            () => '定位'
+          ),
+        ]
+      );
+    },
   },
   {
-    field: 'province',
+    field: 'provinceCode',
     label: '',
     component: 'JAreaSelect',
     show: false,
@@ -45,6 +83,30 @@ export const formSchema: FormSchema[] = [
     component: 'JAreaSelect',
     show: false,
   },
+  {
+    field: 'longitude',
+    label: '经度',
+    component: 'Input',
+    required: true,
+    colProps: {
+      sm: 8,
+    },
+    componentProps: {
+      placeholder: '输入详细地址后点击定位,自动填充',
+    },
+  },
+  {
+    field: 'latitude',
+    label: '维度',
+    component: 'Input',
+    required: true,
+    colProps: {
+      sm: 8,
+    },
+    componentProps: {
+      placeholder: '输入详细地址后点击定位,自动填充',
+    },
+  },
 
   {
     field: 'title1',

+ 16 - 0
src/views/orderManagement/order/components/orderModelView.vue

@@ -0,0 +1,16 @@
+<template>
+  <BasicModal v-bind="$attrs" @register="registerModal" title="产看" width="900px" destroyOnClose> </BasicModal>
+</template>
+<script lang="ts" setup>
+  import { TypographyTitle, Divider } from 'ant-design-vue';
+  import { ref, computed, unref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  // 声明Emits
+  const emit = defineEmits(['success', 'register']);
+  const isUpdate = ref(true);
+  const isDetail = ref(false);
+  //表单赋值
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+    console.log(data);
+  });
+</script>

+ 137 - 0
src/views/orderManagement/order/index.vue

@@ -0,0 +1,137 @@
+<template>
+  <BasicTable @register="registerTable">
+    <!--插槽:table标题-->
+    <template #tableTitle> </template>
+    <!--操作栏-->
+    <template #action="{ record }">
+      <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
+    </template>
+    <!--字段回显插槽-->
+    <template v-slot:bodyCell="{ column, record, index, text }"> </template>
+    <template #goods>
+      <div class="flex items-center h-20px">
+        <div>订单编号:D202503071608580001</div>
+        <div class="ml3">下单时间:2025-03-07 16:08:58</div>
+      </div>
+      <div class="mt3 flex items-center border-b border-solid pb-3 h-90px" v-for="item in 3">
+        <Image :width="80" class="rounded-16px" src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png" />
+        <div class="ml3">学校场地开放</div>
+      </div>
+    </template>
+    <template #price>
+      <div class="h-20px"></div>
+      <div class="mt3 h-90px flex flex-col justify-center border-b border-solid" v-for="item in 3">
+        <div class="flex items-center">
+          <div>¥0</div>
+          <div class="line-through ml-3 text-gray">¥0</div>
+        </div>
+        <div class="text-gray">x1</div>
+      </div>
+    </template>
+    <template #user>
+      <div class="h-20px"></div>
+      <div class="mt3 h-90px flex flex-col justify-center border-b border-solid" v-for="item in 3">
+        <div>杨金鑫</div>
+        <div class="text-gray">18984144104</div>
+      </div>
+    </template>
+    <template #status>
+      <div class="h-20px"></div>
+      <div class="mt3 h-90px flex flex-col justify-center border-b border-solid" v-for="item in 3">
+        <div>待使用</div>
+      </div>
+    </template>
+    <template #After>
+      <div class="h-20px"></div>
+      <div class="mt3 h-90px flex flex-col justify-center border-b border-solid" v-for="item in 3">
+        <div>暂无售后</div>
+      </div>
+    </template>
+  </BasicTable>
+  <orderModelView @register="registerModal"></orderModelView>
+</template>
+
+<script setup lang="ts">
+  import orderModelView from './components/orderModelView.vue';
+  import { Image } from 'ant-design-vue';
+  import { ref, reactive, computed, unref } from 'vue';
+  import { BasicTable, useTable, TableAction, TableImg } from '/@/components/Table';
+  import { useModal } from '/@/components/Modal';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { columns, searchFormSchema } from './order.data';
+  import { list } from './order.api';
+  import { useUserStore } from '/@/store/modules/user';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  const queryParam = reactive<any>({});
+  const checkedKeys = ref<Array<string | number>>([]);
+  const userStore = useUserStore();
+  const { createMessage } = useMessage();
+  //注册model
+  const [registerModal, { openModal }] = useModal();
+  //注册table数据
+  const { prefixCls, tableContext } = useListPage({
+    tableProps: {
+      api: list,
+      columns,
+      canResize: false,
+      formConfig: {
+        //labelWidth: 120,
+        schemas: searchFormSchema,
+        autoSubmitOnEnter: true,
+        showAdvancedButton: true,
+        fieldMapToNumber: [],
+        fieldMapToTime: [['time', ['startTime', 'endTime'], 'YYYY-MM-DD HH:mm:ss']],
+      },
+      inset: true,
+      actionColumn: {
+        width: 120,
+        fixed: 'right',
+      },
+      beforeFetch: (params) => {
+        return Object.assign(params, queryParam);
+      },
+    },
+  });
+
+  const [registerTable, { reload }, { selectedRowKeys }] = tableContext;
+  /**
+   * 编辑事件
+   */
+  function handleEdit(record: Recordable) {
+    openModal(true, {
+      record,
+    });
+  }
+  // /**
+  //  * 删除事件
+  //  */
+  // async function handleDelete(record) {
+  //   await deleteOne({ id: record.id }, handleSuccess);
+  // }
+  /**
+   * 成功回调
+   */
+  function handleSuccess() {
+    (selectedRowKeys.value = []) && reload();
+  }
+  /**
+   * 操作栏
+   */
+  function getTableAction(record) {
+    return [
+      {
+        label: '查看',
+        onClick: handleEdit.bind(null, record),
+        // auth: 'feedback:nm_feedback:edit',
+      },
+    ];
+  }
+  /**
+   * 下拉操作栏
+   */
+  function getDropDownAction(record) {
+    return [];
+  }
+</script>
+
+<style scoped></style>

+ 13 - 0
src/views/orderManagement/order/order.api.ts

@@ -0,0 +1,13 @@
+import { defHttp } from '/@/utils/http/axios';
+import { useMessage } from '/@/hooks/web/useMessage';
+
+const { createConfirm } = useMessage();
+
+enum Api {
+  list = '/appOrder/list',
+}
+/**
+ * 列表接口
+ * @param params
+ */
+export const list = (params) => defHttp.get({ url: Api.list, params });

+ 113 - 0
src/views/orderManagement/order/order.data.ts

@@ -0,0 +1,113 @@
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+import { h } from 'vue';
+import { Image } from 'ant-design-vue';
+//列表数据
+export const columns: BasicColumn[] = [
+  {
+    title: '商品',
+    align: 'left',
+    dataIndex: 'userName',
+    width: 520,
+    slots: { customRender: 'goods' },
+  },
+  {
+    title: '价格/数量',
+    align: 'left',
+    dataIndex: 'phone',
+    width: 120,
+    slots: { customRender: 'price' },
+  },
+  {
+    title: '使用人',
+    align: 'center',
+    dataIndex: 'feedbackType',
+    width: 120,
+    slots: { customRender: 'user' },
+  },
+  {
+    title: '订单状态',
+    align: 'center',
+    dataIndex: 'status',
+    width: 120,
+    slots: { customRender: 'status' },
+  },
+  {
+    title: '售后状态',
+    align: 'center',
+    dataIndex: 'feedbackImgList',
+    width: 120,
+    slots: { customRender: 'After' },
+  },
+  {
+    title: '实付金额',
+    align: 'center',
+    dataIndex: 'createTime',
+    width: 120,
+  },
+];
+//查询数据
+export const searchFormSchema: FormSchema[] = [
+  {
+    label: '手机号码',
+    field: 'phone',
+    component: 'Input',
+  },
+  {
+    label: '订单编号',
+    field: 'phone',
+    component: 'Input',
+  },
+  {
+    label: '店铺名称',
+    field: 'phone',
+    component: 'Input',
+  },
+  {
+    label: '订单状态',
+    field: 'phone',
+    component: 'Select',
+    componentProps: {
+      options: [
+        {
+          label: '待付款',
+          value: 1,
+        },
+        {
+          label: '待使用',
+          value: 2,
+        },
+        {
+          label: '已使用',
+          value: 3,
+        },
+        {
+          label: '已到期',
+          value: 4,
+        },
+        {
+          label: '已取消',
+          value: 5,
+        },
+      ],
+    },
+  },
+  {
+    label: '下单时间',
+    field: 'time',
+    component: 'RangePicker',
+    componentProps: {
+      placeholder: ['开始时间', '结束时间'],
+    },
+  },
+];
+//表单数据
+export const formSchema: FormSchema[] = [
+  // TODO 主键隐藏字段,目前写死为ID
+  {
+    label: '',
+    field: 'id',
+    component: 'Input',
+    show: false,
+  },
+];

+ 13 - 0
src/views/safetyManagement/Seal/Seal.api.ts

@@ -0,0 +1,13 @@
+import { ex } from '@fullcalendar/core/internal-common';
+import { defHttp } from '/@/utils/http/axios';
+enum Api {
+  list = '/api/esign/orgOwnSeal',
+  getButton = '/api/esign/orgSealsExternal',
+}
+/**
+ * 列表接口
+ * @param params
+ */
+export const list = (params) => defHttp.get({ url: Api.list, params });
+
+export const getButton = (params) => defHttp.get({ url: Api.getButton, params });

+ 31 - 0
src/views/safetyManagement/Seal/Seal.data.ts

@@ -0,0 +1,31 @@
+import { h } from 'vue';
+import { BasicColumn } from '/@/components/Table';
+import { FormSchema } from '/@/components/Table';
+import { Tag } from 'ant-design-vue';
+import { BasicUpload } from '/@/components/Upload';
+//列表数据
+export const columns: BasicColumn[] = [
+  {
+    title: '印章章面',
+    align: 'center',
+    dataIndex: 'sealImageDownloadUrl',
+    slots: { customRender: 'sealImageDownloadUrl' },
+  },
+  {
+    title: '印章名称',
+    align: 'center',
+    dataIndex: 'sealName',
+  },
+  {
+    title: '印章类型',
+    align: 'center',
+    dataIndex: 'sealBizType',
+  },
+  {
+    title: '印章状态',
+    align: 'center',
+    dataIndex: 'statusDescription',
+  },
+];
+//查询数据
+export const searchFormSchema: FormSchema[] = [];

+ 92 - 0
src/views/safetyManagement/Seal/index.vue

@@ -0,0 +1,92 @@
+<template>
+  <div>
+    <!--引用表格-->
+    <BasicTable @register="registerTable">
+      <template #tableTitle> </template>
+      <template #action="{ record }">
+        <TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)" />
+      </template>
+      <template #sealImageDownloadUrl="{ text }">
+        <TableImg :img-list="[text]" :size="120"></TableImg>
+      </template>
+    </BasicTable>
+  </div>
+</template>
+
+<script lang="ts" setup name="cUserInfo">
+  import { onUnmounted, reactive, watch } from 'vue';
+  import { BasicTable, TableAction, TableImg } from '/@/components/Table';
+  import { useListPage } from '/@/hooks/system/useListPage';
+  import { columns, searchFormSchema } from './Seal.data';
+  import { getButton, list } from './Seal.api';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useUserStore } from '/@/store/modules/user';
+  import { useShopInfoStore } from '/@/store/modules/shopInfo';
+  import { storeToRefs } from 'pinia';
+
+  useShopInfoStore().getCurrentDep();
+  const { currentId } = storeToRefs(useShopInfoStore());
+  const { createMessage, createWarningModal } = useMessage();
+  const { userInfo } = storeToRefs(useUserStore());
+  const dataSource = reactive([]);
+  //注册model
+  //注册table数据
+  const { prefixCls, tableContext } = useListPage({
+    tableProps: {
+      title: 'Seal',
+      api: list,
+      dataSource: [],
+
+      columns,
+      canResize: false,
+      formConfig: {
+        //labelWidth: 120,
+        schemas: searchFormSchema,
+        autoSubmitOnEnter: true,
+        showAdvancedButton: true,
+        fieldMapToNumber: [],
+        fieldMapToTime: [],
+      },
+      actionColumn: {
+        width: 300,
+        fixed: 'right',
+      },
+      beforeFetch: (params) => {
+        return Object.assign(params, { orgCode: userInfo.value?.orgCode });
+      },
+    },
+  });
+  const [registerTable, { reload }] = tableContext;
+  async function handleView(record: Recordable) {
+    await getButton({ orgCode: userInfo.value?.orgCode, sealId: record.sealId });
+    reload();
+  }
+  /**
+   * 操作栏
+   */
+  function getTableAction(record) {
+    return [
+      {
+        label: '授权',
+        onClick: handleView.bind(null, record),
+        disabled: record.isStatus,
+      },
+    ];
+  }
+  /**
+   * 下拉操作栏
+   */
+  function getDropDownAction(record) {
+    return [];
+  }
+  onUnmounted(() => {
+    useShopInfoStore().isShowSelect = false;
+  });
+</script>
+
+<style lang="less" scoped>
+  :deep(.ant-picker),
+  :deep(.ant-input-number) {
+    width: 100%;
+  }
+</style>