PrintCard.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <template>
  2. <Navbar title="卡片打印" :is-go-back="true" />
  3. <div class="printDiv">
  4. <div>
  5. <span style="color: red"> * </span>
  6. <label>导入批次:</label>
  7. <a-select
  8. v-model:value="queryParams.batchNo"
  9. show-search
  10. class="commonStyle"
  11. :options="batchNos.map((item) => ({ value: item.label }))"
  12. @change="searchPrintInfo"
  13. />
  14. <label>保管人员:</label>
  15. <a-select
  16. v-model:value="queryParams.depositoryUser"
  17. show-search
  18. class="commonStyle"
  19. :options="depositoryUsers.map((item) => ({ value: item.label }))"
  20. @change="searchPrintInfo"
  21. />
  22. <label>打印状态:</label>
  23. <a-select
  24. v-model:value="status"
  25. show-search
  26. class="commonStyle"
  27. :options="
  28. statusOptions.map((item) => ({
  29. value: `${item.value}-${item.label}`,
  30. label: item.label,
  31. }))
  32. "
  33. @change="searchPrintInfo"
  34. />
  35. </div>
  36. <div style="margin: 8px 0 0 9px">
  37. <label>公司名称:</label>
  38. <a-select
  39. v-model:value="queryParams.clientName"
  40. show-search
  41. class="commonStyle"
  42. :options="clientNames.map((item) => ({ value: item.label }))"
  43. @change="searchPrintInfo"
  44. />
  45. <label>所属部门:</label>
  46. <a-select
  47. v-model:value="queryParams.organizationName"
  48. show-search
  49. class="commonStyle"
  50. :options="organizationNames.map((item) => ({ value: item.label }))"
  51. @change="searchPrintInfo"
  52. />
  53. <label>成本中心:</label>
  54. <a-select
  55. v-model:value="queryParams.costCenterName"
  56. show-search
  57. class="commonStyle"
  58. :options="costCenterNames.map((item) => ({ value: item.label }))"
  59. @change="searchPrintInfo"
  60. />
  61. <a-button type="primary" @click="searchPrintInfo">查询</a-button>
  62. </div>
  63. <div style="margin: 8px 0 0 9px">
  64. <label>打印模板:</label>
  65. <a-select
  66. v-model:value="printTemplate"
  67. show-search
  68. class="commonStyle"
  69. :options="
  70. templateNames.map((item) => ({
  71. value: `${item.id}-${item.name}`,
  72. label: item.name,
  73. }))
  74. "
  75. />
  76. <a-button
  77. type="dashed"
  78. style="margin-right: 16px"
  79. @click="imageVisible = true"
  80. >
  81. 打印预览
  82. </a-button>
  83. <a-button type="dashed" style="margin-right: 16px" @click="showPrintInfo">
  84. 打印
  85. </a-button>
  86. </div>
  87. <a-divider />
  88. <CommonTable
  89. :total="total"
  90. :columns="columns"
  91. :is-loading="isLoading"
  92. :is-select="isSelect"
  93. :data-source="dataSource"
  94. @select-column="selectColumn"
  95. @page-params="getPageParams"
  96. >
  97. <template #bodyCell="{ column, record }">
  98. <template v-if="column.key === 'imageUrl'">
  99. <a-image :width="100" :height="50" :src="record.imageUrl" />
  100. </template>
  101. </template>
  102. </CommonTable>
  103. <a-modal
  104. v-model:visible="printVisible"
  105. title="包装信息"
  106. ok-text="确认"
  107. cancel-text="取消"
  108. @ok="printCard"
  109. >
  110. <label>包装批号:</label>
  111. <a-input
  112. id="displayName"
  113. v-model:value="packageBatchNo"
  114. :disabled="true"
  115. />
  116. <label>上次的批号:</label>
  117. <a-input
  118. id="displayName"
  119. v-model:value="lastPackageBatchNo"
  120. :disabled="true"
  121. />
  122. <label>包装名称:</label>
  123. <a-input id="displayName" v-model:value="packageName" :disabled="true" />
  124. <label>上次的名称:</label>
  125. <a-input
  126. id="displayName"
  127. v-model:value="lastPackageName"
  128. :disabled="true"
  129. />
  130. <div class="operationBtn">
  131. <a-button type="dashed" style="width: 240px" @click="lastTime">
  132. 同上一次
  133. </a-button>
  134. <a-button
  135. type="dashed"
  136. style="width: 240px; margin-left: 4px"
  137. @click="createNew"
  138. >
  139. 生成新的
  140. </a-button>
  141. </div>
  142. </a-modal>
  143. <a-modal
  144. v-model:visible="imageVisible"
  145. title="打印预览"
  146. ok-text="确认"
  147. cancel-text="取消"
  148. :body-style="bodyStyle"
  149. @ok="imageVisible = false"
  150. >
  151. <a-image
  152. :preview="{ visible: false }"
  153. :width="200"
  154. class="image"
  155. :src="imageUrls[0]"
  156. @click="visible = true"
  157. />
  158. <div style="display: none">
  159. <a-image-preview-group
  160. :preview="{ visible, onVisibleChange: (vis) => (visible = vis) }"
  161. >
  162. <a-image v-for="item in imageUrls" :key="item" :src="item" />
  163. </a-image-preview-group>
  164. </div>
  165. </a-modal>
  166. <div ref="hua" style="float: left; z-index: -999" />
  167. <Loading v-if="globalLoading" />
  168. </div>
  169. </template>
  170. <script setup>
  171. import CommonTable from './CommonTable.vue';
  172. import Common from '../common/Common';
  173. import { message } from 'ant-design-vue';
  174. import { ref, reactive, onMounted } from 'vue';
  175. import {
  176. columns,
  177. dateConvert,
  178. multipleImageUpload,
  179. getTemplate,
  180. } from './config';
  181. import CreateJPEG from '../common/X6';
  182. import { SqlApi, Notify } from 'pc-component-v3';
  183. import { getImageSrc } from '../common/image-src';
  184. const imageUrls = reactive([
  185. 'https://gw.alipayobjects.com/zos/antfincdn/LlvErxo8H9/photo-1503185912284-5271ff81b9a8.webp',
  186. 'https://gw.alipayobjects.com/zos/antfincdn/cV16ZqzMjW/photo-1473091540282-9b846e7965e3.webp',
  187. 'https://gw.alipayobjects.com/zos/antfincdn/x43I27A55%26/photo-1438109491414-7198515b166b.webp',
  188. ]);
  189. const total = ref(0);
  190. const isSelect = ref(true);
  191. const isLoading = ref(false);
  192. const selectedRows = ref([]);
  193. const dataSource = ref([]);
  194. const printVisible = ref(false);
  195. const imageVisible = ref(false);
  196. const visible = ref(false);
  197. const globalLoading = ref(false);
  198. const bodyStyle = {
  199. display: 'flex',
  200. justifyContent: 'center',
  201. };
  202. const status = ref('');
  203. const batchNos = ref([]);
  204. const clientNames = ref([]);
  205. const depositoryUsers = ref([]);
  206. const costCenterNames = ref([]);
  207. const organizationNames = ref([]);
  208. const statusOptions = ref([
  209. {
  210. value: '',
  211. label: ' ',
  212. },
  213. {
  214. value: 'To_Be_Printed',
  215. label: '待打印',
  216. },
  217. {
  218. value: 'Printing',
  219. label: '打印中',
  220. },
  221. {
  222. value: 'Printed',
  223. label: '已打印',
  224. },
  225. ]);
  226. const queryParams = reactive({
  227. batchNo: '',
  228. depositoryUser: '',
  229. labelPrintType: '',
  230. clientName: '',
  231. organizationName: '',
  232. costCenterName: '',
  233. });
  234. const pager = reactive({
  235. start: 0,
  236. length: 20,
  237. });
  238. const templateId = ref('');
  239. const allTemplate = ref([]);
  240. const templateData = ref([]);
  241. const lastBatchNo = ref('');
  242. const printTemplate = ref('');
  243. const templateNames = ref([]);
  244. const packageBatchNo = ref('');
  245. const lastPackageBatchNo = ref('');
  246. const packageName = ref('');
  247. const lastPackageName = ref('');
  248. const newPackageName = ref('');
  249. const hua = ref(null);
  250. let getImageData;
  251. // 获取分页
  252. const getPageParams = (start, length) => {
  253. pager.start = (start - 1) * length;
  254. pager.length = length;
  255. searchPrintInfo();
  256. };
  257. // 查询信息
  258. const searchPrintInfo = () => {
  259. isLoading.value = true;
  260. if (status.value !== undefined) {
  261. queryParams.labelPrintType = status.value.slice(
  262. 0,
  263. status.value.indexOf('-'),
  264. );
  265. }
  266. let params = { ...queryParams, ...pager };
  267. if (queryParams.batchNo !== '') {
  268. SqlApi.execute('20230613_140456', params).then(
  269. successData => {
  270. const { lines, errorMessage, errorCode } = successData;
  271. if (errorCode == 0) {
  272. total.value = successData.total;
  273. lines.forEach(item => {
  274. item.key = item.id;
  275. });
  276. dataSource.value = lines;
  277. isLoading.value = false;
  278. } else {
  279. Notify.error('查询异常', errorMessage, true);
  280. }
  281. isLoading.value = false;
  282. },
  283. errorData => {
  284. Common.processException(errorData);
  285. isLoading.value = false;
  286. },
  287. );
  288. } else {
  289. message.error('请选择导入批次');
  290. status.value = '';
  291. dataSource.value = [];
  292. queryParams.clientName = '';
  293. queryParams.costCenterName = '';
  294. queryParams.depositoryUser = '';
  295. queryParams.organizationName = '';
  296. isLoading.value = false;
  297. }
  298. };
  299. // 获取所选项的数据
  300. const selectColumn = rows => {
  301. selectedRows.value = rows;
  302. console.log('onSelectChange', selectedRows.value);
  303. };
  304. // 展开打印框
  305. const showPrintInfo = () => {
  306. if (printTemplate.value !== '') {
  307. printVisible.value = true;
  308. const nameArr = [];
  309. const obj = JSON.parse(JSON.stringify(queryParams));
  310. delete obj.labelPrintType;
  311. for (let key in obj) {
  312. if (obj[key] !== '') nameArr.push(obj[key]);
  313. }
  314. packageName.value = nameArr.join('-');
  315. newPackageName.value = nameArr.join('-');
  316. packageBatchNo.value = dateConvert(new Date());
  317. } else {
  318. message.error('请选择打印模板');
  319. }
  320. };
  321. // 同上一次包装信息
  322. const lastTime = () => {
  323. if (lastPackageName.value == null && lastPackageBatchNo.value == null) {
  324. message.info('没有上次的包装信息');
  325. } else {
  326. packageName.value = lastPackageName.value;
  327. packageBatchNo.value = lastPackageBatchNo.value;
  328. }
  329. };
  330. // const base64toFile = (url, imageName) => {
  331. // const arr = url.split(',');
  332. // const mime = arr[0].match(/.*?:(.*?);/)[1];
  333. // const suffix = mime.split('/')[1];
  334. // const bstr = window.atob(arr[1]);
  335. // let n = bstr.length;
  336. // const u8arr = new Uint8Array(n);
  337. // while (n--) {
  338. // u8arr[n] = bstr.charCodeAt(n);
  339. // }
  340. // return new File([u8arr], `${imageName}.${suffix}`, {
  341. // type: 'multipart/form-data',
  342. // });
  343. // };
  344. // 生产新的包装信息
  345. const createNew = () => {
  346. packageBatchNo.value = dateConvert(new Date());
  347. packageName.value = newPackageName.value;
  348. };
  349. // 确认打印
  350. const printCard = () => {
  351. globalLoading.value = true;
  352. const formData = new FormData();
  353. templateId.value = printTemplate.value.slice(
  354. 0,
  355. printTemplate.value.indexOf('-'),
  356. );
  357. allTemplate.value.forEach(item => {
  358. if (item.id == templateId.value) {
  359. templateData.value = JSON.stringify(item.contentX6);
  360. }
  361. });
  362. selectedRows.value.forEach(async item => {
  363. item.number = item.assetNo;
  364. item.name = item.assetName;
  365. item.unit = item.depositoryUser;
  366. item.keeper = item.organizationName;
  367. item.EPC = item.depositoryUser;
  368. item.BarCode =
  369. 'https://rfid.fa.sjtu.edu.cn/c/5C5CFA24F72542B8910F247BA014DDBB';
  370. let base64 = await getImageData(item, templateData.value);
  371. console.log('图片base64:',base64);
  372. });
  373. formData.append('customerPrintTemplateId', templateId.value);
  374. formData.append('packageBatchNo', packageBatchNo.value);
  375. formData.append('packageName', packageName.value);
  376. // formData.append('file', file);
  377. multipleImageUpload(formData).then(
  378. successData => {
  379. if (successData.success === true) {
  380. message.success('资产生产图片成功');
  381. } else {
  382. message.error('资产生产图片失败');
  383. }
  384. globalLoading.value = false;
  385. printVisible.value = false;
  386. searchPrintInfo();
  387. },
  388. errorData => {
  389. Common.processException(errorData);
  390. globalLoading.value = false;
  391. printVisible.value = false;
  392. },
  393. );
  394. };
  395. onMounted(() => {
  396. init();
  397. getImageData = CreateJPEG(hua.value);
  398. });
  399. // 封装通用sqlApi请求函数
  400. const commonSqlApi = (url, data) => {
  401. SqlApi.execute(url).then(
  402. successData => {
  403. if (successData.errorCode == 0) {
  404. if (successData.lines !== null) {
  405. data.value = successData.lines.map(item => {
  406. return (item = { label: item });
  407. });
  408. data.value.unshift({ label: '' });
  409. }
  410. } else {
  411. Notify.error('查询信息异常', successData.errorMessage, true);
  412. }
  413. },
  414. errorData => {
  415. Common.processException(errorData);
  416. },
  417. );
  418. };
  419. // 初始化数据
  420. const init = () => {
  421. getTemplate().then(res => {
  422. allTemplate.value = res.datas;
  423. console.log(res);
  424. });
  425. commonSqlApi('20230613_192444', depositoryUsers); // 查询保管人
  426. commonSqlApi('20230613_193808', clientNames); // 查询公司
  427. commonSqlApi('20230613_194108', organizationNames); // 查询部门
  428. commonSqlApi('20230613_194557', costCenterNames); // 查询成本中心
  429. // 查询批次号
  430. SqlApi.execute('20230613_134214').then(
  431. successData => {
  432. if (successData.errorCode == 0) {
  433. if (successData.lines !== null) {
  434. batchNos.value = successData.lines.map(item => {
  435. return (item = { label: item });
  436. });
  437. }
  438. } else {
  439. Notify.error('查询导入批次异常', successData.errorMessage, true);
  440. }
  441. },
  442. errorData => {
  443. Common.processException(errorData);
  444. },
  445. );
  446. // 查询模板
  447. SqlApi.execute('20230613_135541').then(
  448. successData => {
  449. if (successData.errorCode == 0) {
  450. if (successData.label !== null) {
  451. templateNames.value = successData.lines;
  452. }
  453. } else {
  454. Notify.error('获取包装信息异常', successData.errorMessage, true);
  455. }
  456. },
  457. errorData => {
  458. Common.processException(errorData);
  459. },
  460. );
  461. // 获取上一次的包装信息
  462. SqlApi.execute('20230613_194855').then(
  463. successData => {
  464. if (successData.errorCode == 0) {
  465. const { packageName, packageBatchNo } = successData.lines;
  466. lastPackageName.value = packageName;
  467. lastPackageBatchNo.value = packageBatchNo;
  468. } else {
  469. Notify.error('获取包装信息异常', successData.errorMessage, true);
  470. }
  471. },
  472. errorData => {
  473. Common.processException(errorData);
  474. },
  475. );
  476. };
  477. </script>
  478. <style scoped>
  479. .printDiv {
  480. padding: 24px;
  481. }
  482. .commonStyle {
  483. margin-right: 16px;
  484. width: 160px;
  485. }
  486. .search,
  487. .operationBtn {
  488. margin-top: 8px;
  489. }
  490. .operationBtn {
  491. display: flex;
  492. justify-content: space-between;
  493. }
  494. #displayName:disabled {
  495. background: white;
  496. color: black;
  497. }
  498. </style>