list.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. <template>
  2. <div class="scren">
  3. <PageWrapper contentBackground>
  4. <!-- <template #footer>
  5. <a-tabs v-model:activeKey="tableType" @change="changeTable">
  6. <Tabs.TabPane :key="0" tab="案件管理" :disabled="loading" />
  7. <Tabs.TabPane :key="1" tab="案件共享" :disabled="loading" />
  8. </a-tabs
  9. ></template> -->
  10. <div class="desc-wrap-BasicTable">
  11. <BasicTable @register="registerTable">
  12. <template #toolbar>
  13. <a-button type="primary" @click="handleAdd" > {{t('routes.account.add')}}</a-button>
  14. </template>
  15. <template #href="{ record }">
  16. <a
  17. v-if="record.caseTitle"
  18. target="_blank"
  19. :title="record.caseTitle"
  20. :href="`/code/index.html?caseId=${record.caseId}#/show`"
  21. >{{ record.caseTitle }}</a
  22. >
  23. <span v-else>-</span>
  24. </template>
  25. <template #action="{ record }">
  26. <TableAction
  27. stopButtonPropagation
  28. :actions="[
  29. {
  30. label: t('common.edit'),
  31. disabled: tableType == 1 && !record.isEdit,
  32. //ifShow: getTypeCheckPerm('case-edit'),
  33. onClick: handlegotoEdit.bind(null, record),
  34. },
  35. {
  36. label: t('common.delText'),
  37. ifShow: !record.isOpen,
  38. //icon: 'ic:outline-delete-outline',
  39. disabled: tableType == 1,
  40. color: 'error',
  41. onClick: handleDelete.bind(null, record),
  42. },
  43. ]"
  44. />
  45. </template>
  46. </BasicTable>
  47. </div>
  48. <DownLoadModal
  49. :downloadOption="downloadOption"
  50. @cancel="afterClose"
  51. @register="registerDownModal"
  52. @update="reload"
  53. cancelText="取消下载"
  54. okText="下载"
  55. @cancelDownload="cancelDownload"
  56. :okButtonProps="{ disabled: canDownload }"
  57. />
  58. <MoveModal @register="registerMoveModal" />
  59. <AddModal @register="registerAddModal" @update="reload"/>
  60. <PowersModal @register="registerPowersModal" />
  61. </PageWrapper>
  62. </div>
  63. </template>
  64. <script lang="ts">
  65. import { defineComponent, h, computed, toRefs, ref, onMounted } from 'vue';
  66. import Icon from '/@/components/Icon/index';
  67. import dayjs from 'dayjs';
  68. import { QrCode } from '/@/components/Qrcode/index';
  69. import {
  70. BasicTable,
  71. useTable,
  72. TableAction,
  73. BasicColumn,
  74. TableImg,
  75. FormProps,
  76. } from '/@/components/Table';
  77. import { PageWrapper } from '/@/components/Page';
  78. import AddModal from './addCaseModal.vue'
  79. import DownLoadModal from './DownLoadModal.vue';
  80. import MoveModal from '/@/views/productOperation/modal/MoveModal.vue';
  81. import PowersModal from '/@/views/productOperation/modal/PowersModal.vue';
  82. import { Time } from '/@/components/Time';
  83. import { Descriptions, Tabs, Progress } from 'ant-design-vue';
  84. import { useI18n } from '/@/hooks/web/useI18n';
  85. import { useMessage } from '/@/hooks/web/useMessage';
  86. import { useModal } from '/@/components/Modal';
  87. import {
  88. operateSceneList,
  89. sceneMove,
  90. sceneDelete,
  91. sceneReset,
  92. sceneDownload,
  93. caseCheckDown,
  94. downloadProcess,
  95. sceneCopy,
  96. rebuildScene,
  97. buildSceneObj,
  98. sceneDetail,
  99. sceneCount,
  100. caseDelApi,
  101. caseListApi,
  102. caseProcess,
  103. caseDown,
  104. } from '/@/api/operate';
  105. import { message } from 'ant-design-vue';
  106. import { usePermissionStore } from '/@/store/modules/permission';
  107. import { useUserStore } from '/@/store/modules/user';
  108. import { func } from 'vue-types';
  109. export default defineComponent({
  110. components: {
  111. DownLoadModal,
  112. MoveModal,
  113. PowersModal,
  114. BasicTable,
  115. TableAction,
  116. PageWrapper,
  117. [Descriptions.name]: Descriptions,
  118. [Descriptions.Item.name]: Descriptions.Item,
  119. QrCode,
  120. AddModal,
  121. // Tabs,
  122. [Tabs.name]: Tabs,
  123. // [Tabs.TabPane?.name]: Tabs.TabPane,
  124. },
  125. setup() {
  126. const { t, locale } = useI18n();
  127. const { createMessage, createConfirm } = useMessage();
  128. const userStore = useUserStore();
  129. const userInfo = computed(() => userStore.getUserInfo);
  130. const permissionStore = usePermissionStore();
  131. const { getCheckPerm } = permissionStore;
  132. const loading = ref(false);
  133. const tableType = ref<number>(0); //0看看 、1看见、2深时
  134. const columns: BasicColumn[] = [
  135. {
  136. title: t('routes.account.title'),
  137. dataIndex: 'sceneName',
  138. ellipsis: true,
  139. slots: { customRender: 'href' },
  140. resizable: true,
  141. minWidth: 150,
  142. width: 300,
  143. },
  144. {
  145. title: t('routes.account.userName'),
  146. dataIndex: 'userName',
  147. ellipsis: true,
  148. width: 220,
  149. },
  150. // {
  151. // title: '姓名',
  152. // dataIndex: 'nickName',
  153. // ellipsis: true,
  154. // width: 100,
  155. // },
  156. {
  157. title: t('routes.account.createTime'),
  158. dataIndex: 'createTime',
  159. width: 230,
  160. customRender: ({ record }) => {
  161. return (
  162. record.createTime &&
  163. h(Time, {
  164. value: record.createTime,
  165. mode: 'datetime',
  166. })
  167. );
  168. },
  169. },
  170. // {
  171. // title: '计算完成时间',
  172. // dataIndex: 'amount',
  173. // width: 180,
  174. // customRender: ({ record }) => {
  175. // return (
  176. // (record.algorithmTime &&
  177. // h(Time, {
  178. // value: record.algorithmTime,
  179. // mode: 'datetime',
  180. // })) ||
  181. // '-'
  182. // );
  183. // },
  184. // },
  185. // {
  186. // title: 'SN码',
  187. // dataIndex: 'snCode',
  188. // width: 180,
  189. // },
  190. // {
  191. // title: '场景大小',
  192. // dataIndex: 'sceneSize',
  193. // width: 80,
  194. // customRender: ({ record }) => {
  195. // return record.sceneSize && record.sceneSize != 0
  196. // ? h('span', { class: 'sceneSize' }, Math.ceil(record.sceneSize / 1024 / 1024) + 'M')
  197. // : '-';
  198. // },
  199. // },
  200. // {
  201. // title: '是否复制',
  202. // dataIndex: 'isCopy',
  203. // width: 80,
  204. // customRender: ({ record }) => {
  205. // return record.isCopy ? '是' : '否';
  206. // },
  207. // },
  208. // {
  209. // title: '复制时间',
  210. // dataIndex: 'copyTime',
  211. // width: 180,
  212. // customRender: ({ record }) => {
  213. // return record.copyTime
  214. // ? h(Time, {
  215. // value: record.copyTime,
  216. // mode: 'datetime',
  217. // })
  218. // : '-';
  219. // },
  220. // },
  221. // {
  222. // title: '人员编号',
  223. // dataIndex: 'userName',
  224. // width: 100,
  225. // },
  226. // {
  227. // title: t('routes.staff.userName'),
  228. // dataIndex: 'nickName',
  229. // width: 100,
  230. // customRender: ({ record }) => {
  231. // return record.nickName || '-';
  232. // },
  233. // },
  234. // {
  235. // title: '浏览量',
  236. // dataIndex: 'viewCount',
  237. // width: 80,
  238. // },
  239. // {
  240. // title: '状态',
  241. // dataIndex: 'status',
  242. // width: 80,
  243. // customRender: ({ record }) => {
  244. // let str;
  245. // switch (record.status - 0) {
  246. // case 0:
  247. // str = '计算中';
  248. // break;
  249. // case 1:
  250. // str = '计算成功';
  251. // break;
  252. // case -2:
  253. // str = '计算成功';
  254. // break;
  255. // case -1:
  256. // str = '计算失败';
  257. // break;
  258. // }
  259. // return record.payStatus == -2 ? '封存' : str;
  260. // },
  261. // },
  262. {
  263. title: t('common.operating'),
  264. dataIndex: 'action',
  265. slots: { customRender: 'action' },
  266. ifShow: true,
  267. fixed: 'right',
  268. flag: 'ACTION',
  269. width: 200,
  270. },
  271. ];
  272. const searchForm: Partial<FormProps> = {
  273. labelWidth: 100,
  274. autoSubmitOnEnter: true,
  275. autoAdvancedLine: 1,
  276. schemas: [
  277. {
  278. field: 'caseTitle',
  279. label: t('routes.account.name'),
  280. component: 'Input',
  281. componentProps: {
  282. maxLength: 100,
  283. },
  284. colProps: {
  285. xl: 7,
  286. xxl: 7,
  287. },
  288. },
  289. ],
  290. };
  291. function cancelDownload() {
  292. downloadOption.value = {};
  293. }
  294. const [registerAddModal, { openModal: openAddModal }] = useModal();
  295. const [registerDownModal, { openModal: openDownModal }] = useModal();
  296. const [registerMoveModal, { openModal: openMoveModal }] = useModal();
  297. const [registerPowersModal, { openModal: openPowersModal }] = useModal();
  298. const [registerTable, { reload, setColumns }] = useTable({
  299. api: caseListApi,
  300. title: ``,
  301. // titleHelpMessage: ['已启用expandRowByClick', '已启用stopButtonPropagation'],
  302. columns: columns,
  303. searchInfo: { isShare: tableType },
  304. useSearchForm: true,
  305. formConfig: searchForm,
  306. showIndexColumn: false,
  307. showTableSetting: true,
  308. beforeFetch: (T) => {
  309. loading.value = true;
  310. return T;
  311. },
  312. afterFetch: (T) => {
  313. loading.value = false;
  314. return T;
  315. },
  316. rowKey: 'caseId',
  317. fetchSetting: {
  318. pageField: 'pageNum',
  319. sizeField: 'pageSize',
  320. listField: 'list',
  321. totalField: 'total',
  322. },
  323. canResize: true,
  324. });
  325. function changeTable(val: number) {
  326. tableType.value = val;
  327. reload();
  328. }
  329. function handleAdd() {
  330. openAddModal(true, {})
  331. // router.push({ path: '/scene/add' });
  332. }
  333. async function handleCopy(record: Recordable) {
  334. createConfirm({
  335. title: '复制场景',
  336. content: '确定要复制场景吗?',
  337. onOk: async () => {
  338. sceneCopy({ num: record.num }).then(() => {
  339. message.success({
  340. content: '复制成功',
  341. });
  342. reload();
  343. });
  344. },
  345. });
  346. }
  347. async function handleDelete(record: Recordable) {
  348. createConfirm({
  349. title: '删除',
  350. content: '确定要删除吗?',
  351. onOk: async () => {
  352. caseDelApi({ caseId: record.caseId }).then(() => {
  353. message.success({
  354. content: '删除成功',
  355. });
  356. reload();
  357. });
  358. },
  359. });
  360. }
  361. async function handleMove(record: Recordable) {
  362. openMoveModal(true, {
  363. ...record,
  364. });
  365. // sceneMove({ snCode: record.snCode, num: record.num })
  366. // .then(() => {
  367. // message.success({
  368. // content: '迁移成功',
  369. // });
  370. // })
  371. // .catch(() => {
  372. // message.success({
  373. // content: '迁移失败',
  374. // });
  375. // });
  376. }
  377. let timer: null = ref(null);
  378. const downloadOption = ref<Object>({});
  379. const canDownload = ref<boolean>(true);
  380. function createConfirmDownload(record: Recordable) {
  381. createConfirm({
  382. title: '提示',
  383. okText: '继续',
  384. content: '案件资源过大会导致离线包下载失败,请尽可能缩小案件资源后再下载。',
  385. onOk: async () => {
  386. handleDownload(record)
  387. },
  388. });
  389. }
  390. function handleDownload(record: Recordable) {
  391. console.log('handleDownload', record, canDownload.value);
  392. canDownload.value = true;
  393. let isObj = tableType.value == 5 || tableType.value == 7 ? 1 : 0;
  394. caseCheckDown({ caseId: record.caseId }).then((res) => {
  395. console.log(res);
  396. if (res.downloadStatus != 3) {
  397. // 未下载过,需要打包
  398. caseDown({ caseId: record.caseId }).then((res) => {
  399. console.log(res);
  400. openDownModal(true, {
  401. ...record,
  402. });
  403. if (res.downloadStatus == 1) {
  404. if (timer.value) {
  405. afterClose();
  406. }
  407. timer.value = setInterval(() => {
  408. caseProcess({ caseId: record.caseId, }).then((res) => {
  409. if (res.status == '1003') {
  410. createMessage.error('下载失败');
  411. afterClose();
  412. return;
  413. }
  414. if (res.percent >= 100) {
  415. canDownload.value = false;
  416. afterClose();
  417. }
  418. downloadOption.value = res;
  419. console.log(res);
  420. });
  421. }, 1000);
  422. }
  423. });
  424. } else {
  425. canDownload.value = false;
  426. window.open(res.downloadUrl);
  427. }
  428. });
  429. }
  430. function handleEdit(record: Recordable) {
  431. window.open(record.thumbEdit + '&&token=' + token.value);
  432. }
  433. async function handleGenerate(record: Recordable) {
  434. console.log('record', record);
  435. let data = await sceneDetail({ id: record.id });
  436. console.log('data', data);
  437. let { buildObjStatus } = data;
  438. let toastText =
  439. buildObjStatus == 2
  440. ? 'Mesh场景正在计算中,请耐心等待'
  441. : buildObjStatus == 1
  442. ? '重新生成Mesh场景将覆盖现有场景信息,计算过程中Mesh场景无法打开,确定要重新生成吗?'
  443. : '生成obj需要较长时间,请耐心等待';
  444. // if (data.code === 200) {
  445. createConfirm({
  446. iconType: 'warning',
  447. title: () => h('span', '生成 obj'),
  448. content: () => h('span', toastText),
  449. onOk: async () => {
  450. if (buildObjStatus !== 2) {
  451. await buildSceneObj({ id: record.id, sceneNum: record.num });
  452. }
  453. createMessage.success(t('common.optSuccess'));
  454. reload();
  455. },
  456. });
  457. // } else {
  458. // createMessage.error(t(`apiCode.errCode${data.code}`));
  459. // }
  460. }
  461. function afterClose() {
  462. clearInterval(timer.value);
  463. timer.value = null;
  464. }
  465. function handleReset(record: Recordable) {
  466. console.log('handleReset', record);
  467. rebuildScene({ num: record.num }).then(() => {
  468. message.success({
  469. content: '操作成功',
  470. });
  471. reload();
  472. });
  473. }
  474. function getTypeCheckPerm(val) {
  475. let myType = tableType.value;
  476. return getCheckPerm(val) || getCheckPerm(`${val}-${myType}`);
  477. }
  478. function handlegotoEdit(record) {
  479. window.open(`/mix3d/index.html?lang=${locale.value}#/homes/${record.caseId}`);
  480. // let url = record.webSite.replace('smg', 'epg');
  481. // if (!record.editAuthTime || (record.editAuthTime && dayjs() < dayjs(record.editAuthTime))) {
  482. // window.open(url);
  483. // } else {
  484. // createMessage.error('编辑权限已过期');
  485. // }
  486. }
  487. function handlePowers(record: Recordable) {
  488. openPowersModal(true, {
  489. ...record,
  490. tableType: tableType.value,
  491. });
  492. }
  493. onMounted(() => {
  494. });
  495. return {
  496. registerTable,
  497. registerPowersModal,
  498. handleDelete,
  499. handleCopy,
  500. handleMove,
  501. handleDownload,
  502. handleReset,
  503. tableType,
  504. loading,
  505. changeTable,
  506. t,
  507. openDownModal,
  508. registerDownModal,
  509. registerMoveModal,
  510. registerAddModal,
  511. afterClose,
  512. timer,
  513. canDownload,
  514. downloadOption,
  515. cancelDownload,
  516. handleGenerate,
  517. getTypeCheckPerm,
  518. handlegotoEdit,
  519. handlePowers,
  520. userInfo,
  521. handleAdd,
  522. reload,
  523. getCheckPerm,
  524. createConfirmDownload,
  525. };
  526. },
  527. });
  528. </script>
  529. <style lang="less" scoped>
  530. .scren {
  531. .noScene {
  532. position: absolute;
  533. top: calc(50% - 126px);
  534. width: 100%;
  535. text-align: center;
  536. &-content {
  537. font-size: 14px;
  538. color: rgba(0, 0, 0, 0.85);
  539. line-height: 22px;
  540. font-style: normal;
  541. text-transform: none;
  542. .codelist {
  543. margin-top: 36px;
  544. width: 424px;
  545. height: auto;
  546. display: flex;
  547. justify-content: space-between;
  548. margin: 0 auto;
  549. .codediv {
  550. font-weight: 400;
  551. font-size: 17px;
  552. color: rgba(0, 0, 0, 0.85);
  553. line-height: 22px;
  554. height: auto;
  555. padding: 24px;
  556. background: #fff;
  557. text-align: center;
  558. .codetext {
  559. margin-top: 10px;
  560. }
  561. }
  562. }
  563. }
  564. }
  565. }
  566. // .tableHeader {
  567. // height: 50px;
  568. // display: flex;
  569. // align-items: center;
  570. // .item {
  571. // font-size: 14px;
  572. // color: #666;
  573. // margin-right: 10px;
  574. // cursor: pointer;
  575. // &.active {
  576. // font-weight: bold;
  577. // color: #222;
  578. // }
  579. // }
  580. // }
  581. .desc-wrap-BasicTable {
  582. background-color: #f0f2f5;
  583. .vben-basic-table-form-container {
  584. padding: 0;
  585. }
  586. }
  587. </style>