tangning 5 月之前
父节点
当前提交
959a42aa42

+ 103 - 9
src/api/account/index.ts

@@ -3,14 +3,22 @@ import { PageParams, userList } from './model';
 import { Result } from '/#/axios';
 
 enum Api {
-  pageList = '/service/manage/user/list',
-  getIncrementListByUserId = '/service/manage/user/getIncrementListByUserId',
-  IncrementDelay = '/service/manage/user/incrementDelay',
-  addUserIncrement = '/service/manage/user/addUserIncrement',
-  addDownNum = '/service/manage/user/addDownNum',
-  getCameraDetail = '/service/manage/user/getCameraDetail',
-  unbindCamera = '/service/agent/camera/unBindCamera',
-  allList = '/service/manage/incrementType/allList',
+  pageList = '/service/agent/user/list',
+  userDetail = '/service/agent/user/userDetail',
+  getIncrementListByUserId = '/service/agent/user/getIncrementListByUserId',
+  IncrementDelay = '/service/agent/user/incrementDelay',
+  addUserIncrement = '/service/agent/user/addUserIncrement',
+  addDownNum = '/service/agent/user/addDownNum',
+  getCameraDetail = '/service/agent/user/getCameraDetail',
+  unbindCamera = '/service/agent/user/unbindCamera',
+  allList = '/service/agent/incrementType/allList',
+  cameraAllType = '/service/agent/cameraType/allList',
+  wifiPrefixAll = '/service/agent/cameraWifiPrefix/allList',
+  incrementUseTypeList = '/service/agent/incrementUseType/allList',
+  getAddUserIncrementTime = '/service/agent/user/getAddUserIncrementTime',
+  currencyList = '/service/agent/currency/allList',
+  incrementBindCamera = '/service/agent/user/incrementBindCamera',
+  incrementUnBindCamera = '/service/agent/user/incrementUnBindCamera',
 }
 
 /**
@@ -29,6 +37,18 @@ export const ListApi = (params: PageParams) =>
   });
 
 //权益详情
+export const userDetail = (params: PageParams) =>
+  defHttp.get<userList>({
+    url: Api.userDetail,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+//权益详情
 export const DetailsApi = (params: PageParams) =>
   defHttp.post<userList>({
     url: Api.getIncrementListByUserId,
@@ -62,6 +82,17 @@ export const dincrementList = (params: PageParams) =>
     },
   });
 
+//延期时间
+export const getAddUserIncrementTime = (params: PageParams) =>
+  defHttp.post<userList>({
+    url: Api.getAddUserIncrementTime,
+    params: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
 //添加用户权益
 export const AddUserIncrementApi = (params: PageParams) =>
   defHttp.post<userList>({
@@ -94,10 +125,30 @@ export const GetCameraDetailApi = (params: PageParams) =>
       ignoreCancelToken: true,
     },
   });
+//获取相机详情
+export const incrementBindCamera = (params: PageParams) =>
+  defHttp.post<userList>({
+    url: Api.incrementBindCamera,
+    params: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+//获取相机详情
+export const incrementUnBindCamera = (params: PageParams) =>
+  defHttp.post<userList>({
+    url: Api.incrementUnBindCamera,
+    params: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
 
 //相机解绑
 export const UnbindCameraApi = (params: PageParams) =>
-  defHttp.post<userList>({
+  defHttp.get<userList>({
     url: Api.unbindCamera,
     params: params,
     headers: {
@@ -105,3 +156,46 @@ export const UnbindCameraApi = (params: PageParams) =>
       ignoreCancelToken: true,
     },
   });
+
+//全部权益使用类型
+export const incrementUseTypeList = (params: PageParams) =>
+  defHttp.get<userList>({
+    url: Api.incrementUseTypeList,
+    params: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+//全部权益使用类型
+export const currencyList = (params: PageParams) =>
+  defHttp.get<userList>({
+    url: Api.currencyList,
+    params: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+//设备类型字典
+export const cameraAllType = (params: PageParams) =>
+  defHttp.get<userList>({
+    url: Api.cameraAllType,
+    params: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+//wifi前缀字典
+export const wifiPrefixAll = (params: PageParams) =>
+  defHttp.get<userList>({
+    url: Api.wifiPrefixAll,
+    params: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });

+ 165 - 0
src/api/authorizeModeling/index.ts

@@ -0,0 +1,165 @@
+import { defHttp } from '/@/utils/http/axios';
+import { Result } from '/#/axios';
+
+enum Api {
+  authorizeModelingList = '/service/agent/authorizeModeling/list',
+  authorizeModelingaddOrUpdate = '/service/agent/authorizeModeling/addOrUpdate',
+  authorizeModelingdelete = '/service/agent/authorizeModeling/delete',
+  authorizeInstallList = '/service/agent/authorizeInstall/list',
+  authorizeInstalladdOrUpdate = '/service/agent/authorizeInstall/addOrUpdate',
+  authorizeInstalldelete = '/service/agent/authorizeInstall/delete',
+  checkMachineCode = '/service/agent/authorizeInstall/checkMachineCode',
+  authorizeCameraList = '/service/agent/authorizeCamera/list',
+  authorizeCameraaddOrUpdate = '/service/agent/authorizeCamera/addOrUpdate',
+  authorizeCameradelete = '/service/agent/authorizeCamera/delete',
+  authorizeCameradetail = '/service/agent/authorizeCamera/detail/',
+  authorizeCameraupdateSnCode = '/service/agent/authorizeCamera/updateSnCode/',
+  authorizeCamerasnUpdateLog = '/service/agent/authorizeCamera/snUpdateLog/',
+}
+
+/**
+ * @description: Get sample list value
+ */
+
+export const authorizeModelingList = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeModelingList,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeModelingaddOrUpdate = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeModelingaddOrUpdate,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeModelingdelete = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeModelingdelete,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeInstallList = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeInstallList,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeInstalladdOrUpdate = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeInstalladdOrUpdate,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const checkMachineCode = (params) =>
+  defHttp.post<Result>({
+    url: Api.checkMachineCode,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeInstalldelete = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeInstalldelete,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeCameraList = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeCameraList,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeCameraaddOrUpdate = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeCameraaddOrUpdate,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+export const authorizeCameradelete = (params) =>
+  defHttp.post<Result>({
+    url: Api.authorizeCameradelete,
+    params: params,
+    // data: params,
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+//全部权益使用类型
+export const authorizeCameradetail = (id) =>
+  defHttp.get<Result>({
+    url: Api.authorizeCameradetail + id,
+    params: {},
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+//全部权益使用类型
+export const authorizeCameraupdateSnCode = ({ id, snCode }) =>
+  defHttp.get<Result>({
+    url: Api.authorizeCameraupdateSnCode + id + '/' + snCode,
+    params: {},
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });
+
+//全部权益使用类型
+export const authorizeCamerasnUpdateLog = (id) =>
+  defHttp.get<Result>({
+    url: Api.authorizeCamerasnUpdateLog + id,
+    params: {},
+    headers: {
+      // @ts-ignore
+      ignoreCancelToken: true,
+    },
+  });

+ 39 - 0
src/router/routes/modules/account.ts

@@ -0,0 +1,39 @@
+import type { AppRouteRecordRaw } from '/@/router/types';
+import { t } from '/@/hooks/web/useI18n';
+import { LAYOUT } from '/@/router/constant';
+
+export const Device: AppRouteRecordRaw = {
+  path: '/account',
+  name: 'Account',
+  redirect: '/account/list',
+  component: LAYOUT,
+  meta: {
+    title: '用户管理',
+    icon: 'codicon:device-camera',
+    orderNo: 6,
+    hideChildrenInMenu: true,
+  },
+  children: [
+    {
+      path: 'details',
+      name: 'AccountDetails',
+      component: () => import('/@/views/account/details/index.vue'),
+      meta: {
+        title: '用户管理',
+        hideBreadcrumb: true,
+        // icon: 'codicon:device-camera',
+      },
+    },
+    {
+      path: 'list',
+      name: 'AccountList',
+      component: () => import('/@/views/account/lists.vue'),
+      meta: {
+        title: '用户管理',
+        hideBreadcrumb: true,
+        // icon: 'codicon:device-camera',
+      },
+    },
+  ],
+};
+export default Device;

+ 29 - 0
src/router/routes/modules/empower.ts

@@ -0,0 +1,29 @@
+import type { AppRouteRecordRaw } from '/@/router/types';
+import { t } from '/@/hooks/web/useI18n';
+import { LAYOUT } from '/@/router/constant';
+
+export const Device: AppRouteRecordRaw = {
+  path: '/empower',
+  name: 'Empower',
+  redirect: '/empower/index',
+  component: LAYOUT,
+  meta: {
+    title: '本地版授权管理',
+    icon: 'codicon:device-camera',
+    orderNo: 20,
+    hideChildrenInMenu: true,
+  },
+  children: [
+    {
+      path: 'index',
+      name: 'EmpowerIndex',
+      component: () => import('/@/views/empower/index.vue'),
+      meta: {
+        title: '本地版授权管理',
+        hideBreadcrumb: true,
+        // icon: 'codicon:device-camera',
+      },
+    },
+  ],
+};
+export default Device;

+ 243 - 0
src/views/account/data.ts

@@ -0,0 +1,243 @@
+import { FormSchema } from '/@/components/Form/index';
+import { BasicColumn } from '/@/components/Table/src/types/table';
+import { Time } from '/@/components/Time';
+import { h } from 'vue';
+const isDev = window.location.hostname.includes('eur');
+export interface ListItem {
+  key: string;
+  title: string;
+  description: string;
+  extra?: string;
+  avatar?: string;
+  color?: string;
+}
+
+// tab的list
+export const settingList = [
+  {
+    key: '1',
+    name: '基本设置',
+    component: 'BaseSetting',
+  },
+  {
+    key: '2',
+    name: '安全设置',
+    component: 'SecureSetting',
+  },
+  {
+    key: '3',
+    name: '账号绑定',
+    component: 'AccountBind',
+  },
+  {
+    key: '4',
+    name: '新消息通知',
+    component: 'MsgNotify',
+  },
+];
+
+// 基础设置 form
+export const baseSetschemas: FormSchema[] = [
+  {
+    field: 'email',
+    component: 'Input',
+    label: '下单时间',
+    colProps: { span: 18 },
+  },
+  {
+    field: 'name',
+    component: 'Input',
+    label: '昵称',
+    colProps: { span: 18 },
+  },
+  {
+    field: 'introduction',
+    component: 'InputTextArea',
+    label: '个人简介',
+    componentProps: {
+      rows:4,
+    },
+    colProps: { span: 18 },
+  },
+  {
+    field: 'phone',
+    component: 'Input',
+    label: '联系电话',
+    colProps: { span: 18 },
+  },
+  {
+    field: 'address',
+    component: 'Input',
+    label: '所在地区',
+    colProps: { span: 18 },
+  },
+];
+
+// 安全设置 list
+export const secureSettingList: ListItem[] = [
+  {
+    key: '1',
+    title: '账户密码',
+    description: '当前密码强度::强',
+    extra: '修改',
+  },
+  {
+    key: '2',
+    title: '密保手机',
+    description: '已绑定手机::138****8293',
+    extra: '修改',
+  },
+  {
+    key: '3',
+    title: '密保问题',
+    description: '未设置密保问题,密保问题可有效保护账户安全',
+    extra: '修改',
+  },
+  {
+    key: '4',
+    title: '备用邮箱',
+    description: '已绑定邮箱::ant***sign.com',
+    extra: '修改',
+  },
+  {
+    key: '5',
+    title: 'MFA 设备',
+    description: '未绑定 MFA 设备,绑定后,可以进行二次确认',
+    extra: '修改',
+  },
+];
+
+// 账号绑定 list
+export const accountBindList: ListItem[] = [
+  {
+    key: '1',
+    title: '绑定淘宝',
+    description: '当前未绑定淘宝账号',
+    extra: '绑定',
+    avatar: 'ri:taobao-fill',
+    color: '#ff4000',
+  },
+  {
+    key: '2',
+    title: '绑定支付宝',
+    description: '当前未绑定支付宝账号',
+    extra: '绑定',
+    avatar: 'fa-brands:alipay',
+    color: '#2eabff',
+  },
+  {
+    key: '3',
+    title: '绑定钉钉',
+    description: '当前未绑定钉钉账号',
+    extra: '绑定',
+    avatar: 'ri:dingding-fill',
+    color: '#2eabff',
+  },
+];
+
+// 新消息通知 list
+export const msgNotifyList: ListItem[] = [
+  {
+    key: '1',
+    title: '账户密码',
+    description: '其他用户的消息将以站内信的形式通知',
+  },
+  {
+    key: '2',
+    title: '系统消息',
+    description: '系统消息将以站内信的形式通知',
+  },
+  {
+    key: '3',
+    title: '待办任务',
+    description: '待办任务将以站内信的形式通知',
+  },
+];
+export const refundTimeTableSchema: BasicColumn[] = [
+  {
+    title: '下单时间',
+    width: 150,
+    dataIndex: 'createTime',
+    customRender: ({ record }) => {
+      return (
+        record.createTime &&
+        h(Time, {
+          value: record.createTime,
+          mode: 'datetime',
+        })
+      );
+    },
+  },{
+    title: '订单号',
+    width: 150,
+    dataIndex: 'version',
+  },
+  {
+    title: '用户账号',
+    width: 150,
+    dataIndex: 'description',
+  },
+  {
+    title: '数量',
+    width: 150,
+    dataIndex: 'minVersion',
+  },{
+    title: '订单金额(元)',
+    width: 150,
+    dataIndex: 'minVersion',
+  },{
+    title: '支付方式',
+    width: 150,
+    dataIndex: 'recStatus',
+  },{
+    title: '交易号',
+    width: 150,
+    dataIndex: 'minVersion',
+  },{
+    title: '订单状态',
+    width: 150,
+    dataIndex: 'recStatus',
+  },
+];
+
+export const userListSchema: BasicColumn[] = [
+  {
+    title: '用户ID',
+    width: 150,
+    dataIndex: 'id',
+  },{
+    title: '昵称',
+    width: 150,
+    dataIndex: 'nickName',
+  },{
+    title: '账号',
+    width: 150,
+    dataIndex: 'userName',
+  },{
+    title: '邮箱',
+    width: 150,
+    ifShow: !isDev,
+    dataIndex: 'email',
+  },{
+    title: '注册时间',
+    width: 150,
+    dataIndex: 'createTime',
+    customRender: ({ record }) => {
+      return (
+        record.createTime &&
+        h(Time, {
+          value: record.createTime,
+          mode: 'datetime',
+        })
+      );
+    },
+  },
+  {
+    title: '四维看看会员',
+    width: 150,
+    dataIndex: 'vip',
+    customRender: ({ record }) => {
+      return record.vip == 0?'否':'是'
+    }
+    }
+];

+ 59 - 0
src/views/account/details/AccountBind.vue

@@ -0,0 +1,59 @@
+<template>
+  <CollapseContainer title="账号绑定" :canExpan="false">
+    <List>
+      <template v-for="item in list" :key="item.key">
+        <ListItem>
+          <ListItemMeta>
+            <template #avatar>
+              <Icon v-if="item.avatar" class="avatar" :icon="item.avatar" :color="item.color" />
+            </template>
+            <template #title>
+              {{ item.title }}
+              <a-button type="link" size="small" v-if="item.extra" class="extra">
+                {{ item.extra }}
+              </a-button>
+            </template>
+            <template #description>
+              <div>{{ item.description }}</div>
+            </template>
+          </ListItemMeta>
+        </ListItem>
+      </template>
+    </List>
+  </CollapseContainer>
+</template>
+<script lang="ts">
+  import { List } from 'ant-design-vue';
+  import { defineComponent } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import Icon from '/@/components/Icon/index';
+
+  import { accountBindList } from './data';
+
+  export default defineComponent({
+    components: {
+      CollapseContainer,
+      List,
+      ListItem: List.Item,
+      ListItemMeta: List.Item.Meta,
+      Icon,
+    },
+    setup() {
+      return {
+        list: accountBindList,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .avatar {
+    font-size: 40px !important;
+  }
+
+  .extra {
+    float: right;
+    margin-top: 10px;
+    margin-right: 30px;
+    cursor: pointer;
+  }
+</style>

+ 95 - 0
src/views/account/details/BaseSetting.vue

@@ -0,0 +1,95 @@
+<template>
+  <CollapseContainer title="基本设置" :canExpan="false">
+    <a-row :gutter="24">
+      <a-col :span="14">
+        <BasicForm @register="register" />
+      </a-col>
+      <a-col :span="10">
+        <div class="change-avatar">
+          <div class="mb-2">头像</div>
+          <CropperAvatar
+            :uploadApi="uploadApi"
+            :value="avatar"
+            btnText="更换头像"
+            :btnProps="{ preIcon: 'ant-design:cloud-upload-outlined' }"
+            @change="updateAvatar"
+            width="150"
+          />
+        </div>
+      </a-col>
+    </a-row>
+    <Button type="primary" @click="handleSubmit"> 更新基本信息 </Button>
+  </CollapseContainer>
+</template>
+<script lang="ts">
+  import { Button, Row, Col } from 'ant-design-vue';
+  import { computed, defineComponent, onMounted } from 'vue';
+  import { BasicForm, useForm } from '/@/components/Form/index';
+  import { CollapseContainer } from '/@/components/Container';
+  import { CropperAvatar } from '/@/components/Cropper';
+
+  import { useMessage } from '/@/hooks/web/useMessage';
+
+  import headerImg from '/@/assets/images/header.jpg';
+  // import { accountInfoApi } from '/@/api/demo/account';
+  import { baseSetschemas } from './data';
+  import { useUserStore } from '/@/store/modules/user';
+  import { uploadApi } from '/@/api/sys/upload';
+
+  export default defineComponent({
+    components: {
+      BasicForm,
+      CollapseContainer,
+      Button,
+      ARow: Row,
+      ACol: Col,
+      CropperAvatar,
+    },
+    setup() {
+      const { createMessage } = useMessage();
+      const userStore = useUserStore();
+
+      const [register,] = useForm({
+        labelWidth: 120,
+        schemas: baseSetschemas,
+        showActionButtonGroup: false,
+      });
+
+      onMounted(async () => {
+        // const data = await accountInfoApi();
+        // setFieldsValue(data);
+      });
+
+      const avatar = computed(() => {
+        const { avatar } = userStore.getUserInfo;
+        return avatar || headerImg;
+      });
+
+      function updateAvatar(src: string) {
+        const userinfo = userStore.getUserInfo;
+        userinfo.avatar = src;
+        userStore.setUserInfo(userinfo);
+      }
+
+      return {
+        avatar,
+        register,
+        uploadApi: uploadApi as any,
+        updateAvatar,
+        handleSubmit: () => {
+          createMessage.success('更新成功!');
+        },
+      };
+    },
+  });
+</script>
+
+<style lang="less" scoped>
+  .change-avatar {
+    img {
+      display: block;
+      margin-bottom: 15px;
+      border-radius: 50%;
+    }
+  }
+</style>

+ 53 - 0
src/views/account/details/MsgNotify.vue

@@ -0,0 +1,53 @@
+<template>
+  <CollapseContainer title="新消息通知" :canExpan="false">
+    <List>
+      <template v-for="item in list" :key="item.key">
+        <ListItem>
+          <ListItemMeta>
+            <template #title>
+              {{ item.title }}
+              <Switch
+                class="extra"
+                checked-children="开"
+                un-checked-children="关"
+                default-checked
+              />
+            </template>
+            <template #description>
+              <div>{{ item.description }}</div>
+            </template>
+          </ListItemMeta>
+        </ListItem>
+      </template>
+    </List>
+  </CollapseContainer>
+</template>
+<script lang="ts">
+  import { List, Switch } from 'ant-design-vue';
+  import { defineComponent } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+
+  import { msgNotifyList } from './data';
+
+  export default defineComponent({
+    components: {
+      CollapseContainer,
+      List,
+      ListItem: List.Item,
+      ListItemMeta: List.Item.Meta,
+      Switch,
+    },
+    setup() {
+      return {
+        list: msgNotifyList,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .extra {
+    float: right;
+    margin-top: 10px;
+    margin-right: 30px;
+  }
+</style>

+ 279 - 0
src/views/account/details/OrderList.vue

@@ -0,0 +1,279 @@
+<template>
+  <a-tabs v-model:activeKey="searchInfo.activeKey">
+    <a-tab-pane key="1" tab="权益订单">
+      <BasicTable @register="registerTimeTable">
+        <template #action="{ record }">
+          <TableAction
+            :actions="[
+              {
+                label: '编辑',
+                ifShow: getCheckPerm('account-equityEdit'),
+                onClick: handleEdit.bind(null, record),
+              },
+              {
+                label: '删除',
+                ifShow: getCheckPerm('account-equityDelete'),
+                popConfirm: {
+                  title: '是否确认删除',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
+      </BasicTable>
+    </a-tab-pane>
+    <a-tab-pane key="2" tab="下载订单">
+      <BasicTable @register="registerDown"></BasicTable>
+    </a-tab-pane>
+    <a-tab-pane key="3" tab="相机订单">
+      <BasicTable @register="registerCamera" @expand="handleExpanded">
+        <template #expandedRowRender="{ record }">
+          <div>
+            <a-descriptions title="商品信息" :column="2">
+              <!-- <a-descriptions-item label="商品名称">{{record.shipName}} </a-descriptions-item>
+            <a-descriptions-item label="角色码"> 1234567 </a-descriptions-item> -->
+              <a-descriptions-item label="套餐"> {{ record.goodsName }}</a-descriptions-item>
+              <a-descriptions-item label="收件人"> {{ record.shipName }} </a-descriptions-item>
+              <a-descriptions-item label="数量"> {{ record.goodsCount }} </a-descriptions-item>
+              <a-descriptions-item label="手机号码"> {{ record.shipMobile }} </a-descriptions-item>
+              <a-descriptions-item label="商品单价"> {{ record.goodsPrice }} </a-descriptions-item>
+              <a-descriptions-item label="地址">
+                {{ record.shipAreaPath }}{{ record.shipAddress }}
+              </a-descriptions-item>
+              <a-descriptions-item label="" :span="1">
+                <TableImg
+                  style="margin: 0"
+                  :size="120"
+                  :simpleShow="true"
+                  :imgList="[record.goodsPic]"
+                />
+              </a-descriptions-item>
+            </a-descriptions>
+          </div>
+        </template>
+      </BasicTable>
+    </a-tab-pane>
+  </a-tabs>
+</template>
+<script lang="ts">
+  import { defineComponent, reactive, computed } from 'vue';
+  import { BasicTable, useTable, FormProps, TableAction, TableImg } from '/@/components/Table';
+  import { PageWrapper } from '/@/components/Page';
+  import { Divider, Card, Empty, Descriptions, Steps, Tabs } from 'ant-design-vue';
+  import { DelAndUpload } from '/@/api/product';
+  import { IncrementList } from '/@/api/order';
+  import { DownList, CameraList } from '/@/api/order';
+  import { useModal } from '/@/components/Modal';
+  import { CameraItem } from '/@/api/order';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { cameraColumns, dowmColumns, equityColumns, orderSearchForm } from './data';
+  import { otherInfoStore } from '/@/store/modules/other';
+  import { usePermissionStore } from '/@/store/modules/permission';
+  export default defineComponent({
+    components: {
+      BasicTable,
+      TableImg,
+      TableAction,
+      PageWrapper,
+      [Divider.name]: Divider,
+      [Card.name]: Card,
+      Empty,
+      [Descriptions.name]: Descriptions,
+      [Descriptions.Item.name]: Descriptions.Item,
+      [Steps.name]: Steps,
+      [Steps.Step.name]: Steps.Step,
+      [Tabs.name]: Tabs,
+      [Tabs.TabPane.name]: Tabs.TabPane,
+    },
+    setup() {
+      const { t } = useI18n();
+      const permissionStore = usePermissionStore();
+      const { getCheckPerm } = permissionStore;
+      const otherInfo = otherInfoStore();
+      const OverviewInfo = computed(() => otherInfo.getOverviewInfo);
+      const { userName } = OverviewInfo.value;
+      const searchInfo = reactive<Recordable>({
+        activeKey: '1',
+        userName,
+      });
+      console.log('OverviewInfo', searchInfo, OverviewInfo, userName);
+      const [registerAddModal, { openModal: openAddModal }] = useModal();
+      const [registerEditModal, { openModal: openEditModal }] = useModal();
+      const { createMessage } = useMessage();
+
+      const searchForm: Partial<FormProps> = {
+        labelWidth: 100,
+        schemas: [
+          {
+            field: 'version',
+            label: '版本号',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 6,
+              xxl: 6,
+            },
+          },
+        ],
+      };
+
+      const [registerDown, { reload: Downreload }] = useTable({
+        api: DownList,
+        title: '下载列表',
+        columns: dowmColumns,
+        useSearchForm: true,
+        formConfig: orderSearchForm,
+        showTableSetting: true,
+        showIndexColumn: false,
+        rowKey: 'id',
+        searchInfo,
+        beforeFetch: (T) => {
+          if (T.ctivated) {
+            T.startTime = T.ctivated[0];
+            T.endTime = T.ctivated[1];
+          }
+          return T;
+        },
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        // actionColumn: {
+        //   width: 180,
+        //   title: '操作',
+        //   dataIndex: 'action',
+        //   slots: { customRender: 'action' },
+        // },
+        canResize: true,
+      });
+
+      const [registerCamera, { reload: Camerareload }] = useTable({
+        api: CameraList,
+        title: '相机列表',
+        columns: cameraColumns,
+        useSearchForm: true,
+        formConfig: orderSearchForm,
+        showIndexColumn: false,
+        showTableSetting: true,
+        canResize: true,
+        expandRowByClick: true,
+        rowKey: 'id',
+        searchInfo,
+        beforeFetch: (T) => {
+          if (T.ctivated) {
+            T.startTime = T.ctivated[0];
+            T.endTime = T.ctivated[1];
+          }
+          return T;
+        },
+        rowKey: 'id',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        canResize: true,
+      });
+      const [registerTimeTable, { reload }] = useTable({
+        api: IncrementList,
+        title: '权益列表',
+        columns: equityColumns,
+        useSearchForm: true,
+        formConfig: orderSearchForm,
+        showIndexColumn: false,
+        showTableSetting: true,
+        searchInfo,
+        beforeFetch: (T) => {
+          if (T.ctivated) {
+            T.startTime = T.ctivated[0];
+            T.endTime = T.ctivated[1];
+          }
+          return T;
+        },
+        rowKey: 'id',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        // searchInfo: searchInfo,
+        // actionColumn: {
+        //   width: 180,
+        //   title: '操作',
+        //   dataIndex: 'action',
+        //   slots: { customRender: 'action' },
+        // },
+        canResize: true,
+      });
+      function tabChange(val: string) {
+        console.log('tabChange', val);
+        reload();
+      }
+      async function handleDelete(record: Recordable) {
+        console.log('点击了删除', record);
+        await DelAndUpload({ id: record.id });
+        createMessage.success(t('common.optSuccess'));
+        reload();
+      }
+      function handleOpen(record: Recordable) {
+        console.log('点击了启用', record);
+      }
+
+      function handlerowClick(record: Recordable) {
+        CameraItem({ id: record.id }).then((res) => {
+          if (res.length) {
+            let item = res[0];
+            Reflect.set(record, 'goodsCount', item.goodsCount);
+            Reflect.set(record, 'goodsName', item.goodsName);
+            Reflect.set(record, 'goodsPic', item.goodsPic);
+            Reflect.set(record, 'goodsPrice', item.goodsPrice);
+          }
+        });
+      }
+      function handleExpanded(_, record: Recordable) {
+        handlerowClick(record);
+      }
+      function handleEdit(record: Recordable) {
+        console.log('record', record);
+        openEditModal(true, {
+          ...record,
+        });
+      }
+      return {
+        handleExpanded,
+        registerTimeTable,
+        registerCamera,
+        registerDown,
+        handleDelete,
+        handleOpen,
+        tabChange,
+        reload,
+        Downreload,
+        Camerareload,
+        registerAddModal,
+        registerEditModal,
+        openAddModal,
+        handleEdit,
+        getCheckPerm,
+        t,
+        searchInfo,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .desc-wrap-BasicTable {
+    background-color: #f0f2f5;
+    .vben-basic-table-form-container {
+      padding: 0;
+    }
+  }
+</style>

+ 748 - 0
src/views/account/details/data.ts

@@ -0,0 +1,748 @@
+import { FormSchema } from '/@/components/Form/index';
+import { BasicColumn, FormProps } from '/@/components/Table';
+import { Time } from '/@/components/Time';
+import { h } from 'vue';
+import { incrementUseTypeList } from '/@/api/account';
+import { useI18n } from '/@/hooks/web/useI18n';
+const { t } = useI18n();
+
+export interface ListItem {
+  key: string;
+  title: string;
+  description: string;
+  extra?: string;
+  avatar?: string;
+  color?: string;
+}
+
+// tab的list
+export const settingList = [
+  {
+    key: '1',
+    name: '用户概览',
+    component: 'Overview',
+  },
+  // {
+  //   key: '2',
+  //   name: '订单列表',
+  //   component: 'OrderList',
+  // },
+  // {
+  //   key: '3',
+  //   name: '产品数据',
+  //   component: 'Product',
+  // },
+];
+
+// 基础设置 form
+export const baseSetschemas: FormSchema[] = [
+  {
+    field: 'email',
+    component: 'Input',
+    label: '邮箱',
+    colProps: { span: 18 },
+  },
+  {
+    field: 'name',
+    component: 'Input',
+    label: '昵称',
+    colProps: { span: 18 },
+  },
+  {
+    field: 'introduction',
+    component: 'InputTextArea',
+    label: '个人简介',
+    colProps: { span: 18 },
+  },
+  {
+    field: 'phone',
+    component: 'Input',
+    label: '联系电话',
+    colProps: { span: 18 },
+  },
+  {
+    field: 'address',
+    component: 'Input',
+    label: '所在地区',
+    colProps: { span: 18 },
+  },
+];
+
+// 安全设置 list
+export const secureSettingList: ListItem[] = [
+  {
+    key: '1',
+    title: '账户密码',
+    description: '当前密码强度::强',
+    extra: '修改',
+  },
+  {
+    key: '2',
+    title: '密保手机',
+    description: '已绑定手机::138****8293',
+    extra: '修改',
+  },
+  {
+    key: '3',
+    title: '密保问题',
+    description: '未设置密保问题,密保问题可有效保护账户安全',
+    extra: '修改',
+  },
+  {
+    key: '4',
+    title: '备用邮箱',
+    description: '已绑定邮箱::ant***sign.com',
+    extra: '修改',
+  },
+  {
+    key: '5',
+    title: 'MFA 设备',
+    description: '未绑定 MFA 设备,绑定后,可以进行二次确认',
+    extra: '修改',
+  },
+];
+
+// 账号绑定 list
+export const accountBindList: ListItem[] = [
+  {
+    key: '1',
+    title: '绑定淘宝',
+    description: '当前未绑定淘宝账号',
+    extra: '绑定',
+    avatar: 'ri:taobao-fill',
+    color: '#ff4000',
+  },
+  {
+    key: '2',
+    title: '绑定支付宝',
+    description: '当前未绑定支付宝账号',
+    extra: '绑定',
+    avatar: 'fa-brands:alipay',
+    color: '#2eabff',
+  },
+  {
+    key: '3',
+    title: '绑定钉钉',
+    description: '当前未绑定钉钉账号',
+    extra: '绑定',
+    avatar: 'ri:dingding-fill',
+    color: '#2eabff',
+  },
+];
+
+// 新消息通知 list
+export const msgNotifyList: ListItem[] = [
+  {
+    key: '1',
+    title: '账户密码',
+    description: '其他用户的消息将以站内信的形式通知',
+  },
+  {
+    key: '2',
+    title: '系统消息',
+    description: '系统消息将以站内信的形式通知',
+  },
+  {
+    key: '3',
+    title: '待办任务',
+    description: '待办任务将以站内信的形式通知',
+  },
+];
+//权益订单
+export const equityColumns: 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: 100,
+  },
+  {
+    title: '合同所属公司',
+    dataIndex: 'companyName',
+    ellipsis: true,
+    width: 230,
+  },
+  {
+    title: '业务部门',
+    dataIndex: 'businessDept',
+    ellipsis: true,
+    width: 120,
+  },
+  {
+    title: '业务员',
+    dataIndex: 'businessName',
+    ellipsis: true,
+    width: 120,
+  },
+  {
+    title: '客户付款时间',
+    dataIndex: 'customerPayTime',
+    ellipsis: true,
+    width: 160,
+  },
+  {
+    title: '客户名称',
+    dataIndex: 'customerName',
+    width: 100,
+  },
+  {
+    title: '客户类别',
+    dataIndex: 'customerTypeStr',
+    width: 100,
+    customRender: ({ record }) => {
+      return record.customerTypeStr ? record.customerTypeStr : '直销';
+    },
+  },
+  {
+    title: '终端客户名称',
+    dataIndex: 'endCustomer',
+    width: 100,
+  },
+  {
+    title: '经销商名称',
+    dataIndex: 'agentName',
+    width: 100,
+  },
+  {
+    title: '使用类型',
+    dataIndex: 'useTypeStr',
+    width: 100,
+  },
+  {
+    title: '权益类型',
+    dataIndex: 'memberLevels',
+    width: 100,
+  },
+  {
+    title: '订单金额',
+    dataIndex: 'amount',
+    width: 80,
+  },
+  {
+    title: '币种',
+    dataIndex: 'currencySymbol',
+    width: 80,
+  },
+  {
+    title: '数量',
+    dataIndex: 'count',
+    width: 80,
+  },
+  {
+    title: '支付方式',
+    dataIndex: 'payType',
+    // slots: { customRender: 'orderType' },
+    width: 80,
+  },
+  {
+    title: '交易号',
+    dataIndex: 'number',
+    width: 180,
+  },
+  {
+    title: '付款状态',
+    dataIndex: 'payStatus',
+    // slots: { customRender: 'orderStatus' },
+    width: 80,
+  },
+  {
+    title: '充值方式',
+    dataIndex: 'payMethod',
+    width: 100,
+  },
+  {
+    title: '会员服务期限',
+    dataIndex: 'incrementTime',
+    width: 100,
+  },
+  {
+    title: 'SN码',
+    dataIndex: 'snCode',
+    width: 100,
+  },
+  {
+    title: '项目号',
+    dataIndex: 'projectNum',
+    width: 100,
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+    width: 100,
+  },
+];
+export const equitySearchForm: Partial<FormProps> = {
+  labelWidth: 100,
+  autoSubmitOnEnter: true,
+  autoAdvancedLine: 1,
+  actionColOptions: {
+    span: 24,
+  },
+  schemas: [
+    {
+      field: 'ctivated',
+      label: '下单时间',
+      component: 'RangePicker',
+      componentProps: {
+        maxLength: 100,
+        format: 'YYYY-MM-DD',
+        valueFormat: 'YYYY-MM-DD',
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    },
+    {
+      field: 'orderSn',
+      label: '订单号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    },
+    {
+      field: 'userName',
+      label: '用户账号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    },
+    {
+      field: 'tradeNum',
+      label: '交易号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        span: 8,
+      },
+    },
+    {
+      field: 'customerType',
+      component: 'Select',
+      label: '客户类别',
+      colProps: {
+        span: 8,
+      },
+      componentProps: {
+        options: [
+          {
+            label: '直销',
+            value: 0,
+            key: '0',
+          },
+          {
+            label: '经销',
+            value: 1,
+            key: '1',
+          },
+        ],
+      },
+    },
+    {
+      field: 'useType',
+      component: 'ApiSelect',
+      label: '使用类型',
+      componentProps: {
+        // filterOption: onFilterOption,
+        // showSearch: true,
+        api: incrementUseTypeList,
+        labelField: 'name',
+        valueField: 'id',
+        immediate: true,
+      },
+      colProps: {
+        span: 8,
+      },
+    },
+    {
+      field: 'payMethod',
+      component: 'Select',
+      label: '充值方式',
+      colProps: {
+        span: 8,
+      },
+      componentProps: {
+        options: [
+          {
+            label: '线上',
+            value: 0,
+            key: '0',
+          },
+          {
+            label: '线下',
+            value: 1,
+            key: '1',
+          },
+        ],
+      },
+    },
+    {
+      field: 'companyName',
+      component: 'Select',
+      label: '合同所属公司',
+      colProps: {
+        span: 8,
+      },
+      itemProps: {
+        autoLink: false,
+      },
+      componentProps: {
+        options: [
+          {
+            label: '珠海市四维时代网络科技有限公司',
+            value: '珠海市四维时代网络科技有限公司',
+            key: '珠海市四维时代网络科技有限公司',
+          },
+          {
+            label: '广东四维看看智能设备有限公司',
+            value: '广东四维看看智能设备有限公司',
+            key: '广东四维看看智能设备有限公司',
+          },
+          {
+            label: '四维看看(香港)有限公司',
+            value: '四维看看(香港)有限公司',
+            key: '四维看看(香港)有限公司',
+          },
+          {
+            label: '四维看看(北京)数据科技有限公司',
+            value: '四维看看(北京)数据科技有限公司',
+            key: '四维看看(北京)数据科技有限公司',
+          },
+        ],
+      },
+    },
+    {
+      field: 'businessDept',
+      component: 'Select',
+      label: '业务部门',
+      colProps: {
+        span: 8,
+      },
+      itemProps: {
+        autoLink: false,
+      },
+      componentProps: {
+        options: [
+          {
+            label: '数字营销事业部',
+            value: '数字营销事业部',
+            key: '数字营销事业部',
+          },
+          {
+            label: '政企事业部',
+            value: '政企事业部',
+            key: '政企事业部',
+          },
+          {
+            label: '海外事业部',
+            value: '海外事业部',
+            key: '海外事业部',
+          },
+          {
+            label: '市场部',
+            value: '市场部',
+            key: '市场部',
+          },
+          {
+            label: '总经办',
+            value: '总经办',
+            key: '总经办',
+          },
+        ],
+      },
+    },
+    {
+      field: 'amount',
+      component: 'Input',
+      label: '订单金额',
+      colProps: { span: 7 },
+      componentProps: {
+        type: 'number',
+      },
+    },
+  ],
+};
+export const orderSearchForm: Partial<FormProps> = {
+  labelWidth: 100,
+  autoSubmitOnEnter: true,
+  autoAdvancedLine: 1,
+  actionColOptions: {
+    span: 24,
+  },
+  schemas: [
+    {
+      field: 'orderSn',
+      label: '订单号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    },
+    // {
+    //   field: 'userName',
+    //   label: '用户账号',
+    //   component: 'Input',
+    //   componentProps: {
+    //     maxLength: 100,
+    //   },
+    //   colProps: {
+    //     xl: 7,
+    //     xxl: 7,
+    //   },
+    // },
+    {
+      field: 'tradeNum',
+      label: '交易号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    },
+    {
+      field: 'ctivated',
+      label: '下单时间',
+      component: 'RangePicker',
+      componentProps: {
+        maxLength: 100,
+        format: 'YYYY-MM-DD',
+        valueFormat: 'YYYY-MM-DD',
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    },
+  ],
+};
+//下载订单
+export const dowmColumns: 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: 120,
+  },
+  {
+    title: '合同所属公司',
+    dataIndex: 'companyName',
+    ellipsis: true,
+    width: 230,
+  },
+  {
+    title: '业务部门',
+    dataIndex: 'businessDept',
+    ellipsis: true,
+    width: 120,
+  },
+  {
+    title: '业务员',
+    dataIndex: 'businessName',
+    ellipsis: true,
+    width: 120,
+  },
+  {
+    title: '客户付款时间',
+    dataIndex: 'customerPayTime',
+    ellipsis: true,
+    width: 160,
+  },
+  {
+    title: 'SN码',
+    dataIndex: 'snCode',
+    width: 120,
+  },
+  {
+    title: '场景',
+    dataIndex: 'sceneNum',
+    width: 100,
+  },
+  {
+    title: '客户名称',
+    dataIndex: 'customerName',
+    width: 100,
+  },
+  {
+    title: '客户类别',
+    dataIndex: 'customerTypeStr',
+    width: 100,
+  },
+  {
+    title: '终端客户名称',
+    dataIndex: 'endCustomer',
+    width: 100,
+  },
+  {
+    title: '经销商名称',
+    dataIndex: 'agentName',
+    width: 100,
+  },
+  {
+    title: '使用类型',
+    dataIndex: 'useTypeStr',
+    width: 100,
+  },
+  {
+    title: '下载类型',
+    dataIndex: 'downTypeStr',
+    width: 100,
+    customRender: ({ record }) => {
+      return record.payMethod == '线下' ? '-' : record.downTypeStr;
+    },
+  },
+  {
+    title: '订单金额(元)',
+    dataIndex: 'amount',
+    width: 80,
+  },
+  {
+    title: '币种',
+    dataIndex: 'currencySymbol',
+    width: 80,
+  },
+  {
+    title: '数量',
+    dataIndex: 'count',
+    width: 100,
+  },
+  {
+    title: '支付方式',
+    dataIndex: 'payType',
+    // slots: { customRender: 'orderType' },
+    width: 80,
+  },
+  {
+    title: '交易号',
+    dataIndex: 'number',
+    width: 180,
+  },
+  {
+    title: '付款状态',
+    dataIndex: 'payStatus',
+    // slots: { customRender: 'orderStatus' },
+    width: 80,
+  },
+  {
+    title: '充值方式',
+    dataIndex: 'payMethod',
+    width: 180,
+  },
+  {
+    title: '项目号',
+    dataIndex: 'projectNum',
+    width: 100,
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+    width: 100,
+  },
+];
+//相机订单
+export const cameraColumns: BasicColumn[] = [
+  {
+    title: '下单时间',
+    dataIndex: 'orderTime',
+    width: 150,
+    customRender: ({ record }) => {
+      return (
+        record.orderTime &&
+        h(Time, {
+          value: record.orderTime,
+          mode: 'datetime',
+        })
+      );
+    },
+  },
+  {
+    title: '订单号',
+    dataIndex: 'orderSn',
+    ellipsis: false,
+    width: 180,
+  },
+  {
+    title: '用户账号',
+    dataIndex: 'userName',
+    ellipsis: false,
+    width: 120,
+  },
+  {
+    title: '订单金额(元)',
+    dataIndex: 'goodsAmount',
+    ellipsis: false,
+    width: 120,
+  },
+  {
+    title: '支付方式',
+    dataIndex: 'paymentTypeName',
+    width: 80,
+  },
+  {
+    title: '交易号',
+    dataIndex: 'tradeNum',
+    width: 220,
+  },
+  {
+    title: '订单状态',
+    dataIndex: 'paymentStatus',
+    // slots: { customRender: 'orderStatus' },
+    width: 80,
+  },
+];

+ 78 - 0
src/views/account/details/index.vue

@@ -0,0 +1,78 @@
+<template>
+  <ScrollContainer>
+    <div ref="wrapperRef" :class="prefixCls">
+      <div style="text-align: right;padding:20px;">
+        <a-button type="primary" @click="routerGo">返回</a-button>
+      </div>
+      <Tabs tab-position="left" :tabBarStyle="tabBarStyle">
+        <template v-for="item in settingList" :key="item.key">
+          <TabPane :tab="item.name">
+            <component :is="item.component" :userName="userName" />
+          </TabPane>
+        </template>
+      </Tabs>
+    </div>
+  </ScrollContainer>
+</template>
+
+<script lang="ts">
+  import { defineComponent, computed } from 'vue';
+  import { Tabs } from 'ant-design-vue';
+  import { ScrollContainer } from '/@/components/Container/index';
+  import { settingList } from './data';
+  import { useRouter } from 'vue-router';
+
+  import Overview from '../overview/index.vue';
+  // import OrderList from './OrderList.vue';
+  // import Product from '../product/index.vue';
+  // import Product from '/@/views/productOperation/cameraScene.vue';
+  import { otherInfoStore } from '/@/store/modules/other';
+
+  export default defineComponent({
+    components: {
+      ScrollContainer,
+      Tabs,
+      TabPane: Tabs.TabPane,
+      Overview,
+      // OrderList,
+      // Product,
+    },
+    setup() {
+      const router = useRouter();
+      const otherInfo = otherInfoStore();
+      const OverviewInfo = computed(() => otherInfo.getOverviewInfo);
+      const { userName } = OverviewInfo.value;
+      function routerGo(){
+          router.go(-1)
+      }
+      return {
+        routerGo,
+        prefixCls: 'account-setting Level2Tab',
+        settingList,
+        userName,
+        tabBarStyle: {
+          width: '220px',
+        },
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .account-setting {
+    margin: 12px;
+    background-color: @component-background;
+
+    .base-title {
+      padding-left: 0;
+    }
+
+    .ant-tabs-tab-active {
+      background-color: @item-active-bg;
+    }
+  }
+  .Level2Tab{
+    .ant-tabs .ant-tabs-left-content{
+      padding-left:0px;
+    }
+  }
+</style>

+ 133 - 0
src/views/account/lists.vue

@@ -0,0 +1,133 @@
+<template>
+  <BasicTable @register="registerTimeTable">
+    <template #action="{ record }">
+      <TableAction
+        :actions="[
+          {
+            label: '详情',
+            onClick: handleEdit.bind(null, record),
+          }
+        ]"
+      />
+    </template>
+  </BasicTable>
+</template>
+<script lang="ts">
+import { defineComponent, computed } from 'vue';
+import { BasicTable, useTable, FormProps, TableAction } from '/@/components/Table';
+import { PageWrapper } from '/@/components/Page';
+import { Divider, Card, Empty, Descriptions, Steps, Tabs } from 'ant-design-vue';
+import { ListApi } from '/@/api/account';
+import { userListSchema } from './data';
+import { useI18n } from '/@/hooks/web/useI18n';
+import { useRouter } from 'vue-router'
+import { otherInfoStore } from '/@/store/modules/other'
+import { usePermissionStore } from '/@/store/modules/permission';
+import { useUserStore } from '/@/store/modules/user';
+export default defineComponent({
+components: {
+BasicTable,
+TableAction,
+PageWrapper,
+[Divider.name]: Divider,
+[Card.name]: Card,
+Empty,
+[Descriptions.name]: Descriptions,
+[Descriptions.Item.name]: Descriptions.Item,
+[Steps.name]: Steps,
+[Steps.Step.name]: Steps.Step,
+[Tabs.name]: Tabs,
+[Tabs.TabPane.name]: Tabs.TabPane,
+},
+setup() {
+const { t } = useI18n();
+const { setOverviewInfo } = otherInfoStore();
+const router = useRouter()
+const userStore = useUserStore();
+const isDev = computed(() => userStore.getSystemEnv);
+const permissionStore = usePermissionStore();
+const { getCheckPerm } = permissionStore;
+const searchForm: Partial<FormProps> = {
+  labelWidth: 100,
+  schemas: [
+    {
+      field: 'userName',
+      label: '用户账号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 6,
+        xxl: 6,
+      },
+    },{
+      field: 'email',
+      label: '用户邮箱',
+      component: 'Input',
+      ifShow: !isDev.value,
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    }
+  ],
+};
+const [registerTimeTable, { reload }] = useTable({
+  api: ListApi,
+  title: '用户列表',
+  columns: userListSchema,
+  useSearchForm: true,
+  formConfig: searchForm,
+  showTableSetting: true,
+  showIndexColumn:false,
+  rowKey: 'id',
+  fetchSetting: {
+    pageField: 'pageNum',
+    sizeField: 'pageSize',
+    listField: 'list',
+    totalField: 'total',
+  },
+  actionColumn: {
+    width: 100,
+    title: '操作',
+    dataIndex: 'action',
+    slots: { customRender: 'action' },
+  },
+  canResize:true,
+});
+function tabChange(val: string) {
+  console.log('tabChange', val);
+  reload();
+}
+function handleOpen(record: Recordable) {
+  console.log('点击了启用', record);
+}
+function handleEdit(record: Recordable) {
+  console.log('record', record);
+  setOverviewInfo(record)
+  router.push({path:'details'})
+}
+return {
+  registerTimeTable,
+  handleOpen,
+  tabChange,
+  reload,
+  handleEdit,
+  getCheckPerm,
+  t,
+};
+},
+});
+</script>
+<style lang="less" scoped>
+.desc-wrap-BasicTable {
+background-color: #f0f2f5;
+.vben-basic-table-form-container {
+padding: 0;
+}
+}
+</style>

+ 205 - 0
src/views/account/overview/AddDownModal.vue

@@ -0,0 +1,205 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    :title="fileFlow.title"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleConfirm"
+  >
+    <div class="pt-2px pr-3px zdysrk">
+      <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, h } 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 { currencyList, dincrementList, AddUserIncrementApi, AddDownNumApi } from '/@/api/account';
+  import dayjs from 'dayjs';
+  import { remarkschemas, Addschemas } from "./data";
+  import { otherInfoStore } from '/@/store/modules/other';
+  import { useUserStore } from '/@/store/modules/user';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const userStore = useUserStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      // const overviewInfo = getOverviewInfo() || {}
+      const fileFlow = reactive({
+        file: null,
+        id: '',
+        type: 'down', //down-下载,equity-权益
+        title: '新增下载',
+      });
+      const { createMessage, createConfirm } = useMessage();
+      const schemas: FormSchema[] = [
+        ...Addschemas,
+        // {
+        //   field: 'id',
+        //   component: 'Input',
+        //   show: false,
+        //   label: 'id',
+        // },
+        {
+          field: 'count',
+          component: 'InputNumber',
+          label: '新增次数',
+          required: true,
+          componentProps: {
+            min: 1,
+          },
+          colProps: {
+            span: 22,
+          },
+        },
+        {
+          field: 'amount',
+          component: 'InputNumber',
+          label: '订单金额',
+          required: true,
+          colProps: {
+            span: 16,
+          },
+          componentProps: {
+            precision: 2,
+            min: 0,
+            step: 1
+          },
+        },
+        {
+          field: 'currencySymbol',
+          component: 'ApiSelect',
+          required: true,
+          label: '币种',
+          defaultValue: userStore.isEnv ? '' : 'CNY',
+          componentProps: {
+            // filterOption: onFilterOption,
+            // showSearch: true,
+            api: currencyList,
+            labelField: 'name',
+            valueField: 'symbol',
+            immediate: true,
+          },
+          colProps: {
+            span: 20,
+          },
+        },
+        ...remarkschemas,
+      ];
+
+      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);
+        updateSchema([
+          {
+            field: 'useType',
+            componentProps: {
+              onChange: useTypeChange,
+            },
+          },
+          {
+            field: 'projectNum',
+            ifShow: false,
+          },
+        ]);
+        useTypeChange(0)
+      });
+      async function onDataReceive(data) {
+        const res = await dincrementList();
+        console.log('onDataReceive', data, res);
+        resetFields();
+        fileFlow.type = data.type;
+        fileFlow.id = data.id;
+        // fileFlow.title = data.type == '1' ? '新增下载(四维深时)' : '新增下载(四维看看)';
+        // setFieldsValue(data);
+      }
+      const useTypeChange = (value) => {
+        updateSchema([
+          { field: 'projectNum', ifShow: value == '4' },
+          { field: 'companyName', ifShow: value != '3' },
+          { field: 'businessDept', ifShow: value != '3' },
+          { field: 'businessName', ifShow: value != '3' },
+          { field: 'customerPayTime', ifShow: value != '3' },
+          { field: 'customerName', ifShow: value != '3' },
+          { field: 'customerType', ifShow: value != '3' },
+          { field: 'endCustomer', ifShow: value != '3' },
+        ]);
+      };
+      async function handleConfirm() {
+        await validate();
+        createConfirm({
+          iconType: 'warning',
+          title: () => h('span', '温馨提示'),
+          content: () => h('span', `确定要新增下载次数吗?`),
+          onOk: async () => {
+            handleSubmit();
+          },
+        });
+      }
+      const handleSubmit = async () => {
+        const submitUrl = AddDownNumApi;
+        try {
+          const params = await validate();
+          console.log('validate', params);
+          const res = await submitUrl({ userId: fileFlow.id, ...params }); //downType:fileFlow.type,
+          overviewInfo.value.surDownNum = overviewInfo.value.surDownNum + params.count;
+          console.log('res', res);
+          otherInfo.updateOverviewInfo();
+          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,
+        handleConfirm,
+        t,
+      };
+    },
+  });
+</script>
+
+<style lang="less">
+  .zdysrk {
+    .ant-calendar-picker {
+      min-width: 285px;
+    }
+  }
+</style>

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

@@ -0,0 +1,412 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    :title="title"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    minHeight="900px"
+    @ok="handleConfirm"
+  >
+    <div class="pt-2px pr-3px zdysrk">
+      <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, h, ref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { remarkschemas, Addschemas } from './data';
+  import { InvoiceRegister } from '/@/api/order';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { uploadApi } from '/@/api/product/index';
+  import { ResultEnum } from '/@/enums/httpEnum';
+  import {
+    DetailsApi,
+    dincrementList,
+    AddUserIncrementApi,
+    getAddUserIncrementTime,
+    currencyList,
+  } from '/@/api/account';
+  import dayjs from 'dayjs';
+  import { otherInfoStore } from '/@/store/modules/other';
+  import { useUserStore } from '/@/store/modules/user';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const userStore = useUserStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      // const overviewInfo = getOverviewInfo() || {}
+      const title = ref('新增权益');
+      const fileFlow = reactive({
+        file: null,
+        id: '',
+        type: 'down', //down-下载,equity-权益
+      });
+      const { createMessage, createConfirm } = useMessage();
+      const schemas: FormSchema[] = [
+        {
+          field: 'id',
+          component: 'Input',
+          show: false,
+          label: 'id',
+        },
+        {
+          field: 'userId',
+          component: 'Input',
+          show: false,
+          label: 'userId',
+        },
+        {
+          field: 'incrementTypeId',
+          component: 'ApiSelect',
+          label: '权益类型',
+          required: true,
+          itemProps: {
+            autoLink: false,
+          },
+          componentProps: {
+            api: async function () {
+              const res = await dincrementList();
+              return res.map((ele) => {
+                return { name: ele.name, value: ele.id };
+              });
+            },
+            // numberToString: true,
+            labelField: 'name',
+            valueField: 'value',
+            immediate: true,
+            params: {
+              agentName: '',
+            },
+            onChange: (value) => {
+              console.log('onChange', value);
+              let { monthQy = 1, count = 1 } = getFieldsValue();
+              let unitStr = value == '3' ? '个月' : '年';
+              let incrementEndTime = dayjs()
+                .add(1, value == '3' ? 'month' : 'year')
+                .format('YYYY-MM-DD');
+              updateSchema([
+                {
+                  field: 'monthQy',
+                  ifShow: true,
+                  componentProps: { options: showOptions(value == '3' ? 12 : 5) },
+                },
+                { field: 'count', suffix: count * monthQy + unitStr },
+                {
+                  field: 'incrementEndTime',
+                  componentProps: {
+                    // disabledDate: (current) => {
+                    //   return current && current < dayjs().subtract(1, 'day').add(1, value == '3' ? 'month' : 'year');
+                    // },
+                  },
+                },
+              ]);
+              setFieldsValue({
+                monthQy: 1,
+                incrementEndTime: incrementEndTime,
+              });
+            },
+          },
+          // componentProps: {
+          //   options: [
+          //     {
+          //       label: '专业会员',
+          //       value: 'PR',
+          //       key: '0',
+          //     },
+          //     {
+          //       label: '高级会员',
+          //       value: 'SE',
+          //       key: '1',
+          //     },
+          //   ],
+          //   onChange: (incrementTypeId) => {
+          //     updateSchema([{field: 'monthQy',ifShow:incrementTypeId=='SE',},
+          //                   {field: 'incrementEndTime',componentProps: { disabled:incrementTypeId=='SE',}}])
+          //     setFieldsValue({
+          //       monthQy:1,
+          //       incrementEndTime: dayjs().add(1,incrementTypeId=='SE'?'month':'year').format('YYYY-MM-DD'),
+          //     });
+          //   },
+          // },
+          colProps: {
+            span: 20,
+          },
+        },
+        {
+          field: 'monthQy',
+          component: 'Select',
+          label: '会员期限',
+          ifShow: false,
+          required: true,
+          defaultValue: 1,
+          componentProps: {
+            options: showOptions(5),
+            onChange: (data = 1) => {
+              let { incrementTypeId, count = 1 } = getFieldsValue();
+              let unit = incrementTypeId == '3' ? 'month' : 'year';
+              let unitStr = incrementTypeId == '3' ? '个月' : '年';
+              updateSchema({ field: 'count', suffix: count * data + unitStr });
+              setFieldsValue({
+                incrementEndTime: dayjs().add(data, unit).format('YYYY-MM-DD'),
+              });
+            },
+          },
+          colProps: {
+            span: 16,
+          },
+        },
+        {
+          field: 'count',
+          component: 'InputNumber',
+          label: '新增权益数',
+          required: true,
+          defaultValue: 1,
+          componentProps: {
+            min: 1,
+            onChange: (data = 1) => {
+              let { incrementTypeId, monthQy = 1 } = getFieldsValue();
+              let unit = incrementTypeId == '3' ? '个月' : '年';
+              updateSchema({ field: 'count', suffix: monthQy * data + unit });
+            },
+          },
+          colProps: {
+            span: 18,
+          },
+        },
+        {
+          field: 'incrementEndTime',
+          component: 'DatePicker',
+          label: '到期日期',
+          required: true,
+          defaultValue: dayjs().add(1, 'month').format('YYYY-MM-DD'),
+          colProps: {
+            span: 16,
+          },
+          componentProps: {
+            // disabled: true,
+            valueFormat: 'YYYY-MM-DD',
+            format: 'YYYY-MM-DD',
+            disabledDate: (current) => {
+              return current && current < dayjs().endOf('day');
+            },
+          },
+        },
+        {
+          field: 'amount',
+          component: 'InputNumber',
+          label: '订单金额',
+          required: true,
+          colProps: {
+            span: 16,
+          },
+          componentProps: {
+            precision: 2,
+            min: 0,
+            step: 1,
+          },
+        },
+        {
+          field: 'currencySymbol',
+          component: 'ApiSelect',
+          required: true,
+          defaultValue: userStore.isEnv ? '' : 'CNY',
+          label: '币种',
+          componentProps: {
+            // filterOption: onFilterOption,
+            // showSearch: true,
+            api: currencyList,
+            labelField: 'name',
+            valueField: 'symbol',
+            immediate: true,
+          },
+          colProps: {
+            span: 20,
+          },
+        },
+      ];
+
+      const [
+        registerForm,
+        { validate, getFieldsValue, resetFields, setFieldsValue, updateSchema, validateFields, scrollToField },
+      ] = useForm({
+        labelWidth: 120,
+        schemas: [...Addschemas, ...schemas, ...remarkschemas],
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+        updateSchema([
+          {
+            field: 'useType',
+            componentProps: {
+              onChange: useTypeChange,
+            },
+          },
+          {
+            field: 'incrementTypeId',
+            componentProps: {
+              disabled: data.id ? true : false,
+            },
+          },
+          {
+            field: 'projectNum',
+            ifShow: data.useType == '4',
+          },
+          {
+            field: 'count',
+            ifShow: !data.id,
+          },
+          {
+            field: 'incrementEndTime',
+            componentProps: {
+              disabled: data.id,
+              valueFormat: 'YYYY-MM-DD',
+              format: 'YYYY-MM-DD',
+              disabledDate: (current) => {
+                return current && current < dayjs(data.incrementEndTime).subtract(1, 'day');
+              },
+            },
+          },
+        ]);
+        useTypeChange(data.useType || 0);
+      });
+      async function onDataReceive(data) {
+        let incrementEndTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
+        if (data.incrementTypeId) {
+          const res = await getAddUserIncrementTime({
+            id: data.id,
+            userId: data.userId,
+            incrementTypeId: data.incrementTypeId,
+          });
+          incrementEndTime = dayjs(res.deadLine).format('YYYY-MM-DD HH:mm:ss');
+        }
+        title.value = data.id ? '续费权益' : '新增权益';
+        resetFields();
+        fileFlow.type = data.type;
+        fileFlow.id = data.id;
+        if(data.id){
+          delete data.customerPayTime
+        }
+        setFieldsValue({
+          ...data,
+          incrementEndTime,
+          // incrementEndTime: dayjs(incrementEndTime).add(1, data.incrementTypeId == '3' ? 'month' : 'year').format('YYYY-MM-DD'),
+        });
+      }
+      function showOptions(type = 5) {
+        let uint = type == 5 ? '年' : '个月';
+        let arr = [];
+        for (let index = 0; index < type; index++) {
+          arr.push({
+            label: index + 1 + uint,
+            value: index + 1,
+            key: index + 1,
+          });
+        }
+        return arr || [];
+      }
+      async function handleConfirm() {
+        try {
+          await validate();
+          createConfirm({
+            iconType: 'warning',
+            title: () => h('span', '温馨提示'),
+            content: () => h('span', `确定要${title.value}吗?`),
+            onOk: async () => {
+              handleSubmit();
+            },
+          });
+        } catch (error) {
+          console.log('validate', error);
+          let errorFields = error?.errorFields[0];
+          createMessage.error(errorFields?.errors[0]);
+          // scrollToField(errorFields.name[0])
+        }
+        // let text = record.id ? `您确定给权益ID${record.id}续期${record.validTimeType == 1?'1月':'1年'}!`:`确定要${title.value}吗?`
+        // createConfirm({
+        //   iconType: 'warning',
+        //   title: () => h('span', '续费提示'),
+        //   content: () => h('span', `您确定给权益ID${record.id}续期${record.validTimeType == 1?'1月':'1年'}!`),
+        //   onOk: async () => {
+        //     await await IncrementDelayApi({id:record.id,year:1})
+        //     createMessage.success(t('common.optSuccess'));
+        //     otherInfo.updateOverviewInfo()
+        //     reload()
+        //   },
+        // });
+      }
+      const useTypeChange = (value) => {
+        updateSchema([
+          { field: 'projectNum', ifShow: value == '4' },
+          { field: 'companyName', ifShow: value != '3' },
+          { field: 'businessDept', ifShow: value != '3' },
+          { field: 'businessName', ifShow: value != '3' },
+          { field: 'customerPayTime', ifShow: value != '3' },
+          { field: 'customerName', ifShow: value != '3' },
+          { field: 'customerType', ifShow: value != '3' },
+          { field: 'endCustomer', ifShow: value != '3' },
+        ]);
+      };
+      const handleSubmit = async () => {
+        const submitUrl = AddUserIncrementApi;
+        try {
+          const params = await validate();
+          console.log('validate', params);
+          const apiData = {
+            ...params,
+          };
+          const res = await submitUrl(apiData);
+          overviewInfo.value.incrementCount = overviewInfo.value.incrementCount + apiData.count;
+          otherInfo.updateOverviewInfo();
+          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,
+        handleConfirm,
+        t,
+        title,
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .zdysrk {
+    .ant-calendar-picker {
+      min-width: 285px;
+    }
+  }
+</style>

+ 144 - 0
src/views/account/overview/AddSnModal.vue

@@ -0,0 +1,144 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="授权相机"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    minHeight="900px"
+    @ok="handleSubmit"
+  >
+    <div class="pt-2px pr-3px zdysrk">
+      <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, h, ref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { remarkschemas, Addschemas } from './data';
+  import { InvoiceRegister } from '/@/api/order';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { uploadApi } from '/@/api/product/index';
+  import { ResultEnum } from '/@/enums/httpEnum';
+  import {
+    DetailsApi,
+    dincrementList,
+    AddUserIncrementApi,
+    incrementBindCamera,
+    getAddUserIncrementTime,
+    currencyList,
+  } from '/@/api/account';
+  import dayjs from 'dayjs';
+  import { otherInfoStore } from '/@/store/modules/other';
+  import { useUserStore } from '/@/store/modules/user';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const userStore = useUserStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      // const overviewInfo = getOverviewInfo() || {}
+      const title = ref('新增权益');
+      const fileFlow = reactive({
+        file: null,
+        id: '',
+        type: 'down', //down-下载,equity-权益
+      });
+      const { createMessage, createConfirm } = useMessage();
+      const schemas: FormSchema[] = [
+        {
+          field: 'id',
+          component: 'Input',
+          show: false,
+          label: 'id',
+        },
+        {
+          field: 'userId',
+          component: 'Input',
+          show: false,
+          label: 'userId',
+        },
+        {
+          field: 'snCode',
+          component: 'Input',
+          label: '相机SN码',
+          required: true,
+        },
+      ];
+
+      const [
+        registerForm,
+        { validate, getFieldsValue, resetFields, setFieldsValue, updateSchema, validateFields, scrollToField },
+      ] = 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) {
+        setFieldsValue({
+          ...data,
+          // incrementEndTime: dayjs(incrementEndTime).add(1, data.incrementTypeId == '3' ? 'month' : 'year').format('YYYY-MM-DD'),
+        });
+      }
+      const handleSubmit = async () => {
+        const submitUrl = incrementBindCamera;
+        try {
+          const params = await validate();
+          console.log('validate', params);
+          const apiData = {
+            ...params,
+            incrementId: params.id,
+          };
+          const res = await submitUrl(apiData);
+          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,
+        title,
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .zdysrk {
+    .ant-calendar-picker {
+      min-width: 285px;
+    }
+  }
+</style>

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

@@ -0,0 +1,178 @@
+<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: '解绑',
+                   color: 'error',
+                   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,TableAction } 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';
+  import { usePermissionStore } from '/@/store/modules/permission';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm, BasicTable,TableAction },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      const { createMessage, createConfirm } = useMessage();
+      const permissionStore = usePermissionStore();
+      const { getCheckPerm } = permissionStore;
+      console.log('overviewInfo',overviewInfo)
+      // const overviewInfo = getOverviewInfo() || {}
+      const fileFlow = reactive({
+        file:null,
+        id:'',
+        type:'down',//down-下载,equity-权益
+      })
+      const columns: BasicColumn[] = [
+        {
+          title: 'SN码',
+          dataIndex: 'snCode',
+          width: 120,
+        },
+        {
+          title: '设备类型',
+          dataIndex: 'type',
+          width: 150,
+          customRender: ({ record }) => {
+            return record.type ? t(`routes.product.type.${record.type}`) : '-';
+          },
+        },
+        {
+          title: '激活时间',
+          dataIndex: 'activatedTime',
+          width: 150,
+          customRender: ({ record }) => {
+            return record.activatedTime
+              ? h(Time, {
+                  value: record.activatedTime,
+                  mode: 'datetime',
+                })
+              : '-';
+          },
+        },
+        {
+          title: '出库时间',
+          dataIndex: 'outTime',
+          width: 150,
+          customRender: ({ record }) => {
+            return record.outTime
+              ? h(Time, {
+                  value: record.outTime,
+                  mode: 'datetime',
+                })
+              : '-';
+          },
+        },
+        {
+          title: t('common.operating'),
+          dataIndex: 'action',
+          ifShow:getCheckPerm('account-equityCameraUnbind'),
+          slots: { customRender: 'action' },
+          fixed: 'right',
+          width: 80,
+        },
+      ];
+      const [
+        registerSubtable,
+        {
+          reload,
+        },
+      ] = useTable({
+        title: `查看相机列表`,
+        rowKey: 'phone',
+        searchInfo:{
+          userId:overviewInfo.value?.id
+        },
+        api: GetCameraDetailApi,
+        columns: columns,
+        rowKey: 'id',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        showIndexColumn: false,
+        canResize: true,
+        bordered: true,
+      });
+
+      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', `您确定解绑该相机!`),
+          onOk: async () => {
+            await await UnbindCameraApi({cameraId:record.id})
+            otherInfo.updateOverviewInfo();
+            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>

+ 399 - 0
src/views/account/overview/data.tsx

@@ -0,0 +1,399 @@
+import { DescItem } from '/@/components/Description/index';
+import { BasicColumn } from '/@/components/Table/src/types/table';
+import { Button } from '/@/components/Button';
+import { FormSchema } from '/@/components/Form/index';
+import { incrementUseTypeList } from '/@/api/account';
+import { Badge } from 'ant-design-vue';
+import moment from 'moment';
+
+export const refundData = {
+  a1: '1000000000',
+  a2: '已取货',
+  a3: '1234123421',
+  a4: '3214321432',
+  a5: '3214321432',
+  b1: '付小小',
+  b2: '18100000000',
+  b3: '菜鸟仓储',
+  b4: '浙江省杭州市西湖区万塘路18号',
+  b5: '无',
+};
+
+export const personData = {
+  b1: '付小小',
+  b2: '18100000000',
+  b3: '菜鸟仓储',
+  b4: '浙江省杭州市西湖区万塘路18号',
+  b5: '无',
+};
+export const refundSchema: DescItem[] = [
+  {
+    field: 'nickName',
+    label: '昵称',
+  },
+  {
+    field: 'userName',
+    label: '账号',
+  },
+  {
+    field: 'email',
+    label: '邮箱',
+  },
+  {
+    field: 'createTime',
+    label: '注册时间',
+  },
+  // {
+  //   field: 'vip',
+  //   label: '四维看看会员',
+  // },
+];
+export const personSchema: DescItem[] = [
+  {
+    field: 'incrementCount',
+    label: '权益数量',
+  },
+  {
+    field: 'surDownNum',
+    label: '剩余下载次数',
+  },
+  {
+    field: 'cameraCount',
+    label: '相机数量',
+  },
+  {
+    field: 'sceneNum',
+    label: '场景数量',
+  },
+];
+
+export const refundTableSchema: BasicColumn[] = [
+  {
+    title: '商品编号',
+    width: 150,
+    dataIndex: 't1',
+    customRender: ({ record }) => {
+      return (
+        <Button type="link" size="small">
+          {() => record.t1}
+        </Button>
+      );
+    },
+  },
+  {
+    title: '商品名称',
+    width: 150,
+    dataIndex: 't2',
+  },
+  {
+    title: '商品条码',
+    width: 150,
+    dataIndex: 't3',
+  },
+  {
+    title: '单价	',
+    width: 150,
+    dataIndex: 't4',
+  },
+  {
+    title: '数量(件)	',
+    width: 150,
+    dataIndex: 't5',
+  },
+  {
+    title: '金额',
+    width: 150,
+    dataIndex: 't6',
+  },
+];
+export const refundTimeTableSchema: BasicColumn[] = [
+  {
+    title: '时间',
+    width: 150,
+    dataIndex: 't1',
+  },
+  {
+    title: '当前进度',
+    width: 150,
+    dataIndex: 't2',
+  },
+  {
+    title: '状态',
+    width: 150,
+    dataIndex: 't3',
+    customRender: ({ record }) => {
+      return <Badge status="success" text={record.t3} />;
+    },
+  },
+  {
+    title: '操作员ID	',
+    width: 150,
+    dataIndex: 't4',
+  },
+  {
+    title: '耗时',
+    width: 150,
+    dataIndex: 't5',
+  },
+];
+
+export const refundTableData: any[] = [
+  {
+    t1: 1234561,
+    t2: '矿泉水 550ml',
+    t3: '12421432143214321',
+    t4: '2.00',
+    t5: 1,
+    t6: 2.0,
+  },
+  {
+    t1: 1234562,
+    t2: '矿泉水 550ml',
+    t3: '12421432143214321',
+    t4: '2.00',
+    t5: 2,
+    t6: 2.0,
+  },
+  {
+    t1: 1234562,
+    t2: '矿泉水 550ml',
+    t3: '12421432143214321',
+    t4: '2.00',
+    t5: 2,
+    t6: 2.0,
+  },
+  {
+    t1: 1234562,
+    t2: '矿泉水 550ml',
+    t3: '12421432143214321',
+    t4: '2.00',
+    t5: 2,
+    t6: 2.0,
+  },
+];
+
+export const refundTimeTableData: any[] = [
+  {
+    t1: '2017-10-01 14:10',
+    t2: '联系客户',
+    t3: '进行中',
+    t4: '取货员 ID1234',
+    t5: '5mins',
+  },
+  {
+    t1: '2017-10-01 14:10',
+    t2: '取货员出发',
+    t3: '成功',
+    t4: '取货员 ID1234',
+    t5: '5mins',
+  },
+  {
+    t1: '2017-10-01 14:10',
+    t2: '取货员接单',
+    t3: '成功',
+    t4: '系统',
+    t5: '5mins',
+  },
+  {
+    t1: '2017-10-01 14:10',
+    t2: '申请审批通过',
+    t3: '成功',
+    t4: '用户',
+    t5: '1h',
+  },
+];
+// 基础设置 form
+export const remarkschemas: FormSchema[] = [
+  {
+    field: 'remark',
+    component: 'InputTextArea',
+    label: '备注',
+    componentProps: {
+      placeholder: '请输入钉钉审批单号',
+      rows: 4,
+    },
+    colProps: { span: 20 },
+  },
+];
+export const Addschemas: FormSchema[] = [
+  {
+    field: 'useType',
+    component: 'ApiSelect',
+    required: true,
+    label: '使用类型',
+    componentProps: {
+      // filterOption: onFilterOption,
+      // showSearch: true,
+      api: incrementUseTypeList,
+      labelField: 'name',
+      valueField: 'id',
+      immediate: true,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    colProps: {
+      span: 20,
+    },
+  },
+  {
+    field: 'companyName',
+    component: 'Select',
+    label: '合同所属公司',
+    rules: [{ required: true }],
+    colProps: {
+      span: 20,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    componentProps: {
+      options: [
+        {
+          label: '珠海市四维时代网络科技有限公司',
+          value: '珠海市四维时代网络科技有限公司',
+          key: '珠海市四维时代网络科技有限公司',
+        },
+        {
+          label: '广东四维看看智能设备有限公司',
+          value: '广东四维看看智能设备有限公司',
+          key: '广东四维看看智能设备有限公司',
+        },
+        {
+          label: '四维看看(香港)有限公司',
+          value: '四维看看(香港)有限公司',
+          key: '四维看看(香港)有限公司',
+        },
+        {
+          label: '四维看看(北京)数据科技有限公司',
+          value: '四维看看(北京)数据科技有限公司',
+          key: '四维看看(北京)数据科技有限公司',
+        },
+      ],
+    },
+  },
+  {
+    field: 'businessDept',
+    component: 'Select',
+    label: '业务部门',
+    rules: [{ required: true }],
+    colProps: {
+      span: 20,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    componentProps: {
+      options: [
+        {
+          label: '数字营销事业部',
+          value: '数字营销事业部',
+          key: '数字营销事业部',
+        },
+        {
+          label: '政企事业部',
+          value: '政企事业部',
+          key: '政企事业部',
+        },
+        {
+          label: '海外事业部',
+          value: '海外事业部',
+          key: '海外事业部',
+        },
+        {
+          label: '市场部',
+          value: '市场部',
+          key: '市场部',
+        },
+        {
+          label: '总经办',
+          value: '总经办',
+          key: '总经办',
+        },
+      ],
+    },
+  },
+  {
+    field: 'businessName',
+    component: 'Input',
+    label: '业务员',
+    required: true,
+    componentProps: {
+      maxlength: 100,
+    },
+    colProps: { span: 20 },
+  },
+  {
+    field: 'customerPayTime',
+    component: 'DatePicker',
+    label: '客户付款时间',
+    required: true,
+    colProps: {
+      span: 16,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    componentProps: {
+      // showTime: true, //{ defaultValue: moment('23:59:59', 'HH:mm:ss') }
+      valueFormat: 'YYYY-MM-DD',
+      // defaultValue: dayjs().add(7, 'day').format('YYYY-MM-DD') + ' 23:59:59',
+      format: 'YYYY-MM-DD',
+    },
+  },
+  {
+    field: 'customerName',
+    component: 'Input',
+    label: '客户名称',
+    required: true,
+    componentProps: {
+      maxlength: 100,
+    },
+    colProps: { span: 20 },
+  },
+  {
+    field: 'customerType',
+    component: 'Select',
+    label: '客户类别',
+    required: true,
+    colProps: { span: 20 },
+    itemProps: {
+      autoLink: false,
+    },
+    componentProps: {
+      options: [
+        {
+          label: '直销',
+          value: 0,
+          key: '0',
+        },
+        {
+          label: '经销',
+          value: 1,
+          key: '1',
+        },
+      ],
+    },
+  },
+  {
+    field: 'endCustomer',
+    component: 'Input',
+    label: '终端客户',
+    required: true,
+    componentProps: {
+      maxlength: 100,
+    },
+    colProps: { span: 20 },
+  },
+
+  {
+    field: 'projectNum',
+    component: 'Input',
+    label: '项目号',
+    required: true,
+    componentProps: {
+      maxlength: 100,
+    },
+    colProps: { span: 20 },
+  },
+];

+ 189 - 0
src/views/account/overview/index.vue

@@ -0,0 +1,189 @@
+<template>
+  <div class="info">
+    <div class="infodetail">
+      <div class="title">基本信息</div>
+      <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">
+              <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">
+            <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 />
+    <div class="infodetail">
+      <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" v-if="getCheckPerm('account-equityDetails')" size="small" @click="openInteresModal(true,{})"> 权益详情 </Button>
+              <Button type="primary" v-if="getCheckPerm('increment-add')" 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" v-if="getCheckPerm('download-add')" @click="handleaddDown('0')"> 新增下载 </Button>
+            </div>
+          </div>
+          <!-- <div class="list_item">
+            <div class="lable">四维深时</div>
+            <div class="value">
+              <div class="text">下载次数 {{overviewInfo.surSSDownNum}}次</div>              
+              <Button type="primary" size="small" v-if="getCheckPerm('download-add')" @click="handleaddDown('1')"> 新增下载 </Button>
+            </div>
+          </div> -->
+      </div>
+    </div>
+    <a-divider />
+    <AddModal @register="registerAddModal" />
+    <AddDownModal @register="registerAddDowmModal" />
+    <interesModal @register="registerInteres" />
+    <caremModal @register="registerCarem" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, computed } from 'vue';
+  import { Description } from '/@/components/Description/index';
+  import { BasicTable } from '/@/components/Table';
+  import { PageWrapper } from '/@/components/Page';
+  import { Icon } from '/@/components/Icon';
+  import { Divider, Button } from 'ant-design-vue';
+  import { otherInfoStore } from '/@/store/modules/other';
+  import AddModal from './AddModal.vue';
+  import AddDownModal from './AddDownModal.vue';
+  import caremModal from './caremModal.vue';
+  import interesModal from './interesModal.vue';
+  import { useModal } from '/@/components/Modal';
+  import { usePermissionStore } from '/@/store/modules/permission';
+
+  import {
+    refundSchema,
+    refundData,
+    personSchema,
+    personData,
+  } from './data';
+  export default defineComponent({
+    components: { Icon, Button,interesModal, Description, AddModal, AddDownModal, caremModal,  BasicTable, PageWrapper, [Divider.name]: Divider },
+    setup() {
+      const otherInfo = otherInfoStore();
+      const [registerAddModal, { openModal: openAddModal }] = useModal();
+      const [registerAddDowmModal, { openModal: openAddDowmModal }] = useModal();
+      const [registerInteres, { openModal: openInteresModal }] = useModal();
+      const [registerCarem, { openModal: openCaremModal }] = useModal();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      const permissionStore = usePermissionStore();
+      const { getCheckPerm } = permissionStore;
+      function handleaddDown(type: string) {
+        openAddDowmModal(true, {
+          ...overviewInfo.value,
+          type: type,
+        });
+      }
+      function handleAddEquity(type: string) {
+        console.log('type', type);
+        if(type == 'down'){
+          openAddDowmModal(true, {
+          ...overviewInfo.value,
+          type,
+        });
+        }else{
+          openAddModal(true, {
+          type,
+          userId:overviewInfo.value.id,
+        });
+        }
+      }
+      function handleSetEquity(){
+        openInteresModal(true, {
+          ...overviewInfo.value,
+        });
+      }
+      return {
+        registerAddModal,
+        registerInteres,
+        registerAddDowmModal,
+        registerCarem,
+        openAddModal,
+        openInteresModal,
+        openCaremModal,
+        refundSchema,
+        refundData,
+        personSchema,
+        personData,
+        overviewInfo,
+        handleAddEquity,
+        handleaddDown,
+        handleSetEquity,
+        getCheckPerm,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .info{
+    margin: 16px;
+    background-color: #fff;
+    padding: 12px 10px 6px;
+    .title{
+      min-height: 48px;
+      margin-bottom: -1px;
+      padding: 0 24px;
+      color: #000000d9;
+      font-weight: 500;
+      font-size: 16px;
+      background: transparent;
+      border-bottom: 1px solid #f0f0f0;
+      border-radius: 2px 2px 0 0;
+    }
+    .list{
+      padding: 0 24px;
+      .list_item{
+        display: flex;
+        padding-top: 12px;
+        .lable{
+          width: 100px;
+          text-align: right;
+          margin-right: 20px;
+        }
+        .value{
+          .ant-btn{
+            margin-right: 30px;
+          }
+          .text{
+            width: 130px;
+            display: inline-block;
+          }
+        }
+      }
+    }
+  }
+  .desc-wrap {
+    padding: 16px;
+    background-color: @component-background;
+  }
+</style>

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

@@ -0,0 +1,226 @@
+<template>
+  <div>
+    <AddModal @register="registerAddModal" @update="reload" />
+    <AddSnModal @register="registerAddSnModal" @update="reload" />
+    <BasicModal
+      v-bind="$attrs"
+      @register="register"
+      title="权益详情"
+      :width="900"
+      @visible-change="handleVisibleChange"
+      @ok="handleSubmit"
+    >
+      <div class="pt-3px pr-3px">
+        <div class="table_list">
+          <BasicTable @register="registerSubtable">
+            <template #action="{ record }">
+              <TableAction
+                :actions="[
+                  {
+                    label: '续费',
+                    ifShow: getCheckPerm('account-equityRenew'),
+                    onClick: handleDelete.bind(null, record, 'edit'),
+                  },
+                  {
+                    label: record.snCode ? '解除' : '授权',
+                    ifShow: getCheckPerm('account-authorize-lift'),
+                    onClick: handleSnCode.bind(null, record, 'edit'),
+                  },
+                ]"
+              />
+            </template>
+          </BasicTable>
+        </div>
+      </div>
+    </BasicModal>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, nextTick, onMounted, reactive, computed, h } from 'vue';
+  import { BasicTable, useTable, BasicColumn, TableAction } from '/@/components/Table';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm } from '/@/components/Form/index';
+  import { Time } from '/@/components/Time';
+  import AddModal from './AddModal.vue';
+  import AddSnModal from './AddSnModal.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { GetCameraDetailApi, UnbindCameraApi, incrementUnBindCamera, incrementBindCamera} from '/@/api/account';
+  import { otherInfoStore } from '/@/store/modules/other';
+  import { DetailsApi, IncrementDelayApi } from '/@/api/account';
+  import { usePermissionStore } from '/@/store/modules/permission';
+  import { useModal } from '/@/components/Modal';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm, AddSnModal, BasicTable, TableAction, AddModal },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const otherInfo = otherInfoStore();
+      const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      const { createMessage, createConfirm } = useMessage();
+      const [registerAddModal, { openModal: openAddModal }] = useModal();
+      const [registerAddSnModal, { openModal: openAddSnModal }] = useModal();
+      const permissionStore = usePermissionStore();
+      const { getCheckPerm } = permissionStore;
+      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: 100,
+          customRender: ({ record }) => {
+            return record.memberLevels ? record.memberLevels + ' ' + record.id : record.id;
+          },
+        },
+        {
+          title: '权益类型',
+          width: 100,
+          dataIndex: 'memberLevels',
+          customRender: ({ record }) => {
+            let obj = {
+              PR: '专业会员',
+              SE: '高级会员',
+            };
+            return obj[record.memberLevels] || '';
+          },
+        },
+        {
+          title: '使用类型',
+          width: 100,
+          dataIndex: 'useTypeStr',
+        },
+        {
+          title: '授权相机S/N码',
+          width: 160,
+          dataIndex: 'snCode',
+        },
+        {
+          title: '购买日期',
+          dataIndex: 'incrementStartTime',
+          width: 120,
+          customRender: ({ record }) => {
+            return record.incrementStartTime
+              ? h(Time, {
+                  value: record.incrementStartTime,
+                  mode: 'date',
+                })
+              : '-';
+          },
+        },
+        {
+          title: '到期日期',
+          dataIndex: 'incrementEndTime',
+          width: 120,
+          customRender: ({ record }) => {
+            return record.incrementEndTime
+              ? h(Time, {
+                  value: record.incrementEndTime,
+                  mode: 'date',
+                })
+              : '-';
+          },
+        },
+        // {
+        //   title: '项目号',
+        //   width: 100,
+        //   dataIndex: 'projectNum',
+        // },
+        // {
+        //   title: '备注',
+        //   width: 100,
+        //   dataIndex: 'remark',
+        // },
+        {
+          title: t('common.operating'),
+          dataIndex: '',
+          slots: { customRender: 'action' },
+          width: 100,
+        },
+      ];
+      const [registerSubtable, { reload }] = useTable({
+        // title: `查看相机详情`,
+        searchInfo: {
+          id: overviewInfo.value?.id,
+        },
+        api: DetailsApi,
+        rowKey: 'id',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        columns: columns,
+        showIndexColumn: false,
+        bordered: true,
+        canResize: true,
+        // pagination: false,
+      });
+
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        reload();
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        console.log('onDataReceive', data);
+        fileFlow.id = data.id;
+      }
+      function handleSnCode(record) {
+        if (record.snCode) {
+          createConfirm({
+            title: '删除',
+            content: '确定要解除该相机的权益吗?',
+            onOk: async () => {
+              incrementUnBindCamera({ snCode: record.snCode, incrementId: record.id }).then(() => {
+                createMessage.success('操作成功');
+                reload();
+              });
+            },
+          });
+        }else{
+          openAddSnModal(true, record);
+        }
+      }
+      async function handleDelete(record: Recordable) {
+        openAddModal(true, {
+          userId: overviewInfo.value && overviewInfo.value.id,
+          ...record,
+        });
+      }
+      const handleSubmit = async () => {
+        closeModal();
+        emit('update');
+      };
+      function handleVisibleChange(v) {
+        v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      return {
+        register,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        registerSubtable,
+        reload,
+        registerAddModal,
+        registerAddSnModal,
+        handleDelete,
+        handleSnCode,
+        getCheckPerm,
+        t,
+      };
+    },
+  });
+</script>

+ 120 - 0
src/views/account/user/index.vue

@@ -0,0 +1,120 @@
+<template>
+  <BasicTable @register="registerTimeTable">
+    <template #action="{ record }">
+      <TableAction
+        :actions="[
+          {
+            label: '详情',
+            onClick: handleEdit.bind(null, record),
+          }
+        ]"
+      />
+    </template>
+  </BasicTable>
+</template>
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { BasicTable, useTable, FormProps, TableAction } from '/@/components/Table';
+import { PageWrapper } from '/@/components/Page';
+import { Divider, Card, Empty, Descriptions, Steps, Tabs } from 'ant-design-vue';
+import { ListApi } from '/@/api/account';
+import { userListSchema } from '../data';
+import { useI18n } from '/@/hooks/web/useI18n';
+import { useRouter } from 'vue-router'
+import { otherInfoStore } from '/@/store/modules/other'
+export default defineComponent({
+components: {
+BasicTable,
+TableAction,
+PageWrapper,
+[Divider.name]: Divider,
+[Card.name]: Card,
+Empty,
+[Descriptions.name]: Descriptions,
+[Descriptions.Item.name]: Descriptions.Item,
+[Steps.name]: Steps,
+[Steps.Step.name]: Steps.Step,
+[Tabs.name]: Tabs,
+[Tabs.TabPane.name]: Tabs.TabPane,
+},
+setup() {
+const { t } = useI18n();
+const { setOverviewInfo } = otherInfoStore();
+const router = useRouter()
+const searchForm: Partial<FormProps> = {
+  labelWidth: 100,
+  schemas: [
+    {
+      field: 'userName',
+      label: '用户账号',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 6,
+        xxl: 6,
+      },
+    },{
+      field: 'email',
+      label: '用户邮箱',
+      component: 'Input',
+      componentProps: {
+        maxLength: 100,
+      },
+      colProps: {
+        xl: 8,
+        xxl: 8,
+      },
+    }
+  ],
+};
+const [registerTimeTable, { reload }] = useTable({
+  api: ListApi,
+  title: '用户列表',
+  columns: userListSchema,
+  useSearchForm: true,
+  formConfig: searchForm,
+  showTableSetting: true,
+  showIndexColumn:false,
+  rowKey: 'id',
+  fetchSetting: {
+    pageField: 'pageNum',
+    sizeField: 'pageSize',
+    listField: 'list',
+    totalField: 'total',
+  },
+  actionColumn: {
+    width: 100,
+    title: '操作',
+    dataIndex: 'action',
+    slots: { customRender: 'action' },
+  },
+  canResize: false,
+});
+function handleOpen(record: Recordable) {
+  console.log('点击了启用', record);
+}
+function handleEdit(record: Recordable) {
+  console.log('record', record);
+  setOverviewInfo(record)
+  router.push({path:'details'})
+}
+return {
+  registerTimeTable,
+  handleOpen,
+  reload,
+  handleEdit,
+  t,
+};
+},
+});
+</script>
+<style lang="less" scoped>
+.desc-wrap-BasicTable {
+background-color: #f0f2f5;
+.vben-basic-table-form-container {
+padding: 0;
+}
+}
+</style>

+ 317 - 0
src/views/empower/AddModal.vue

@@ -0,0 +1,317 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="本地版算法授权"
+    @visible-change="handleVisibleChange"
+    @cancel="resetFields"
+    @ok="handleConfirm"
+  >
+    <div class="pt-2px pr-3px zdysrk">
+      <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, h } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { remarkschemas } from './data';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { authorizeModelingaddOrUpdate } from '/@/api/authorizeModeling';
+  import { incrementUseTypeList } from '/@/api/account';
+  import { useUserStore } from '/@/store/modules/user';
+  import { getSubAgent } from '/@/api/retailer';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      // const otherInfo = otherInfoStore();
+      const userStore = useUserStore();
+      const agent = computed(() => userStore.getAgent);
+      // const overviewInfo = computed(() => otherInfo.getOverviewInfo);
+      // const overviewInfo = getOverviewInfo() || {}
+      const fileFlow = reactive({
+        file: null,
+        id: '',
+        type: 'down', //down-下载,equity-权益
+      });
+      const { createMessage, createConfirm } = useMessage();
+      const schemas: FormSchema[] = [
+        {
+          field: 'id',
+          component: 'Input',
+          show: false,
+          label: 'id',
+        },
+        {
+          field: 'useType',
+          component: 'ApiSelect',
+          required: true,
+          label: '使用类型',
+          componentProps: {
+            // filterOption: onFilterOption,
+            // showSearch: true,
+            api: incrementUseTypeList,
+            labelField: 'name',
+            valueField: 'id',
+            immediate: true,
+          },
+          itemProps: {
+            autoLink: false,
+          },
+          colProps: {
+            span: 20,
+          },
+        },
+        {
+          field: 'customerName',
+          component: 'Input',
+          label: '客户名称',
+          required: true,
+          colProps: { span: 20 },
+        },
+        {
+          field: 'customerType',
+          component: 'Select',
+          label: '客户类别',
+          required: true,
+          colProps: { span: 20 },
+          componentProps: {
+            options: [
+              {
+                label: '直销',
+                value: 0,
+                key: '0',
+              },
+              {
+                label: '经销',
+                value: 1,
+                key: '1',
+              },
+            ],
+            onChange: (value) => {
+              updateSchema({ field: 'agentId', ifShow: value == '1' });
+            },
+          },
+        },
+        {
+          field: 'endCustomer',
+          component: 'Input',
+          label: '终端客户',
+          required: true,
+          colProps: { span: 20 },
+        },
+        {
+          field: 'projectNum',
+          component: 'Input',
+          label: '项目号',
+          required: true,
+          colProps: { span: 20 },
+        },
+        {
+          field: 'authorizeKey',
+          component: 'Input',
+          required: true,
+          label: '授权码',
+          colProps: { span: 20 },
+        },
+        {
+          field: 'authorizeStartTime',
+          label: '生效日期',
+          component: 'DatePicker',
+          componentProps: {
+            maxLength: 100,
+            format: 'YYYY-MM-DD',
+            valueFormat: 'YYYY-MM-DD',
+            // showTime: true,
+          },
+          colProps: {
+            xl: 20,
+            xxl: 20,
+          },
+        },
+        {
+          field: 'authorizeEndTime',
+          label: '到期日期',
+          component: 'DatePicker',
+          componentProps: {
+            maxLength: 100,
+            format: 'YYYY-MM-DD',
+            valueFormat: 'YYYY-MM-DD',
+            // showTime: true,
+          },
+          colProps: {
+            xl: 20,
+            xxl: 20,
+          },
+        },
+        {
+          field: 'agentId',
+          component: 'ApiSelect',
+          label: '所属经销商',
+          componentProps: {
+            maxLength: 50,
+            api: getSubAgent,
+            // numberToString: true,
+            labelField: 'name',
+            valueField: 'id',
+            immediate: true,
+            params: {
+              type: 1,
+            },
+            style: 'max-width: 250px',
+          },
+          colProps: {
+            xl: 20,
+            xxl: 20,
+          },
+        },
+        // {
+        //   field: 'authorizeTime',
+        //   component: 'Select',
+        //   label: '授权期限',
+        //   required: true,
+        //   defaultValue: '10_1',
+        //   componentProps: {
+        //     options: [
+        //       {
+        //         label: '10天',
+        //         value: '10_1',
+        //         key: '10',
+        //       },
+        //       {
+        //         label: '1个月',
+        //         value: '1_2',
+        //         key: '30',
+        //       },
+        //       {
+        //         label: '3个月',
+        //         value: '3_2',
+        //         key: '90',
+        //       },
+        //       {
+        //         label: '1年',
+        //         value: '1_3',
+        //         key: '365',
+        //       },
+        //       {
+        //         label: '2年',
+        //         value: '2_3',
+        //         key: '730',
+        //       },
+        //       {
+        //         label: '3年',
+        //         value: '3_3',
+        //         key: '1095',
+        //       },
+        //       {
+        //         label: '5年',
+        //         value: '3_5',
+        //         key: '1825',
+        //       },
+        //     ],
+        //   },
+        //   colProps: {
+        //     span: 18,
+        //   },
+        // },
+      ];
+
+      const [registerForm, { validate, resetFields, setFieldsValue, updateSchema }] = useForm({
+        labelWidth: 120,
+        schemas: [...schemas, ...remarkschemas],
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      async function onDataReceive(data) {
+        resetFields();
+        fileFlow.id = data.id;
+        updateSchema([
+          {
+            field: 'useType',
+            componentProps: {
+              onChange: (value) => {
+                updateSchema({ field: 'projectNum', ifShow: value == '4' });
+              },
+            },
+          },
+          { field: 'agentId', ifShow: data.customerType == '1' },
+          {
+            field: 'projectNum',
+            ifShow: data.useType == '4',
+          },
+        ]);
+        data.authorizeTime = [data.authorizeStartTime, data.authorizeEndTime]
+        setFieldsValue(data);
+      }
+      async function handleConfirm() {
+        const { id } = await validate();
+        createConfirm({
+          iconType: 'warning',
+          title: () => h('span', '温馨提示'),
+          content: () => h('span', `确定要${id ? '编辑' : '新增'}授权吗?`),
+          onOk: async () => {
+            handleSubmit();
+          },
+        });
+      }
+      const handleSubmit = async () => {
+        try {
+          const params = await validate();
+          console.log(params);
+          // let authorizeTime = params.authorizeTime;
+          const apiData = {
+            agentId: agent.value.id,
+            ...params,
+            // authorizeStartTime: authorizeTime[0],
+            // authorizeEndTime: authorizeTime[1],
+          };
+          await authorizeModelingaddOrUpdate(apiData);
+          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,
+        handleConfirm,
+        t,
+      };
+    },
+  });
+</script>
+<style lang="less">
+  .zdysrk {
+    .ant-calendar-picker {
+      min-width: 285px;
+    }
+  }
+</style>

+ 188 - 0
src/views/empower/data.ts

@@ -0,0 +1,188 @@
+import { FormSchema } from '/@/components/Form/index';
+import { incrementUseTypeList } from '/@/api/account';
+
+// 基础设置 form
+export const remarkschemas: FormSchema[] = [
+  {
+    field: 'remark',
+    component: 'InputTextArea',
+    label: '备注',
+    componentProps: {
+      placeholder: '请输入钉钉审批单号',
+      rows: 4,
+    },
+    colProps: { span: 20 },
+  },
+];
+export const newAddschemas: FormSchema[] = [
+  {
+    field: 'useType',
+    component: 'ApiSelect',
+    required: true,
+    label: '使用类型',
+    componentProps: {
+      // filterOption: onFilterOption,
+      // showSearch: true,
+      api: incrementUseTypeList,
+      labelField: 'name',
+      valueField: 'id',
+      immediate: true,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    colProps: {
+      span: 20,
+    },
+  },
+  {
+    field: 'companyName',
+    component: 'Select',
+    label: '合同所属公司',
+    rules: [{ required: true }],
+    colProps: {
+      span: 20,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    componentProps: {
+      options: [
+        {
+          label: '珠海市四维时代网络科技有限公司',
+          value: '珠海市四维时代网络科技有限公司',
+          key: '珠海市四维时代网络科技有限公司',
+        },
+        {
+          label: '广东四维看看智能设备有限公司',
+          value: '广东四维看看智能设备有限公司',
+          key: '广东四维看看智能设备有限公司',
+        },
+        {
+          label: '四维看看(香港)有限公司',
+          value: '四维看看(香港)有限公司',
+          key: '四维看看(香港)有限公司',
+        },
+        {
+          label: '四维看看(北京)数据科技有限公司',
+          value: '四维看看(北京)数据科技有限公司',
+          key: '四维看看(北京)数据科技有限公司',
+        },
+      ],
+    },
+  },
+  {
+    field: 'businessDept',
+    component: 'Select',
+    label: '业务部门',
+    rules: [{ required: true }],
+    colProps: {
+      span: 20,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    componentProps: {
+      options: [
+        {
+          label: '数字营销事业部',
+          value: '数字营销事业部',
+          key: '数字营销事业部',
+        },
+        {
+          label: '政企事业部',
+          value: '政企事业部',
+          key: '政企事业部',
+        },
+        {
+          label: '海外事业部',
+          value: '海外事业部',
+          key: '海外事业部',
+        },
+        {
+          label: '市场部',
+          value: '市场部',
+          key: '市场部',
+        },
+        {
+          label: '总经办',
+          value: '总经办',
+          key: '总经办',
+        },
+      ],
+    },
+  },
+  {
+    field: 'businessName',
+    component: 'Input',
+    label: '业务员',
+    required: true,
+    colProps: { span: 20 },
+    componentProps: {
+      maxlength: 100,
+    },
+  },
+  {
+    field: 'customerPayTime',
+    component: 'DatePicker',
+    label: '客户付款时间',
+    required: true,
+    colProps: {
+      span: 16,
+    },
+    itemProps: {
+      autoLink: false,
+    },
+    componentProps: {
+      // showTime: true, //{ defaultValue: moment('23:59:59', 'HH:mm:ss') }
+      valueFormat: 'YYYY-MM-DD',
+      // defaultValue: dayjs().add(7, 'day').format('YYYY-MM-DD') + ' 23:59:59',
+      format: 'YYYY-MM-DD',
+    },
+  },
+];
+
+export const Addschemas: FormSchema[] = [
+  {
+    field: 'customerName',
+    component: 'Input',
+    label: '客户名称',
+    required: true,
+    colProps: { span: 20 },
+  },
+  {
+    field: 'customerType',
+    component: 'Select',
+    label: '客户类别',
+    required: true,
+    colProps: { span: 20 },
+    componentProps: {
+      options: [
+        {
+          label: '直销',
+          value: 0,
+          key: '0',
+        },
+        {
+          label: '经销',
+          value: 1,
+          key: '1',
+        },
+      ],
+    },
+  },
+  {
+    field: 'endCustomer',
+    component: 'Input',
+    label: '终端客户',
+    required: true,
+    colProps: { span: 20 },
+  },
+  {
+    field: 'projectNum',
+    component: 'Input',
+    label: '项目号',
+    required: true,
+    colProps: { span: 20 },
+  },
+];

+ 261 - 0
src/views/empower/index.vue

@@ -0,0 +1,261 @@
+<template>
+  <div>
+    <BasicTable @register="registerTable">
+      <template #toolbar>
+        <a-button type="primary" @click="handleEdit">授权</a-button>
+      </template>
+      <template #copy="{ record }">
+        <a @click="handleCopy(record.authorizeKey)">
+          {{ record.authorizeKey }}
+        </a>
+      </template>
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '编辑',
+              //ifShow: getCheckPerm('algorithm-updata'),
+              onClick: handleEdit.bind(null, record),
+            },
+            {
+              label: '删除',
+              color: 'error',
+              //ifShow: getCheckPerm('algorithm-delete'),
+              onClick: handleDelete.bind(null, record),
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <AddModal @register="register" @update="reload" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, h } from 'vue';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    BasicColumn,
+    TableImg,
+    FormProps,
+  } from '/@/components/Table';
+  import { authorizeModelingList, authorizeModelingdelete } from '/@/api/authorizeModeling';
+  import { useModal } from '/@/components/Modal';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { copyTextToClipboard } from '/@/hooks/web/useCopyToClipboard';
+  import { Time } from '/@/components/Time';
+  import AddModal from './AddModal.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  // import { usePermissionStore } from '/@/store/modules/permission';
+  import { incrementUseTypeList } from '/@/api/account';
+  export default defineComponent({
+    components: {
+      BasicTable,
+      AddModal,
+      TableAction,
+      Time,
+    },
+    setup() {
+      const { t } = useI18n();
+      const { createMessage, createConfirm } = useMessage();
+      // const permissionStore = usePermissionStore();
+      // const { getCheckPerm } = permissionStore;
+      const [register, { openModal }] = useModal();
+      const columns: BasicColumn[] = [
+        {
+          title: '客户名称',
+          dataIndex: 'customerName',
+          ellipsis: true,
+          width: 250,
+        },
+        {
+          title: '客户类别',
+          dataIndex: 'customerType',
+          ellipsis: true,
+          width: 80,
+          customRender: ({ record }) => {
+            return record.customerType == 1 ? '经销' : '直销';
+          },
+        },
+        {
+          title: '终端客户',
+          ellipsis: true,
+          dataIndex: 'endCustomer',
+          width: 120,
+        },
+        {
+          title: '使用类型',
+          ellipsis: true,
+          dataIndex: 'useTypeStr',
+          width: 120,
+        },
+        {
+          title: '项目号',
+          ellipsis: true,
+          dataIndex: 'projectNum',
+          width: 120,
+        },
+        {
+          title: '算法授权Key',
+          ellipsis: true,
+          slots: { customRender: 'copy' },
+          dataIndex: 'authorizeKey',
+          width: 120,
+        },
+        {
+          title: '授权期限',
+          ellipsis: true,
+          dataIndex: 'authorizeTime',
+          width: 220,
+          customRender: ({ record }) => {
+            return record.authorizeStartTime + '~' + record.authorizeEndTime
+          },
+        },
+        {
+          title: '授权说明',
+          ellipsis: true,
+          dataIndex: 'remark',
+          width: 120,
+        },
+        {
+          title: '创建人',
+          ellipsis: true,
+          dataIndex: 'sysUserName',
+          width: 120,
+        },
+        {
+          title: '创建时间',
+          ellipsis: true,
+          dataIndex: 'createTime',
+          width: 160,
+          customRender: ({ record }) => {
+            return (
+              record.createTime &&
+              h(Time, {
+                value: record.createTime,
+                mode: 'datetime',
+              })
+            );
+          },
+        },
+      ];
+      const searchForm: Partial<FormProps> = {
+        labelWidth: 100,
+        autoSubmitOnEnter: true,
+        schemas: [
+          {
+            field: 'customerName',
+            label: '客户名称',
+            component: 'Input',
+            colProps: {
+              xl: 8,
+              xxl: 8,
+            },
+          },
+          {
+            field: 'customerType',
+            label: '客户类别',
+            component: 'Select',
+            componentProps: {
+              options: [
+                {
+                  label: '直销',
+                  value: 0,
+                  key: '0',
+                },
+                {
+                  label: '经销',
+                  value: 1,
+                  key: '1',
+                },
+              ],
+            },
+            colProps: {
+              xl: 8,
+              xxl: 8,
+            },
+          },
+          {
+            field: 'useType',
+            label: '使用类型',
+            component: 'ApiSelect',
+            componentProps: {
+              api: incrementUseTypeList,
+              labelField: 'name',
+              valueField: 'id',
+              immediate: true,
+            },
+            colProps: {
+              xl: 8,
+              xxl: 8,
+            },
+          },
+          {
+            field: 'authorizeKey',
+            label: '算法授权Key',
+            component: 'Input',
+            colProps: {
+              xl: 8,
+              xxl: 8,
+            },
+          },
+        ],
+      };
+      const [registerTable, { reload }] = useTable({
+        api: authorizeModelingList,
+        title: '算法授权列表',
+        columns: columns,
+        useSearchForm: true,
+        formConfig: searchForm,
+        showTableSetting: true,
+        showIndexColumn: false,
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        actionColumn: {
+          width: 100,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
+        rowKey: 'id',
+        canResize: true,
+      });
+      async function handleDelete(record) {
+        createConfirm({
+          iconType: 'warning',
+          title: () => h('span', '温馨提示'),
+          content: () => h('span', '确定要删除授权吗?'),
+          onOk: async () => {
+            await authorizeModelingdelete({ id: record.id });
+            reload();
+            createMessage.success(t('common.optSuccess'));
+          },
+        });
+      }
+      function handleCopy(str: string) {
+        copyTextToClipboard(str);
+        createMessage.success('复制成功');
+      }
+      function handleEdit(record = {}) {
+        openModal(true, {
+          ...record,
+          authorizeTime: `${record.authorizeTime || '10'}_${record.authorizeTimeUnit || '1'}`,
+        });
+      }
+      return {
+        registerTable,
+        handleCopy,
+        handleDelete,
+        reload,
+        register,
+        // getCheckPerm,
+        handleEdit,
+      };
+    },
+  });
+</script>