tangning 1 місяць тому
батько
коміт
d7dd05aba0

+ 1 - 1
.env.development

@@ -6,7 +6,7 @@ VITE_PUBLIC_PATH = ./
 
 # Cross-domain proxy, you can configure multiple
 # Please note that no line breaks
-VITE_PROXY = [["/service","http://192.168.0.125:1804"], ["/fusion","http://192.168.0.125:1804"]]
+VITE_PROXY = [["/service","https://survey.4dkankan.com"], ["/fusion","https://survey.4dkankan.com"]]
 # VITE_PROXY=[["/api","https://vvbin.cn/test"]]
 
 # Delete console

+ 170 - 0
public/browser.html

@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html lang="zh-CN">
+<head>
+  <meta charset="UTF-8" />
+  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+  <title><%= title %></title>
+  <link rel="icon" href="/favicon.ico" />
+  <style>
+    /* 基础重置与布局 */
+    * {
+      margin: 0; 
+      padding: 0; 
+      box-sizing: border-box;
+    }
+    body {
+      font-family: "PingFang SC", "Microsoft YaHei", sans-serif;
+      background-color: #fff;
+      display: flex;
+      flex-direction: column;
+      justify-content: center;
+      align-items: center;
+      min-height: 100vh;
+      color: #999;
+    }
+    /* 容器与文本样式 */
+    .container {
+      text-align: center;
+    }
+    .tips {
+      margin: 8px 0;
+      line-height: 1.6;
+    }
+    /* 浏览器图标区域布局 */
+    .browser-icons {
+      display: flex;
+      justify-content: center;
+      gap: 40px;
+      margin-top: 20px;
+      flex-wrap: wrap; /* 适配小屏幕换行 */
+    }
+    .browser-item {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      cursor: pointer;
+      transition: transform 0.2s ease;
+    }
+    .browser-item:hover {
+      transform: scale(1.05);
+    }
+    .browser-item img {
+      width: 60px;
+      height: 60px;
+      margin-bottom: 8px;
+    }
+    .browser-item span {
+      font-size: 14px;
+    }
+    /* 国产系统专属提示(可选样式) */
+    .domestic-os-tip {
+      color: #ff6600;
+      font-weight: bold;
+      margin-top: 20px;
+    }
+    .icon-area {
+      display: flex;
+      justify-content: center;
+      gap: 40px;
+      margin-top: 20px;
+    }
+
+    /* 单个图标及文字的样式 */
+    .browser-icon {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      cursor: pointer;
+    }
+
+    .browser-icon img {
+      width: 60px;
+      height: 60px;
+      margin-bottom: 8px;
+    }
+
+    .browser-icon span {
+      font-size: 14px;
+    }
+
+    /* 顶部提示文字样式 */
+    .tips {
+      margin-bottom: 10px;
+    }
+  </style>
+</head>
+<body>
+  <div class="container">
+    <!-- 通用提示文案 -->
+    <p class="tips">无法打开页面,请升级或更换浏览器后重新打开</p>
+    <p class="tips">建议使用以下浏览器</p>
+    
+    <!-- 浏览器图标区 -->
+    <div class="browser-icons" id="noDomestic">
+      <div class="browser-item">
+        <!-- 可替换为 Firefox 官方图标地址或本地资源 -->
+        <span style="font-size: 60px; color: #FF7B00;">🦊</span> 
+        <span>Firefox</span>
+      </div>
+      <div class="browser-item">
+        <!-- Edge 图标 -->
+        <span style="font-size: 60px; color: #0078D7;">🌊</span> 
+        <span>Microsoft Edge</span>
+      </div>
+      <div class="browser-item">
+        <!-- Chrome 图标 -->
+        <span style="font-size: 60px; color: #000;">🍎</span> 
+        <span>Chrome</span>
+      </div>
+    </div>
+    <!-- 国产系统检测结果展示区 -->
+    <div class="icon-area" id="domestic">
+      <div class="browser-icon">
+        <!-- 这里用文字简单模拟图标,实际可替换为 Firefox 浏览器图标的路径 -->
+        <span style="font-size: 60px; color: #FF7B00;">🦊</span> 
+        <span>火狐</span>
+      </div>
+      <div class="browser-icon">
+        <!-- 同理,替换为 Edge 浏览器图标的路径 -->
+        <span style="font-size: 60px; color: #0078D7;">🌊</span> 
+        <span>奇安信可浏览器</span>
+      </div>
+      <div class="browser-icon">
+        <!-- 替换为 Safari 浏览器图标的路径 -->
+        <span style="font-size: 60px; color: #000;">🍎</span> 
+        <span>360安全浏览器</span>
+      </div>
+      <div class="browser-icon">
+        <!-- 替换为 Chrome 浏览器图标的路径 -->
+        <span style="font-size: 60px; color: #4285F4;">🔴</span> 
+        <span>Chromeium</span>
+      </div>
+    </div>
+  </div>
+
+  <script>
+    // 识别国产操作系统逻辑(示例覆盖常见标识,可根据需要补充)
+    function isDomesticOS() {
+      const userAgent = navigator.userAgent.toLowerCase();
+      const platform = navigator.platform.toLowerCase();
+      // 统信 UOS、银河麒麟、深度 Deepin、中标麒麟等标识
+      return /uos|kylin|deepin|neokylin/.test(userAgent) 
+          || /linux/.test(platform) && /国产|中国/.test(userAgent); 
+    }
+
+    // 执行检测
+    const isDomestic = isDomesticOS();
+    const domestic = document.getElementById('domestic');
+    const noDomestic = document.getElementById('noDomestic');
+    
+    if (isDomestic) {
+      domestic.style.display = 'flex'; 
+      noDomestic.style.display = 'none'; 
+    } else {
+      // 非国产系统可隐藏或自定义提示
+      domestic.style.display = 'none'; 
+      noDomestic.style.display = 'flex'; 
+    }
+  </script>
+</body>
+</html>

+ 78 - 0
src/views/planImg/DownLoadModal.vue

