materialMerge.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589
  1. <template>
  2. <gui-page :custom-header="true" :is-header-sized="false" :header-class="['gui-theme-background-color']">
  3. <template #gHeader>
  4. <view style="height:44px;" class="gui-flex gui-nowrap gui-rows gui-align-items-center">
  5. <!-- 使用组件实现返回按钮及返回首页按钮 -->
  6. <text style="font-size:44rpx;" class="gui-header-leader-btns gui-color-white font-icons"
  7. @tap="goBack">&#xe6c5;</text>
  8. <!-- 导航文本此处也可以是其他自定义内容 -->
  9. <text
  10. class="gui-h4 gui-blod gui-flex1 gui-text-center gui-ellipsis gui-color-white gui-primary-text">物料拆合</text>
  11. <!-- 此处加一个右侧展位元素与左侧同宽,实现标题居中 -->
  12. <!-- 实际宽度请根据自己情况设置 -->
  13. <view style="width:40px;" />
  14. <!-- 如果右侧有其他内容可以利用条件编译和定位来实现-->
  15. </view>
  16. </template>
  17. <template #gBody>
  18. <list class="form">
  19. <cell>
  20. <view class="row-1">
  21. <view class="row-1-card">
  22. <uni-easyinput ref="easyinput" v-model="submitParams.materialOne.qrCode"
  23. :input-border="false" :clearable="false" type="text" focus @focus="handleInputFocus"
  24. placeholder="请扫描物料条码" @confirm="confirmMaterialOne" />
  25. <text class="font-icons" @click="handleMapass('row1')">&#xe6b7;</text>
  26. </view>
  27. </view>
  28. <view class="row-2">
  29. <view class="row-2-card">
  30. <view class="row-space-between">
  31. <text>物料编码</text>
  32. <text>{{ submitParams.materialOne.materialNo }}</text>
  33. </view>
  34. <view class="row-space-between">
  35. <text>物料名称</text>
  36. <text>{{ submitParams.materialOne.materialName }}</text>
  37. </view>
  38. <view class="row-space-between">
  39. <text>物料条码</text>
  40. <text>{{ submitParams.materialOne.qrCode }}</text>
  41. </view>
  42. <view class="row-space-between">
  43. <text>批次数量</text>
  44. <text>{{ submitParams.materialOne.inQty }}</text>
  45. </view>
  46. </view>
  47. </view>
  48. <view class="row-3">
  49. <view class="row-3-card">
  50. <uni-easyinput ref="easyinput2" v-model="submitParams.materialTwo.qrCode"
  51. :input-border="false" :clearable="false" type="text" focus @focus="handleInputFocus"
  52. placeholder="请扫描物料条码" @confirm="confirmMaterialTwo" />
  53. <text class="font-icons" @click="handleMapass('row2')">&#xe6b7;</text>
  54. </view>
  55. </view>
  56. <view class="row-2">
  57. <view class="row-2-card">
  58. <view class="row-space-between">
  59. <text>物料编码</text>
  60. <text>{{ submitParams.materialTwo.materialNo }}</text>
  61. </view>
  62. <view class="row-space-between">
  63. <text>物料名称</text>
  64. <text>{{ submitParams.materialTwo.materialName }}</text>
  65. </view>
  66. <view class="row-space-between">
  67. <text>物料条码</text>
  68. <text>{{ submitParams.materialTwo.qrCode }}</text>
  69. </view>
  70. <view class="row-space-between">
  71. <text>批次数量</text>
  72. <text>{{ submitParams.materialTwo.inQty }}</text>
  73. </view>
  74. </view>
  75. </view>
  76. <view class="row-operation">
  77. <view class="row-operation-card">
  78. <view class="button" size="primary" @click="handleMerge">
  79. <text class="gui-color-white">合批</text>
  80. </view>
  81. </view>
  82. </view>
  83. </cell>
  84. </list>
  85. <view>
  86. <!-- 提示窗示例 -->
  87. <uni-popup ref="popup" type="dialog">
  88. <uni-popup-dialog type="warn" cancel-text="取消" confirm-text="确认" title="重新分配货位"
  89. content="欢迎使用 uni-popup!" @confirm="dialogConfirm" @close="popup.close()">
  90. <!-- eslint-disable-next-line -->
  91. <template #default="custom">
  92. <view class="select-group">
  93. <view class="select-item">
  94. <text class="store-text">仓库</text>
  95. <view class="custom-select">
  96. <uni-data-select v-model="submitParams.erpStockId" :localdata="warehouseList"
  97. @change="handleSelectWareHouse" />
  98. </view>
  99. </view>
  100. <view class="select-item">
  101. <text class="store-text">区域</text>
  102. <view class="custom-select">
  103. <uni-data-select v-model="submitParams.wmsStoreAreaId" :localdata="regionList"
  104. @change="handleSelectRegion" />
  105. </view>
  106. </view>
  107. <view class="select-item">
  108. <text class="store-text">货位</text>
  109. <view class="custom-select">
  110. <uni-data-select v-model="submitParams.wmsStoreId" :localdata="locationList" />
  111. </view>
  112. </view>
  113. </view>
  114. </template>
  115. </uni-popup-dialog>
  116. </uni-popup>
  117. <uni-popup ref="errorTip" type="dialog">
  118. <uni-popup-dialog type="error" cancel-text="关闭" confirm-text="确认" title="提示"
  119. :content="errorTipMessage" @confirm="handleCloseErrorTipsModal"
  120. @close="handleCloseErrorTipsModal" />
  121. </uni-popup>
  122. </view>
  123. </template>
  124. </gui-page>
  125. </template>
  126. <script>
  127. import {
  128. defineComponent,
  129. ref,
  130. onBeforeMount
  131. } from 'vue'
  132. import {
  133. useSetWareHouseStore
  134. } from '@/stores/useSetWareHouseStore.js';
  135. export default defineComponent({
  136. setup() {
  137. const goBack = function() {
  138. uni.$goBack('/pages/workbranch/warehouse/materialDisass/materialWorkBranch')
  139. }
  140. const errorTip = ref('')
  141. const errorTipMessage = ref('')
  142. const easyinput = ref('')
  143. const easyinput2 = ref('')
  144. const errorState = ref(0)
  145. const isFetch = ref(false)
  146. const modalTitle = ref('重新分配货位')
  147. const popup = ref()
  148. const submitParams = ref({
  149. erpStockId: '', // 入库仓库
  150. wmsStoreAreaId: '', // 入库区域
  151. wmsStoreId: '', // 入库货位
  152. materialOne: {
  153. materialNo: '',
  154. materialName: '',
  155. qrCode: '',
  156. inQty: ''
  157. },
  158. materialTwo: {
  159. materialNo: '',
  160. materialName: '',
  161. qrCode: '',
  162. inQty: ''
  163. }
  164. })
  165. // 校验参数
  166. const validatorList = ref({
  167. erpStockId: '入库仓库',
  168. wmsStoreAreaId: '入库区域',
  169. wmsStoreId: '入库货位',
  170. materialOne: {
  171. materialNo: '1号物料编码',
  172. materialName: '1号物料名称',
  173. qrCode: '1号物料条码',
  174. inQty: '1号批次数量'
  175. },
  176. materialTwo: {
  177. materialNo: '2号物料编码',
  178. materialName: '2号物料名称',
  179. qrCode: '2号物料条码',
  180. inQty: '2号批次数量'
  181. }
  182. })
  183. const regionList = ref([])
  184. const warehouseList = ref([])
  185. const locationList = ref([])
  186. const store = useSetWareHouseStore();
  187. onBeforeMount(() => {
  188. warehouseList.value = store.$state.warehouseList
  189. })
  190. const confirmMaterialOne = function(e) {
  191. uni.$reqGet('splitOrMergeScanMaterial', {
  192. qrCode: e
  193. })
  194. .then(({
  195. code,
  196. data,
  197. msg
  198. }) => {
  199. if (code === 0) {
  200. submitParams.value.materialOne = {
  201. id: data?.id, // ID
  202. materialNo: data?.materialNo, // 物料编码
  203. materialName: data?.materialName, // 物料名称
  204. qrCode: data?.qrCode, // 物料条码
  205. inQty: data?.inQty // 批次数量
  206. }
  207. } else {
  208. // #ifdef APP-PLUS
  209. plus.device.beep(2)
  210. // #endif
  211. errorTipMessage.value = msg
  212. errorTip.value.open()
  213. errorState.value = 0
  214. }
  215. })
  216. }
  217. const confirmMaterialTwo = function(e) {
  218. uni.$reqGet('splitOrMergeScanMaterial', {
  219. qrCode: e
  220. })
  221. .then(({
  222. code,
  223. data,
  224. msg
  225. }) => {
  226. if (code === 0) {
  227. submitParams.value.materialTwo = {
  228. id: data?.id, // ID
  229. materialNo: data?.materialNo, // 物料编码
  230. materialName: data?.materialName, // 物料名称
  231. qrCode: data?.qrCode, // 物料条码
  232. inQty: data?.inQty // 批次数量
  233. }
  234. } else {
  235. // #ifdef APP-PLUS
  236. plus.device.beep(2)
  237. // #endif
  238. errorTipMessage.value = msg
  239. errorTip.value.open()
  240. errorState.value = 1
  241. }
  242. })
  243. }
  244. const handleMapass = function(state) {
  245. const mpaasScanModule = uni.requireNativePlugin('Mpaas-Scan-Module')
  246. mpaasScanModule.mpaasScan({
  247. // 扫码识别类型,参数可多选,qrCode、barCode,不设置,默认识别所有
  248. 'scanType': ['qrCode', 'barCode'],
  249. // 是否隐藏相册,默认false不隐藏
  250. 'hideAlbum': false
  251. },
  252. (ret) => {
  253. if (ret.resp_code === 1000) {
  254. uni.$grace.msg('扫描到内容:' + ret.resp_result)
  255. if (state === 'row1') {
  256. uni.$reqGet('splitOrMergeScanMaterial', {
  257. qrCode: ret.resp_result
  258. })
  259. .then(({
  260. code,
  261. data,
  262. msg
  263. }) => {
  264. if (code === 0) {
  265. submitParams.value.materialOne = {
  266. id: data?.id, // ID
  267. materialNo: data?.materialNo, // 物料编码
  268. materialName: data?.materialName, // 物料名称
  269. qrCode: data?.qrCode, // 物料条码
  270. inQty: data?.inQty // 批次数量
  271. }
  272. } else {
  273. // #ifdef APP-PLUS
  274. plus.device.beep(2)
  275. // #endif
  276. errorTipMessage.value = msg
  277. errorTip.value.open()
  278. errorState.value = 0
  279. }
  280. })
  281. } else {
  282. uni.$reqGet('splitOrMergeScanMaterial', {
  283. qrCode: ret.resp_result
  284. })
  285. .then(({
  286. code,
  287. data,
  288. msg
  289. }) => {
  290. if (code === 0) {
  291. submitParams.value.materialTwo = {
  292. id: data?.id, // ID
  293. materialNo: data?.materialNo, // 物料编码
  294. materialName: data?.materialName, // 物料名称
  295. qrCode: data?.qrCode, // 物料条码
  296. inQty: data?.inQty // 批次数量
  297. }
  298. } else {
  299. // #ifdef APP-PLUS
  300. plus.device.beep(2)
  301. // #endif
  302. errorTipMessage.value = msg
  303. errorTip.value.open()
  304. errorState.value = 1
  305. }
  306. })
  307. }
  308. }
  309. })
  310. }
  311. // 合批
  312. const handleMerge = function() {
  313. popup.value.open('center')
  314. }
  315. const handleSelectWareHouse = function(e) {
  316. submitParams.value.wmsStoreAreaId = ''
  317. submitParams.value.wmsStoreId = ''
  318. locationList.value = []
  319. store.handleGetRegionList(e).then(ret => {
  320. regionList.value = ret
  321. })
  322. }
  323. const handleSelectRegion = function(e) {
  324. submitParams.value.wmsStoreId = ''
  325. locationList.value = []
  326. store.handleGetLocationList(e).then(ret => {
  327. locationList.value = ret
  328. })
  329. }
  330. // 合批弹框确认事件
  331. const dialogConfirm = function() {
  332. if (isFetch.value === true) {
  333. uni.$grace.msg('物料合批中...')
  334. } else {
  335. const keys = Object.keys(submitParams.value.materialOne)
  336. const keys2 = Object.keys(submitParams.value.materialTwo)
  337. for (let x = 0; x < keys.length; x++) {
  338. const validataIsItEmpty = ['', null, undefined, NaN].includes(submitParams.value
  339. .materialOne[keys[x]])
  340. if (validataIsItEmpty) {
  341. uni.showToast({
  342. title: validatorList.value.materialOne[keys[x]] + '不能为空!',
  343. icon: 'none',
  344. duration: 2000
  345. })
  346. return
  347. }
  348. }
  349. for (let x = 0; x < keys2.length; x++) {
  350. const validataIsItEmpty = ['', null, undefined, NaN].includes(submitParams.value
  351. .materialTwo[keys[x]])
  352. if (validataIsItEmpty) {
  353. uni.showToast({
  354. title: validatorList.value.materialTwo[keys[x]] + '不能为空!',
  355. icon: 'none',
  356. duration: 2000
  357. })
  358. return
  359. }
  360. }
  361. if (submitParams.value.erpStockId === '' || submitParams.value.wmsStoreAreaId === '' ||
  362. submitParams.value.wmsStoreId === '') {
  363. uni.showToast({
  364. title: '区域、仓库、货位必填!',
  365. icon: 'none',
  366. duration: 2000
  367. })
  368. return
  369. }
  370. popup.value.close()
  371. isFetch.value = true
  372. const params = {
  373. materialOne: submitParams.value.materialOne,
  374. materialTwo: submitParams.value.materialTwo,
  375. erpStockId: submitParams.value.erpStockId,
  376. wmsStoreAreaId: submitParams.value.wmsStoreAreaId,
  377. wmsStoreId: submitParams.value.wmsStoreId
  378. }
  379. uni.$reqPost('materialMerge', params)
  380. .then(({
  381. code,
  382. data,
  383. msg
  384. }) => {
  385. isFetch.value = false
  386. submitParams.value = {
  387. materialOne: {
  388. materialNo: '', // 物料编码
  389. materialName: '', // 物料名称
  390. qrCode: '', // 物料条码
  391. inQty: '' // 批次数量
  392. },
  393. materialTwo: {
  394. materialNo: '', // 物料编码
  395. materialName: '', // 物料名称
  396. qrCode: '', // 物料条码
  397. inQty: '' // 批次数量
  398. },
  399. wmsStoreAreaId: '', // 区域
  400. wmsStoreId: '', // 货位
  401. erpStockId: '' // 仓库
  402. }
  403. if (code === 0) {
  404. // 时间格式转换
  405. data?.forEach(item => {
  406. item.createTime = $parseTime(item
  407. .createTime)
  408. })
  409. const message = {
  410. 'ClientId': 'webclient',
  411. 'templateName': 'http://192.168.1.156:9900/Upload/Tables/s_reportmodel/202303011151371504/materialMerge.btw',
  412. 'DataList': data
  413. }
  414. // uni.$useStore().mqttConfig.publish('adminS001', JSON.stringify(message), {
  415. // qos: 1
  416. // })
  417. } else {
  418. uni.$grace.msg(msg)
  419. }
  420. })
  421. }
  422. }
  423. const setInputFocus = function() {
  424. submitParams.value.materialOne.qrCode = ''
  425. easyinput.value.onBlur()
  426. easyinput.value.onFocus()
  427. }
  428. // 关闭错误信息弹窗
  429. const handleCloseErrorTipsModal = async function() {
  430. errorTip.value.close()
  431. if (errorState.value === 0) {
  432. await setInputFocus()
  433. }
  434. }
  435. // 禁用软键盘
  436. const handleInputFocus = function() {
  437. setTimeout(() => {
  438. uni.hideKeyboard()
  439. }, 100)
  440. }
  441. return {
  442. goBack,
  443. easyinput,
  444. easyinput2,
  445. errorTip,
  446. errorTipMessage,
  447. submitParams,
  448. confirmMaterialOne,
  449. confirmMaterialTwo,
  450. handleInputFocus,
  451. handleMapass,
  452. handleMerge,
  453. modalTitle,
  454. handleSelectWareHouse,
  455. handleSelectRegion,
  456. popup,
  457. dialogConfirm,
  458. regionList,
  459. warehouseList,
  460. locationList,
  461. handleCloseErrorTipsModal
  462. }
  463. }
  464. })
  465. </script>
  466. <style lang="scss" scoped>
  467. .gui-header-leader-btns {
  468. color: black;
  469. font-size: 24px !important;
  470. margin-left: 24rpx;
  471. }
  472. .gui-sbody {
  473. font-size: 14px;
  474. background-color: rgba(234, 239, 242, 1);
  475. }
  476. .form {
  477. margin-top: 85px;
  478. }
  479. .row-1,
  480. .row-2,
  481. .row-3 {
  482. height: 55px;
  483. display: flex;
  484. justify-content: center;
  485. background-color: white;
  486. }
  487. .row-2,
  488. .row-3 {
  489. margin-top: 10px;
  490. }
  491. .row-1,
  492. .row-3 {
  493. .row-1-card,
  494. .row-3-card {
  495. display: flex;
  496. flex-direction: row;
  497. justify-content: space-between;
  498. align-items: center;
  499. width: 100%;
  500. padding-left: 10px;
  501. padding-right: 10px;
  502. }
  503. }
  504. .row-2 {
  505. height: 200px;
  506. .row-2-card {
  507. display: flex;
  508. flex-direction: column;
  509. .row-space-between {
  510. flex: 1;
  511. width: calc(100vw - 40px);
  512. display: flex;
  513. flex-direction: row;
  514. justify-content: space-between;
  515. align-items: center;
  516. padding-top: 12px;
  517. padding-bottom: 12px;
  518. }
  519. }
  520. }
  521. .row-operation {
  522. height: 110px;
  523. padding-left: 20px;
  524. padding-right: 20px;
  525. display: flex;
  526. flex-direction: row;
  527. justify-content: center;
  528. align-items: center;
  529. .row-operation-card {
  530. flex: 1;
  531. .btn-row-1 {
  532. margin-bottom: 5px !important;
  533. }
  534. }
  535. }
  536. .input-200 {
  537. width: 200px;
  538. padding-left: 10px;
  539. }
  540. .input-300 {
  541. width: 300px;
  542. padding-left: 10px;
  543. }
  544. .font-icons {
  545. width: 40px;
  546. font-size: 20px;
  547. }
  548. .select-group {
  549. display: flex;
  550. flex-direction: column;
  551. flex: 1;
  552. .select-item {
  553. display: flex;
  554. flex-direction: row;
  555. align-items: center;
  556. margin-bottom: 10px;
  557. .store-text {
  558. margin-right: 14px;
  559. }
  560. }
  561. }
  562. </style>