locationPage.vue 18 KB

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