@@ -0,0 +1,78 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="系统正在为您打包数据"
+    :minHeight="0"
+    @visible-change="handleVisibleChange"
+    @cancel="hundleCancel"
+    @ok="handleSubmit"
+  >
+    <div class="pt-2px pr-3px">
+      <div class="warp">
+        <p>正在打包场景离线数据{{ downloadPercent }}</p>
+        <span>{{ modelRef.sceneName }}.zip</span>
+        <Progress :percent="downloadOption.percent" />
+        <p>* 打包完成后将关闭弹窗自动下载。</p>
+      </div>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, nextTick, onMounted, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { Progress } from 'ant-design-vue';
+  const { t } = useI18n();
+
+  export default defineComponent({
+    components: { BasicModal, Progress },
+    props: {
+      userData: { type: Object },
+      downloadOption: { type: Object },
+    },
+    emits: ['update', 'register', 'cancelDownload'],
+    setup(props, { emit }) {
+      const modelRef = ref({});
+
+      const { createMessage } = useMessage();
+
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        // data && onDataReceive(data);
+        modelRef.value = data;
+      });
+
+      const handleSubmit = async () => {
+        console.log(props.downloadOption);
+        if (props.downloadOption.url) {
+          window.open(props.downloadOption.url);
+        }
+      };
+      const hundleCancel = async () => {
+        emit('cancelDownload');
+      };
+
+      return {
+        register,
+        modelRef,
+        handleSubmit,
+        hundleCancel,
+        addListFunc,
+        t,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .pt-2px {
+  }
+  .warp {
+    display: flex;
+    align-items: flex-start;
+    justify-content: flex-start;
+    flex-flow: column;
+  }
+</style>

+ 154 - 0
src/views/planImg/addCaseModal.vue

@@ -0,0 +1,154 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="重命名"
+    @visible-change="handleVisibleChange"
+    @ok="handleSubmit"
+    :confirmLoading="loading"
+    :width="420"
+    :min-height="0"
+  >
+    <div class="pt-2px pr-3px">
+      <div class="mx-5 BasicForm flex">
+        <div class="input">
+          <a-input
+            style="width: 350px"
+            maxlength="100"
+            showCount
+            allowClear
+            v-model:value="fileFlow.title"
+            placeholder="请输入"
+          />
+        </div>
+        <!-- <a-button type="primary" @click="handleAdd"> 新增</a-button> -->
+      </div>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, nextTick, onMounted, reactive, h } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { sceneMove } from '/@/api/operate';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { getByKey, addOrUpdate, del } from '/@/api/media';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    BasicColumn,
+    TableImg,
+    FormProps,
+  } from '/@/components/Table';
+  import { caseaddOrUpdateApi, operateSceneList } from '/@/api/operate';
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicTable, TableAction },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update', 'register'],
+    setup(props, { emit }) {
+      const modelRef = ref({});
+      const loading = ref(false);
+      const fileFlow = reactive({
+        title: '',
+        caseTitle: '',
+        file: null,
+        dylist: [],
+        mslist: [],
+      });
+      const { createMessage, createConfirm } = useMessage();
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        fileFlow.caseTitle = '';
+        modelRef.value = data;
+        fileFlow.dylist = [];
+        fileFlow.mslist = [];
+        fileFlow.title = data.caseTitle;
+        fileFlow.caseTitle = '';
+      }
+      function handleAdd() {
+        console.log('handleAdd', fileFlow.dictName);
+        let params = {
+          dictName: fileFlow.dictName.trim(),
+        };
+        if (!fileFlow.dictName.trim()) {
+          return createMessage.warning('请输入名称');
+        }
+        addOrUpdate(params).then((res) => {
+          createMessage.success('添加成功');
+          fileFlow.dictName = '';
+        });
+      }
+      const handleSubmit = async () => {
+        if (!fileFlow.caseTitle?.trim()) {
+          return createMessage.warning('请输入案件名称');
+        }
+        try {
+          loading.value = true;
+          const apiData = {
+            caseTitle: fileFlow.caseTitle?.trim(),
+            sceneNumParam: [
+              {
+                type: 0,
+                numList: fileFlow.dylist,
+              },
+              {
+                type: 1,
+                numList: fileFlow.mslist,
+              },
+            ],
+          };
+          console.log('res', apiData);
+          const res = await caseaddOrUpdateApi(apiData);
+          console.log('res', res);
+          closeModal();
+          createMessage.success('新增案件成功。');
+          emit('update');
+          loading.value = false;
+        } catch (error) {
+          loading.value = false;
+          console.log('not passing', error);
+        }
+      };
+      function handleVisibleChange(v) {
+        // console.log(v);
+        // v && props.userData && nextTick(() => onDataReceive(props.userData));
+      }
+      async function handleDelete(record: Recordable) {
+        console.log('handleDelete', record);
+        createConfirm({
+          title: '删除',
+          content: '确定要删除吗?',
+          onOk: async () => {
+            del({ id: record.id }).then(() => {
+              createMessage.success({
+                content: '删除成功',
+              });
+              reload();
+            });
+          },
+        });
+      }
+      return {
+        register,
+        handleAdd,
+        model: modelRef,
+        fileFlow,
+        handleVisibleChange,
+        handleSubmit,
+        addListFunc,
+        handleDelete,
+        t,
+        loading,
+      };
+    },
+  });
+</script>

+ 517 - 0
src/views/planImg/list.vue

