list.vue 18 KB

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