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.

400 lines
7.9 KiB

6 months ago
6 months ago
  1. <template>
  2. <div class="pda-container">
  3. <!-- 头部栏 -->
  4. <div class="header-bar">
  5. <div class="header-left" @click="$router.back()">
  6. <i class="el-icon-arrow-left"></i>
  7. <span>其他入库</span>
  8. </div>
  9. <div class="header-right" @click="$router.push({ path: '/' })">
  10. 首页
  11. </div>
  12. </div>
  13. <!-- 搜索框 -->
  14. <div class="search-container">
  15. <el-input clearable
  16. v-model="searchCode"
  17. placeholder="请扫描入库单或关联单号"
  18. prefix-icon="el-icon-search"
  19. @keyup.enter.native="handleSearch"
  20. ref="searchInput"
  21. />
  22. </div>
  23. <!-- 入库单列表 -->
  24. <div class="content-area">
  25. <div
  26. v-for="(item, index) in inboundList"
  27. :key="index"
  28. class="inbound-card"
  29. @click="goToInboundPage(item)"
  30. >
  31. <div class="card-title">
  32. <span class="title-label">入库单号</span>
  33. <span class="title-value">{{ item.inboundNo }}</span>
  34. </div>
  35. <div class="card-details">
  36. <div class="detail-item">
  37. <div class="detail-label">关联订单</div>
  38. <div class="detail-value">{{ item.relatedNo }}</div>
  39. </div>
  40. <div class="detail-item">
  41. <div class="detail-label">标签张数</div>
  42. <div class="detail-value">
  43. <span class="qualified">{{ item.totalLabels }}</span>
  44. </div>
  45. </div>
  46. <div class="detail-item">
  47. <div class="detail-label">物料总数</div>
  48. <div class="detail-value">
  49. <span class="qualified">{{ item.totalQty }}</span>
  50. </div>
  51. </div>
  52. </div>
  53. </div>
  54. <!-- 空状态 -->
  55. <div v-if="inboundList.length === 0 && !loading" class="empty-state">
  56. <i class="el-icon-box"></i>
  57. <p>暂无待入库单据</p>
  58. </div>
  59. <!-- 加载状态 -->
  60. <div v-if="loading" class="loading-state">
  61. <i class="el-icon-loading"></i>
  62. <p>加载中...</p>
  63. </div>
  64. </div>
  65. </div>
  66. </template>
  67. <script>
  68. import { getOtherInboundList } from "@/api/other-inbound/other-inbound.js";
  69. import { getCurrentWarehouse } from '@/utils'
  70. import moment from 'moment';
  71. export default {
  72. data() {
  73. return {
  74. searchCode: '',
  75. inboundList: [],
  76. loading: false
  77. };
  78. },
  79. methods: {
  80. formatDate(date) {
  81. return date ? moment(date).format('YYYY-MM-DD') : '';
  82. },
  83. // 处理搜索
  84. handleSearch() {
  85. if (this.searchCode.trim()) {
  86. this.searchInboundList(this.searchCode.trim());
  87. } else {
  88. this.loadInboundList();
  89. }
  90. },
  91. // 加载其他入库单列表
  92. loadInboundList() {
  93. const currentWarehouse = getCurrentWarehouse();
  94. if (!currentWarehouse) {
  95. this.$message.error('请先选择仓库');
  96. return;
  97. }
  98. this.loading = true;
  99. const params = {
  100. warehouseId: currentWarehouse,
  101. site: localStorage.getItem('site'),
  102. status: '待入库',
  103. };
  104. getOtherInboundList(params).then(({ data }) => {
  105. this.loading = false;
  106. if (data && data.code === 0) {
  107. this.inboundList = data.data || [];
  108. } else {
  109. this.$message.error(data.msg || '获取数据失败');
  110. }
  111. }).catch(error => {
  112. this.loading = false;
  113. console.error('获取其他入库单列表失败:', error);
  114. this.$message.error('获取数据失败');
  115. });
  116. },
  117. // 搜索特定入库单
  118. searchInboundList(searchCode) {
  119. const currentWarehouse = getCurrentWarehouse();
  120. if (!currentWarehouse) {
  121. this.$message.error('请先选择仓库');
  122. return;
  123. }
  124. this.loading = true;
  125. const params = {
  126. warehouseId: currentWarehouse,
  127. searchCode: searchCode,
  128. site: localStorage.getItem('site'),
  129. status: '待入库'
  130. };
  131. getOtherInboundList(params).then(({ data }) => {
  132. this.loading = false;
  133. if (data && data.code === 0) {
  134. if (data.data.length === 0) {
  135. this.$message.warning('未找到匹配的入库单');
  136. }
  137. this.inboundList = data.data || [];
  138. } else {
  139. this.$message.error(data.msg || '查询失败');
  140. }
  141. }).catch(error => {
  142. this.loading = false;
  143. console.error('搜索失败:', error);
  144. this.$message.error('查询失败');
  145. });
  146. },
  147. // 跳转到入库页面
  148. goToInboundPage(item) {
  149. this.$router.push({
  150. name: 'otherInboundDetail',
  151. params: {
  152. inboundNo: item.inboundNo,
  153. buNo: item.buNo
  154. }
  155. });
  156. }
  157. },
  158. mounted() {
  159. // 聚焦搜索框
  160. this.$nextTick(() => {
  161. if (this.$refs.searchInput) {
  162. this.$refs.searchInput.focus();
  163. }
  164. });
  165. // 加载数据
  166. this.loadInboundList();
  167. }
  168. };
  169. </script>
  170. <style scoped>
  171. .pda-container {
  172. width: 100vw;
  173. height: 100vh;
  174. display: flex;
  175. flex-direction: column;
  176. background: #f5f5f5;
  177. }
  178. /* 头部栏 */
  179. .header-bar {
  180. display: flex;
  181. justify-content: space-between;
  182. align-items: center;
  183. padding: 8px 16px;
  184. background: #17B3A3;
  185. color: white;
  186. height: 40px;
  187. min-height: 40px;
  188. }
  189. .header-left {
  190. display: flex;
  191. align-items: center;
  192. cursor: pointer;
  193. font-size: 16px;
  194. font-weight: 500;
  195. }
  196. .header-left i {
  197. margin-right: 8px;
  198. font-size: 18px;
  199. }
  200. .header-right {
  201. cursor: pointer;
  202. font-size: 16px;
  203. font-weight: 500;
  204. }
  205. /* 搜索容器 */
  206. .search-container {
  207. padding: 12px 16px;
  208. background: white;
  209. }
  210. /* 内容区域 */
  211. .content-area {
  212. flex: 1;
  213. overflow-y: auto;
  214. padding: 12px 16px;
  215. }
  216. /* 入库卡片 */
  217. .inbound-card {
  218. background: white;
  219. border-radius: 8px;
  220. margin-bottom: 12px;
  221. padding: 16px;
  222. box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  223. cursor: pointer;
  224. transition: all 0.2s ease;
  225. }
  226. .inbound-card:hover {
  227. box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
  228. transform: translateY(-1px);
  229. }
  230. .inbound-card:active {
  231. transform: translateY(0);
  232. }
  233. /* 卡片标题 */
  234. .card-title {
  235. margin-bottom: 12px;
  236. }
  237. .title-label {
  238. font-size: 12px;
  239. color: #666;
  240. display: block;
  241. margin-bottom: 4px;
  242. }
  243. .title-value {
  244. font-size: 16px;
  245. font-weight: bold;
  246. color: #333;
  247. margin-left: 20px;
  248. }
  249. /* 卡片详情 */
  250. .card-details {
  251. display: flex;
  252. justify-content: space-between;
  253. align-items: flex-start;
  254. gap: 4px;
  255. }
  256. .detail-item {
  257. flex: 1;
  258. text-align: center;
  259. min-width: 60px;
  260. max-width: 60px;
  261. }
  262. .detail-label {
  263. font-size: 11px;
  264. color: #666;
  265. margin-bottom: 4px;
  266. line-height: 1.2;
  267. margin-left: -12px;
  268. }
  269. .detail-value {
  270. font-size: 13px;
  271. color: #333;
  272. line-height: 1.2;
  273. margin-left: -12px;
  274. }
  275. .detail-value .qualified {
  276. color: #17B3A3;
  277. font-weight: 500;
  278. }
  279. .detail-value .total {
  280. color: #333;
  281. font-weight: 500;
  282. }
  283. .detail-value .total::before {
  284. content: '/';
  285. color: #333;
  286. }
  287. /* 空状态 */
  288. .empty-state {
  289. display: flex;
  290. flex-direction: column;
  291. align-items: center;
  292. justify-content: center;
  293. padding: 60px 20px;
  294. color: #999;
  295. }
  296. .empty-state i {
  297. font-size: 48px;
  298. margin-bottom: 16px;
  299. }
  300. .empty-state p {
  301. font-size: 14px;
  302. margin: 0;
  303. }
  304. /* 加载状态 */
  305. .loading-state {
  306. display: flex;
  307. flex-direction: column;
  308. align-items: center;
  309. justify-content: center;
  310. padding: 60px 20px;
  311. color: #17B3A3;
  312. }
  313. .loading-state i {
  314. font-size: 24px;
  315. margin-bottom: 12px;
  316. animation: spin 1s linear infinite;
  317. }
  318. @keyframes spin {
  319. from { transform: rotate(0deg); }
  320. to { transform: rotate(360deg); }
  321. }
  322. .loading-state p {
  323. font-size: 14px;
  324. margin: 0;
  325. }
  326. /* 响应式设计 */
  327. @media (max-width: 360px) {
  328. .header-bar {
  329. padding: 8px 12px;
  330. }
  331. .search-container {
  332. padding: 8px 12px;
  333. }
  334. .content-area {
  335. padding: 8px 12px;
  336. }
  337. .inbound-card {
  338. padding: 12px;
  339. }
  340. .card-details {
  341. flex-wrap: wrap;
  342. gap: 6px;
  343. }
  344. .detail-item {
  345. flex: 0 0 48%;
  346. margin-bottom: 6px;
  347. min-width: 50px;
  348. }
  349. }
  350. </style>