@@ -0,0 +1,517 @@
+<template>
+  <div class="scren">
+    <PageWrapper contentBackground>
+      <template #footer>
+        <a-tabs v-model:activeKey="tableType" @change="changeTable">
+          <Tabs.TabPane :key="0" tab="户型图" :disabled="loading" />
+          <Tabs.TabPane :key="1" tab="方位图" :disabled="loading" /> </a-tabs
+      ></template>
+      <div class="desc-wrap-BasicTable">
+        <BasicTable @register="registerTable">
+          <template #toolbar>
+            <a-button type="primary" @click="handleAdd"> 新增</a-button>
+          </template>
+
+          <template #href="{ record }">
+            <a
+              v-if="record.caseTitle"
+              target="_blank"
+              :title="record.caseTitle"
+              :href="`/code/index.html?caseId=${record.caseId}#/show`"
+              >{{ record.caseTitle }}</a
+            >
+            <span v-else>-</span>
+          </template>
+          <template #action="{ record }">
+            <TableAction
+              stopButtonPropagation
+              :actions="[
+                {
+                  label: '重命名',
+                  ifShow: getTypeCheckPerm('case-powers'),
+                  onClick: handleRename.bind(null, record),
+                },
+                {
+                  label: '编辑',
+                  disabled: tableType == 1 && !record.isEdit,
+                  ifShow: getTypeCheckPerm('case-edit'),
+                  onClick: handlegotoEdit.bind(null, record),
+                },
+                {
+                  label: '下载',
+                  ifShow: getTypeCheckPerm('case-download') && !record.isOpen,
+                  disabled: tableType == 1,
+                  onClick: createConfirmDownload.bind(null, record),
+                },
+                {
+                  label: '删除',
+                  ifShow: getTypeCheckPerm('case-delete') && !record.isOpen,
+                  //icon: 'ic:outline-delete-outline',
+                  disabled: tableType == 1,
+                  color: 'error',
+                  onClick: handleDelete.bind(null, record),
+                },
+              ]"
+            />
+          </template>
+        </BasicTable>
+      </div>
+      <DownLoadModal
+        :downloadOption="downloadOption"
+        @cancel="afterClose"
+        @register="registerDownModal"
+        @update="reload"
+        cancelText="取消下载"
+        okText="下载"
+        @cancelDownload="cancelDownload"
+        :okButtonProps="{ disabled: canDownload }"
+      />
+      <MoveModal @register="registerMoveModal" />
+      <AddModal @register="registerAddModal" @update="reload" />
+      <PowersModal @register="registerPowersModal" />
+    </PageWrapper>
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent, h, computed, toRefs, ref, onMounted } from 'vue';
+  import Icon from '/@/components/Icon/index';
+  import dayjs from 'dayjs';
+  import { QrCode } from '/@/components/Qrcode/index';
+  import {
+    BasicTable,
+    useTable,
+    TableAction,
+    BasicColumn,
+    TableImg,
+    FormProps,
+  } from '/@/components/Table';
+  import { PageWrapper } from '/@/components/Page';
+  import AddModal from './addCaseModal.vue';
+  import DownLoadModal from './DownLoadModal.vue';
+  import MoveModal from '/@/views/productOperation/modal/MoveModal.vue';
+  import PowersModal from '/@/views/productOperation/modal/PowersModal.vue';
+  import { Time } from '/@/components/Time';
+  import { Descriptions, Tabs, Progress } from 'ant-design-vue';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useModal } from '/@/components/Modal';
+  import {
+    operateSceneList,
+    sceneMove,
+    sceneDelete,
+    sceneReset,
+    sceneDownload,
+    caseCheckDown,
+    downloadProcess,
+    sceneCopy,
+    rebuildScene,
+    buildSceneObj,
+    sceneDetail,
+    sceneCount,
+    caseDelApi,
+    caseListApi,
+    caseProcess,
+    caseDown,
+  } from '/@/api/operate';
+  import { message } from 'ant-design-vue';
+  import { usePermissionStore } from '/@/store/modules/permission';
+  import { useUserStore } from '/@/store/modules/user';
+  import { func } from 'vue-types';
+  export default defineComponent({
+    components: {
+      DownLoadModal,
+      MoveModal,
+      PowersModal,
+      BasicTable,
+      TableAction,
+      PageWrapper,
+      [Descriptions.name]: Descriptions,
+      [Descriptions.Item.name]: Descriptions.Item,
+      QrCode,
+      AddModal,
+      // Tabs,
+      [Tabs.name]: Tabs,
+      // [Tabs.TabPane?.name]: Tabs.TabPane,
+    },
+    setup() {
+      const { t } = useI18n();
+      const { createMessage, createConfirm } = useMessage();
+      const userStore = useUserStore();
+      const userInfo = computed(() => userStore.getUserInfo);
+      const permissionStore = usePermissionStore();
+      const { getCheckPerm } = permissionStore;
+      const loading = ref(false);
+      const tableType = ref<number>(0); //0看看 、1看见、2深时
+      const columns: BasicColumn[] = [
+        {
+          title: '标题',
+          dataIndex: 'sceneName',
+          ellipsis: true,
+          slots: { customRender: 'href' },
+          resizable: true,
+          minWidth: 150,
+          width: 300,
+        },
+        {
+          title: '来源',
+          dataIndex: 'userName',
+          ellipsis: true,
+          width: 100,
+        },
+        {
+          title: '创建时间',
+          dataIndex: 'createTime',
+          width: 230,
+          customRender: ({ record }) => {
+            return (
+              record.createTime &&
+              h(Time, {
+                value: record.createTime,
+                mode: 'datetime',
+              })
+            );
+          },
+        },
+        {
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+          ifShow: true,
+          fixed: 'right',
+          flag: 'ACTION',
+          width: 200,
+        },
+      ];
+      const searchForm: Partial<FormProps> = {
+        labelWidth: 100,
+        autoSubmitOnEnter: true,
+        autoAdvancedLine: 1,
+        schemas: [
+          {
+            field: 'caseTitle',
+            label: '平面图名称',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 7,
+              xxl: 7,
+            },
+          },
+          {
+            field: 'title',
+            label: '场景名称',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 7,
+              xxl: 7,
+            },
+          },
+        ],
+      };
+      function cancelDownload() {
+        downloadOption.value = {};
+      }
+      const [registerAddModal, { openModal: openAddModal }] = useModal();
+      const [registerDownModal, { openModal: openDownModal }] = useModal();
+      const [registerMoveModal, { openModal: openMoveModal }] = useModal();
+      const [registerPowersModal, { openModal: openPowersModal }] = useModal();
+      const [registerTable, { reload, setColumns }] = useTable({
+        api: caseListApi,
+        title: ``,
+        // titleHelpMessage: ['已启用expandRowByClick', '已启用stopButtonPropagation'],
+        columns: columns,
+        searchInfo: { isShare: tableType },
+        useSearchForm: true,
+        formConfig: searchForm,
+        showIndexColumn: false,
+        showTableSetting: true,
+        beforeFetch: (T) => {
+          loading.value = true;
+          return T;
+        },
+        afterFetch: (T) => {
+          loading.value = false;
+          return T;
+        },
+        rowKey: 'caseId',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        canResize: true,
+      });
+      function changeTable(val: number) {
+        tableType.value = val;
+        reload();
+      }
+      function handleAdd() {
+        openAddModal(true, {
+          title: tableType.value == 0 ? '户型图' : '方位图',
+        });
+        // router.push({ path: '/scene/add' });
+      }
+      async function handleCopy(record: Recordable) {
+        createConfirm({
+          title: '复制场景',
+          content: '确定要复制场景吗?',
+          onOk: async () => {
+            sceneCopy({ num: record.num }).then(() => {
+              message.success({
+                content: '复制成功',
+              });
+              reload();
+            });
+          },
+        });
+      }
+      async function handleDelete(record: Recordable) {
+        createConfirm({
+          title: '删除',
+          content: '确定要删除吗?',
+          onOk: async () => {
+            caseDelApi({ caseId: record.caseId }).then(() => {
+              message.success({
+                content: '删除成功',
+              });
+
+              reload();
+            });
+          },
+        });
+      }
+      async function handleMove(record: Recordable) {
+        openMoveModal(true, {
+          ...record,
+        });
+        // sceneMove({ snCode: record.snCode, num: record.num })
+        //   .then(() => {
+        //     message.success({
+        //       content: '迁移成功',
+        //     });
+        //   })
+        //   .catch(() => {
+        //     message.success({
+        //       content: '迁移失败',
+        //     });
+        //   });
+      }
+      let timer: null = ref(null);
+      const downloadOption = ref<Object>({});
+      const canDownload = ref<boolean>(true);
+      function createConfirmDownload(record: Recordable) {
+        createConfirm({
+          title: '提示',
+          okText: '继续',
+          content: '案件资源过大会导致离线包下载失败,请尽可能缩小案件资源后再下载。',
+          onOk: async () => {
+            handleDownload(record);
+          },
+        });
+      }
+
+      function handleDownload(record: Recordable) {
+        console.log('handleDownload', record, canDownload.value);
+        canDownload.value = true;
+        let isObj = tableType.value == 5 || tableType.value == 7 ? 1 : 0;
+        caseCheckDown({ caseId: record.caseId }).then((res) => {
+          console.log(res);
+          if (res.downloadStatus != 3) {
+            // 未下载过,需要打包
+            caseDown({ caseId: record.caseId }).then((res) => {
+              console.log(res);
+              openDownModal(true, {
+                ...record,
+              });
+              if (res.downloadStatus == 1) {
+                if (timer.value) {
+                  afterClose();
+                }
+                timer.value = setInterval(() => {
+                  caseProcess({ caseId: record.caseId }).then((res) => {
+                    if (res.status == '1003') {
+                      createMessage.error('下载失败');
+                      afterClose();
+                      return;
+                    }
+                    if (res.percent >= 100) {
+                      canDownload.value = false;
+                      afterClose();
+                    }
+                    downloadOption.value = res;
+                    console.log(res);
+                  });
+                }, 1000);
+              }
+            });
+          } else {
+            canDownload.value = false;
+            window.open(res.downloadUrl);
+          }
+        });
+      }
+      function handleEdit(record: Recordable) {
+        window.open(record.thumbEdit + '&&token=' + token.value);
+      }
+      async function handleGenerate(record: Recordable) {
+        console.log('record', record);
+        let data = await sceneDetail({ id: record.id });
+        console.log('data', data);
+        let { buildObjStatus } = data;
+        let toastText =
+          buildObjStatus == 2
+            ? 'Mesh场景正在计算中,请耐心等待'
+            : buildObjStatus == 1
+            ? '重新生成Mesh场景将覆盖现有场景信息,计算过程中Mesh场景无法打开,确定要重新生成吗?'
+            : '生成obj需要较长时间,请耐心等待';
+        // if (data.code === 200) {
+        createConfirm({
+          iconType: 'warning',
+          title: () => h('span', '生成 obj'),
+          content: () => h('span', toastText),
+          onOk: async () => {
+            if (buildObjStatus !== 2) {
+              await buildSceneObj({ id: record.id, sceneNum: record.num });
+            }
+            createMessage.success(t('common.optSuccess'));
+            reload();
+          },
+        });
+        // } else {
+        //   createMessage.error(t(`apiCode.errCode${data.code}`));
+        // }
+      }
+      function afterClose() {
+        clearInterval(timer.value);
+        timer.value = null;
+      }
+      function handleReset(record: Recordable) {
+        console.log('handleReset', record);
+        rebuildScene({ num: record.num }).then(() => {
+          message.success({
+            content: '操作成功',
+          });
+          reload();
+        });
+      }
+      function getTypeCheckPerm(val) {
+        let myType = tableType.value;
+        return getCheckPerm(val) || getCheckPerm(`${val}-${myType}`);
+      }
+      function handlegotoEdit(record) {
+        window.open(`/mix3d/#/home/${record.caseId}`);
+        // let url = record.webSite.replace('smg', 'epg');
+        // if (!record.editAuthTime || (record.editAuthTime && dayjs() < dayjs(record.editAuthTime))) {
+        //   window.open(url);
+        // } else {
+        //   createMessage.error('编辑权限已过期');
+        // }
+      }
+      function handleRename(record) {
+        openAddModal(true, record);
+        // openPowersModal(true, {
+        //   ...record,
+        //   tableType: tableType.value,
+        // });
+      }
+      onMounted(() => {});
+      return {
+        registerTable,
+        registerPowersModal,
+        handleDelete,
+        handleCopy,
+        handleMove,
+        handleDownload,
+        handleReset,
+        tableType,
+        loading,
+        changeTable,
+        t,
+        openDownModal,
+        registerDownModal,
+        registerMoveModal,
+        registerAddModal,
+        afterClose,
+        timer,
+        canDownload,
+        downloadOption,
+        cancelDownload,
+        handleGenerate,
+        getTypeCheckPerm,
+        handlegotoEdit,
+        handleRename,
+        userInfo,
+        handleAdd,
+        reload,
+        getCheckPerm,
+        createConfirmDownload,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .scren {
+    .noScene {
+      position: absolute;
+      top: calc(50% - 126px);
+      width: 100%;
+      text-align: center;
+      &-content {
+        font-size: 14px;
+        color: rgba(0, 0, 0, 0.85);
+        line-height: 22px;
+        font-style: normal;
+        text-transform: none;
+        .codelist {
+          margin-top: 36px;
+          width: 424px;
+          height: auto;
+          display: flex;
+          justify-content: space-between;
+          margin: 0 auto;
+          .codediv {
+            font-weight: 400;
+            font-size: 17px;
+            color: rgba(0, 0, 0, 0.85);
+            line-height: 22px;
+            height: auto;
+            padding: 24px;
+            background: #fff;
+            text-align: center;
+            .codetext {
+              margin-top: 10px;
+            }
+          }
+        }
+      }
+    }
+  }
+  // .tableHeader {
+  //   height: 50px;
+  //   display: flex;
+  //   align-items: center;
+
+  //   .item {
+  //     font-size: 14px;
+  //     color: #666;
+  //     margin-right: 10px;
+  //     cursor: pointer;
+  //     &.active {
+  //       font-weight: bold;
+  //       color: #222;
+  //     }
+  //   }
+  // }
+  .desc-wrap-BasicTable {
+    background-color: #f0f2f5;
+    .vben-basic-table-form-container {
+      padding: 0;
+    }
+  }
+</style>

+ 10 - 10
src/views/productOperation/cameraScene.vue

@@ -340,25 +340,25 @@
             let str;
             switch (record.type) {
               case 0:
-                str = '四维看看/Mesh';
+                str = '四维看看';
                 break;
               case 1:
-                str = '四维看见/Mesh';
+                str = '四维看见';
                 break;
               case 2:
                 str = '四维深时/点云';
                 break;
               case 5:
-                str = '四维深时/Mesh';
+                str = '四维深时';
                 break;
               case 6:
                 str = '四维深光/点云';
                 break;
               case 7:
-                str = '四维深光/Mesh';
+                str = '四维深光';
                 break;
               case 8:
-                str = '圆周率/Mesh';
+                str = '圆周率';
                 break;
             }
             return str;
@@ -486,12 +486,12 @@
               // allowClear: false,
               options: [
                 {
-                  label: '四维看看/Mesh',
+                  label: '四维看看',
                   value: '0',
                   key: '0',
                 },
                 {
-                  label: '四维看见/Mesh',
+                  label: '四维看见',
                   value: '1',
                   key: '1',
                 },
@@ -501,7 +501,7 @@
                 //   key: '2',
                 // },
                 {
-                  label: '四维深时/Mesh',
+                  label: '四维深时',
                   value: '5',
                   key: '5',
                 },
@@ -511,12 +511,12 @@
                 //   key: '6',
                 // },
                 {
-                  label: '四维深光/Mesh',
+                  label: '四维深光',
                   value: '7',
                   key: '7',
                 },
                 {
-                  label: '圆周率/Mesh',
+                  label: '圆周率',
                   value: '8',
                   key: '8',
                 },

+ 48 - 48
src/views/statistics/components/sceneEchart.vue

@@ -1,7 +1,7 @@
 <template>
-  <Card :title="title||'订单数据统计'">
+  <Card :title="title || '订单数据统计'">
     <template #extra>
-      <condition type="2"  @change="Search" @expor="expor" />
+      <condition type="2" @change="Search" @expor="expor" />
     </template>
     <div ref="chartRef" :style="{ height, width }"></div>
   </Card>
@@ -12,12 +12,12 @@
   import { Card, DatePicker } from 'ant-design-vue';
   import { ref, Ref, watch, defineEmits } from 'vue';
   import { useECharts } from '/@/hooks/web/useECharts';
-  import { exportElsxFile, } from '/@/utils/file/download';
+  import { exportElsxFile } from '/@/utils/file/download';
   const props = defineProps({
-  loading: Boolean,
+    loading: Boolean,
     ...basicProps,
   });
-  const emit = defineEmits(["alertSome"])
+  const emit = defineEmits(['alertSome']);
   const kjList = ref<number[]>([]);
   const kkList = ref<number[]>([]);
   const ssList = ref<number[]>([]);
@@ -26,43 +26,43 @@
   const sgobjList = ref<number[]>([]);
   const yzlList = ref<number[]>([]);
   const yixStringData = ref<string[]>([]);
-  const echartTypr = ref('line')
-  const nameList = ref<string[]>(['四维看见/Mesh','四维看看/Mesh','四维深时/点云','四维深时/Mesh','四维深光/点云','四维深光/Mesh','圆周率/Mesh']);
+  const echartTypr = ref('line');
+  const nameList = ref<string[]>(['四维看见', '四维看看', '四维深时', '四维深光', '圆周率']);
   const maxSize = ref(0);
   const chartRef = ref<HTMLDivElement | null>(null);
-  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>)
+  const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
 
-  function Search(val){
-    emit('change',val)
+  function Search(val) {
+    emit('change', val);
   }
-  function expor(val){
-    let fileTile = props.title||'订单数据'
-    let fields  = {
-    'time':'日期',
-    'kj': nameList.value[0],
-    'kk': nameList.value[1],
-    'ss':nameList.value[2],
-    'dy':nameList.value[3],
-    'sg':nameList.value[4],
-    'sgdy':nameList.value[5],
-    'yzl':nameList.value[6],
+  function expor(val) {
+    let fileTile = props.title || '订单数据';
+    let fields = {
+      time: '日期',
+      kj: nameList.value[0],
+      kk: nameList.value[1],
+      ss: nameList.value[2],
+      // 'dy':nameList.value[3],
+      sg: nameList.value[3],
+      // 'sgdy':nameList.value[5],
+      yzl: nameList.value[4],
+    };
+    if ('场景趋势分析' == fileTile) {
+      fileTile = `${val && val.value == 0 ? '新增' : '累计'}` + fileTile;
     }
-    if('场景趋势分析' == fileTile){
-      fileTile = `${val && val.value == 0?'新增':'累计'}`+fileTile
-    }
-    let data = yixStringData.value.map((ele,index) => {
+    let data = yixStringData.value.map((ele, index) => {
       return {
-        'time':ele,
-        'kj':kjList.value && kjList.value[index] || 0,
-        'kk':kkList.value && kkList.value[index] || 0,
-        'ss':ssList.value && ssList.value[index] || 0,
-        'dy':ssobjList.value && ssobjList.value[index] || 0,
-        'sg':sgList.value && sgList.value[index] || 0,
-        'sgdy':sgobjList.value && sgobjList.value[index] || 0,
-        'yzl':yzlList.value && yzlList.value[index] || 0,
-      }
-    })
-    exportElsxFile(data,fields,fileTile)
+        time: ele,
+        kj: (kjList.value && kjList.value[index]) || 0,
+        kk: (kkList.value && kkList.value[index]) || 0,
+        ss: (ssList.value && ssList.value[index]) || 0,
+        // 'dy':ssobjList.value && ssobjList.value[index] || 0,
+        sg: (sgList.value && sgList.value[index]) || 0,
+        // 'sgdy':sgobjList.value && sgobjList.value[index] || 0,
+        yzl: (yzlList.value && yzlList.value[index]) || 0,
+      };
+    });
+    exportElsxFile(data, fields, fileTile);
   }
   function handlesetOptions() {
     setOptions({
@@ -146,19 +146,19 @@
   watch(
     () => props.echartData,
     (echartData) => {
-      kjList.value = echartData.kjList ||[]
-      kkList.value = echartData.kkList ||[]
-      ssList.value = echartData.ssList ||[]
-      ssobjList.value = echartData.ssobjList ||[]
-      sgList.value = echartData.sgList ||[]
-      sgobjList.value = echartData.sgobjList ||[]
-      yzlList.value = echartData.yzlList ||[]
-      yixStringData.value = echartData.xdata ||[]
-      if(echartData.nameList){
-        nameList.value = echartData.nameList
+      kjList.value = echartData.kjList || [];
+      kkList.value = echartData.kkList || [];
+      ssList.value = echartData.ssList || [];
+      ssobjList.value = echartData.ssobjList || [];
+      sgList.value = echartData.sgList || [];
+      sgobjList.value = echartData.sgobjList || [];
+      yzlList.value = echartData.yzlList || [];
+      yixStringData.value = echartData.xdata || [];
+      if (echartData.nameList) {
+        nameList.value = echartData.nameList;
       }
-      if(echartData.echartTypr){
-        echartTypr.value = echartData.echartTypr
+      if (echartData.echartTypr) {
+        echartTypr.value = echartData.echartTypr;
       }
       handlesetOptions();
     },

+ 174 - 0
src/views/workerShare/addModal.vue

@@ -0,0 +1,174 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="新增人员"
+    @cancel="resetFields"
+    @ok="handleSubmit"
+  >
+    <div class="pt-2px pr-3px">
+      <BasicForm @register="registerForm">
+        <template #text="{ model, field }">
+          {{ model[field] }}
+        </template>
+      </BasicForm>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, ref, onMounted, reactive } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { getinnerByRyId, userShareAdd } from '/@/api/operate';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicForm },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['ok'],
+    setup(_, { emit }) {
+      const modelRef = ref(false);
+      const fileFlow = reactive({
+        file: null,
+      });
+      const { createMessage } = useMessage();
+      const optionsName = ref([]);
+      const schemas: FormSchema[] = [
+        {
+          field: 'id',
+          component: 'Input',
+          show: false,
+          label: 'id',
+          defaultValue: '111',
+          required: false,
+        },
+        {
+          field: 'ryNo',
+          component: 'Input',
+          label: '人员编号',
+          required: true,
+          rules: [
+            {
+              required: true,
+              // @ts-ignore
+              validator: async (rule, value) => {
+                let myData = await getFieldsValue();
+                if (!value) {
+                  return Promise.reject('请输入人员编号');
+                }
+                let res = await getinnerByRyId({ ryNo: value });
+                console.log('value', value, res);
+                if (res && !res.data) {
+                  return Promise.reject('人员编号不存在');
+                }
+                Promise.resolve();
+                let ryNickName = res && res.data && res.data.ryNickName;
+                if(myData.ryNickName != ryNickName || !myData.ryNickName){
+                  setFieldsValue({
+                    ryNickName: res && res.data ? res.data.ryNickName : '',
+                    id: res && res.data ? res.data.id : '',
+                  });
+                }
+              },
+              trigger: 'blur',
+            },
+          ],
+          colProps: {
+            span: 20,
+          },
+        },
+        {
+          field: 'ryNickName',
+          component: 'Input',
+          label: '姓名',
+          colProps: {
+            span: 20,
+          },
+          componentProps: {
+            disabled: true,
+          },
+        },
+        {
+          field: 'isTop',
+          component: 'CheckboxGroup',
+          required: true,
+          label: '共享内容',
+          componentProps: {
+            options: [
+              { label: '所有场景', value: 1 },
+              { label: '所有案件', value: 0 },
+            ],
+          },
+          colProps: {
+            span: 24,
+          },
+        },
+      ];
+      const [
+        registerForm,
+        { validate, resetFields, setFieldsValue, getFieldsValue, updateSchema },
+      ] = useForm({
+        labelWidth: 110,
+        schemas,
+        showActionButtonGroup: false,
+        actionColOptions: {
+          span: 24,
+        },
+      });
+
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner(async (data) => {
+        console.log('option', data);
+      });
+      function onFilterOption(inputText: string, option) {
+        console.log('option', inputText, option.value);
+        if (option.value) {
+          return option.value.indexOf(inputText) >= 0;
+        }
+        // return option.value.indexOf(inputText.toUpperCase()) >= 0;
+      }
+      async function onSearch(searchText) {
+        const res = await getinnerByRyId({ ryNo: searchText });
+        console.log('res', res.data);
+        if (!res.data) return;
+        optionsName.value = res.data || {};
+        updateSchema({
+          field: 'ryNo',
+          componentProps: {
+            options: [optionsName.value],
+          },
+        });
+      }
+      const handleSubmit = async () => {
+        const params = await validate();
+        try {
+          console.log('params', params);
+          await userShareAdd(params);
+          closeModal();
+          resetFields();
+          emit('ok');
+          createMessage.success('操作成功');
+        } catch (error) {
+          console.log('not passing', error);
+        }
+      };
+
+      return {
+        register,
+        schemas,
+        registerForm,
+        modelRef,
+        fileFlow,
+        handleSubmit,
+        addListFunc,
+        resetFields,
+        t,
+      };
+    },
+  });
+</script>

+ 32 - 0
src/views/workerShare/data.ts

@@ -0,0 +1,32 @@
+// import { FormSchema } from '/@/components/Form/index';
+import { BasicColumn } from '/@/components/Table/src/types/table';
+
+export const userListSchema: BasicColumn[] = [
+  {
+    title: '姓名',
+    width: 200,
+    dataIndex: 'ryNickName',
+    fixed: 'left',
+  },
+  {
+    title: '人员编号',
+    width: 200,
+    dataIndex: 'ryNo',
+  },
+  {
+    title: '共享内容',
+    width: 200,
+    dataIndex: 'ryNo1',
+    customRender: ({ record }) => {
+      return record.status == 1 ? '场景' : '案件';
+    },
+  },
+  {
+    title: '状态',
+    width: 200,
+    dataIndex: 'state',
+    customRender: ({ record }) => {
+      return record.status == 1 ? '正常' : '冻结';
+    },
+  },
+];

+ 121 - 0
src/views/workerShare/giveList.vue

@@ -0,0 +1,121 @@
+<template>
+  <div>
+    <BasicTable @register="registerTimeTable">
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: record.sceneCount || '-',
+              onClick: handleCreate.bind(null, record),
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <sceneListModal @register="register" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTable, useTable, FormProps, TableAction } from '/@/components/Table';
+  import { userShareList } from '/@/api/account';
+  import { userListSchema } from './data';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { usePermissionStore } from '/@/store/modules/permission';
+  import sceneListModal from './sceneListModal.vue';
+  import { useModal } from '/@/components/Modal';
+
+  export default defineComponent({
+    components: {
+      BasicTable,
+      sceneListModal,
+      TableAction,
+    },
+    setup() {
+      const { t } = useI18n();
+      const permissionStore = usePermissionStore();
+      const [register, { openModal }] = useModal();
+      const { getCheckPerm } = permissionStore;
+      const searchForm: Partial<FormProps> = {
+        labelWidth: 100,
+        schemas: [
+          {
+            field: 'ryNickName',
+            label: '姓名',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 6,
+              xxl: 6,
+            },
+          },
+          {
+            field: 'ryNo',
+            label: '人员编号',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 8,
+              xxl: 8,
+            },
+          },
+        ],
+      };
+      const [registerTimeTable, { reload }] = useTable({
+        api: userShareList,
+        columns: userListSchema,
+        useSearchForm: true,
+        formConfig: searchForm,
+        showTableSetting: true,
+        showIndexColumn: false,
+        searchInfo: { type: 1 },
+        rowKey: 'id',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        actionColumn: {
+          width: 100,
+          title: '场景',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
+        canResize: true,
+      });
+      function handleCreate(record) {
+        openModal(true, record);
+      }
+      function tabChange(val: string) {
+        console.log('tabChange', val);
+        reload();
+      }
+      function handleOpen(record) {
+        console.log('点击了启用', record);
+      }
+      return {
+        registerTimeTable,
+        handleOpen,
+        tabChange,
+        reload,
+        register,
+        getCheckPerm,
+        handleCreate,
+        t,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .desc-wrap-BasicTable {
+    background-color: #f0f2f5;
+    .vben-basic-table-form-container {
+      padding: 0;
+    }
+  }
+</style>

+ 142 - 0
src/views/workerShare/index.vue

@@ -0,0 +1,142 @@
+<template>
+  <div>
+    <BasicTable @register="registerTimeTable">
+      <template #toolbar>
+        <a-button type="primary" @click="handleCreate" v-if="getCheckPerm('sceneShare-add')">
+          新增</a-button
+        >
+      </template>
+      <template #action="{ record }">
+        <TableAction
+          :actions="[
+            {
+              label: '删除',
+              color: 'error',
+              ifShow: getCheckPerm('sceneShare-del'),
+              onClick: handleDlet.bind(null, record),
+            },
+          ]"
+        />
+      </template>
+    </BasicTable>
+    <addModal @register="registerAdd" @ok="reload" />
+  </div>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { BasicTable, useTable, FormProps, TableAction } from '/@/components/Table';
+  import { userShareList, userShareDel } from '/@/api/account';
+  import { userListSchema } from './data';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { useModal } from '/@/components/Modal';
+  import { usePermissionStore } from '/@/store/modules/permission';
+  import addModal from './addModal.vue';
+  import { useMessage } from '/@/hooks/web/useMessage';
+
+  export default defineComponent({
+    components: {
+      BasicTable,
+      TableAction,
+      addModal,
+    },
+    setup() {
+      const { t } = useI18n();
+      const { createMessage, createConfirm } = useMessage();
+      const permissionStore = usePermissionStore();
+      const [registerAdd, { openModal: openAddModal }] = useModal();
+      const { getCheckPerm } = permissionStore;
+      const searchForm: Partial<FormProps> = {
+        labelWidth: 100,
+        schemas: [
+          {
+            field: 'ryNickName',
+            label: '姓名',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 6,
+              xxl: 6,
+            },
+          },
+          {
+            field: 'ryNo',
+            label: '人员编号',
+            component: 'Input',
+            componentProps: {
+              maxLength: 100,
+            },
+            colProps: {
+              xl: 8,
+              xxl: 8,
+            },
+          },
+        ],
+      };
+      const [registerTimeTable, { reload }] = useTable({
+        api: userShareList,
+        columns: userListSchema,
+        useSearchForm: true,
+        formConfig: searchForm,
+        showTableSetting: true,
+        showIndexColumn: false,
+        searchInfo: { type: 0 },
+        rowKey: 'id',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        actionColumn: {
+          width: 100,
+          title: '操作',
+          dataIndex: 'action',
+          slots: { customRender: 'action' },
+        },
+        canResize: true,
+      });
+      function handleCreate() {
+        openAddModal(true, {});
+      }
+      function tabChange(val: string) {
+        console.log('tabChange', val);
+        reload();
+      }
+      function handleOpen(record) {
+        console.log('点击了启用', record);
+      }
+      async function handleDlet(record) {
+        createConfirm({
+          title: '删除',
+          content: `确定要删除 ${record.ryNo} 吗?`,
+          onOk: async () => {
+            await userShareDel({id: record.id });
+            createMessage.success('操作成功');
+            reload();
+          },
+        });
+      }
+      return {
+        registerTimeTable,
+        registerAdd,
+        handleOpen,
+        tabChange,
+        reload,
+        handleDlet,
+        getCheckPerm,
+        handleCreate,
+        t,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .desc-wrap-BasicTable {
+    background-color: #f0f2f5;
+    .vben-basic-table-form-container {
+      padding: 0;
+    }
+  }
+</style>

+ 166 - 0
src/views/workerShare/sceneListModal.vue

@@ -0,0 +1,166 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    @register="register"
+    title="场景列表"
+    :width="1200"
+    :showOkBtn="false"
+    @ok="handleSubmit"
+  >
+    <div class="pt-3px pr-3px">
+      <div class="table_list">
+        <BasicTable @register="registerSubtable">
+          <template #href="{ record }">
+            <a
+              :title="record.sceneName"
+              v-if="record.webSite"
+              target="_blank"
+              :href="record.webSite"
+              >{{ record.title }}</a
+            >
+            <span v-else-if="record.sceneName">{{ record.sceneName }}</span>
+            <span v-else>-</span>
+          </template>
+        </BasicTable>
+      </div>
+    </div>
+  </BasicModal>
+</template>
+<script lang="ts">
+  import { defineComponent, onMounted, ref, h } from 'vue';
+  import { BasicTable, useTable, BasicColumn } from '/@/components/Table';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { Time } from '/@/components/Time';
+  import { useI18n } from '/@/hooks/web/useI18n';
+  import { sceneList } from '/@/api/operate';
+
+  const { t } = useI18n();
+  export default defineComponent({
+    components: { BasicModal, BasicTable },
+    props: {
+      userData: { type: Object },
+    },
+    emits: ['update'],
+    setup(props, { emit }) {
+      const id = ref(null);
+      const columns: BasicColumn[] = [
+        {
+          title: '场景标题',
+          dataIndex: 'sceneName',
+          ellipsis: true,
+          slots: { customRender: 'href' },
+          width: 150,
+        },
+        {
+          title: '场景码',
+          dataIndex: 'num',
+          ellipsis: true,
+          width: 180,
+        },
+        {
+          title: '拍摄时间',
+          dataIndex: 'createTime',
+          width: 180,
+          customRender: ({ record }) => {
+            return (
+              record.createTime &&
+              h(Time, {
+                value: record.createTime,
+                mode: 'datetime',
+              })
+            );
+          },
+        },
+        {
+          title: '计算完成时间',
+          dataIndex: 'amount',
+          width: 180,
+          customRender: ({ record }) => {
+            return (
+              (record.algorithmTime &&
+                h(Time, {
+                  value: record.algorithmTime,
+                  mode: 'datetime',
+                })) ||
+              '-'
+            );
+          },
+        },
+        {
+          title: '人员编号',
+          dataIndex: 'ryNo',
+          width: 100,
+        },
+        {
+          title: t('routes.staff.userName'),
+          dataIndex: 'ryNickName',
+          width: 100,
+          customRender: ({ record }) => {
+            return record.ryNickName || '-';
+          },
+        },
+        {
+          title: '状态',
+          dataIndex: 'status',
+          width: 80,
+          customRender: ({ record }) => {
+            let str;
+            switch (record.status - 0) {
+              case 0:
+                str = '计算中';
+                break;
+              case 1:
+                str = '计算成功';
+                break;
+              case -2:
+                str = '计算成功';
+                break;
+              case -1:
+                str = '计算失败';
+                break;
+            }
+            return record.payStatus == -2 ? '封存' : str;
+          },
+        },
+      ];
+      const [registerSubtable, { reload }] = useTable({
+        api: sceneList,
+        showIndexColumn: true,
+        columns: columns,
+        searchInfo: { jyUserId: id },
+        rowKey: 'id',
+        fetchSetting: {
+          pageField: 'pageNum',
+          sizeField: 'pageSize',
+          listField: 'list',
+          totalField: 'total',
+        },
+        canResize: true,
+        bordered: true,
+      });
+
+      onMounted(() => {});
+      let addListFunc = () => {};
+      const [register, { closeModal }] = useModalInner((data) => {
+        data && onDataReceive(data);
+      });
+      function onDataReceive(data) {
+        console.log('onDataReceive', data);
+        id.value = data.userId;
+        reload();
+      }
+      const handleSubmit = async () => {
+        closeModal();
+        emit('update');
+      };
+      return {
+        register,
+        handleSubmit,
+        addListFunc,
+        registerSubtable,
+        reload,
+        t,
+      };
+    },
+  });
+</script>