tangning пре 3 година
родитељ
комит
6a7682e087

+ 22 - 0
package-lock.json

@@ -17,7 +17,9 @@
         "@zxcvbn-ts/core": "^1.0.0-beta.0",
         "ant-design-vue": "2.2.8",
         "axios": "^0.24.0",
+        "cropperjs": "^1.5.12",
         "crypto-js": "^4.1.1",
+        "dayjs": "^1.11.5",
         "echarts": "^5.2.2",
         "lodash-es": "^4.17.21",
         "mockjs": "^1.1.0",
@@ -7579,6 +7581,11 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/cropperjs": {
+      "version": "1.5.12",
+      "resolved": "https://registry.npmmirror.com/cropperjs/-/cropperjs-1.5.12.tgz",
+      "integrity": "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw=="
+    },
     "node_modules/cross-env": {
       "version": "7.0.3",
       "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
@@ -7974,6 +7981,11 @@
         "node": "*"
       }
     },
+    "node_modules/dayjs": {
+      "version": "1.11.5",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz",
+      "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA=="
+    },
     "node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz",
@@ -28040,6 +28052,11 @@
       "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
       "dev": true
     },
+    "cropperjs": {
+      "version": "1.5.12",
+      "resolved": "https://registry.npmmirror.com/cropperjs/-/cropperjs-1.5.12.tgz",
+      "integrity": "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw=="
+    },
     "cross-env": {
       "version": "7.0.3",
       "resolved": "https://registry.npmmirror.com/cross-env/-/cross-env-7.0.3.tgz",
@@ -28313,6 +28330,11 @@
       "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==",
       "dev": true
     },
+    "dayjs": {
+      "version": "1.11.5",
+      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz",
+      "integrity": "sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA=="
+    },
     "debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz",

+ 1 - 0
package.json

@@ -43,6 +43,7 @@
     "axios": "^0.24.0",
     "cropperjs": "^1.5.12",
     "crypto-js": "^4.1.1",
+    "dayjs": "^1.11.5",
     "echarts": "^5.2.2",
     "lodash-es": "^4.17.21",
     "mockjs": "^1.1.0",

+ 72 - 0
src/api/account/index.ts

