index.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. <template>
  2. <div class="pageIndexClass">
  3. <div>
  4. <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
  5. :selectConfig="selectConfig" :action-list="[
  6. ]" @get-list="getList">
  7. <template #pic="{ item }">
  8. <div v-if="item.fileList &&item.fileList.length > 0">
  9. <img :src="item.fileList[0].fileUrl" class="pic" @click="handleClickFile(item.fileList[0])" />
  10. </div>
  11. <div v-else></div>
  12. </template>
  13. <template #picOne="{ item }">
  14. <div v-if="item.fileListOne &&item.fileListOne.length > 0">
  15. <img :src="item.fileListOne[0].fileUrl" class="pic" @click="handleClickFile(item.fileListOne[0])" />
  16. </div>
  17. <div v-else></div>
  18. </template>
  19. <template v-for="(slotItem, index) in processesData" v-slot:[slotItem.id]="{ item }" :key="slotItem.id">
  20. <div style="width:100%">
  21. <div v-if="isShowCotent(slotItem,item)">
  22. <el-icon :size="20" color="green">
  23. <CircleCheckFilled />
  24. </el-icon>
  25. </div>
  26. <div v-else>
  27. <el-icon :size="20" color="red">
  28. <CircleClose />
  29. </el-icon>
  30. </div>
  31. </div>
  32. </template>
  33. </byTable>
  34. </div>
  35. <el-dialog :title="'打印二维码'" v-model="dialogVisible" width="350px" destroy-on-close>
  36. <div>
  37. <div id="pdfDom" style="width:100%">
  38. <div style="font-size:20px;text-align:center">
  39. {{printData.name}}
  40. </div>
  41. <div style="border-top: 1px solid #000;border-bottom: 1px solid #000; padding: 10px 0; margin:10px auto;text-align:center">
  42. <div :ref="printData.id" style="width:200px;margin-left:55px">
  43. {{printData.scanValue}}
  44. </div>
  45. <div style="font-size:20px;text-align:center;font-weight:700;margin-top:10px">
  46. {{printData.createTime}}
  47. </div>
  48. <!-- 换页 -->
  49. <!-- <div style="page-break-after: always"></div> -->
  50. </div>
  51. <div style="margin-left:10px;display:flex;flex-direction:column;justify-content:space-around">
  52. <div style="font-size:14px;margin-top:8px"> 产品编码:{{printData.productName}}</div>
  53. <div style="font-size:14px;margin-top:8px">
  54. 产品名称:{{printData.productSpec}}
  55. </div>
  56. <div style="font-size:14px;margin-top:8px">
  57. 原材料编码:{{printData.productSpec}}
  58. </div>
  59. <div style="font-size:14px;margin-top:8px">
  60. 原材料名称:{{printData.productSpec}}
  61. </div>
  62. </div>
  63. </div>
  64. </div>
  65. <template #footer>
  66. <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
  67. <el-button type="primary" v-print="printObj" size="defualt">打 印</el-button>
  68. </template>
  69. </el-dialog>
  70. </div>
  71. </template>
  72. <script setup>
  73. import byTable from "@/components/byTable/index";
  74. import byForm from "@/components/byForm/index";
  75. import QRCode from "qrcodejs2-fix";
  76. const { proxy } = getCurrentInstance();
  77. const loading = ref(false);
  78. const submitLoading = ref(false);
  79. const sourceList = ref({
  80. data: [],
  81. pagination: {
  82. total: 3,
  83. pageNum: 1,
  84. pageSize: 10,
  85. keyword: "",
  86. },
  87. });
  88. const treeData = ref([]);
  89. const dialogVisible = ref(false);
  90. const modalType = ref("add");
  91. const statusData = ref([
  92. {
  93. label: "未开始",
  94. value: "0",
  95. },
  96. {
  97. label: "进行中",
  98. value: "1",
  99. },
  100. {
  101. label: "已完成",
  102. value: "2",
  103. },
  104. ]);
  105. const selectConfig = computed(() => [
  106. {
  107. label: "生产状态",
  108. prop: "produceStatus",
  109. data: statusData.value,
  110. },
  111. {
  112. type: "time",
  113. label: "交期",
  114. placeholder: "开始日期",
  115. prop: "staDeliveryPeriod",
  116. placeholderOne: "结束日期",
  117. propOne: "endDeliveryPeriod",
  118. },
  119. {
  120. type: "time",
  121. label: "下单日期",
  122. placeholder: "开始日期",
  123. prop: "beginTime",
  124. placeholderOne: "结束日期",
  125. propOne: "endTime",
  126. },
  127. ]);
  128. const config = ref([
  129. {
  130. attrs: {
  131. label: "订单号",
  132. prop: "orderCode",
  133. width: 130,
  134. },
  135. },
  136. {
  137. attrs: {
  138. label: "设计图",
  139. slot: "picOne",
  140. width: 80,
  141. },
  142. },
  143. {
  144. attrs: {
  145. label: "产品图片",
  146. slot: "pic",
  147. width: 80,
  148. },
  149. },
  150. {
  151. attrs: {
  152. label: "产品编码",
  153. prop: "productCode",
  154. width: 130,
  155. },
  156. },
  157. {
  158. attrs: {
  159. label: "产品名称",
  160. prop: "productName",
  161. "min-width": 130,
  162. },
  163. },
  164. {
  165. attrs: {
  166. label: "生产件数",
  167. prop: "quantity",
  168. width: 100,
  169. },
  170. },
  171. {
  172. attrs: {
  173. label: "生产状态",
  174. prop: "produceStatus",
  175. width: 100,
  176. },
  177. render(val) {
  178. return proxy.dictValueLabel(val, statusData.value);
  179. },
  180. },
  181. {
  182. attrs: {
  183. label: "下单时间",
  184. prop: "orderCreateTime",
  185. width: 160,
  186. },
  187. },
  188. {
  189. attrs: {
  190. label: "交期",
  191. prop: "deliveryPeriod",
  192. width: 160,
  193. },
  194. },
  195. {
  196. attrs: {
  197. label: "投产时间",
  198. prop: "produceTime",
  199. width: 160,
  200. },
  201. },
  202. {
  203. attrs: {
  204. label: "完成时间",
  205. prop: "finishTime",
  206. width: 160,
  207. },
  208. },
  209. {
  210. attrs: {
  211. label: "生产用时",
  212. prop: "usageTime",
  213. width: 100,
  214. },
  215. },
  216. ]);
  217. const formData = reactive({
  218. data: {},
  219. });
  220. const formOption = reactive({
  221. inline: true,
  222. labelWidth: 100,
  223. itemWidth: 100,
  224. });
  225. const formDom = ref(null);
  226. const formConfig = computed(() => {
  227. return [
  228. {
  229. type: "input",
  230. prop: "code",
  231. label: "店铺编号",
  232. itemWidth: 100,
  233. disabled: false,
  234. },
  235. {
  236. type: "input",
  237. prop: "name",
  238. label: "店铺名称",
  239. itemWidth: 100,
  240. disabled: false,
  241. },
  242. {
  243. type: "treeSelect",
  244. prop: "deptId",
  245. label: "负责部门",
  246. data: treeData.value,
  247. propsTreeLabel: "deptName",
  248. propsTreeValue: "deptId",
  249. itemWidth: 100,
  250. disabled: false,
  251. },
  252. ];
  253. });
  254. const rules = ref({
  255. deptId: [{ required: true, message: "请选择负责部门", trigger: "change" }],
  256. name: [{ required: true, message: "请输入店铺名称", trigger: "blur" }],
  257. code: [{ required: true, message: "请输入店铺编号", trigger: "blur" }],
  258. });
  259. const getList = async (req) => {
  260. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  261. loading.value = true;
  262. proxy
  263. .post("/produceOrderDetail/page", sourceList.value.pagination)
  264. .then((res) => {
  265. sourceList.value.data = res.rows;
  266. sourceList.value.pagination.total = res.total;
  267. setTimeout(() => {
  268. loading.value = false;
  269. }, 200);
  270. const productIdList = res.rows.map((x) => x.productId);
  271. // 请求文件数据并回显
  272. if (productIdList.length > 0) {
  273. proxy.getFile(productIdList, sourceList.value.data, "productId");
  274. }
  275. const productIdListOne = res.rows.map((x) => x.contractDetailId);
  276. // 请求文件数据并回显
  277. if (productIdListOne.length > 0) {
  278. proxy.getFile(
  279. productIdListOne,
  280. sourceList.value.data,
  281. "contractDetailId",
  282. "fileListOne"
  283. );
  284. }
  285. });
  286. };
  287. const openModal = () => {
  288. dialogVisible.value = true;
  289. modalType.value = "add";
  290. formData.data = {
  291. definition: "2",
  292. fileList: [],
  293. };
  294. if (currencyData.value && currencyData.value.length > 0) {
  295. formData.data.currency = currencyData.value[0].dictKey;
  296. formData.data.costCurrency = currencyData.value[0].dictKey;
  297. }
  298. };
  299. const submitForm = () => {
  300. formDom.value.handleSubmit((valid) => {
  301. submitLoading.value = true;
  302. proxy.post("/shopInfo/" + modalType.value, formData.data).then(
  303. (res) => {
  304. proxy.msgTip("操作成功", 1);
  305. dialogVisible.value = false;
  306. submitLoading.value = false;
  307. getList();
  308. },
  309. (err) => {
  310. submitLoading.value = false;
  311. }
  312. );
  313. });
  314. };
  315. const getDtl = (row) => {
  316. modalType.value = "edit";
  317. proxy.post("/shopInfo/detail", { id: row.id }).then((res) => {
  318. formData.data = res;
  319. dialogVisible.value = true;
  320. });
  321. };
  322. const processesData = ref([]);
  323. const getProcesses = () => {
  324. proxy
  325. .post("/productionProcesses/page", { pageNum: 1, pageSize: 9999 })
  326. .then((res) => {
  327. for (let i = 0; i < res.rows.length; i++) {
  328. const ele = res.rows[i];
  329. let attrs = {
  330. label: `[ ${ele.name} ]`,
  331. slot: ele.id,
  332. isNeedHeaderSlot: false,
  333. width: 90,
  334. fixed: "right",
  335. };
  336. config.value.push({
  337. attrs,
  338. });
  339. }
  340. config.value.push({
  341. attrs: {
  342. label: "操作",
  343. width: "100",
  344. align: "center",
  345. fixed: "right",
  346. },
  347. renderHTML(row) {
  348. return [
  349. {
  350. attrs: {
  351. label: "打印二维码",
  352. type: "primary",
  353. text: true,
  354. },
  355. el: "button",
  356. click() {
  357. printQrCode(row);
  358. },
  359. },
  360. ];
  361. },
  362. });
  363. processesData.value = res.rows;
  364. });
  365. };
  366. getProcesses();
  367. getList();
  368. const printData = ref({});
  369. const printQrCode = (row) => {
  370. printData.value = row;
  371. dialogVisible.value = true;
  372. nextTick(() => {
  373. proxy.$refs[row.id].innerHTML = ""; //清除二维码方法一
  374. new QRCode(proxy.$refs[row.id], {
  375. text: row.id,
  376. width: 200,
  377. height: 200,
  378. colorDark: "#000000",
  379. colorLight: "#ffffff",
  380. correctLevel: QRCode.CorrectLevel.H,
  381. });
  382. });
  383. };
  384. const printObj = ref({
  385. id: "pdfDom",
  386. popTitle: "",
  387. extraCss:
  388. "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",
  389. extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>',
  390. });
  391. const handleClickFile = (file) => {
  392. window.open(file.fileUrl, "_blank");
  393. };
  394. const isShowCotent = (slot, item) => {
  395. if (item && item.productionProcessesList) {
  396. return item.productionProcessesList.some((x) => x.id == slot.id);
  397. } else {
  398. return false;
  399. }
  400. };
  401. </script>
  402. <style lang="scss" scoped>
  403. ::v-deep(.el-progress__text) {
  404. font-size: 14px !important;
  405. }
  406. .content {
  407. padding: 20px;
  408. }
  409. .pic {
  410. object-fit: contain;
  411. width: 50px;
  412. height: 50px;
  413. cursor: pointer;
  414. vertical-align: middle;
  415. }
  416. </style>