index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. <template>
  2. <el-card class="box-card">
  3. <byTable
  4. :source="sourceList.data"
  5. :pagination="sourceList.pagination"
  6. :config="config"
  7. :loading="loading"
  8. :searchConfig="searchConfig"
  9. highlight-current-row
  10. :table-events="{
  11. select: selectRow,
  12. 'select-all': selectRow,
  13. }"
  14. :action-list="[
  15. {
  16. text: '打印生产面单',
  17. action: () => clickSelectPrint(),
  18. },
  19. {
  20. text: '合并工单',
  21. disabled: selectData.length < 2,
  22. action: () => clickMerge(),
  23. },
  24. ]"
  25. @get-list="getList"
  26. @clickReset="clickReset">
  27. <template #code="{ item }">
  28. <div>
  29. <a style="color: #409eff; cursor: pointer; word-break: break-all" @click="clickCode(item)">{{ item.code }}</a>
  30. </div>
  31. </template>
  32. <template #address="{ item }">
  33. <div>{{ item.province }}, {{ item.city }}, {{ item.county }}, {{ item.detailedAddress }}</div>
  34. </template>
  35. </byTable>
  36. <div style="display: none">
  37. <div style="width: 250px" id="printMe">
  38. <div v-for="(item, index) in QRcodeList" :key="index">
  39. <div style="height: 442px; padding-top: 2px; overflow: hidden; position: relative">
  40. <div style="border-bottom: 1px solid #000; display: flex; align-items: center; justify-content: center">
  41. <CycleBarcode :value="item.orderWlnCode || item.orderCode" :index="index" style="max-width: 100%"></CycleBarcode>
  42. </div>
  43. <div style="display: flex; align-items: center; justify-content: center">
  44. <div style="width: 150px; height: 150px; margin-top: 8px" :id="'print' + index" :ref="'print' + index">
  45. <img src="" alt="" style="vertical-align: middle; height: 100%; width: 100%" />
  46. </div>
  47. </div>
  48. <div style="text-align: center; font-size: 18px; font-weight: 700; padding: 4px 0; border-bottom: 1px solid #000">{{ item.completeTime }}</div>
  49. <div style="word-break: break-all; padding: 2px">SKU品号:{{ item.skuSpecCode }}</div>
  50. <div style="word-break: break-all; padding: 2px">SKU品名:{{ item.skuSpecName }}</div>
  51. <div style="word-break: break-all; padding: 2px">BOM品号:{{ item.bomSpecCode }}</div>
  52. <div style="word-break: break-all; padding: 2px">BOM品名:{{ item.bomSpecName }}</div>
  53. <div v-if="item.orderWlnCode" class="one">
  54. <div class="two">
  55. <div class="three">万里牛</div>
  56. </div>
  57. </div>
  58. </div>
  59. <div style="page-break-after: always"></div>
  60. </div>
  61. </div>
  62. <el-button type="primary" style="display: none" v-print="printObj" id="printBtnMini"></el-button>
  63. </div>
  64. </el-card>
  65. </template>
  66. <script setup>
  67. import byTable from "/src/components/byTable/index";
  68. import QRCode from "qrcodejs2-fix";
  69. import { ElMessage, ElMessageBox } from "element-plus";
  70. import CycleBarcode from "/src/components/CycleBarcode";
  71. const { proxy } = getCurrentInstance();
  72. const statusList = ref([
  73. {
  74. dictKey: 0,
  75. dictValue: "待投产",
  76. },
  77. {
  78. dictKey: 1,
  79. dictValue: "已扫描",
  80. },
  81. {
  82. dictKey: 2,
  83. dictValue: "生产中",
  84. },
  85. {
  86. dictKey: 3,
  87. dictValue: "生产完成",
  88. },
  89. {
  90. dictKey: 4,
  91. dictValue: "生产异常",
  92. },
  93. {
  94. dictKey: 5,
  95. dictValue: "重新排单",
  96. },
  97. ]);
  98. const sourceList = ref({
  99. data: [],
  100. pagination: {
  101. total: 0,
  102. pageNum: 1,
  103. pageSize: 10,
  104. orderCode: "",
  105. orderWlnCode: "",
  106. skuSpecCode: "",
  107. skuSpecName: "",
  108. bomSpecCode: "",
  109. bomSpecName: "",
  110. productionWorkOrderCode: "",
  111. status: [0, 4],
  112. },
  113. });
  114. const loading = ref(false);
  115. const searchConfig = computed(() => {
  116. return [
  117. {
  118. type: "input",
  119. prop: "orderCode",
  120. label: "订单号",
  121. },
  122. {
  123. type: "input",
  124. prop: "orderWlnCode",
  125. label: "E10单号",
  126. },
  127. {
  128. type: "input",
  129. prop: "skuSpecCode",
  130. label: "SKU品号",
  131. },
  132. {
  133. type: "input",
  134. prop: "skuSpecName",
  135. label: "SKU品名",
  136. },
  137. {
  138. type: "input",
  139. prop: "bomSpecCode",
  140. label: "BOM品号",
  141. },
  142. {
  143. type: "input",
  144. prop: "bomSpecName",
  145. label: "BOM品名",
  146. },
  147. {
  148. type: "input",
  149. prop: "productionWorkOrderCode",
  150. label: "工单号",
  151. },
  152. {
  153. type: "select",
  154. prop: "status",
  155. label: "生产状态",
  156. data: statusList.value,
  157. multiple: true,
  158. },
  159. ];
  160. });
  161. const config = computed(() => {
  162. return [
  163. {
  164. type: "selection",
  165. attrs: {
  166. checkAtt: "isCheck",
  167. },
  168. },
  169. {
  170. attrs: {
  171. label: "订单号",
  172. prop: "orderCode",
  173. width: 150,
  174. },
  175. },
  176. {
  177. attrs: {
  178. label: "工单号",
  179. prop: "code",
  180. width: 190,
  181. },
  182. },
  183. {
  184. attrs: {
  185. label: "E10单号",
  186. prop: "orderWlnCode",
  187. width: 150,
  188. },
  189. },
  190. {
  191. attrs: {
  192. label: "SKU品号",
  193. prop: "skuSpecCode",
  194. width: 140,
  195. },
  196. },
  197. {
  198. attrs: {
  199. label: "SKU品名",
  200. prop: "skuSpecName",
  201. "min-width": 220,
  202. },
  203. },
  204. {
  205. attrs: {
  206. label: "BOM品号",
  207. prop: "bomSpecCode",
  208. width: 130,
  209. },
  210. },
  211. {
  212. attrs: {
  213. label: "BOM品名",
  214. prop: "bomSpecName",
  215. "min-width": 280,
  216. },
  217. },
  218. {
  219. attrs: {
  220. label: "生产状态",
  221. prop: "status",
  222. width: 80,
  223. },
  224. render(val) {
  225. return proxy.dictKeyValue(val, statusList.value);
  226. },
  227. },
  228. {
  229. attrs: {
  230. label: "完成时间",
  231. prop: "completeTime",
  232. width: 160,
  233. align: "center",
  234. fixed: "right",
  235. },
  236. },
  237. {
  238. attrs: {
  239. label: "操作",
  240. width: 120,
  241. align: "center",
  242. fixed: "right",
  243. },
  244. renderHTML(row) {
  245. return [
  246. {
  247. attrs: {
  248. label: "打印生产面单",
  249. type: "primary",
  250. text: true,
  251. },
  252. el: "button",
  253. click() {
  254. clickPrint([row]);
  255. },
  256. },
  257. ];
  258. },
  259. },
  260. ];
  261. });
  262. const selectData = ref([]);
  263. const selectRow = (data) => {
  264. selectData.value = data;
  265. };
  266. const getList = async (req, status) => {
  267. selectData.value = [];
  268. if (status) {
  269. sourceList.value.pagination = {
  270. pageNum: sourceList.value.pagination.pageNum,
  271. pageSize: sourceList.value.pagination.pageSize,
  272. status: [0, 4],
  273. };
  274. } else {
  275. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  276. }
  277. loading.value = true;
  278. proxy.post("/productionWorkOrder/page", sourceList.value.pagination).then((res) => {
  279. if (res.rows && res.rows.length > 0) {
  280. sourceList.value.data = res.rows.map((item) => {
  281. if (item.status == 0 && !item.type) {
  282. return {
  283. ...item,
  284. isCheck: true,
  285. };
  286. } else {
  287. return {
  288. ...item,
  289. isCheck: false,
  290. };
  291. }
  292. });
  293. } else {
  294. sourceList.value.data = [];
  295. }
  296. sourceList.value.pagination.total = res.total;
  297. setTimeout(() => {
  298. loading.value = false;
  299. }, 200);
  300. });
  301. };
  302. getList();
  303. const clickReset = () => {
  304. getList("", true);
  305. };
  306. const clickCode = (row) => {
  307. proxy.$router.replace({
  308. path: "/addOrder",
  309. query: {
  310. detailId: row.id,
  311. text: "订单详情",
  312. random: proxy.random(),
  313. orderInquiry: true,
  314. },
  315. });
  316. };
  317. const printObj = ref({
  318. id: "printMe",
  319. popTitle: "",
  320. extraCss: "https://cdn.bootcdn.net/ajax/libs/animate.css/4.1.1/animate.compat.css, https://cdn.bootcdn.net/ajax/libs/hover.css/2.3.1/css/hover-min.css",
  321. extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
  322. });
  323. const QRcodeList = ref([]);
  324. const clickPrint = (list) => {
  325. QRcodeList.value = list;
  326. nextTick(() => {
  327. for (let i = 0; i < QRcodeList.value.length; i++) {
  328. proxy.$refs["print" + i][0].innerHTML = ""; //清除二维码方法一
  329. let text = QRcodeList.value[i].id;
  330. new QRCode(proxy.$refs["print" + i][0], {
  331. text: text, //页面地址 ,如果页面需要参数传递请注意哈希模式#
  332. width: 150,
  333. height: 150,
  334. colorDark: "#000000",
  335. colorLight: "#ffffff",
  336. correctLevel: QRCode.CorrectLevel.H,
  337. });
  338. }
  339. nextTick(() => {
  340. const btn = document.getElementById("printBtnMini");
  341. btn.click();
  342. });
  343. });
  344. };
  345. const clickSelectPrint = () => {
  346. if (selectData.value && selectData.value.length > 0) {
  347. clickPrint(selectData.value);
  348. } else {
  349. return ElMessage("请选择需要打印的工单");
  350. }
  351. };
  352. const clickMerge = () => {
  353. ElMessageBox.confirm("你是否确认此操作", "提示", {
  354. confirmButtonText: "确定",
  355. cancelButtonText: "取消",
  356. type: "warning",
  357. })
  358. .then(() => {
  359. proxy
  360. .post(
  361. "/productionWorkOrder/combined",
  362. selectData.value.map((item) => item.id)
  363. )
  364. .then(() => {
  365. ElMessage({ message: "操作成功", type: "success" });
  366. getList();
  367. });
  368. })
  369. .catch(() => {});
  370. };
  371. watch(selectData, (newVal) => {
  372. if (newVal && newVal.length > 0) {
  373. sourceList.value.data.forEach((x) => {
  374. if (x.status == 0 && !x.type) {
  375. if (x.bomSpecCode === newVal[0].bomSpecCode && x.skuSpecCode === newVal[0].skuSpecCode) {
  376. x.isCheck = true;
  377. } else {
  378. x.isCheck = false;
  379. }
  380. } else {
  381. x.isCheck = false;
  382. }
  383. });
  384. } else {
  385. sourceList.value.data.forEach((x) => {
  386. if (x.status == 0 && !x.type) {
  387. x.isCheck = true;
  388. } else {
  389. x.isCheck = false;
  390. }
  391. });
  392. }
  393. });
  394. </script>
  395. <style lang="scss" scoped>
  396. :deep(.el-dialog) {
  397. margin-top: 10px !important;
  398. margin-bottom: 10px !important;
  399. }
  400. .one {
  401. position: absolute;
  402. right: 10px;
  403. top: 320px;
  404. width: 70px;
  405. height: 70px;
  406. z-index: 99;
  407. line-height: 80px;
  408. text-align: center;
  409. border-radius: 50%;
  410. border: 1px solid #000;
  411. .two {
  412. position: absolute;
  413. top: 50%;
  414. left: 50%;
  415. transform: translate(-50%, -50%);
  416. width: 60px;
  417. height: 60px;
  418. line-height: 60px;
  419. text-align: center;
  420. border-radius: 50%;
  421. border: 1px dashed #000;
  422. .three {
  423. rotate: -45deg;
  424. font-size: 14px;
  425. }
  426. }
  427. }
  428. :deep(.el-table__header-wrapper .el-checkbox) {
  429. display: none;
  430. }
  431. </style>