@@ -7,6 +7,12 @@ import { Result } from '/#/axios';
 
 enum Api {
   pageList = '/newV4/service/manage/user/list',
+  getIncrementListByUserId = '/newV4/service/manage/user/getIncrementListByUserId',
+  IncrementDelay = '/newV4/service/manage/user/IncrementDelay',
+  addUserIncrement = '/newV4/service/manage/user/addUserIncrement',
+  addDownNum = '/newV4/service/manage/user/addDownNum',
+  getCameraDetail = '/newV4/service/manage/user/getCameraDetail',
+  unbindCamera = '/newV4/service/manage/user/unbindCamera',
 }
 
 /**
@@ -24,3 +30,69 @@ export const ListApi = (params: PageParams) =>
     },
   });
 
+//权益详情
+export const DetailsApi = (params: PageParams) =>
+defHttp.post<userList>({
+  url: Api.getIncrementListByUserId,
+  params: params,
+  // data: params,
+  headers: {
+    // @ts-ignore
+    ignoreCancelToken: true,
+  },
+});
+
+//权益延期
+export const IncrementDelayApi = (params: PageParams) =>
+defHttp.post<userList>({
+  url: Api.IncrementDelay,
+  params: params,
+  headers: {
+    // @ts-ignore
+    ignoreCancelToken: true,
+  },
+});
+
+//添加用户权益
+export const AddUserIncrementApi = (params: PageParams) =>
+defHttp.post<userList>({
+  url: Api.addUserIncrement,
+  params: params,
+  headers: {
+    // @ts-ignore
+    ignoreCancelToken: true,
+  },
+});
+
+//加用户下载次数
+export const AddDownNumApi = (params: PageParams) =>
+defHttp.post<userList>({
+  url: Api.addDownNum,
+  params: params,
+  headers: {
+    // @ts-ignore
+    ignoreCancelToken: true,
+  },
+});
+
+//获取相机详情
+export const GetCameraDetailApi = (params: PageParams) =>
+defHttp.post<userList>({
+  url: Api.getCameraDetail,
+  params: params,
+  headers: {
+    // @ts-ignore
+    ignoreCancelToken: true,
+  },
+});
+
+//相机解绑
+export const UnbindCameraApi = (params: PageParams) =>
+defHttp.post<userList>({
+  url: Api.unbindCamera,
+  params: params,
+  headers: {
+    // @ts-ignore
+    ignoreCancelToken: true,
+  },
+});

+ 37 - 2
src/api/order/index.ts

@@ -7,7 +7,7 @@ import {
   updateParams,
   getItemParams,
 } from './model';
-import { Result } from '/#/axios';
+import { Result, UploadFileParams } from '/#/axios';
 
 enum Api {
   cameraList = '/newV4/service/manage/order/camera/list',
@@ -18,7 +18,9 @@ enum Api {
   downList = '/newV4/service/manage/order/down/list',
   downExport = '/newV4/service/manage/order/down/export',
   pageInvoice = '/newV4/service/manage/invoice/pageInvoice',
-  
+  exportInvoice = '/newV4/service/manage/invoice/export',
+  invoiceRegister = '/newV4/service/manage/invoice/invoiceRegister',
+  getInvoiceRegisterDetail = '/newV4/service/manage/invoice/getInvoiceRegisterDetail',
 }
 
 /**
@@ -122,3 +124,36 @@ export const InvoiceList = (params: PageParams) =>
       ignoreCancelToken: true,
     },
   });
+
+export const InvoiceExport = (params: PageParams) =>
+  defHttp.post<InvoiceListResul>({
+    url: Api.exportInvoice,
+    params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const InvoiceDetail = (params: PageParams) =>
+  defHttp.get<InvoiceListResul>({
+    url: Api.getInvoiceRegisterDetail,
+    params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+  //上传文件
+export function InvoiceRegister(
+  params: UploadFileParams,
+  onUploadProgress: (progressEvent: ProgressEvent) => void,
+) {
+  return defHttp.uploadFile<Result>(
+    {
+      url: Api.invoiceRegister,
+      onUploadProgress,
+    },
+    params,
+  );
+ }

+ 4 - 2
src/components/Table/src/components/TableImg.vue

@@ -52,12 +52,14 @@
       margin: propTypes.number.def(4),
       // src前缀,将会附加在imgList中每一项之前
       srcPrefix: propTypes.string.def(''),
+      // 图片靠左自适应布局
+      adaptations: propTypes.bool.def(false),
     },
     setup(props) {
       const getWrapStyle = computed((): CSSProperties => {
-        const { size } = props;
+        const { size, adaptations } = props;
         const s = `${size}px`;
-        return { height: s, width: s };
+        return adaptations?{height: 'auto', width: 'auto',maxWidth:'100%'}:{ height:s, width:s };
       });
 
       const { prefixCls } = useDesign('basic-table-img');

+ 60 - 0
src/store/modules/other.ts

@@ -0,0 +1,60 @@
+import type { OverviewInfo } from '/#/store';
+
+import { defineStore } from 'pinia';
+
+import { LOCK_INFO_KEY } from '/@/enums/cacheEnum';
+import { Persistent } from '/@/utils/cache/persistent';
+import { useUserStore } from './user';
+
+interface LockState {
+  overviewInfo: Nullable<OverviewInfo> | string;
+}
+
+export const otherInfoStore = defineStore({
+  id: 'other-info',
+  state: (): LockState => ({
+    overviewInfo:  sessionStorage.getItem('overviewInfo') || null,
+  }),
+  getters: {
+    getOverviewInfo(): Nullable<OverviewInfo> {
+      return this.overviewInfo && JSON.parse(this.overviewInfo);
+    },
+  },
+  actions: {
+    setOverviewInfo(info: LockInfo) {
+      this.overviewInfo = JSON.stringify(info);
+      console.log('getOverviewInfo',this.overviewInfo,info)
+      sessionStorage.setItem('overviewInfo',this.overviewInfo)
+    },
+    resetLockInfo() {
+      Persistent.removeLocal(LOCK_INFO_KEY, true);
+      this.overviewInfo = null;
+    },
+    // Unlock
+    async unLock(password?: string) {
+      const userStore = useUserStore();
+      if (this.overviewInfo?.pwd === password) {
+        this.resetLockInfo();
+        return true;
+      }
+      const tryLogin = async () => {
+        try {
+          const username = userStore.getUserInfo?.username;
+          const res = await userStore.login({
+            username,
+            password: password!,
+            goHome: false,
+            mode: 'none',
+          });
+          if (res) {
+            this.resetLockInfo();
+          }
+          return res;
+        } catch (error) {
+          return false;
+        }
+      };
+      return await tryLogin();
+    },
+  },
+});

+ 1 - 0
src/utils/cache/persistent.ts

@@ -23,6 +23,7 @@ interface BasicStore {
   [USER_INFO_KEY]: UserInfo;
   [ROLES_KEY]: string[];
   [LOCK_INFO_KEY]: LockInfo;
+  [LOCK_INFO_KEY]: LockInfo;
   [PROJ_CFG_KEY]: ProjectConfig;
   [MULTIPLE_TABS_KEY]: RouteLocationNormalized[];
 }

+ 1 - 1
src/views/account/details/data.ts

@@ -223,7 +223,7 @@ export const dowmColumns: BasicColumn[] = [
   {
     title: '时间',
     dataIndex: 'createTime',
-    width: 150,
+    width: 180,
     customRender: ({ record }) => {
       return (
         record.createTime &&

+ 6 - 1
src/views/account/details/index.vue

@@ -34,7 +34,7 @@
     },
     setup() {
       return {
-        prefixCls: 'account-setting',
+        prefixCls: 'account-setting Level2Tab',
         settingList,
         tabBarStyle: {
           width: '220px',
@@ -56,4 +56,9 @@
       background-color: @item-active-bg;
     }
   }
+  .Level2Tab{
+    .ant-tabs .ant-tabs-left-content{
+      padding-left:0px;
+    }
+  }
 </style>

+ 3 - 0
src/views/account/index.vue

@@ -23,6 +23,7 @@ import { userListSchema } from './data';
 import { useModal } from '/@/components/Modal';
 import { useI18n } from '/@/hooks/web/useI18n';
 import { useRouter } from 'vue-router'
+import { otherInfoStore } from '/@/store/modules/other'
 // import { useMessage } from '/@/hooks/web/useMessage';
 export default defineComponent({
   components: {
@@ -43,6 +44,7 @@ export default defineComponent({
     const { t } = useI18n();
     const [registerAddModal, { openModal: openAddModal }] = useModal();
     const [registerEditModal, { openModal: openEditModal }] = useModal();
+    const { setOverviewInfo } = otherInfoStore();
     // const { createMessage } = useMessage(); 
     const router = useRouter()
     const searchForm: Partial<FormProps> = {
@@ -94,6 +96,7 @@ export default defineComponent({
     }
     function handleEdit(record: Recordable) {
       console.log('record', record);
+      setOverviewInfo(record)
       router.push({path:'details'})
     }
     return {

+ 193 - 0
src/views/account/overview/AddModal.vue

@@ -0,0 +1,193 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="开票登记"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleSubmit"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm">
+        <template #text="{ model, field }">
+          {{ model[field]  }}{{fileFlow.type}}
+        </template>
+      </BasicForm>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, nextTick, onMounted, reactive, computed } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { InvoiceRegister } from '/@/api/order';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { uploadApi } from '/@/api/product/index';
+  import { ResultEnum } from '/@/enums/httpEnum';
+  import { DetailsApi, IncrementDelayApi, AddUserIncrementApi, AddDownNumApi } from '/@/api/account';
+  import dayjs from 'dayjs';
+  import { otherInfoStore } from '/@/store/modules/other'
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      // const overviewInfo = getOverviewInfo() || {}
+      const fileFlow = reactive({
+        file:null,
+        id:'',
+        type:'down',//down-下载,equity-权益
+      })
+      const { createMessage } = useMessage();
+      const schemas: FormSchema[] = [
+          {
+            field: 'id',
+            component: 'Input',
+            show:false,
+            label: '发票编号',
+            required: true,
+          },
+          {
+            field: 'counts',
+            component: 'InputNumber',
+            label: '新增权益数',
+            componentProps: {
+              min:1,
+            },
+            colProps: {
+              span: 22,
+            },
+          },
+          {
+            field: 'incrementEndTime',
+            component: 'DatePicker',
+            label: '到期日期',
+            required: true,
+            componentProps: {
+              valueFormat: 'YYYY-MM-DD',
+              format: 'YYYY-MM-DD',
+              disabledDate: (current) => {
+                return current && current < dayjs().endOf('day');
+              },
+            },
+          },
+          // {
+          // field: 'year',
+          // component: 'Select',
+          // label: '到期日期',
+          // colProps: {
+          //   span: 22,
+          // },
+          // required: true,
+          // componentProps: {
+          //   options:[{
+          //     label: '1年',
+          //     value: 1,
+          //     key: '1',
+          //   },{
+          //     label: '2年',
+          //     value: 2,
+          //     key: '2',
+          //   },{
+          //     label: '3年',
+          //     value: 3,
+          //     key: '3',
+          //   },{
+          //     label: '4年',
+          //     value: 4,
+          //     key: '4',
+          //   }]
+          // },
+          // },
+          {
+            field: 'count',
+            component: 'InputNumber',
+            label: '新增次数',
+            required: true,
+            componentProps: {
+              min:1,
+            },
+            colProps: {
+              span: 22,
+            },
+          }
+      ];
+
+      const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm({
+        labelWidth: 120,
+        schemas:schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        console.log('onDataReceive',data)
+        resetFields();
+        fileFlow.type = data.type
+        fileFlow.id = data.id
+        setFieldsValue(data);
+        updateSchema([
+          {field: 'count',ifShow:fileFlow.type == 'down',},
+          {field: 'incrementEndTime',ifShow:fileFlow.type == 'equity',},
+          {field: 'counts',ifShow:fileFlow.type == 'equity',},
+        ])
+      }
+      const handleSubmit = async () => {
+        const submitUrl = fileFlow.type == 'equity'?AddUserIncrementApi:AddDownNumApi
+        try {
+          const params = await validate();
+          console.log('validate',params)
+          const apiData = fileFlow.type == 'equity'?{
+              userId:params.id,
+              incrementEndTime:params.incrementEndTime,
+              count:params.counts,
+            }:{
+              userId:params.id,
+              count:params.count,
+            // file:params.file[0],
+            }
+          const res = await submitUrl(apiData);
+          if(fileFlow.type == 'equity'){
+            overviewInfo.value.incrementCount = overviewInfo.value.incrementCount + apiData.count
+          }else{
+            overviewInfo.value.surDownNum = overviewInfo.value.surDownNum + apiData.count
+          }
+          console.log('res', overviewInfo.value);
+          otherInfo.setOverviewInfo(overviewInfo.value)
+          closeModal();
+          resetFields();
+          createMessage.success(t('common.optSuccess'));
+          emit('update');
+        } catch (error) {
+          console.log('not passing', error);
+        }
+      };
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      return {
+        register,
+        registerForm,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        resetFields,
+        t,
+      };
+    },
+  });
+</script>

+ 162 - 0
src/views/account/overview/caremModal.vue

@@ -0,0 +1,162 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="权益详情"
+    :width="800"
+    @visible-change="handleVisibleChange"
+    @ok="handleSubmit"
+  >
+    <div class="pt-3px pr-3px">
+      <div class="table_list">
+        <BasicTable @register="registerSubtable" >
+          <template #action="{ record }">
+            <TableAction
+              :actions="[
+                 {
+                   label: '解绑',
+                   icon: 'mdi:account-edit-outline',
+                   onClick: handleDelete.bind(null, record, 'edit'),
+                 },
+              ]"
+            />
+          </template>
+        </BasicTable>
+      </div>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, nextTick, onMounted, reactive, computed,h } from 'vue';
+  import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm } from '/@/components/Form/index';
+  import { Time } from '/@/components/Time';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { GetCameraDetailApi,UnbindCameraApi } from '/@/api/account';
+  import { otherInfoStore } from '/@/store/modules/other'
+  import { DetailsApi,IncrementDelayApi } from '/@/api/account';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm, BasicTable },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      const { createMessage, createConfirm } = useMessage();
+      console.log('overviewInfo',overviewInfo)
+      // const overviewInfo = getOverviewInfo() || {}
+      const fileFlow = reactive({
+        file:null,
+        id:'',
+        type:'down',//down-下载,equity-权益
+      })
+            const columns: BasicColumn[] = [
+        {
+          title: '会员权益ID',
+          dataIndex: 'id',
+          width: 80,
+        },
+        {
+          title: '授权相机S/N吗',
+          width: 160,
+          dataIndex: 'snCode',
+        },
+        {
+          title: '购买日期',
+          dataIndex: 'incrementStartTime',
+          width: 180,
+          customRender: ({ record }) => {
+            return record.incrementStartTime
+              ? h(Time, {
+                  value: record.incrementStartTime,
+                  mode: 'date',
+                })
+              : '-';
+          },
+        },
+        {
+          title: '到期日期',
+          dataIndex: 'incrementEndTime',
+          width: 180,
+          customRender: ({ record }) => {
+            return record.incrementEndTime
+              ? h(Time, {
+                  value: record.incrementEndTime,
+                  mode: 'date',
+                })
+              : '-';
+          },
+        },
+        {
+          title: t('common.operating'),
+          dataIndex: '',
+          slots: { customRender: 'action' },
+          width: 80,
+        },
+      ];
+      const [
+        registerSubtable,
+        {
+          reload,
+        },
+      ] = useTable({
+        title: `查看相机详情`,
+        rowKey: 'phone',
+        searchInfo:{
+          userId:overviewInfo.value?.id
+        },
+        api: DetailsApi,
+        columns: columns,
+        showIndexColumn: false,
+        bordered: true,
+        pagination: false,
+      });
+
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        console.log('onDataReceive',data)
+        fileFlow.id = data.id
+      }
+      async function handleDelete (record: Recordable) {
+        createConfirm({
+          iconType: 'warning',
+          title: () => h('span', '续费提示'),
+          content: () => h('span', `您确定给权益ID${record.id}续期1年!`),
+          onOk: async () => {
+            await await IncrementDelayApi({id:record.id,year:1})
+            createMessage.success(t('common.optSuccess'));
+            reload()
+          },
+        });
+      }
+      const handleSubmit = async () => {
+          closeModal();
+          emit('update');
+      };
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      return {
+        register,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        registerSubtable,
+        reload,
+        handleDelete,
+        t,
+      };
+    },
+  });
+</script>

+ 9 - 9
src/views/account/overview/data.tsx

@@ -26,41 +26,41 @@ export const personData = {
 };
 export const refundSchema: DescItem[] = [
   {
-    field: 'a1',
+    field: 'nickName',
     label: '昵称',
   },
   {
-    field: 'a2',
+    field: 'userName',
     label: '账号',
   },
   {
-    field: 'a3',
+    field: 'email',
     label: '邮箱',
   },
   {
-    field: 'a4',
+    field: 'createTime',
     label: '注册时间',
   },
   {
-    field: 'a5',
+    field: 'vip',
     label: '四维看看会员',
   },
 ];
 export const personSchema: DescItem[] = [
   {
-    field: 'b1',
+    field: 'incrementCount',
     label: '权益数量',
   },
   {
-    field: 'b2',
+    field: 'surDownNum',
     label: '剩余下载次数',
   },
   {
-    field: 'b3',
+    field: 'cameraCount',
     label: '相机数量',
   },
   {
-    field: 'b4',
+    field: 'sceneNum',
     label: '场景数量',
   },
 ];

+ 81 - 10
src/views/account/overview/index.vue

@@ -2,32 +2,68 @@
   <div class="info">
     <div class="infodetail">
       <div class="title">基本信息</div>
-      <div class="list">
+      <div class="list" v-if="overviewInfo">
           <div class="list_item" v-for="item in refundSchema" :key="item.field">
             <div class="lable">{{item.label}}</div>
-            <div class="value">{{refundData[item.field]}}</div>
+            <div class="value">
+              <Icon icon="icon-park-outline:vip-one" :style="`color:${overviewInfo[item.field] == 1?'#d3d334':''}`" v-if="item.field == 'vip'" />
+              <span v-else>{{overviewInfo[item.field]}}</span>
+            </div>
           </div>
       </div>
     </div>
     <a-divider />
     <div class="infodetail">
-      <div class="title">基本信息</div>
-      <div class="list">
-          <div class="list_item" v-for="item in refundSchema" :key="item.field">
-            <div class="lable">{{item.label}}</div>
-            <div class="value">{{refundData[item.field]}}</div>
+      <div class="title">数据统计</div>
+      <div class="list" v-if="overviewInfo">
+          <div class="list_item">
+            <div class="lable">权益数量</div>
+            <div class="value">
+              <div class="text">{{overviewInfo.incrementCount}}个</div>              
+              <Button type="primary" size="small" @click="openInteresModal(true)"> 权益详情 </Button>
+              <Button type="primary" size="small" @click="handleAddEquity('equity')"> 新增权益 </Button>
+            </div>
+          </div>
+          <div class="list_item">
+            <div class="lable">剩余下载次数</div>
+            <div class="value">
+              <div class="text">{{overviewInfo.surDownNum}}次</div>              
+              <Button type="primary" size="small"  @click="handleAddEquity('down')"> 新增下载 </Button>
+            </div>
+          </div>
+          <div class="list_item">
+            <div class="lable">相机数量</div>
+            <div class="value">
+              <div class="text">{{overviewInfo.cameraCount}}台</div>              
+              <Button type="primary" size="small" @click="openCaremModal(true)"> 查看详情 </Button>
+            </div>
+          </div>
+          <div class="list_item">
+            <div class="lable">场景数量</div>
+            <div class="value">
+              <div class="text">{{overviewInfo.sceneNum}}个</div>              
+            </div>
           </div>
       </div>
     </div>
     <a-divider />
+    <AddModal @register="registerAddModal" />
+    <interesModal @register="registerInteres" />
+    <caremModal @register="registerCarem" />
   </div>
 </template>
 <script lang="ts">
-  import { defineComponent } from 'vue';
+  import { defineComponent, computed } from 'vue';
   import { Description } from '/@/components/Description/index';
   import { BasicTable } from '/@/components/Table';
   import { PageWrapper } from '/@/components/Page';
-  import { Divider } from 'ant-design-vue';
+  import { Icon } from '/@/components/Icon';
+  import { Divider, Button } from 'ant-design-vue';
+  import { otherInfoStore } from '/@/store/modules/other'
+  import AddModal from './AddModal.vue';
+  import caremModal from './caremModal.vue';
+  import interesModal from './interesModal.vue';
+  import { useModal } from '/@/components/Modal';
 
   import {
     refundSchema,
@@ -36,13 +72,39 @@
     personData,
   } from './data';
   export default defineComponent({
-    components: { Description, BasicTable, PageWrapper, [Divider.name]: Divider },
+    components: { Icon, Button,interesModal, Description, AddModal, caremModal,  BasicTable, PageWrapper, [Divider.name]: Divider },
     setup() {
+      const otherInfo = otherInfoStore();
+      const [registerAddModal, { openModal: openAddModal }] = useModal();
+      const [registerInteres, { openModal: openInteresModal }] = useModal();
+      const [registerCarem, { openModal: openCaremModal }] = useModal();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      console.log('overviewInfo',overviewInfo.value)
+      function handleAddEquity(type:string){
+        openAddModal(true, {
+          ...overviewInfo.value,
+          type,
+        });
+      }
+      function handleSetEquity(){
+        openInteresModal(true, {
+          ...overviewInfo.value,
+        });
+      }
       return {
+        registerAddModal,
+        registerInteres,
+        registerCarem,
+        openAddModal,
+        openInteresModal,
+        openCaremModal,
         refundSchema,
         refundData,
         personSchema,
         personData,
+        overviewInfo,
+        handleAddEquity,
+        handleSetEquity,
       };
     },
   });
@@ -73,6 +135,15 @@
           text-align: right;
           margin-right: 20px;
         }
+        .value{
+          .ant-btn{
+            margin-right: 30px;
+          }
+          .text{
+            width: 80px;
+            display: inline-block;
+          }
+        }
       }
     }
   }

+ 162 - 0
src/views/account/overview/interesModal.vue

@@ -0,0 +1,162 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="权益详情"
+    :width="800"
+    @visible-change="handleVisibleChange"
+    @ok="handleSubmit"
+  >
+    <div class="pt-3px pr-3px">
+      <div class="table_list">
+        <BasicTable @register="registerSubtable" >
+          <template #action="{ record }">
+            <TableAction
+              :actions="[
+                 {
+                   label: '解绑',
+                   icon: 'mdi:account-edit-outline',
+                   onClick: handleDelete.bind(null, record, 'edit'),
+                 },
+              ]"
+            />
+          </template>
+        </BasicTable>
+      </div>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, nextTick, onMounted, reactive, computed,h } from 'vue';
+  import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm } from '/@/components/Form/index';
+  import { Time } from '/@/components/Time';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { GetCameraDetailApi,UnbindCameraApi } from '/@/api/account';
+  import { otherInfoStore } from '/@/store/modules/other'
+  import { DetailsApi,IncrementDelayApi } from '/@/api/account';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm, BasicTable },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      const { createMessage, createConfirm } = useMessage();
+      console.log('overviewInfo',overviewInfo)
+      // const overviewInfo = getOverviewInfo() || {}
+      const fileFlow = reactive({
+        file:null,
+        id:'',
+        type:'down',//down-下载,equity-权益
+      })
+            const columns: BasicColumn[] = [
+        {
+          title: '会员权益ID',
+          dataIndex: 'id',
+          width: 80,
+        },
+        {
+          title: '授权相机S/N吗',
+          width: 160,
+          dataIndex: 'snCode',
+        },
+        {
+          title: '购买日期',
+          dataIndex: 'incrementStartTime',
+          width: 180,
+          customRender: ({ record }) => {
+            return record.incrementStartTime
+              ? h(Time, {
+                  value: record.incrementStartTime,
+                  mode: 'date',
+                })
+              : '-';
+          },
+        },
+        {
+          title: '到期日期',
+          dataIndex: 'incrementEndTime',
+          width: 180,
+          customRender: ({ record }) => {
+            return record.incrementEndTime
+              ? h(Time, {
+                  value: record.incrementEndTime,
+                  mode: 'date',
+                })
+              : '-';
+          },
+        },
+        {
+          title: t('common.operating'),
+          dataIndex: '',
+          slots: { customRender: 'action' },
+          width: 80,
+        },
+      ];
+      const [
+        registerSubtable,
+        {
+          reload,
+        },
+      ] = useTable({
+        title: `查看相机详情`,
+        rowKey: 'phone',
+        searchInfo:{
+          userId:overviewInfo.value?.id
+        },
+        api: DetailsApi,
+        columns: columns,
+        showIndexColumn: false,
+        bordered: true,
+        pagination: false,
+      });
+
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        console.log('onDataReceive',data)
+        fileFlow.id = data.id
+      }
+      async function handleDelete (record: Recordable) {
+        createConfirm({
+          iconType: 'warning',
+          title: () => h('span', '续费提示'),
+          content: () => h('span', `您确定给权益ID${record.id}续期1年!`),
+          onOk: async () => {
+            await await IncrementDelayApi({id:record.id,year:1})
+            createMessage.success(t('common.optSuccess'));
+            reload()
+          },
+        });
+      }
+      const handleSubmit = async () => {
+          closeModal();
+          emit('update');
+      };
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      return {
+        register,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        registerSubtable,
+        reload,
+        handleDelete,
+        t,
+      };
+    },
+  });
+</script>

+ 150 - 0
src/views/invoice/EditModal.vue

@@ -0,0 +1,150 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="开票详情"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleSubmit"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm">
+        <template #text="{ model, field }">
+          {{ model[field]  }}{{fileFlow.type}}
+        </template>
+        <template #img="{ model }">
+          <TableImg v-if="model.invoiceUrl" :size="200" :adaptations="true" :simpleShow="true" :imgList="[model.invoiceUrl]" />
+        </template>
+      </BasicForm>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, nextTick, onMounted, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { TableImg } from '/@/components/Table';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { InvoiceRegister, InvoiceDetail } from '/@/api/order';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { uploadApi } from '/@/api/product/index';
+  import { ResultEnum } from '/@/enums/httpEnum';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm, TableImg },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const fileFlow = reactive({
+        file:null,
+        type:2,//2-普通发票,3-专用发票
+      })
+      const { createMessage } = useMessage();
+      const schemas: FormSchema[] = [
+          {
+            field: 'id',
+            component: 'Input',
+            show:false,
+            label: '发票编号',
+            required: true,
+          },
+          {
+            field: 'email',
+            component: 'Input',
+            label: '邮箱',
+            slot: 'text',
+            ifShow:fileFlow.type == 2,
+            colProps: {
+              span: 24,
+            },
+          },{
+            field: 'invoiceNum',
+            component: 'Input',
+            label: '发票编号',
+            slot: 'text',
+            required: true,
+            colProps: {
+              span: 24,
+            },
+          },{
+            field: 'invoiceUrl',
+            component: 'Upload',
+            label: '电子发票',
+            ifShow:fileFlow.type == 2,
+            required: true,
+            slot: 'img',
+            colProps: {
+              span: 22,
+            },
+          },{
+            field: 'invoiceNum',
+            component: 'Input',
+            label: '发票编号',
+            required: true,
+            slot: 'text',
+            colProps: {
+              span: 24,
+            },
+          },{
+            field: 'shipNum',
+            component: 'Input',
+            ifShow:fileFlow.type == 3,
+            slot: 'text',
+            label: '快递单号',
+            required: true,
+            colProps: {
+              span: 24,
+            },
+          },
+      ];
+
+      const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm({
+        labelWidth: 120,
+        schemas:schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      async function onDataReceive(data) {
+        resetFields();
+        let detail = await InvoiceDetail({id:data.id})
+        fileFlow.type = data.type
+        setFieldsValue({
+          ...data,
+          ...detail,
+        });
+        updateSchema([
+          {field: 'shipNum',ifShow:fileFlow.type == 3,},
+          {field: 'email',ifShow:fileFlow.type == 2,},
+          {field: 'invoiceUrl',ifShow:fileFlow.type == 2,},
+        ])
+      }
+      const handleSubmit = async () => {
+          closeModal();
+          emit('update');
+      };
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      return {
+        register,
+        registerForm,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        resetFields,
+        t,
+      };
+    },
+  });
+</script>

+ 182 - 0
src/views/invoice/InvoiceModal.vue

@@ -0,0 +1,182 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="开票登记"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleSubmit"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm">
+        <template #text="{ model, field }">
+          {{ model[field]  }}{{fileFlow.type}}
+        </template>
+      </BasicForm>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, nextTick, onMounted, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { InvoiceRegister } from '/@/api/order';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { uploadApi } from '/@/api/product/index';
+  import { ResultEnum } from '/@/enums/httpEnum';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const fileFlow = reactive({
+        file:null,
+        type:2,//2-普通发票,3-专用发票
+      })
+      const { createMessage } = useMessage();
+      const schemas: FormSchema[] = [
+          {
+            field: 'id',
+            component: 'Input',
+            show:false,
+            label: '发票编号',
+            required: true,
+          },
+          {
+            field: 'email',
+            component: 'Input',
+            label: '邮箱',
+            slot: 'text',
+            ifShow:fileFlow.type == 2,
+            colProps: {
+              span: 24,
+            },
+          },{
+            field: 'invoiceNum',
+            component: 'Input',
+            label: '发票编号',
+            required: true,
+            colProps: {
+              span: 24,
+            },
+          },{
+            field: 'file',
+            component: 'Upload',
+            label: '电子发票',
+            ifShow:fileFlow.type == 2,
+            required: true,
+            rules: [{ required: true, message: t('common.uploadMessge') }],
+            itemProps: {
+              validateTrigger: 'onBlur',
+            },
+            componentProps: {
+              api: uploadApi,
+              fileFlow:true,
+              maxNumber: 1,
+              maxSize: 1000,
+              accept: ['jpeg','jpg','png'],
+              afterFetch: function (data) {
+                console.log('url',data)
+                Reflect.set(data, 'url', data.file);
+                fileFlow.file = data.file
+                return data;
+              },
+            },
+
+            colProps: {
+              span: 22,
+            },
+          },{
+            field: 'invoiceNum',
+            component: 'Input',
+            label: '发票编号',
+            required: true,
+            colProps: {
+              span: 24,
+            },
+          },{
+            field: 'shipNum',
+            component: 'Input',
+            ifShow:fileFlow.type == 3,
+            label: '快递单号',
+            required: true,
+            colProps: {
+              span: 24,
+            },
+          },
+      ];
+
+      const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm({
+        labelWidth: 120,
+        schemas:schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        resetFields();
+        fileFlow.type = data.type
+        setFieldsValue(data);
+        updateSchema([
+          {field: 'shipNum',ifShow:fileFlow.type == 3,},
+          {field: 'email',ifShow:fileFlow.type == 2,},
+          {field: 'file',ifShow:fileFlow.type == 2,},
+        ])
+      }
+      const handleSubmit = async () => {
+        try {
+          const params = await validate();
+          const apiData = {
+            data:fileFlow.type == 3?{
+              id:params.id,
+              invoiceNum:params.invoiceNum,
+              shipNum:params.shipNum,
+            }:{
+              id:params.id,
+              invoiceNum:params.invoiceNum,
+              file:fileFlow.file,
+            // file:params.file[0],
+            }
+          }
+          console.log('res', apiData,params);
+          const {data} = await InvoiceRegister(apiData);
+          console.log('res', data);
+          if(data.code !== ResultEnum.SUCCESS){
+            createMessage.error(  data.message  ||  t('common.optFail'))
+          }else{
+          closeModal();
+          resetFields();
+          createMessage.success(t('common.optSuccess'));
+          emit('update');
+          }
+        } catch (error) {
+          console.log('not passing', error);
+        }
+      };
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      return {
+        register,
+        registerForm,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        resetFields,
+        t,
+      };
+    },
+  });
+</script>

+ 226 - 0
src/views/invoice/data.tsx

@@ -0,0 +1,226 @@
+import { Time } from '/@/components/Time';
+import { FormProps, BasicColumn } from '/@/components/Table';
+import { h } from 'vue';
+import { FormSchema } from '/@/components/Form/index';
+import { useI18n } from '/@/hooks/web/useI18n';
+const { t } = useI18n();
+
+export const columns: BasicColumn[] = [
+        
+  {
+    title: '订单号',
+    dataIndex: 'orderSn',
+    ellipsis: false,
+    width: 180,
+  },
+  {
+    title: '支付时间',
+    dataIndex: 'payTime',
+    width: 150,
+    customRender: ({ record }) => {
+      return (
+        record.payTime &&
+        h(Time, {
+          value: record.payTime,
+          mode: 'datetime',
+        })
+      );
+    },
+  },
+  {
+    title: '开票申请时间',
+    dataIndex: 'invoiceTime',
+    width: 150,
+    customRender: ({ record }) => {
+      return (
+        record.invoiceTime &&
+        h(Time, {
+          value: record.invoiceTime,
+          mode: 'datetime',
+        })
+      );
+    },
+  },
+  {
+    title: '开票金额',
+    dataIndex: 'money',
+    width: 80,
+  },
+  {
+    title: '开票类型',
+    dataIndex: 'type',
+    width: 80,
+    customRender:({record})=>{
+      if(record.type == 2){
+        return '普通发票'
+      }else{
+        return '专用发票'
+      }
+    }
+  },
+  {
+    title: '发票抬头',
+    dataIndex: 'title',
+    // slots: { customRender: 'orderType' },
+    width: 150,
+  },
+  {
+    title: '纳税人识别号',
+    dataIndex: 'code',
+    // slots: { customRender: 'orderStatus' },
+    width: 180,
+  },
+  {
+    title: '注册地址',
+    dataIndex: 'organizedAddress',
+    // slots: { customRender: 'orderStatus' },
+    width: 180,
+  },
+  {
+    title: '注册电话',
+    dataIndex: 'registerPhone',
+    // slots: { customRender: 'orderStatus' },
+    width: 120,
+  },
+  {
+    title: '开户银行',
+    dataIndex: 'bankName',
+    // slots: { customRender: 'orderStatus' },
+    width: 150,
+  },
+  {
+    title: '银行账号',
+    dataIndex: 'bankAccount',
+    // slots: { customRender: 'orderStatus' },
+    width: 130,
+  },
+  {
+    title: '收件人姓名',
+    dataIndex: 'shipName',
+    // slots: { customRender: 'orderStatus' },
+    width: 120,
+  },
+  {
+    title: '收件人电话',
+    dataIndex: 'shipMobile',
+    // slots: { customRender: 'orderStatus' },
+    width: 110,
+  },
+  {
+    title: '收货地址',
+    dataIndex: 'shipAddress',
+    // slots: { customRender: 'orderStatus' },
+    width: 130,
+  },
+  {
+    title: '邮箱',
+    dataIndex: 'email',
+    // slots: { customRender: 'orderStatus' },
+    width: 150,
+  },
+  {
+    title: '状态',
+    dataIndex: 'invoiced',
+    // slots: { customRender: 'orderStatus' },
+    width: 80,
+    customRender:({record})=>{
+      if(record.invoiced == 0){
+        return '未开票'
+      }else{
+        return '已开票'
+      }
+    }
+  },
+];
+export const searchForm: Partial<FormProps> = {
+  labelWidth: 100,
+  schemas: [
+    {
+      field: 'invoiceTime',
+      label: '开票申请时间',
+      component: 'RangePicker',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 7,
+        xxl: 7,
+      },
+    },
+    {
+      field: 'payTime',
+      label: '支付时间',
+      component: 'RangePicker',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 7,
+        xxl: 7,
+      },
+    },{
+      field: 'orderSn',
+      label: '订单号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 6,
+        xxl: 6,
+      },
+    }
+  ],
+};
+export const InvoiceSchemas: FormSchema[] = [
+  {
+    field: 'type',
+    component: 'Input',
+    label: t('routes.product.types'),
+    slot: 'text',
+    colProps: {
+      span: 24,
+    },
+  },
+  {
+    field: 'version',
+    component: 'Input',
+    label: t('routes.product.version'),
+    required: true,
+    colProps: {
+      span: 24,
+    },
+    rules: [
+      {
+        required: true,
+        // @ts-ignore
+        validator: async (rule, value) => {
+          if (!value) {
+            return Promise.reject(t('common.inputText')+t('routes.product.version'));
+          }
+          if(/.*[\u4e00-\u9fa5]+.*$/.test(value)){
+            /* eslint-disable-next-line */
+            return Promise.reject('不支持中文字符');
+          }
+          return Promise.resolve();
+        },
+        trigger: 'change',
+      },
+    ],
+    componentProps: {
+      maxLength: 15,
+      onChange: (data) => {
+        console.log('data', data);
+      },
+    },
+  },
+  {
+    field: 'description',
+    component: 'InputTextArea',
+    required: true,
+    label: t('routes.product.description'),
+    colProps: {
+      span: 24,
+    },
+  },
+]

