list.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <template>
  2. <PageWrapper contentBackground>
  3. <!-- <template #footer>
  4. <a-tabs v-model:activeKey="tableType" @change="changeTable">
  5. <a-tab-pane :key="0" :tab="t('routes.scene.tableType.0')" />
  6. <a-tab-pane :key="1" :tab="t('routes.scene.tableType.1')" />
  7. <a-tab-pane :key="2" :tab="t('routes.scene.tableType.2')" />
  8. <a-tab-pane :key="5" :tab="t('routes.scene.tableType.5')" />
  9. <a-tab-pane :key="6" :tab="t('routes.scene.tableType.6')" />
  10. <a-tab-pane :key="7" :tab="t('routes.scene.tableType.7')" />
  11. </a-tabs></template
  12. > -->
  13. <div class="desc-wrap-BasicTable">
  14. <BasicTable @register="registerTable">
  15. <template #toolbar>
  16. <a-button type="primary" @click="handleMove"> 同步场景</a-button>
  17. </template>
  18. <template #href="{ record }">
  19. <a v-if="record.title && record.webSite" target="_blank" :href="record.webSite">{{
  20. record.title
  21. }}</a>
  22. <span v-else-if="record.title">{{ record.title }}</span>
  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,
  32. onClick: handleSee.bind(null, record),
  33. },
  34. {
  35. label: '删除',
  36. color: 'error',
  37. onClick: handleDelete.bind(null, record),
  38. },
  39. ]"
  40. />
  41. </template>
  42. </BasicTable>
  43. </div>
  44. <DownLoadModal
  45. :downloadOption="downloadOption"
  46. @cancel="afterClose"
  47. @register="registerDownModal"
  48. @update="reload"
  49. :cancelText="t('routes.scene.canlenDown')"
  50. :okText="t('routes.scene.down')"
  51. @cancelDownload="cancelDownload"
  52. :okButtonProps="{ disabled: canDownload }"
  53. />
  54. <!-- <MoveModal @register="registerMoveModal" /> -->
  55. <SyncModal @register="registerMoveModal" @update="reload" />
  56. </PageWrapper>
  57. </template>
  58. <script lang="ts">
  59. import { defineComponent, h, reactive, toRefs, ref } from 'vue';
  60. import {
  61. BasicTable,
  62. useTable,
  63. TableAction,
  64. BasicColumn,
  65. TableImg,
  66. FormProps,
  67. } from '/@/components/Table';
  68. import { PageWrapper } from '/@/components/Page';
  69. import DownLoadModal from './modal/DownLoadModal.vue';
  70. import MoveModal from './modal/MoveModal.vue';
  71. import SyncModal from './modal/SyncModal.vue';
  72. import { Time } from '/@/components/Time';
  73. import { Descriptions, Tabs, Progress } from 'ant-design-vue';
  74. import { useI18n } from '/@/hooks/web/useI18n';
  75. import { useMessage } from '/@/hooks/web/useMessage';
  76. import { useModal } from '/@/components/Modal';
  77. import {
  78. operateSceneList,
  79. sceneMove,
  80. sceneDelete,
  81. sceneReset,
  82. caseDelApi,
  83. sceneDownload,
  84. checkDownLoad,
  85. downloadProcess,
  86. sceneCopy,
  87. rebuildScene,
  88. } from '/@/api/operate';
  89. import { message } from 'ant-design-vue';
  90. import { usePermissionStore } from '/@/store/modules/permission';
  91. import { func } from 'vue-types';
  92. export default defineComponent({
  93. components: {
  94. DownLoadModal,
  95. MoveModal,
  96. BasicTable,
  97. TableAction,
  98. PageWrapper,
  99. SyncModal,
  100. [Descriptions.name]: Descriptions,
  101. [Descriptions.Item.name]: Descriptions.Item,
  102. [Tabs.name]: Tabs,
  103. [Tabs.TabPane.name]: Tabs.TabPane,
  104. },
  105. setup() {
  106. const { t } = useI18n();
  107. const { createMessage, createConfirm } = useMessage();
  108. const permissionStore = usePermissionStore();
  109. const { getCheckPerm } = permissionStore;
  110. const tableType = ref<Recordable>(0); //0看看 、1看见、2深时
  111. const columns: BasicColumn[] = [
  112. {
  113. title: t('routes.scene.sceneName'),
  114. dataIndex: 'sceneName',
  115. slots: { customRender: 'href' },
  116. width: 300,
  117. },
  118. {
  119. title: t('routes.scene.num'),
  120. dataIndex: 'num',
  121. ellipsis: true,
  122. width: 180,
  123. },
  124. {
  125. title: t('routes.scene.createTime'),
  126. dataIndex: 'createTime',
  127. width: 180,
  128. customRender: ({ record }) => {
  129. return (
  130. record.createTime &&
  131. h(Time, {
  132. value: record.createTime,
  133. mode: 'datetime',
  134. })
  135. );
  136. },
  137. },
  138. {
  139. title: t('routes.scene.amount'),
  140. dataIndex: 'amount',
  141. width: 210,
  142. customRender: ({ record }) => {
  143. return (
  144. (record.algorithmTime &&
  145. h(Time, {
  146. value: record.algorithmTime,
  147. mode: 'datetime',
  148. })) ||
  149. '-'
  150. );
  151. },
  152. },
  153. // {
  154. // title: t('routes.scene.snCode'),
  155. // dataIndex: 'snCode',
  156. // width: 180,
  157. // },
  158. // {
  159. // title: t('routes.scene.sceneSize'),
  160. // dataIndex: 'sceneSize',
  161. // width: 120,
  162. // customRender: ({ record }) => {
  163. // return record.sceneSize && record.sceneSize != 0
  164. // ? h('span', { class: 'sceneSize' }, Math.ceil(record.sceneSize / 1024 / 1024) + 'M')
  165. // : '-';
  166. // },
  167. // },
  168. // {
  169. // title: t('routes.scene.isCopy'),
  170. // dataIndex: 'isCopy',
  171. // width: 130,
  172. // customRender: ({ record }) => {
  173. // return record.isCopy ? t('common.yes') : t('common.no');
  174. // },
  175. // },
  176. // {
  177. // title: t('routes.scene.copyTime'),
  178. // dataIndex: 'copyTime',
  179. // width: 140,
  180. // customRender: ({ record }) => {
  181. // return (
  182. // (record.copyTime &&
  183. // h(Time, {
  184. // value: record.copyTime,
  185. // mode: 'datetime',
  186. // })) ||
  187. // '-'
  188. // );
  189. // },
  190. // },
  191. // {
  192. // title: t('routes.scene.userName'),
  193. // dataIndex: 'userName',
  194. // width: 140,
  195. // },
  196. // {
  197. // title: t('routes.scene.viewCount'),
  198. // dataIndex: 'viewCount',
  199. // width: 80,
  200. // },
  201. {
  202. title: t('routes.scene.status'),
  203. dataIndex: 'status',
  204. width: 110,
  205. customRender: ({ record }) => {
  206. let str;
  207. switch (record.status - 0) {
  208. case 0:
  209. str = t('routes.scene.statusType.0');
  210. break;
  211. case 1:
  212. str = t('routes.scene.statusType.1');
  213. break;
  214. case -2:
  215. str = t('routes.scene.statusType.-2');
  216. break;
  217. case -1:
  218. str = t('routes.scene.statusType.-1');
  219. break;
  220. }
  221. return record.payStatus == -2 ? t('routes.scene.statusType.-3') : str;
  222. },
  223. },
  224. {
  225. title: t('common.operating'),
  226. dataIndex: 'action',
  227. slots: { customRender: 'action' },
  228. ifShow: true,
  229. fixed: 'right',
  230. flag: 'ACTION',
  231. width: 180,
  232. },
  233. ];
  234. const searchForm: Partial<FormProps> = {
  235. labelWidth: 80,
  236. schemas: [
  237. {
  238. field: 'sceneName',
  239. label: t('routes.scene.sceneName'),
  240. component: 'Input',
  241. componentProps: {
  242. maxLength: 100,
  243. },
  244. colProps: {
  245. xl: 5,
  246. xxl: 5,
  247. },
  248. },
  249. {
  250. label: t('routes.scene.num'),
  251. field: 'num',
  252. labelWidth: 60,
  253. component: 'Input',
  254. componentProps: {
  255. maxLength: 100,
  256. },
  257. colProps: {
  258. xl: 5,
  259. xxl: 5,
  260. },
  261. },
  262. {
  263. field: 'snCode',
  264. label: t('routes.scene.snCode'),
  265. component: 'Input',
  266. labelWidth: 50,
  267. componentProps: {
  268. maxLength: 100,
  269. },
  270. colProps: {
  271. xl: 4,
  272. xxl: 4,
  273. },
  274. },
  275. {
  276. field: 'userName',
  277. label: t('routes.scene.userName'),
  278. component: 'Input',
  279. componentProps: {
  280. maxLength: 100,
  281. },
  282. colProps: {
  283. xl: 4,
  284. xxl: 4,
  285. },
  286. },
  287. ],
  288. };
  289. function cancelDownload() {
  290. downloadOption.value = {};
  291. }
  292. const [registerDownModal, { openModal: openDownModal }] = useModal();
  293. const [registerMoveModal, { openModal: openMoveModal }] = useModal();
  294. const [registerTable, { reload }] = useTable({
  295. api: operateSceneList,
  296. // title: `场景列表`,
  297. // titleHelpMessage: ['已启用expandRowByClick', '已启用stopButtonPropagation'],
  298. columns: columns,
  299. searchInfo: { type: tableType },
  300. useSearchForm: true,
  301. // rowSelection: { type: 'checkbox' },
  302. formConfig: searchForm,
  303. showTableSetting: true,
  304. showIndexColumn: false,
  305. rowKey: 'num',
  306. fetchSetting: {
  307. pageField: 'pageNum',
  308. sizeField: 'pageSize',
  309. listField: 'list',
  310. totalField: 'total',
  311. },
  312. canResize: false,
  313. });
  314. function changeTable(val: string) {
  315. tableType.value = val;
  316. reload();
  317. }
  318. async function handleCopy(record: Recordable) {
  319. createConfirm({
  320. title: t('routes.scene.copyTipsTitle'),
  321. content: t('routes.scene.copyTipsText'),
  322. onOk: async () => {
  323. sceneCopy({ num: record.num }).then(() => {
  324. message.success({
  325. content: t('routes.scene.copySccuse'),
  326. });
  327. reload();
  328. });
  329. },
  330. });
  331. }
  332. async function handleDelete(record: Recordable) {
  333. console.log('handleDelete', record);
  334. createConfirm({
  335. iconType: 'warning',
  336. title: '警告',
  337. content: `此操作将对${record.title}进行删除, 是否继续?`,
  338. onOk: async () => {
  339. await caseDelApi([record.id]);
  340. reload();
  341. },
  342. });
  343. }
  344. async function handleMove() {
  345. openMoveModal(true, {});
  346. }
  347. function handleSee(record) {
  348. window.open(record.webSite);
  349. }
  350. let timer: null = ref(null);
  351. const downloadOption = ref<Object>({});
  352. const canDownload = ref<boolean>(true);
  353. function handleDownload(record: Recordable) {
  354. console.log('handleDownload', record, canDownload.value);
  355. canDownload.value = true;
  356. checkDownLoad({ num: record.num }).then((res) => {
  357. console.log(res);
  358. if (res.downloadStatus != 3) {
  359. // 未下载过,需要打包
  360. sceneDownload({ num: record.num }).then((res) => {
  361. console.log(res);
  362. openDownModal(true, {
  363. ...record,
  364. });
  365. if (res.downloadStatus == 1) {
  366. if (timer.value) {
  367. afterClose();
  368. }
  369. timer.value = setInterval(() => {
  370. downloadProcess({ num: record.num }).then((res) => {
  371. if (res.status == '1003') {
  372. createMessage.error(t('routes.scene.downErr'));
  373. afterClose();
  374. return;
  375. }
  376. if (res.percent >= 100) {
  377. canDownload.value = false;
  378. afterClose();
  379. }
  380. downloadOption.value = res;
  381. console.log(res);
  382. });
  383. }, 1000);
  384. }
  385. });
  386. } else {
  387. canDownload.value = false;
  388. window.open(res.downloadUrl);
  389. }
  390. });
  391. }
  392. function afterClose() {
  393. clearInterval(timer.value);
  394. timer.value = null;
  395. }
  396. function handleReset(record: Recordable) {
  397. createConfirm({
  398. title: t('routes.scene.reset'),
  399. content: t('routes.scene.resetTips'),
  400. onOk: async () => {
  401. rebuildScene({ num: record.num }).then(() => {
  402. message.success({
  403. content: t('common.optSuccess'),
  404. });
  405. reload();
  406. });
  407. },
  408. });
  409. }
  410. function getTypeCheckPerm(val) {
  411. let myType = tableType.value;
  412. return getCheckPerm(val) || getCheckPerm(`${val}-${myType}`);
  413. }
  414. return {
  415. registerTable,
  416. handleDelete,
  417. handleCopy,
  418. handleSee,
  419. handleMove,
  420. handleDownload,
  421. handleReset,
  422. tableType,
  423. changeTable,
  424. reload,
  425. t,
  426. openDownModal,
  427. registerDownModal,
  428. registerMoveModal,
  429. afterClose,
  430. timer,
  431. canDownload,
  432. downloadOption,
  433. cancelDownload,
  434. getTypeCheckPerm,
  435. };
  436. },
  437. });
  438. </script>
  439. <style lang="less" scoped>
  440. // .tableHeader {
  441. // height: 50px;
  442. // display: flex;
  443. // align-items: center;
  444. // .item {
  445. // font-size: 14px;
  446. // color: #666;
  447. // margin-right: 10px;
  448. // cursor: pointer;
  449. // &.active {
  450. // font-weight: bold;
  451. // color: #222;
  452. // }
  453. // }
  454. // }
  455. .desc-wrap-BasicTable {
  456. background-color: #f0f2f5;
  457. .vben-basic-table-form-container {
  458. padding: 0;
  459. }
  460. }
  461. </style>