bind-barcode-group.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <!-- @desc:组内粘贴 @auth:寇珊珊 @time:2023年4月20日16:00:36 -->
  2. <template>
  3. <div class="main-div">
  4. <!--加载中-->
  5. <loading :loading="loading" v-if="!modalVisible"></loading>
  6. <DkPageButton :total="editKeys?editKeys.length:0"
  7. :current="editIndex"
  8. v-if="editKeys && editKeys.length > 1"
  9. @pageChange="editPageChange"></DkPageButton>
  10. <DkCollapse ref="collapse" @on-change="changeCollapse">
  11. <DkPanel prop="essentialInformation">
  12. <!-- 下拉区域 -->
  13. <DkForm slot="content" ref="formInline" v-model="formData" style="width: 95%">
  14. <!--成型日期-->
  15. <DkFormItem prop="moldingDate">
  16. <DatePickerPop ref="moldingDate" v-model="formData.moldingDate" :readonly="true"/>
  17. </DkFormItem>
  18. <!--起始条码-->
  19. <DkFormItem prop="produceBarCode">
  20. <InputPop :readonly="productUniqueCodeCount==moldingRecordList.length" ref="produceBarCode"
  21. v-model="formData.produceBarCode"/>
  22. </DkFormItem>
  23. <!-- 绑定条码 -->
  24. <DkButton :disabled="productUniqueCodeCount==moldingRecordList.length" type="primary"
  25. @click="bindBarcodeButton" style="margin-right: 10px">{{ $v('bindBarcode') }}
  26. </DkButton>
  27. <!-- 清空条码 -->
  28. <DkButton :disabled="productUniqueCodeCount==moldingRecordList.length"
  29. @click="clearBindBarcode" style="margin-right: 10px">{{
  30. $v('clearBindBarcode') }}
  31. </DkButton>
  32. <!-- 撤销条码 -->
  33. <DkButton :disabled="productUniqueCodeCount==0" @click="revokeBindBarcode">{{
  34. $v('revokeBindBarcode') }}
  35. </DkButton>
  36. </DkForm>
  37. </DkPanel>
  38. <DkPanel prop="moldingRecordRelation">
  39. <div slot="content" :style="'height: ' + tableHeight + 'px'">
  40. <!--型记录信息-->
  41. <EditTreeTable ref="moldingRecord" :data="moldingRecordList" showFooter
  42. major-field="id"
  43. :operate-flag="false"
  44. :height="tableHeight"
  45. :new-row-flag="false"
  46. @changeValue="changeValue"
  47. :columns="moldingRecordTreeColumns"
  48. exchangeField="pdtModelId"
  49. controlId="pdtModelId"
  50. :bindBarCodeFlag="true"
  51. @check-detail-by-bind-bar-code="checkDetail"
  52. ></EditTreeTable>
  53. </div>
  54. </DkPanel>
  55. </DkCollapse>
  56. <!-- 下部分按钮区域-->
  57. <DkSaveButton ref="saveButton" :loading="loading" @save="save" @close="close"></DkSaveButton>
  58. </div>
  59. </template>
  60. <script>
  61. import { formMixin } from '@/mixins/form'
  62. export default {
  63. name: 'bind-barcode-group',
  64. mixins: [formMixin],
  65. data() {
  66. let self = this
  67. return {
  68. tableData: [],
  69. loading: false,
  70. tableHeight: 620,
  71. params: null,
  72. // 画面表单数据
  73. formData: {
  74. moldingDate: new Date().toDateStr(),
  75. ftyId: this.$store.state.user.ftyId,
  76. produceBarCode: null,//起始条码
  77. },
  78. moldingRecordList: [],// 成型记录明细信息
  79. // 成型记录明细列表
  80. productUniqueCodeCount: 0,//绑定条码个数(如果长度和查询数据长度一致则不能进行绑定条码)
  81. //成型记录明细列表
  82. moldingRecordTreeColumns: [
  83. { type: 'checkbox', },
  84. // 可变更产品名称
  85. {
  86. field: 'repPdtModelName',
  87. title: self.$t('modelAfterBonding'),
  88. dataType: self.$config.tableSelectType.product, controlId: 'pdtModelId',
  89. treeNode: true, type: 'disabled', width: 'auto'
  90. },
  91. // 成型线编码
  92. { field: 'uniqueCode', title: self.$t('moldlineCode'), type: 'disabled', width: 'auto' },
  93. // 成型线名称
  94. { field: 'moldlineName', type: 'disabled', width: 'auto' },
  95. // 成型班长
  96. { field: 'manageUserName', type: 'disabled', width: 'auto' },
  97. // 成型工号
  98. { field: 'moldingUserName', type: 'disabled', width: 'auto' },
  99. // 产品编码
  100. { field: 'modelCode', title: self.$t('productCode'), type: 'disabled', width: 'auto' },
  101. // 产品名称
  102. { field: 'modelName', title: self.$t('productName'), type: 'disabled', width: 'auto' },
  103. // 模具状态
  104. { field: 'moldlineItemKindName', title: self.$t('mouldKindName'), type: 'disabled', width: 'auto' },
  105. // 绑码标识
  106. // {field: 'flgBindUnique', type: 'switch', width: 'auto'},
  107. // 绑定条码
  108. {
  109. field: 'productUniqueCode',
  110. title: self.$t('pdtUniqueCode'),
  111. childCanInput: false,
  112. equal: true,
  113. type: 'text',
  114. width: 'auto'
  115. },
  116. // 成型批次
  117. { field: 'moldingBatch', type: 'disabled', width: 'auto' },
  118. // 成型标识
  119. { field: 'flgMolding', type: 'disabled', switch: true, controlId: 'flgMolding', width: '120px' },
  120. // { field: 'flgMolding', type: 'switch', controlId: 'flgMolding', width: '120px' },
  121. // 未成型原因
  122. { field: 'unmoldedReasonName', type: 'disabled', width: 'auto' },
  123. // 产品商标
  124. { field: 'logoName', type: 'disabled', width: 'auto' },
  125. // 釉色
  126. { field: 'colourName', type: 'disabled', width: 'auto' },
  127. // 损坯标识
  128. { field: 'flgScrap', type: 'disabled', switch: true, width: '120px' },
  129. // 损坯原因
  130. { field: 'scrapReasonName', type: 'disabled', width: 'auto' },
  131. // 备注
  132. { field: 'productRemarks', type: 'text', width: 'auto' },
  133. ],
  134. //商品条码-数字正则
  135. checkProduceBarCode: function (value) {
  136. const reg = /^.*\d+.*$/
  137. if (value === '' || value === undefined || value === null) {
  138. return true
  139. } else {
  140. if ((!reg.test(value)) && value !== '') {
  141. return false
  142. } else {
  143. return true
  144. }
  145. }
  146. },
  147. }
  148. },
  149. methods: {
  150. /**
  151. * @desc : 绑定条码
  152. * @date : 2023/2/28 13:03
  153. * @author : 寇珊珊
  154. */
  155. bindBarcodeButton() {
  156. if (!this.formData.produceBarCode) {
  157. this.$Message.error(this.$t('W_109'))
  158. return
  159. }
  160. if (!this.checkProduceBarCode(this.formData.produceBarCode)) {
  161. this.$Message.error(this.$t('W_104'))
  162. return
  163. }
  164. let reg = /(\d+)/g
  165. let match = null
  166. //截取的数字
  167. let lastNum = null
  168. let beforeStr = null
  169. let lastStr = null
  170. while ((match = reg.exec(this.formData.produceBarCode)) !== null) {
  171. lastNum = match[1]
  172. // 数字下标
  173. let lastNumIndex = parseInt(this.formData.produceBarCode.lastIndexOf(lastNum))
  174. //截取下标前字符
  175. beforeStr = this.formData.produceBarCode.substr(0, lastNumIndex)
  176. //截取下标后字符
  177. lastStr = this.formData.produceBarCode.substr(lastNumIndex + parseInt(lastNum.length)).toString()
  178. }
  179. let index = 0
  180. let zeroFlag = true
  181. let zeroStr = ''
  182. if (lastNum.length > 1 && lastNum.substring(0, 1) == '0') {
  183. zeroFlag = false
  184. for (let it of lastNum) {
  185. if (it == '0') {
  186. zeroStr += '0'
  187. } else {
  188. break
  189. }
  190. }
  191. }
  192. //条码数字长度
  193. let indexLength = (parseInt(lastNum) + parseInt(index)).toString().length
  194. for (let i = 0; i < this.moldingRecordList.length; i++) {
  195. if (this.moldingRecordList[i].productUniqueCodeFlag || this.moldingRecordList[i].canProductUniqueCode) {
  196. let number = parseInt(lastNum) + parseInt(index)
  197. //每次多一位数,就去掉前面一个0
  198. if (indexLength != number.toString().length) {
  199. if (zeroStr.length == 0) {
  200. break
  201. }
  202. zeroStr = zeroStr.substring(0, zeroStr.length - 1)
  203. indexLength = number.toString().length
  204. }
  205. //数字在前
  206. if (beforeStr.length == 0) {
  207. if (zeroFlag) {
  208. this.$set(this.moldingRecordList[i], 'productUniqueCode', number + beforeStr + lastStr)
  209. } else {
  210. this.$set(this.moldingRecordList[i], 'productUniqueCode', zeroStr + number + beforeStr + lastStr)
  211. }
  212. }
  213. //数字在后
  214. else if (lastStr.length == 0) {
  215. if (zeroFlag) {
  216. this.$set(this.moldingRecordList[i], 'productUniqueCode', beforeStr + lastStr + number)
  217. } else {
  218. this.$set(this.moldingRecordList[i], 'productUniqueCode', beforeStr + lastStr + zeroStr + number)
  219. }
  220. }
  221. //数字在中
  222. else {
  223. if (zeroFlag) {
  224. this.$set(this.moldingRecordList[i], 'productUniqueCode', beforeStr + number + lastStr)
  225. } else {
  226. this.$set(this.moldingRecordList[i], 'productUniqueCode', beforeStr + zeroStr + number + lastStr)
  227. }
  228. }
  229. this.$set(this.moldingRecordList[i], 'productUniqueCodeFlag', true)
  230. this.$set(this.moldingRecordList[i], 'productUniqueFlag', true)
  231. index++
  232. //给每个总单下的明细【绑定条码赋值】
  233. for (let item = 0; item < this.moldingRecordList[i].bomItems.length; item++) {
  234. //从后台数据查出来绑定条码已经存在的不需要赋值
  235. if (!this.moldingRecordList[i].bomItems[item].readOnlyUniqueCode) {
  236. this.$set(this.moldingRecordList[i].bomItems[item], 'productUniqueCode', this.moldingRecordList[i].productUniqueCode)
  237. this.$set(this.moldingRecordList[i].bomItems[item], 'productUniqueCodeFlag', true)
  238. this.$set(this.moldingRecordList[i].bomItems[item], 'productUniqueFlag', true)
  239. }
  240. }
  241. }
  242. }
  243. this.$refs.moldingRecord.tableData = this.moldingRecordList
  244. // 处理子级数据
  245. this.$refs.moldingRecord.loadChildrenInit(this.moldingRecordList, ['productUniqueCode'])
  246. // 重新刷新
  247. this.$refs.moldingRecord.reloadTreeTable(this.moldingRecordList)
  248. },
  249. /**
  250. * @desc : 清空条码
  251. * @date : 2023/2/28 13:04
  252. * @author : 寇珊珊
  253. */
  254. clearBindBarcode() {
  255. this.formData.produceBarCode = null
  256. for (let i of this.moldingRecordList) {
  257. if (!i.readOnlyUniqueCode) {
  258. i.productUniqueCode = null
  259. i.productUniqueCodeFlag = false
  260. i.productUniqueFlag = false
  261. }
  262. //清空每条总单下明细的绑定条码
  263. for (let item of i.bomItems) {
  264. if (!item.readOnlyUniqueCode) {
  265. item.productUniqueCode = null
  266. item.productUniqueCodeFlag = false
  267. item.productUniqueFlag = false
  268. }
  269. }
  270. }
  271. // 处理子级数据
  272. this.$refs.moldingRecord.loadChildrenInit(this.moldingRecordList, ['productUniqueCode'])
  273. // 重新刷新
  274. this.$refs.moldingRecord.reloadData(this.moldingRecordList)
  275. },
  276. /**
  277. * @desc : 撤销条码
  278. * @date : 2023/5/8 9:53
  279. * @author : 寇珊珊
  280. */
  281. revokeBindBarcode() {
  282. let pdtUniqueIdList = this.$refs['moldingRecord'].$refs.xTable.getCheckboxRecords().map(map => map.pdtUniqueId)
  283. if (pdtUniqueIdList.length == 0) {
  284. this.$Message.error(this.$t('W_150'))
  285. return
  286. }
  287. this.excute(this.$service.productService, this.$service.productService.undo, pdtUniqueIdList).then(res => {
  288. if (res.code === this.$config.SUCCESS_CODE) {
  289. this.$Message.success(res.message)
  290. this.detail(this.$route.params.id)
  291. } else {
  292. this.$Message.error(res.message)
  293. }
  294. })
  295. },
  296. /**
  297. * @desc : 值改变
  298. * @date : 2023/2/28 11:23
  299. * @author : 寇珊珊
  300. */
  301. changeValue(value) {
  302. let field = value.field
  303. let row = value.row
  304. let rowIndex = value.rowIndex
  305. this.$set(this.moldingRecordList[rowIndex], field, row[field])
  306. this.$set(this.moldingRecordList[rowIndex], 'productUniqueFlag', true)
  307. row.productUniqueFlag = true
  308. //改变每条总单下明细的绑定条码
  309. for (let item = 0; item < row.bomItems.length; item++) {
  310. //从后台数据查出来绑定条码已经存在的不需要赋值
  311. if (!row.bomItems[item].readOnlyUniqueCode) {
  312. this.$set(row.bomItems[item], 'productUniqueFlag', true)
  313. this.$set(row.bomItems[item], 'productUniqueCode', row[field])
  314. }
  315. //修改备注也要修改productUniqueFlag标识 用于后续保存数据过滤
  316. if (field == 'productRemarks') {
  317. this.$set(row.bomItems[item], 'productUniqueFlag', true)
  318. }
  319. }
  320. for (let i = 0; i < this.moldingRecordList.length; i++) {
  321. if (this.moldingRecordList[i].id == row.id) {
  322. this.moldingRecordList[i] = row
  323. }
  324. }
  325. this.$refs.moldingRecord.tableData = this.moldingRecordList
  326. // 处理子级数据
  327. this.$refs.moldingRecord.loadChildrenInit(this.moldingRecordList, ['productUniqueCode'])
  328. // 重新刷新
  329. this.$refs.moldingRecord.reloadTreeTable(this.moldingRecordList)
  330. },
  331. /**
  332. * @desc : 替换子集
  333. * @date : 2023/4/24 15:09
  334. * @author : 寇珊珊
  335. */
  336. checkDetail(oldRow, newRow) {
  337. for (let it of this.moldingRecordList) {
  338. let index = 0
  339. for (let item of it.bomItems) {
  340. if (item.id == oldRow.id) {
  341. newRow.moldingItemId = newRow.itemId
  342. item = Object.assign(item, newRow)
  343. index++
  344. break
  345. }
  346. }
  347. }
  348. this.$refs.moldingRecord.reloadData(this.moldingRecordList)
  349. },
  350. /**
  351. * @desc : 通过id查询
  352. * @date : 2023/2/28 11:25
  353. * @author : 寇珊珊
  354. */
  355. detail(id) {
  356. //绑定条码计数 每次查询之前要清零(因为保存后要重新调用)
  357. this.productUniqueCodeCount = 0
  358. let param = {
  359. 'moldlineId': parseInt(id),
  360. 'pdtGlueKind': this.$route.query.pdtGlueKind,
  361. 'moldingBatch': this.$route.query.moldingBatch,
  362. 'moldingDate': this.$route.query.moldingDate,
  363. 'ftyId': this.$store.state.user.ftyId
  364. }
  365. return this.excute(this.$service.moldingRecordItemService, this.$service.moldingRecordItemService.selectByMoldineId, param).then(res => {
  366. if (res.code === this.$config.SUCCESS_CODE) {
  367. this.formData.moldingDate = this.$route.query.moldingDate
  368. let list = res.data
  369. this.moldingRecordList = list
  370. let index = 0
  371. for (let i of this.moldingRecordList) {
  372. i.pdtModelId = this.$config.bindBarCodePdtModelId.parentId
  373. //明细已有绑定条码个数
  374. let productUniqueCodeLength = 0
  375. //明细已有成型标识个数
  376. let flgMoldingLength = 0
  377. //明细下标
  378. let itemIndex = 0
  379. //明细第一条的绑定条码
  380. let zeroCode = null
  381. //循环明细
  382. for (let item of i.bomItems) {
  383. item.moldingItemId = item.itemId
  384. //如果明细第一条绑定条码有值 存起来
  385. if (itemIndex == 0 && item.productUniqueCode) {
  386. zeroCode = item.productUniqueCode
  387. }
  388. //明细的绑定条码不可以修改
  389. this.$set(item, 'readOnly', ['productUniqueCode'])
  390. //如果明细里绑定条码存在没值的情况;总单绑定条码可以输入 反之不可以;明细有值没值都要禁用
  391. if (item.productUniqueCode) {
  392. //已经绑码了给替换标识false
  393. item.exchangeFlag = false
  394. productUniqueCodeLength++
  395. item.readOnlyUniqueCode = true
  396. }
  397. //明细不是成型
  398. if (!item.flgMolding) {
  399. //不是成型给替换标识false
  400. item.exchangeFlag = false
  401. flgMoldingLength++
  402. }
  403. itemIndex++
  404. }
  405. //明细中每条绑定条码都有值 = 每条总单下的明细数量 或者 是成型标识数量大于0
  406. if (productUniqueCodeLength == i.bomItems.length || flgMoldingLength > 0) {
  407. i.readOnlyUniqueCode = true
  408. //明细第一条绑定条码赋值给父级
  409. this.$set(this.moldingRecordList[index], 'productUniqueCode', zeroCode)
  410. //不可更改绑定条码
  411. this.$set(this.moldingRecordList[index], 'canProductUniqueCode', false)
  412. //绑定条码改为只读
  413. this.$set(i, 'readOnly', ['productUniqueCode'])
  414. //绑定条码总条数累加
  415. this.productUniqueCodeCount++
  416. //总单成型标识(根据明细里是否全是成型标识)
  417. } else {
  418. //可更改绑定条码
  419. this.$set(this.moldingRecordList[index], 'canProductUniqueCode', true)
  420. }
  421. index++
  422. }
  423. }
  424. })
  425. },
  426. /**
  427. * @desc : 设置传参
  428. * @date : 2023/2/28 11:29
  429. * @author : 寇珊珊
  430. */
  431. setParams() {
  432. //productUniqueFlag 校验手动改变绑定条码标识
  433. let list = []
  434. if (this.moldingRecordList.length > 0) {
  435. //提取明细信息
  436. for (let it of this.moldingRecordList.filter(it => it.productUniqueFlag)) {
  437. let bomItems = it.bomItems.filter(item => item.productUniqueFlag)
  438. list.push({
  439. moldingItemIds: bomItems.map(map => map.moldingItemId),
  440. ftyId: bomItems[0].ftyId,
  441. moldingItemId: bomItems[0].moldingItemId,
  442. uniqueId: bomItems[0].productId,
  443. uniqueCode: bomItems[0].productId ? null : it.productUniqueCode,
  444. remarks: it.productRemarks,
  445. flgPdtGlue: true,
  446. modelId:bomItems[0].repPdtModelId,
  447. })
  448. }
  449. }
  450. this.params = list
  451. },
  452. /**
  453. * @desc : 保存数据
  454. * @date : 2023/2/28 11:28
  455. * @author : 寇珊珊
  456. */
  457. save() {
  458. //验重
  459. if (!this.checkData()) {
  460. return
  461. }
  462. this.setParams()
  463. let excute = this.excute(this.$service.productService, this.$service.productService.insertBatch, this.params)
  464. excute.then(res => {
  465. if (res.code === this.$config.SUCCESS_CODE) {
  466. this.$Message.success(res.message)
  467. this.detail(this.$route.params.id)
  468. } else {
  469. this.$Message.error(res.message)
  470. }
  471. })
  472. return excute
  473. },
  474. /**
  475. * @desc : 验重
  476. * @date : 2023/3/3 14:30
  477. * @author : 寇珊珊
  478. */
  479. checkData() {
  480. let codeNoList = []
  481. //校验绑定条码
  482. codeNoList = codeNoList.concat(this.moldingRecordList.copy().filter(f => f.productUniqueCode).map(m => m.productUniqueCode))
  483. if (codeNoList.length != codeNoList.unique().length) {
  484. this.$Message.error(this.$t('W_110'))
  485. return false
  486. }
  487. return true
  488. },
  489. },
  490. created() {
  491. this.resizeTableFlag = true; // 计算表格高度
  492. },
  493. activated() {
  494. this.detail(this.$route.params.id)
  495. }
  496. }
  497. </script>
  498. <style scoped>
  499. </style>