+ 101 - 112
src/views/invoice/index.vue

@@ -1,46 +1,65 @@
 <template>
+  <div>
     <BasicTable @register="registerTable">
       <template #toolbar>
         <a-button type="primary" @click="exportExcel"> 导出</a-button>
       </template>
-      <template #bodyCell="{ column, record }">
-        <template v-if="column.key === 'action'">
+      <template #action="{ record }">
           <TableAction
             stopButtonPropagation
             :actions="[
               {
-                label: '删除',
-                icon: 'ic:outline-delete-outline',
-                onClick: handleDelete.bind(null, record),
+                label: '开票登记',
+                icon: 'la:file-invoice-dollar',
+                ifShow:record.invoiced==0,
+                onClick: handleInvoice.bind(null, record),
+              },
+              {
+                label: '电子发票',
+                ifShow:record.type == 2 && record.invoiced==1,
+                icon: 'simple-icons:invoiceninja',
+                onClick: headleDetails.bind(null, record),
               },
-            ]"
-            :dropDownActions="[
               {
-                label: '启用',
-                popConfirm: {
-                  title: '是否启用?',
-                  confirm: handleOpen.bind(null, record),
-                },
+                label: '快递单号',
+                ifShow:record.type != 2&& record.invoiced==1,
+                icon: 'icon-park-outline:express-delivery',
+                onClick: headleDetails.bind(null, record),
               },
             ]"
           />
