bad-in.vue 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <template>
  2. <view class="common-page" style="padding: 0;" @click="playGlobalSound">
  3. <!-- 顶部导航栏 -->
  4. <view class="header">
  5. <u-navbar title="不良入库" :border="false" fixed safe-area-inset-top>
  6. <template #left>
  7. <u-icon name="arrow-left" color="#333333" size="20" @click="goBack"></u-icon>
  8. </template>
  9. <template #right>
  10. <u-text type="primary" text="提交" @click="onSubmit" v-permission="'app:wms:badIn:submit'"></u-text>
  11. </template>
  12. </u-navbar>
  13. </view>
  14. <!-- 主要内容区域 -->
  15. <view class="content">
  16. <!-- 订单基本信息 -->
  17. <view class="info-section">
  18. <u-form :model="formData" ref="formRef" label-width="80px" label-position="left">
  19. <u-form-item label="订单总数" required>
  20. <span>{{ ordersMap.length }}</span>
  21. </u-form-item>
  22. <u-form-item label="仓库" required>
  23. <view @click="selectWarehouse" style="width: 100%;">
  24. <u-input v-model="formData.godownName" readonly custom-style="font-size:32rpx"
  25. placeholder="请选择仓库" suffixIcon="arrow-right" />
  26. </view>
  27. </u-form-item>
  28. <u-form-item label="库位" required>
  29. <view @click="selectLocation" style="width: 100%;">
  30. <u-input v-model="formData.positionCode" readonly custom-style="font-size:32rpx"
  31. placeholder="请选择库位" suffixIcon="arrow-right" />
  32. </view>
  33. </u-form-item>
  34. </u-form>
  35. </view>
  36. <!-- 订单列表 -->
  37. <view class="order-list">
  38. <bad-item v-for="(order, index) in ordersMap" :key="order.orderId" :data="order" @delete="deleteOrder(index)"
  39. @edit="editOrder(index)"></bad-item>
  40. </view>
  41. <!-- 底部扫码输入框 -->
  42. <view class="fixed-bottom pad-20" style="background: #ffffff;">
  43. <u-search placeholder="请输入物流单号" :searchIconSize="24" bgColor="#f6f7f6"
  44. @search="getDetailByCode(waybillCode)" v-model="waybillCode" custom-style="font-size:32rpx"
  45. placeholder-style="font-size:32rpx" :clearabled="true" :focus="false" :showAction="false"
  46. :height="42"></u-search>
  47. <u-icon name="scan" size="32" color="#19be6b" @click="openScan"></u-icon>
  48. </view>
  49. </view>
  50. <!-- 备注弹窗 -->
  51. <remark-dialog v-model:visible="remarkVisible" :initial-value="currentRemark"
  52. @confirm="handleRemarkConfirm"></remark-dialog>
  53. </view>
  54. </template>
  55. <script setup>
  56. import {
  57. ref,
  58. reactive,
  59. onMounted,
  60. onUnmounted,
  61. } from 'vue';
  62. import { onShow } from '@dcloudio/uni-app';
  63. import BadItem from './components/BadItem.vue';
  64. import RemarkDialog from './components/RemarkDialog.vue'
  65. const waybillCode = ref()
  66. // 表单数据
  67. const formData = reactive({
  68. godownName: '',
  69. godownId: '',
  70. positionCode: ''
  71. });
  72. //点击全局音效
  73. function playGlobalSound(){
  74. uni.$u.playClickSound()
  75. }
  76. // 订单列表
  77. const ordersMap = ref([]);
  78. const codeMap = ref([]); // 记录已扫码的物流单号
  79. //根据扫码的物流单号查询订单详情 /app/stock/searchOrder waybillCode
  80. function getDetailByCode(code) {
  81. if (codeMap.value.includes(code)) {
  82. uni.$u.ttsModule.speak('重复扫描')
  83. return
  84. }
  85. uni.$u.http.get("/app/stock/searchOrder?waybillCode=" + code).then(res => {
  86. if (res.code == 200) {
  87. ordersMap.value.unshift(res.data)
  88. codeMap.value.push(code)
  89. } else if (res.code == 601) {
  90. uni.$u.ttsModule.speak(res.msg)
  91. uni.showModal({
  92. title: '提示',
  93. content: res.msg,
  94. showCancel: false,
  95. success: () => {
  96. playGlobalSound()
  97. }
  98. })
  99. } else {
  100. uni.$u.toast(res.msg)
  101. }
  102. })
  103. }
  104. // 备注弹窗相关
  105. const remarkVisible = ref(false)
  106. const currentRemark = ref('')
  107. const currentEditIndex = ref(-1)
  108. // 方法定义
  109. const goBack = () => {
  110. if (ordersMap.value.length > 0) {
  111. uni.showModal({
  112. title: '退出确认',
  113. content: '是否确认放弃本次入库?',
  114. success: (res) => {
  115. playGlobalSound()
  116. if (res.confirm) {
  117. uni.navigateBack();
  118. }
  119. }
  120. })
  121. } else {
  122. uni.navigateBack();
  123. }
  124. };
  125. const onSubmit = () => {
  126. if (!formData.godownId || !formData.positionCode) {
  127. uni.$u.toast('请先选择仓库和库位')
  128. uni.$u.ttsModule.speak('请先选择仓库和库位')
  129. return
  130. }
  131. uni.showModal({
  132. title: '提交确认',
  133. content: '是否确认提交本次入库?',
  134. success: (res) => {
  135. playGlobalSound()
  136. if (res.confirm) {
  137. handleSubmitConfirm()
  138. }
  139. }
  140. })
  141. }
  142. const handleSubmitConfirm = async () => {
  143. uni.showLoading({
  144. title: '提交中...'
  145. })
  146. let orderInfo = ordersMap.value.map(item => {
  147. return {
  148. orderId: item.orderId,
  149. waybillCode: item.waybillCode,
  150. bookNum: item.badNum,
  151. remark: item.remark
  152. }
  153. })
  154. if (orderInfo.length == 0) {
  155. uni.hideLoading()
  156. uni.$u.ttsModule.speak('请添加订单数据')
  157. return
  158. }
  159. // 提交入库
  160. uni.$u.http.post('/app/stock/addBatch', {
  161. godownId: formData.godownId,
  162. positionCode: formData.positionCode,
  163. orderInfo
  164. }).then(res => {
  165. if (res.code == 200) {
  166. uni.$u.toast('入库成功')
  167. uni.$u.ttsModule.speak('入库成功')
  168. clearData()
  169. } else {
  170. uni.$u.toast(res.msg)
  171. }
  172. }).finally(() => {
  173. uni.hideLoading()
  174. })
  175. }
  176. //成功之后,清空数据
  177. const clearData = () => {
  178. ordersMap.value.length = 0
  179. waybillCode.value = ''
  180. formData.positionCode = ''
  181. // 不清空仓库选择,保留用户最近选择的仓库
  182. }
  183. const editOrder = (index) => {
  184. // 编辑订单
  185. openRemarkDialog(index)
  186. };
  187. const openScan = () => {
  188. // 打开扫码器
  189. uni.scanCode({
  190. success: (res) => {
  191. waybillCode.value = res.result
  192. getDetailByCode(res.result)
  193. },
  194. fail: (err) => {
  195. uni.showToast({
  196. title: '扫码失败',
  197. icon: 'error'
  198. });
  199. }
  200. });
  201. };
  202. //选择库位
  203. function selectLocation() {
  204. if (!formData.godownId) {
  205. uni.$u.toast('请先选择仓库')
  206. uni.$u.ttsModule.speak('请先选择仓库')
  207. return
  208. }
  209. //如果有库位,也带过去
  210. uni.navigateTo({
  211. url: "/pages/index/wms/location-select?godownId=" + formData.godownId + "&positionCode=" + formData.positionCode
  212. })
  213. }
  214. // 删除订单
  215. const deleteOrder = (index) => {
  216. ordersMap.value.splice(index, 1);
  217. };
  218. // #ifdef APP-PLUS
  219. const { unregister } = uni.$u.useEventListener((e) => {
  220. if (e.barcode) {
  221. waybillCode.value = e.barcode
  222. getDetailByCode(e.barcode)
  223. }
  224. });
  225. // #endif
  226. onMounted(() => {
  227. // 从本地存储读取最近选择的仓库
  228. const lastWarehouse = uni.getStorageSync('badInLastWarehouse')
  229. if (lastWarehouse) {
  230. formData.godownName = lastWarehouse.godownName
  231. formData.godownId = lastWarehouse.godownId
  232. }
  233. // 监听库位选择
  234. uni.$on('updateLocation', (locationCode) => {
  235. formData.positionCode = locationCode
  236. })
  237. // 监听仓库选择
  238. uni.$on('updateWarehouse', (data) => {
  239. formData.godownName = data.godownName
  240. formData.godownId = data.id
  241. // 保存到本地存储
  242. uni.setStorageSync('badInLastWarehouse', {
  243. godownName: data.godownName,
  244. godownId: data.id
  245. })
  246. })
  247. })
  248. onUnmounted(() => {
  249. unregister();
  250. uni.$off('updateLocation')
  251. uni.$off('updateWarehouse')
  252. });
  253. // 打开备注弹窗
  254. const openRemarkDialog = (index, remark = '') => {
  255. currentEditIndex.value = index
  256. currentRemark.value = remark
  257. remarkVisible.value = true
  258. }
  259. // 处理备注确认
  260. const handleRemarkConfirm = (remark) => {
  261. if (currentEditIndex.value >= 0) {
  262. ordersMap.value[currentEditIndex.value].remark = remark
  263. }
  264. currentEditIndex.value = -1
  265. currentRemark.value = ''
  266. }
  267. // 打开仓库选择页面
  268. const selectWarehouse = () => {
  269. uni.navigateTo({
  270. url: '/pages/index/wms/warehouse-select?godownId=' + formData.godownId
  271. })
  272. }
  273. </script>
  274. <style scoped>
  275. .content {
  276. padding-top: 44px;
  277. border-radius: 0;
  278. /* #ifdef APP-PLUS */
  279. padding-top: 100px;
  280. /* #endif */
  281. }
  282. .info-section {
  283. background-color: #ffffff;
  284. padding: 15px 20px;
  285. padding-bottom: 5px;
  286. margin-bottom: 12px;
  287. box-sizing: border-box;
  288. }
  289. .order-list {
  290. margin-bottom: 60px;
  291. }
  292. </style>