You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

329 lines
11 KiB

9 months ago
  1. <template>
  2. <div>
  3. <div class="pda-container" v-loading.fullscreen.lock="fullscreenLoading">
  4. <div class="status-bar">
  5. <div class="goBack" @click="handleBack"><i class="el-icon-arrow-left"></i>上一页</div>
  6. <div class="goBack">{{ viewMode === 'records' ? '补打标签' : 'HandlingUnit列表' }}</div>
  7. <div class="network" style="color: #fff" @click="$router.push({ path: '/' })">🏠首页</div>
  8. </div>
  9. <div style="overflow-y: auto">
  10. <!-- 扫描PO单号 -->
  11. <div v-if="viewMode === 'records'" class="scan-box" style="margin: 2px;">
  12. <el-input clearable v-model="scanCode" placeholder="扫描PO条码或输入PO号"
  13. @keyup.enter.native="searchReceiveRecords" ref="scanCodeRef" />
  14. </div>
  15. <!-- 接收记录列表 -->
  16. <div v-if="viewMode === 'records' && receiveRecords.length > 0" class="item-list" style="margin: 2px;">
  17. <el-form label-position="top" style="margin: 3px;">
  18. <el-row :gutter="5"
  19. v-for="(record, index) in receiveRecords"
  20. :key="index"
  21. :class="index < receiveRecords.length - 1 ? 'bottom-line-row' : ''"
  22. @click.native="viewHandlingUnits(record)">
  23. <el-col :span="8">
  24. <el-form-item label="商品编码"><span>{{ record.partNo }}</span></el-form-item>
  25. </el-col>
  26. <el-col :span="8">
  27. <el-form-item label="行号/下达号"><span>{{ record.lineNo }}/{{ record.wdr || '*' }}</span></el-form-item>
  28. </el-col>
  29. <el-col :span="8">
  30. <el-form-item label="">
  31. <el-button type="text" class="viewButton" @click.stop="viewHandlingUnits(record)"
  32. style="margin-top: 10px;margin-left: 20px" size="small">查看</el-button>
  33. </el-form-item>
  34. </el-col>
  35. <el-col :span="24">
  36. <el-form-item label="商品描述"><span>{{ record.description }}</span></el-form-item>
  37. </el-col>
  38. <el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }">
  39. <el-form-item label="接收数量"><span>{{ record.transQty }}</span></el-form-item>
  40. </el-col>
  41. <el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }">
  42. <el-form-item label="批号"><span>{{ record.batchNo }}</span></el-form-item>
  43. </el-col>
  44. <el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }">
  45. <el-form-item label="库位"><span>{{ record.locationNo }}</span></el-form-item>
  46. </el-col>
  47. <el-col :span="6" :class="{ mt10: getTextWidth(record.description) > 34 }">
  48. <el-form-item label="接收日期"><span>{{ formatDate(record.receiveDate) }}</span></el-form-item>
  49. </el-col>
  50. </el-row>
  51. </el-form>
  52. </div>
  53. <!-- HandlingUnit列表 -->
  54. <div v-if="viewMode === 'handlingUnits'" class="item-list" style="margin: 2px;">
  55. <div v-if="currentReceiveRecord" style="background: #f5f7fa; padding: 10px; margin-bottom: 10px; border-radius: 4px;">
  56. <div style="font-weight: bold; margin-bottom: 5px;">接收记录信息</div>
  57. <div style="font-size: 14px; color: #666;">
  58. {{ currentReceiveRecord.partNo }} - {{ currentReceiveRecord.description }}
  59. <br>接收单号: {{ currentReceiveRecord.receiptNo }}
  60. </div>
  61. </div>
  62. <el-form label-position="top" style="margin: 3px;" v-if="handlingUnits.length > 0">
  63. <el-row :gutter="5"
  64. v-for="(unit, index) in handlingUnits"
  65. :key="index"
  66. :class="index < handlingUnits.length - 1 ? 'bottom-line-row' : ''">
  67. <el-col :span="12">
  68. <el-form-item label="Unit ID"><span>{{ unit.unitId }}</span></el-form-item>
  69. </el-col>
  70. <el-col :span="4">
  71. <el-form-item label="数量"><span>{{ unit.qty }}</span></el-form-item>
  72. </el-col>
  73. <el-col :span="8">
  74. <el-form-item label="">
  75. <el-button type="text" class="printButton" @click="reprintHandlingUnitLabel(unit)"
  76. style="margin-top: 10px;margin-left: 20px" size="small">补打</el-button>
  77. </el-form-item>
  78. </el-col>
  79. <el-col :span="12">
  80. <el-form-item label="批号"><span>{{ unit.batchNo }}</span></el-form-item>
  81. </el-col>
  82. <el-col :span="12">
  83. <el-form-item label="库位"><span>{{ unit.locationId }}</span></el-form-item>
  84. </el-col>
  85. <el-col :span="12">
  86. <el-form-item label="状态"><span>{{ unit.status }}</span></el-form-item>
  87. </el-col>
  88. <el-col :span="12">
  89. <el-form-item label="创建日期"><span>{{ formatDate(unit.createdDate) }}</span></el-form-item>
  90. </el-col>
  91. </el-row>
  92. </el-form>
  93. <div v-if="handlingUnits.length === 0 && !fullscreenLoading"
  94. style="text-align: center; padding: 20px; color: #999;">
  95. 该接收记录下没有HandlingUnit
  96. </div>
  97. </div>
  98. <!-- 无数据提示 -->
  99. <div v-if="viewMode === 'records' && scanCode && receiveRecords.length === 0 && !fullscreenLoading"
  100. style="text-align: center; padding: 20px; color: #999;">
  101. 未找到该PO单号的接收记录
  102. </div>
  103. </div>
  104. </div>
  105. </div>
  106. </template>
  107. <script>
  108. import { getPoReceiveRecords, getHandlingUnitsByReceiptNo, printLabel } from "@/api/po/po.js";
  109. export default {
  110. data() {
  111. return {
  112. scanCode: '',
  113. receiveRecords: [],
  114. handlingUnits: [],
  115. currentReceiptNo: '',
  116. currentReceiveRecord: null,
  117. viewMode: 'records', // 'records' | 'handlingUnits'
  118. site: localStorage.getItem('site'),
  119. warehouseId: localStorage.getItem('selectedWarehouse'),
  120. fullscreenLoading: false,
  121. // 打印相关配置
  122. reportId: 'PO_RECEIVE_LABEL',
  123. zplCode: '',
  124. paperSize: 'A4',
  125. orientation: 'Portrait',
  126. dpi: 300
  127. };
  128. },
  129. methods: {
  130. // 计算"显示宽度"
  131. getTextWidth(text) {
  132. if (!text) return 0
  133. let len = 0
  134. for (let char of text) {
  135. // 中文、全角符号
  136. if (/[\u4e00-\u9fa5\u3000-\u303F\uFF00-\uFFEF]/.test(char)) {
  137. len += 2
  138. } else {
  139. len += 1
  140. }
  141. }
  142. return len
  143. },
  144. handleBack() {
  145. if (this.viewMode === 'handlingUnits') {
  146. // 从HandlingUnit列表返回到接收记录列表
  147. this.viewMode = 'records';
  148. this.handlingUnits = [];
  149. this.currentReceiveRecord = null;
  150. this.currentReceiptNo = '';
  151. } else {
  152. // 从接收记录列表返回到上一页
  153. this.$router.back();
  154. }
  155. },
  156. // 搜索PO接收记录
  157. searchReceiveRecords() {
  158. if (!this.scanCode) {
  159. this.receiveRecords = [];
  160. return;
  161. }
  162. this.fullscreenLoading = true;
  163. getPoReceiveRecords({
  164. poNumber: this.scanCode,
  165. site: this.site,
  166. warehouseId: this.warehouseId
  167. }).then(({ data }) => {
  168. if (data.code === 0) {
  169. this.receiveRecords = data.rows || [];
  170. if (this.receiveRecords.length === 0) {
  171. this.$message.warning('未找到该PO单号的接收记录');
  172. }
  173. } else {
  174. this.$message.error(data.msg || '查询失败');
  175. this.receiveRecords = [];
  176. }
  177. }).catch(error => {
  178. console.error('查询接收记录失败:', error);
  179. this.$message.error('网络错误,请重试');
  180. this.receiveRecords = [];
  181. }).finally(() => {
  182. this.fullscreenLoading = false;
  183. });
  184. },
  185. // 查看HandlingUnit列表
  186. viewHandlingUnits(record) {
  187. this.currentReceiveRecord = record;
  188. this.currentReceiptNo = record.receiptNo;
  189. this.fullscreenLoading = true;
  190. getHandlingUnitsByReceiptNo({
  191. site: this.site,
  192. receiptNo: record.receiptNo
  193. }).then(({ data }) => {
  194. if (data.code === 0) {
  195. this.handlingUnits = data.rows || [];
  196. this.viewMode = 'handlingUnits';
  197. if (this.handlingUnits.length === 0) {
  198. this.$message.warning('该接收记录下没有HandlingUnit');
  199. }
  200. } else {
  201. this.$message.error(data.msg || '查询HandlingUnit失败');
  202. }
  203. }).catch(error => {
  204. console.error('查询HandlingUnit失败:', error);
  205. this.$message.error('网络错误,请重试');
  206. }).finally(() => {
  207. this.fullscreenLoading = false;
  208. });
  209. },
  210. // 补打HandlingUnit标签
  211. async reprintHandlingUnitLabel(unit) {
  212. if (this.fullscreenLoading) return;
  213. this.fullscreenLoading = true;
  214. try {
  215. await this.printViaServer(unit.unitId);
  216. this.$message.success('补打标签任务已发送!');
  217. } catch (error) {
  218. console.error('补打标签失败:', error);
  219. this.$message.error(`补打标签失败: ${error.message || error}`);
  220. } finally {
  221. this.fullscreenLoading = false;
  222. }
  223. },
  224. /**
  225. * 通过服务器打印
  226. */
  227. async printViaServer(unitId) {
  228. try {
  229. const printRequest = {
  230. reportId: this.reportId,
  231. zplCode: this.zplCode,
  232. paperSize: this.paperSize,
  233. orientation: this.orientation,
  234. dpi: this.dpi,
  235. userId: localStorage.getItem('userName'),
  236. username: localStorage.getItem('userName'),
  237. site: localStorage.getItem('site'),
  238. unitId: unitId
  239. }
  240. const { data } = await printLabel(printRequest)
  241. if (data.code === 200) {
  242. return Promise.resolve();
  243. } else {
  244. return Promise.reject(new Error(data.msg || '打印失败'));
  245. }
  246. } catch (error) {
  247. return Promise.reject(error);
  248. }
  249. },
  250. // 格式化日期
  251. formatDate(dateString) {
  252. if (!dateString) return '-';
  253. try {
  254. const date = new Date(dateString);
  255. return date.getFullYear() + '-' +
  256. String(date.getMonth() + 1).padStart(2, '0') + '-' +
  257. String(date.getDate()).padStart(2, '0') + ' ' +
  258. String(date.getHours()).padStart(2, '0') + ':' +
  259. String(date.getMinutes()).padStart(2, '0');
  260. } catch (error) {
  261. return dateString;
  262. }
  263. }
  264. },
  265. mounted() {
  266. this.$nextTick(() => {
  267. if (this.$refs.scanCodeRef) {
  268. this.$refs.scanCodeRef.focus();
  269. }
  270. });
  271. }
  272. };
  273. </script>
  274. <style scoped>
  275. .mt10 {
  276. margin-top: 10px;
  277. }
  278. .scan-box input {
  279. width: 100%;
  280. padding: 12px;
  281. font-size: 16px;
  282. }
  283. .item-list {
  284. flex: 1;
  285. overflow-y: auto;
  286. margin: 10px 0;
  287. border: 1px solid rgba(200, 200, 200, 0.8);
  288. }
  289. .item-list span {
  290. color: #000;
  291. font-size: 15px;
  292. }
  293. .bottom-line-row {
  294. border-bottom: 1px solid rgba(200, 200, 200, 0.8);
  295. }
  296. .printButton, .viewButton {
  297. font-size: 16px;
  298. border-radius: 3px;
  299. color: #17b3a3;
  300. }
  301. .item-list .el-row {
  302. cursor: pointer;
  303. transition: background 0.3s;
  304. }
  305. .item-list .el-row:hover {
  306. background: #f5f7fa;
  307. }
  308. .form-section >>> .el-col {
  309. margin-bottom: 12px;
  310. }
  311. .status-bar {
  312. display: flex;
  313. justify-content: space-between;
  314. align-items: center;
  315. background: #17b3a3;
  316. color: white;
  317. }
  318. </style>