-        </template>
       </template>
     </BasicTable>
+    <AddModal @update="reload" @register="registerAddModal" />
+    <EditModal @register="registerEditModal" @update="reload" />
+  </div>
 </template>
 <script lang="ts">
-  import { defineComponent, h } from 'vue';
-  import { BasicTable, useTable, TableAction, BasicColumn, TableImg, FormProps } from '/@/components/Table';
+  import { defineComponent, h, reactive } from 'vue';
+  import { BasicTable, useTable, TableAction, TableImg } from '/@/components/Table';
   import { PageWrapper } from '/@/components/Page';
-  import { Time } from '/@/components/Time';
+  import { useModal } from '/@/components/Modal';
   import { Descriptions } from 'ant-design-vue';
   import { useI18n } from '/@/hooks/web/useI18n';
   import { useMessage } from '/@/hooks/web/useMessage';
-  import { Switch } from 'ant-design-vue';
-  import { InvoiceList,DownExport } from '/@/api/order'
-
+  import { InvoiceList,InvoiceExport } from '/@/api/order'
+  import { downloadByData } from '/@/utils/file/download'
+  import { searchForm, columns } from './data'
+  import AddModal from './InvoiceModal.vue';
+  import EditModal from './EditModal.vue';
+  interface apiDataParam {
+    orderSn?: string;
+    payTimeStart?: string;
+    payTimeEnd?: string;
+    invoiceTimeStart?: string;
+    invoiceTimeEnd?: string;
+    orderBy?: string;
+    sortBy?: string;
+  }
   export default defineComponent({
     components: { 
+      AddModal,
+      EditModal,
       BasicTable, 
       TableAction, 
       PageWrapper,
@@ -50,92 +69,19 @@
     },
     setup() {
       const { t } = useI18n();
+      const apiData = reactive<apiDataParam>({
+        orderSn: '',
+        payTimeStart: '',
+        payTimeEnd: '',
+        invoiceTimeStart: '',
+        invoiceTimeEnd: '',
+        orderBy: '',
+        sortBy: '',
+      });
       const { createMessage,createConfirm } = useMessage();
-      const columns: BasicColumn[] = [
-        {
-          title: '时间',
-          dataIndex: 'createTime',
-          width: 150,
-          customRender: ({ record }) => {
-            return (
-              record.createTime &&
-              h(Time, {
-                value: record.createTime,
-                mode: 'datetime',
-              })
-            );
-          },
-        },
-        {
-          title: '订单号',
-          dataIndex: 'orderSn',
-          ellipsis: false,
-          width: 180,
-        },
-        {
-          title: '用户名',
-          dataIndex: 'userName',
-          width: 80,
-        },
-        {
-          title: '订单金额',
-          dataIndex: 'amount',
-          width: 80,
-        },
-        {
-          title: '支付方式',
-          dataIndex: 'payType',
-          // slots: { customRender: 'orderType' },
-          width: 80,
-        },
-        {
-          title: '订单状态',
-          dataIndex: 'payStatus',
-          // slots: { customRender: 'orderStatus' },
-          width: 80,
-        },
-      ];
-      const searchForm: Partial<FormProps> = {
-        labelWidth: 100,
-        schemas: [
-          {
-            field: 'sceneName',
-            label: '开票申请时间',
-            component: 'RangePicker',
-            componentProps: {
-              maxLength: 100,
-            },
-            colProps: {
-              xl: 7,
-              xxl: 7,
-            },
-          },
-          {
-            field: 'sceneName',
-            label: '支付时间',
-            component: 'RangePicker',
-            componentProps: {
-              maxLength: 100,
-            },
-            colProps: {
-              xl: 7,
-              xxl: 7,
-            },
-          },{
-            field: 'sceneName',
-            label: '订单号',
-            component: 'Input',
-            componentProps: {
-              maxLength: 100,
-            },
-            colProps: {
-              xl: 6,
-              xxl: 6,
-            },
-          }
-        ],
-      };
-      const [registerTable] = useTable({
+      const [registerAddModal, { openModal: openAddModal }] = useModal();
+      const [registerEditModal, { openModal: openEditModal }] = useModal();
+      const [registerTable, { reload }] = useTable({
         api: InvoiceList,
         title: '发票列表',
         // titleHelpMessage: ['已启用expandRowByClick', '已启用stopButtonPropagation'],
@@ -143,36 +89,79 @@
         useSearchForm: true,
         formConfig: searchForm,
         showTableSetting: true,
+        showIndexColumn:false,
         rowKey: 'id',
+        beforeFetch:(params) =>{
+          let searchData = {
+              orderSn: params.orderSn,
+              payTimeStart: params.payTime && params.payTime[0],
+              payTimeEnd: params.payTime && params.payTime[1],
+              invoiceTimeStart: params.invoiceTime && params.invoiceTime[0],
+              invoiceTimeEnd: params.invoiceTime && params.invoiceTime[1],
+          }
+          apiData.orderSn = searchData.orderSn
+          apiData.payTimeStart = searchData.payTimeStart
+          apiData.payTimeEnd = searchData.payTimeEnd
+          apiData.invoiceTimeStart = searchData.invoiceTimeStart
+          apiData.invoiceTimeEnd = searchData.invoiceTimeEnd
+          return {
+            ...params,
+            ...searchData,
+          }
+        },
         fetchSetting: {
           pageField: 'pageNum',
-          sizeField: 'size',
-          listField: 'records',
+          sizeField: 'pageSize',
+          listField: 'list',
           totalField: 'total',
         },
+        actionColumn: {
+          width: 100,
+          title: '操作',
+          fixed: 'right',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
         canResize: false,
       });
       function handleDelete(record: Recordable) {
         console.log('点击了删除', record);
       }
-      function handleOpen(record: Recordable) {
-        console.log('点击了启用', record);
+      function handleInvoice(record: Recordable) {
+        openAddModal(true, {
+          ...record,
+        });
       }
-      function exportExcel() {
+    function handleEdit(record: Recordable) {
+      console.log('record', record);
+    }
+    function headleDetails(record: Recordable) {
+      console.log('record', record);
+      openEditModal(true, {
+        ...record,
+      });
+    }
+    function exportExcel() {
         createConfirm({
           iconType: 'warning',
           title: () => h('span', '温馨提示'),
-          content: () => h('span', '确定当前标签下的订单记录?'),
+          content: () => h('span', '确定导出当前发票所有记录?'),
           onOk: async () => {
-            await DownExport();
+           const blodData:BlobPart =  await InvoiceExport(apiData);
+           downloadByData(blodData,'发票记录')
           },
         });
       }
       return {
         registerTable,
         handleDelete,
-        handleOpen,
+        registerAddModal,
+        registerEditModal,
+        handleInvoice,
         exportExcel,
+        handleEdit,
+        headleDetails,
+        reload,
       };
     },
   });

+ 19 - 0
types/store.d.ts

@@ -10,6 +10,25 @@ export interface LockInfo {
   isLock?: boolean;
 }
 
+// Lock screen information
+export interface OverviewInfo {
+  // Password required
+  pwd?: string | undefined;
+  // Is it locked?
+  id: number;
+  incrementCount?: number;
+  surDownNum?: number;
+  userName: string;
+  nickName: string;
+  createTime: string;
+  email: string;
+  vip: number;
+  incrementCount: number;
+  surDownNum: number;
+  cameraCount: number;
+  sceneNum: number;
+}
+
 // Error-log information
 export interface ErrorLogInfo {
   // Type of error

+ 9 - 4
yarn.lock

@@ -3689,7 +3689,7 @@ create-require@^1.1.0:
 
 cropperjs@^1.5.12:
   version "1.5.12"
-  resolved "https://registry.npmmirror.com/cropperjs/-/cropperjs-1.5.12.tgz#d9c0db2bfb8c0d769d51739e8f916bbc44e10f50"
+  resolved "https://registry.npmmirror.com/cropperjs/-/cropperjs-1.5.12.tgz"
   integrity sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw==
 
 cross-env@^7.0.3:
@@ -3857,6 +3857,11 @@ dateformat@^3.0.0:
   resolved "https://registry.npmmirror.com/dateformat/-/dateformat-3.0.3.tgz"
   integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
 
+dayjs@^1.11.5:
+  version "1.11.5"
+  resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.5.tgz"
+  integrity sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA==
+
 debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
   version "2.6.9"
   resolved "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz"
@@ -9205,9 +9210,9 @@ rollup-plugin-visualizer@^5.5.2:
     yargs "^17.5.1"
 
 rollup@^2.43.1, rollup@^2.56.3, rollup@^2.59.0, rollup@^2.60.2:
-  version "2.78.0"
-  resolved "https://registry.npmmirror.com/rollup/-/rollup-2.78.0.tgz#00995deae70c0f712ea79ad904d5f6b033209d9e"
-  integrity sha512-4+YfbQC9QEVvKTanHhIAFVUFSRsezvQF8vFOJwtGfb9Bb+r014S+qryr9PSmw8x6sMnPkmFBGAvIFVQxvJxjtg==
+  version "2.78.1"
+  resolved "https://registry.npmmirror.com/rollup/-/rollup-2.78.1.tgz#52fe3934d9c83cb4f7c4cb5fb75d88591be8648f"
+  integrity sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==
   optionalDependencies:
     fsevents "~2.3.2"