taskForm.vue 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  1. <template>
  2. <view class="">
  3. <view class="sticky-subsection" :style="{ top: `${stickyTop}px` }">
  4. <view class="subsection-wrap">
  5. <u-subsection
  6. fontSize="25"
  7. mode="subsection"
  8. :list="tabList"
  9. :current="curNow"
  10. @change="sectionChange"
  11. activeColor="#157A2C"
  12. ></u-subsection>
  13. </view>
  14. </view>
  15. <view
  16. class="sticky-subsection-placeholder"
  17. :style="{ height: `${stickyPlaceholderHeight}px` }"
  18. ></view>
  19. <!-- Tab 0: 入库单详情 -->
  20. <view v-show="curNow === 0" class="basic_info">
  21. <view class="info_header">
  22. <view class="info_title">入库单详情</view>
  23. <u-gap height="4" bgColor="#1890FF"></u-gap>
  24. </view>
  25. <view class="info_content">
  26. <u-row>
  27. <u-col span="4">
  28. <view class="label">物品名称:</view>
  29. </u-col>
  30. <u-col span="8">
  31. <view class="value">{{ form.categoryName || "—" }}</view>
  32. </u-col>
  33. </u-row>
  34. <u-row>
  35. <u-col span="4">
  36. <view class="label">物品编码:</view>
  37. </u-col>
  38. <u-col span="8">
  39. <view class="value">{{ form.categoryCode || "—" }}</view>
  40. </u-col>
  41. </u-row>
  42. <u-row>
  43. <u-col span="4">
  44. <view class="label">物品分类:</view>
  45. </u-col>
  46. <u-col span="8">
  47. <view class="value">{{ form.categoryLevelName || "—" }}</view>
  48. </u-col>
  49. </u-row>
  50. <u-row>
  51. <u-col span="4">
  52. <view class="label">包装数量:</view>
  53. </u-col>
  54. <u-col span="8">
  55. <view class="value">{{ totalPackage || "—" }}</view>
  56. </u-col>
  57. </u-row>
  58. <u-row>
  59. <u-col span="4">
  60. <view class="label">计量数量:</view>
  61. </u-col>
  62. <u-col span="8">
  63. <view class="value">{{ totalCount || "—" }}</view>
  64. </u-col>
  65. </u-row>
  66. </view>
  67. </view>
  68. <!-- Tab 1: 基本信息 -->
  69. <view v-show="curNow === 1" class="basic_info">
  70. <view class="info_header">
  71. <view class="info_title">基本信息</view>
  72. <u-gap height="4" bgColor="#1890FF"></u-gap>
  73. </view>
  74. <view class="info_content">
  75. <u-row>
  76. <u-col span="4">
  77. <view class="label">物品类型:</view>
  78. </u-col>
  79. <u-col span="8">
  80. <view class="value">{{ assetTypeLabel || "—" }}</view>
  81. </u-col>
  82. </u-row>
  83. <u-row>
  84. <u-col span="4">
  85. <view class="label">入库类型:</view>
  86. </u-col>
  87. <u-col span="8">
  88. <view class="value">{{ bizTypeLabel || "—" }}</view>
  89. </u-col>
  90. </u-row>
  91. <u-row>
  92. <u-col span="4">
  93. <view class="label">单据来源:</view>
  94. </u-col>
  95. <u-col span="8">
  96. <view class="value">{{ formData.sourceBizNo || "—" }}</view>
  97. </u-col>
  98. </u-row>
  99. <u-row>
  100. <u-col span="4">
  101. <view class="label">入库时间:</view>
  102. </u-col>
  103. <u-col span="8">
  104. <view class="value">{{ formData.storageTime || "—" }}</view>
  105. </u-col>
  106. </u-row>
  107. <u-row>
  108. <u-col span="4">
  109. <view class="label">入库登记人:</view>
  110. </u-col>
  111. <u-col span="8">
  112. <view class="value">{{ formData.createUserName || "—" }}</view>
  113. </u-col>
  114. </u-row>
  115. <u-row>
  116. <u-col span="4">
  117. <view class="label">审核人:</view>
  118. </u-col>
  119. <u-col span="8">
  120. <view class="value">{{ formData.approvalUserName || "—" }}</view>
  121. </u-col>
  122. </u-row>
  123. <u-row>
  124. <u-col span="4">
  125. <view class="label">备注:</view>
  126. </u-col>
  127. <u-col span="8">
  128. <view class="value">{{ formData.remark || "—" }}</view>
  129. </u-col>
  130. </u-row>
  131. </view>
  132. </view>
  133. <!-- Tab 2: 产品信息 -->
  134. <view v-show="curNow === 2" class="basic_info">
  135. <view class="info_header">
  136. <view class="info_title">产品信息</view>
  137. <u-gap height="4" bgColor="#1890FF"></u-gap>
  138. </view>
  139. <view v-if="!productList.length" class="empty_text"> 暂无产品信息 </view>
  140. <view v-for="(row, idx) in productList" :key="idx" class="card_box">
  141. <view class="card_title">产品 {{ idx + 1 }}</view>
  142. <u-row>
  143. <u-col span="3">
  144. <view class="label">编码:</view>
  145. </u-col>
  146. <u-col span="9">
  147. <view class="value">{{ row.categoryCode || "—" }}</view>
  148. </u-col>
  149. </u-row>
  150. <u-row>
  151. <u-col span="3">
  152. <view class="label">名称:</view>
  153. </u-col>
  154. <u-col span="9">
  155. <view class="value">{{ row.categoryName || "—" }}</view>
  156. </u-col>
  157. </u-row>
  158. <u-row>
  159. <u-col span="3">
  160. <view class="label">牌号:</view>
  161. </u-col>
  162. <u-col span="9">
  163. <view class="value">{{ row.brandNum || "—" }}</view>
  164. </u-col>
  165. </u-row>
  166. <u-row>
  167. <u-col span="3">
  168. <view class="label">型号:</view>
  169. </u-col>
  170. <u-col span="9">
  171. <view class="value">{{ row.categoryModel || "—" }}</view>
  172. </u-col>
  173. </u-row>
  174. <u-row>
  175. <u-col span="3">
  176. <view class="label">规格:</view>
  177. </u-col>
  178. <u-col span="9">
  179. <view class="value">{{ row.specification || "—" }}</view>
  180. </u-col>
  181. </u-row>
  182. <u-row>
  183. <u-col span="3">
  184. <view class="label">批次号:</view>
  185. </u-col>
  186. <u-col span="9">
  187. <view class="value">{{ row.batchNo || "—" }}</view>
  188. </u-col>
  189. </u-row>
  190. <u-row>
  191. <u-col span="3">
  192. <view class="label">包装数量:</view>
  193. </u-col>
  194. <u-col span="9">
  195. <view class="value">{{
  196. formatValueWithUnit(
  197. row.packingQuantityDisplay,
  198. row.packingQuantity,
  199. row.packingUnit,
  200. )
  201. }}</view>
  202. </u-col>
  203. </u-row>
  204. <u-row>
  205. <u-col span="3">
  206. <view class="label">计量数量:</view>
  207. </u-col>
  208. <u-col span="9">
  209. <view class="value">{{
  210. formatValueWithUnit(
  211. row.measureQuantityDisplay,
  212. row.measureQuantity,
  213. row.measureUnit,
  214. )
  215. }}</view>
  216. </u-col>
  217. </u-row>
  218. <u-row>
  219. <u-col span="3">
  220. <view class="label">重量:</view>
  221. </u-col>
  222. <u-col span="9">
  223. <view class="value">{{
  224. formatValueWithUnit(row.weightDisplay, row.weight, row.weightUnit)
  225. }}</view>
  226. </u-col>
  227. </u-row>
  228. <u-row>
  229. <u-col span="3">
  230. <view class="label">包装规格:</view>
  231. </u-col>
  232. <u-col span="9">
  233. <view class="value">{{ row.packingSpecification || "—" }}</view>
  234. </u-col>
  235. </u-row>
  236. <u-row>
  237. <u-col span="3">
  238. <view class="label">仓库:</view>
  239. </u-col>
  240. <u-col span="9">
  241. <view class="value">{{ row.warehouseName || "—" }}</view>
  242. </u-col>
  243. </u-row>
  244. <u-row>
  245. <u-col span="3">
  246. <view class="label">供应商:</view>
  247. </u-col>
  248. <u-col span="9">
  249. <view class="value">{{ row.supplierName || "—" }}</view>
  250. </u-col>
  251. </u-row>
  252. <u-row>
  253. <u-col span="3">
  254. <view class="label">供应商代号:</view>
  255. </u-col>
  256. <u-col span="9">
  257. <view class="value">{{ row.supplierCode || "—" }}</view>
  258. </u-col>
  259. </u-row>
  260. <u-row>
  261. <u-col span="3">
  262. <view class="label">机型:</view>
  263. </u-col>
  264. <u-col span="9">
  265. <view class="value">{{ formatField(row.modelKey) }}</view>
  266. </u-col>
  267. </u-row>
  268. <u-row>
  269. <u-col span="3">
  270. <view class="label">颜色:</view>
  271. </u-col>
  272. <u-col span="9">
  273. <view class="value">{{ formatField(row.colorKey) }}</view>
  274. </u-col>
  275. </u-row>
  276. <u-row>
  277. <u-col span="3">
  278. <view class="label">生产要求:</view>
  279. </u-col>
  280. <u-col span="9">
  281. <view class="value">{{ row.productionRequirements || "—" }}</view>
  282. </u-col>
  283. </u-row>
  284. </view>
  285. </view>
  286. <!-- Tab 3: 包装明细 -->
  287. <view v-show="curNow === 3" class="basic_info">
  288. <view class="info_header">
  289. <view class="info_title">包装明细</view>
  290. <u-gap height="4" bgColor="#1890FF"></u-gap>
  291. </view>
  292. <view v-if="!packingList.length" class="empty_text"> 暂无包装明细 </view>
  293. <view v-for="(row, idx) in packingList" :key="idx" class="card_box">
  294. <view class="card_title">包装 {{ idx + 1 }}</view>
  295. <u-row>
  296. <u-col span="3">
  297. <view class="label">编码:</view>
  298. </u-col>
  299. <u-col span="9">
  300. <view class="value">{{ row.categoryCode || "—" }}</view>
  301. </u-col>
  302. </u-row>
  303. <u-row>
  304. <u-col span="3">
  305. <view class="label">名称:</view>
  306. </u-col>
  307. <u-col span="9">
  308. <view class="value">{{ row.categoryName || "—" }}</view>
  309. </u-col>
  310. </u-row>
  311. <u-row>
  312. <u-col span="3">
  313. <view class="label">批次号:</view>
  314. </u-col>
  315. <u-col span="9">
  316. <view class="value">{{ row.batchNo || "—" }}</view>
  317. </u-col>
  318. </u-row>
  319. <u-row>
  320. <u-col span="3">
  321. <view class="label">包装编码:</view>
  322. </u-col>
  323. <u-col span="9">
  324. <view class="value">{{ row.packageNo || "—" }}</view>
  325. </u-col>
  326. </u-row>
  327. <u-row>
  328. <u-col span="3">
  329. <view class="label">包装数量:</view>
  330. </u-col>
  331. <u-col span="9">
  332. <view class="value">{{
  333. formatValueWithUnit(
  334. row.packingQuantityDisplay,
  335. row.packingQuantity,
  336. row.packingUnit,
  337. )
  338. }}</view>
  339. </u-col>
  340. </u-row>
  341. <u-row>
  342. <u-col span="3">
  343. <view class="label">计量数量:</view>
  344. </u-col>
  345. <u-col span="9">
  346. <view class="value">{{
  347. formatValueWithUnit(
  348. row.measureQuantityDisplay,
  349. row.measureQuantity,
  350. row.measureUnit,
  351. )
  352. }}</view>
  353. </u-col>
  354. </u-row>
  355. <u-row>
  356. <u-col span="3">
  357. <view class="label">重量:</view>
  358. </u-col>
  359. <u-col span="9">
  360. <view class="value">{{
  361. formatValueWithUnit(row.weightDisplay, row.weight, row.weightUnit)
  362. }}</view>
  363. </u-col>
  364. </u-row>
  365. <u-row>
  366. <u-col span="3">
  367. <view class="label">仓库:</view>
  368. </u-col>
  369. <u-col span="9">
  370. <view class="value">{{ row.warehouseName || "—" }}</view>
  371. </u-col>
  372. </u-row>
  373. <u-row>
  374. <u-col span="3">
  375. <view class="label">物料代号:</view>
  376. </u-col>
  377. <u-col span="9">
  378. <view class="value">{{ row.materielDesignation || "—" }}</view>
  379. </u-col>
  380. </u-row>
  381. <u-row>
  382. <u-col span="3">
  383. <view class="label">客户代号:</view>
  384. </u-col>
  385. <u-col span="9">
  386. <view class="value">{{ row.clientCode || "—" }}</view>
  387. </u-col>
  388. </u-row>
  389. <u-row>
  390. <u-col span="3">
  391. <view class="label">发货条码:</view>
  392. </u-col>
  393. <u-col span="9">
  394. <view class="value">{{ row.barcodes || "—" }}</view>
  395. </u-col>
  396. </u-row>
  397. <u-row>
  398. <u-col span="3">
  399. <view class="label">刻码:</view>
  400. </u-col>
  401. <u-col span="9">
  402. <view class="value">{{ row.engrave || "—" }}</view>
  403. </u-col>
  404. </u-row>
  405. <u-row>
  406. <u-col span="3">
  407. <view class="label">供应商:</view>
  408. </u-col>
  409. <u-col span="9">
  410. <view class="value">{{ row.supplierName || "—" }}</view>
  411. </u-col>
  412. </u-row>
  413. <u-row>
  414. <u-col span="3">
  415. <view class="label">供应商代号:</view>
  416. </u-col>
  417. <u-col span="9">
  418. <view class="value">{{ row.supplierCode || "—" }}</view>
  419. </u-col>
  420. </u-row>
  421. <u-row>
  422. <u-col span="3">
  423. <view class="label">机型:</view>
  424. </u-col>
  425. <u-col span="9">
  426. <view class="value">{{ formatField(row.modelKey) }}</view>
  427. </u-col>
  428. </u-row>
  429. <u-row>
  430. <u-col span="3">
  431. <view class="label">颜色:</view>
  432. </u-col>
  433. <u-col span="9">
  434. <view class="value">{{ formatField(row.colorKey) }}</view>
  435. </u-col>
  436. </u-row>
  437. <u-row>
  438. <u-col span="3">
  439. <view class="label">质检结果:</view>
  440. </u-col>
  441. <u-col span="9">
  442. <view class="value">{{ row.resultLabel || "—" }}</view>
  443. </u-col>
  444. </u-row>
  445. <u-row>
  446. <u-col span="3">
  447. <view class="label">质检状态:</view>
  448. </u-col>
  449. <u-col span="9">
  450. <view class="value">{{ row.statusLabel || "—" }}</view>
  451. </u-col>
  452. </u-row>
  453. <u-row>
  454. <u-col span="3">
  455. <view class="label">生产日期:</view>
  456. </u-col>
  457. <u-col span="9">
  458. <view class="value">{{ row.productionDate || "—" }}</view>
  459. </u-col>
  460. </u-row>
  461. <u-row>
  462. <u-col span="3">
  463. <view class="label">采购日期:</view>
  464. </u-col>
  465. <u-col span="9">
  466. <view class="value">{{ row.purchaseDate || "—" }}</view>
  467. </u-col>
  468. </u-row>
  469. </view>
  470. </view>
  471. </view>
  472. </template>
  473. <script>
  474. import {
  475. getStorageDetail,
  476. allCategoryLevel,
  477. getLoginUser,
  478. } from "@/api/wt/index.js";
  479. import {
  480. getListByNameOrModeType,
  481. getCategoryPackageDisposition,
  482. getCode,
  483. getAssetNum,
  484. isVerifyRepeatIsStock,
  485. } from "@/api/warehouseManagement/index.js";
  486. const INPUT_SCENE_STATE = [
  487. { code: 1, label: "生产入库" },
  488. { code: 2, label: "采购入库" },
  489. { code: 3, label: "退货入库" },
  490. { code: 4, label: "委外入库" },
  491. { code: 5, label: "受托入库" },
  492. { code: 6, label: "调拨入库" },
  493. { code: 7, label: "委外退货入库" },
  494. { code: 8, label: "委外采购入库" },
  495. { code: 9, label: "仓库委外入库" },
  496. { code: 10, label: "采购退货入库" },
  497. { code: 99, label: "其他入库" },
  498. ];
  499. const QUALITY_RESULTS = {
  500. 0: "无",
  501. 1: "合格",
  502. 2: "不合格",
  503. 3: "让步接收",
  504. };
  505. const QUALITY_STATUS = {
  506. 0: "未质检",
  507. 1: "待检",
  508. 2: "已质检",
  509. };
  510. export default {
  511. props: {
  512. businessId: {
  513. default: "",
  514. },
  515. taskDefinitionKey: {
  516. default: "",
  517. },
  518. },
  519. data() {
  520. return {
  521. form: {},
  522. formData: {
  523. type: 1,
  524. bizType: "",
  525. sourceBizNo: "",
  526. storageTime: "",
  527. createUserId: "",
  528. createUserName: "",
  529. approvalUserId: "",
  530. approvalUserName: "",
  531. remark: "",
  532. extInfo: {
  533. assetType: [],
  534. assetTypeName: "",
  535. deptCode: "",
  536. deptName: "",
  537. createUserName: "",
  538. createUserId: "",
  539. deliveryPhone: "",
  540. documentSource: "",
  541. supplierName: "",
  542. },
  543. outInDetailList: [],
  544. },
  545. tabList: ["入库单详情", "基本信息", "产品信息", "包装明细"],
  546. curNow: 0,
  547. productList: [],
  548. packingList: [],
  549. assetTypeMapping: {},
  550. isDetail: false,
  551. totalPackage: "",
  552. totalCount: "",
  553. stickyPlaceholderHeight: 0,
  554. stickyTop: 44,
  555. };
  556. },
  557. computed: {
  558. bizType() {
  559. return this.taskDefinitionKey === "wmsBizType4" ? 4 : 1;
  560. },
  561. bizTypeLabel() {
  562. const item = INPUT_SCENE_STATE.find(
  563. (s) => s.code === Number(this.formData.bizType),
  564. );
  565. return item ? item.label : "";
  566. },
  567. assetTypeLabel() {
  568. const types = this.formData.extInfo.assetType;
  569. if (Array.isArray(types)) {
  570. return types
  571. .map((id) => this.assetTypeMapping[id] || "")
  572. .filter(Boolean)
  573. .join("、");
  574. }
  575. if (typeof types === "string" && types) {
  576. return types
  577. .split(",")
  578. .map((id) => this.assetTypeMapping[id.trim()] || "")
  579. .filter(Boolean)
  580. .join("、");
  581. }
  582. return "";
  583. },
  584. },
  585. async mounted() {
  586. this.initStickyTop();
  587. await this.loadAssetTypeMapping();
  588. await this.getDetailData(this.businessId);
  589. await this.getLoginUserData();
  590. this.updateStickyPlaceholderHeight();
  591. },
  592. methods: {
  593. padNumber(n) {
  594. return n < 10 ? `0${n}` : String(n);
  595. },
  596. arrayIncludes(list, value) {
  597. return Array.isArray(list) && list.indexOf(value) !== -1;
  598. },
  599. initStickyTop() {
  600. try {
  601. const systemInfo = uni.getSystemInfoSync();
  602. const statusBarHeight = Number(systemInfo.statusBarHeight || 0);
  603. // `uni-nav-bar` 在开启 statusBar 后,内容区默认高度约为 44px。
  604. this.stickyTop = statusBarHeight + 44;
  605. } catch (error) {
  606. this.stickyTop = 50;
  607. }
  608. },
  609. updateStickyPlaceholderHeight() {
  610. this.$nextTick(() => {
  611. const query = uni.createSelectorQuery().in(this);
  612. query
  613. .select(".sticky-subsection")
  614. .boundingClientRect((rect) => {
  615. if (rect && rect.height) {
  616. this.stickyPlaceholderHeight = rect.height;
  617. }
  618. })
  619. .exec();
  620. });
  621. },
  622. sectionChange(index) {
  623. this.curNow = index;
  624. },
  625. formatField(val) {
  626. if (Array.isArray(val)) return val.join(",") || "—";
  627. return val || "—";
  628. },
  629. formatValueWithUnit(displayValue, value, unit) {
  630. if (displayValue || displayValue === 0 || displayValue === "0") {
  631. return String(displayValue);
  632. }
  633. if (value === null || value === undefined || value === "") {
  634. return "—";
  635. }
  636. return `${value}${unit || ""}`;
  637. },
  638. async loadAssetTypeMapping() {
  639. try {
  640. const data = await allCategoryLevel();
  641. const list = Array.isArray(data) ? data : data?.data || [];
  642. const obj = {};
  643. list.forEach((item) => {
  644. obj[item.id] = item.name;
  645. });
  646. this.assetTypeMapping = obj;
  647. } catch (e) {
  648. console.warn("加载物品分类失败", e);
  649. }
  650. },
  651. async getDetailData(id) {
  652. try {
  653. const data = await getStorageDetail(id);
  654. this.form = data;
  655. this.isDetail = data.detailList?.[0]?.isAllPackageData == 1;
  656. this.totalPackage = this.isDetail
  657. ? (data.detailList[0].packingCount || "") +
  658. (data.detailList[0]?.packingUnit || "")
  659. : data.detailList.length + (data.detailList[0]?.packingUnit || "");
  660. this.totalCount =
  661. (data.totalCount || "") + (data.detailList?.[0]?.measuringUnit || "");
  662. this.form.detailList = (data.detailList || []).map((item) => ({
  663. ...item,
  664. productName: item.categoryName,
  665. productCode: item.categoryCode,
  666. }));
  667. let categoryLevelTopIds = data.detailList.map(
  668. (item) => item.rootCategoryLevelId,
  669. );
  670. let filterCategoryLevelTopIds = [
  671. ...new Set(categoryLevelTopIds.filter(Boolean)),
  672. ];
  673. data.categoryLevelTopId = filterCategoryLevelTopIds.join(",");
  674. if (this.taskDefinitionKey === "wmsBizType4") {
  675. this.form.totalCount = data.detailList.reduce(
  676. (sum, item) => sum + (item.quantity || 0),
  677. 0,
  678. );
  679. }
  680. await this.initFormData();
  681. await this.initProducts();
  682. } catch (e) {
  683. console.warn("获取入库单详情失败", e);
  684. }
  685. },
  686. async initFormData() {
  687. this.formData.type = 1;
  688. this.formData.bizType = this.bizType;
  689. this.formData.sourceBizNo = this.form.code || "";
  690. const categoryLevelTopIds = (this.form.detailList || [])
  691. .map((item) => item.rootCategoryLevelId)
  692. .filter(Boolean);
  693. this.formData.extInfo.assetType = [...new Set(categoryLevelTopIds)];
  694. this.formData.extInfo.documentSource = this.form.code || "";
  695. this.formData.extInfo.supplierName = this.form.supplierName || "";
  696. this.getNowFormatDate();
  697. },
  698. getNowFormatDate() {
  699. const now = new Date();
  700. const pad = (n) => this.padNumber(n);
  701. this.formData.storageTime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
  702. },
  703. async getLoginUserData() {
  704. try {
  705. const data = await getLoginUser();
  706. this.formData.createUserId =
  707. this.form.createUserId || data.userId || "";
  708. this.formData.createUserName =
  709. this.form.createUserName || data.name || "";
  710. this.formData.approvalUserId =
  711. this.form.approvalUserId || data.userId || "";
  712. this.formData.approvalUserName =
  713. this.form.approvalUserName || data.name || "";
  714. this.formData.extInfo.createUserId =
  715. this.form.createUserId || data.userId || "";
  716. this.formData.extInfo.createUserName =
  717. this.form.createUserName || data.name || "";
  718. this.formData.extInfo.deliveryPhone = data.phone || "";
  719. this.formData.extInfo.deptName =
  720. this.form.deptName || data.deptName || "";
  721. } catch (e) {
  722. console.warn("获取登录用户数据失败", e);
  723. }
  724. },
  725. async initProducts() {
  726. const detailList = this.form.detailList || [];
  727. if (!detailList.length) return;
  728. const codeList = detailList
  729. .map((item) => item.productCode || item.categoryCode)
  730. .filter(Boolean);
  731. if (!codeList.length) {
  732. this.buildFromDetailList(detailList);
  733. return;
  734. }
  735. try {
  736. const categoryList = await getListByNameOrModeType({ codeList });
  737. if (!categoryList || !categoryList.length) {
  738. this.buildFromDetailList(detailList);
  739. return;
  740. }
  741. const assetTypes = [
  742. ...new Set(
  743. categoryList
  744. .map((item) => item.categoryLevelPathIdParent)
  745. .filter(Boolean),
  746. ),
  747. ];
  748. if (assetTypes.length) {
  749. this.formData.extInfo.assetType = assetTypes;
  750. }
  751. let batchNo = "";
  752. try {
  753. batchNo = await getCode("lot_number_code");
  754. } catch (e) {
  755. console.warn("获取批次号失败", e);
  756. }
  757. let packingSpecs = [];
  758. try {
  759. packingSpecs = await getCategoryPackageDisposition({
  760. categoryIds: categoryList.map((item) => item.id),
  761. });
  762. } catch (e) {
  763. console.warn("获取包装规格失败", e);
  764. }
  765. const isMoreProduct = categoryList.length > 1;
  766. this.productList = categoryList.map((item, index) => {
  767. const detail =
  768. detailList.find(
  769. (d) => item.code === (d.productCode || d.categoryCode),
  770. ) ||
  771. detailList[index] ||
  772. {};
  773. const weightUnit = item.weightUnit || "";
  774. const itemPackingSpecs = (packingSpecs || [])
  775. .filter((s) => s.categoryId === item.id)
  776. .sort((a, b) => a.sort - b.sort);
  777. const packingSpecLabel = itemPackingSpecs
  778. .map((s) =>
  779. s.sort > 0
  780. ? `${s.packageCell}${s.packageUnit}/${s.conversionUnit}`
  781. : null,
  782. )
  783. .filter(Boolean)
  784. .join(", ");
  785. let packingQuantity,
  786. measureQuantity,
  787. packUnit,
  788. measureUnit,
  789. warehouseId,
  790. warehouseName,
  791. warehouseIds,
  792. warehouseNames,
  793. modelKey,
  794. colorKey,
  795. packingUnitId;
  796. if (this.isDetail) {
  797. // isAllPackageData==1: 对齐PC端 saleProductList 路径
  798. packUnit = detail.packingUnit || item.packingUnit || "";
  799. measureUnit = detail.measuringUnit || item.measuringUnit || "";
  800. packingQuantity = detail.packingCount || detail.quantity || 0;
  801. measureQuantity = detail.quantity || 0;
  802. warehouseId = detail.warehouseId || "";
  803. warehouseName = detail.warehouseName || "";
  804. warehouseIds = detail.warehouseId ? [detail.warehouseId] : [];
  805. warehouseNames = detail.warehouseName ? [detail.warehouseName] : [];
  806. modelKey = detail.modelKey ? detail.modelKey.split(",") : "";
  807. colorKey = detail.colorKey ? detail.colorKey.split(",") : "";
  808. packingUnitId = detail.purchaseUnitId || detail.saleUnitId || "";
  809. } else {
  810. // isAllPackageData!=1: 对齐PC端 detailList 路径
  811. packUnit = item.packingUnit || "";
  812. measureUnit = item.measuringUnit || "";
  813. const matchDetails = detailList.filter(
  814. (d) => (d.productCode || d.categoryCode) === item.code,
  815. );
  816. packingQuantity = isMoreProduct
  817. ? matchDetails.length
  818. : detailList.length;
  819. measureQuantity = isMoreProduct
  820. ? matchDetails.reduce((sum, d) => sum + (d.quantity || 0), 0)
  821. : this.form.totalCount || 0;
  822. if (isMoreProduct) {
  823. warehouseId = matchDetails[0]?.warehouseId || "";
  824. warehouseName = matchDetails[0]?.warehouseName || "";
  825. warehouseIds = matchDetails.map((d) => d.warehouseId);
  826. warehouseNames = matchDetails.map((d) => d.warehouseName);
  827. } else {
  828. warehouseId = this.form.warehouseId || "";
  829. warehouseName = this.form.warehouseName || "";
  830. warehouseIds = Array(detailList.length).fill(
  831. this.form.warehouseId || "",
  832. );
  833. warehouseNames = Array(detailList.length).fill(
  834. this.form.warehouseName || "",
  835. );
  836. }
  837. if (this.bizType == 1) {
  838. modelKey = this.form.modelKey
  839. ? this.form.modelKey.split(",")
  840. : "";
  841. colorKey = this.form.colorKey
  842. ? this.form.colorKey.split(",")
  843. : "";
  844. } else {
  845. modelKey = item.modelKey ? item.modelKey.split(",") : "";
  846. colorKey = item.colorKey ? item.colorKey.split(",") : "";
  847. }
  848. packingUnitId = "";
  849. }
  850. let weight = detail.weight || 0;
  851. if (
  852. (detail.sendTotalWeight || detail.receiveTotalWeight) &&
  853. item.weightUnit === item.measuringUnit
  854. ) {
  855. weight = detail.sendTotalWeight || detail.receiveTotalWeight;
  856. }
  857. const singleWeight = detail.singleWeight || 0;
  858. if (!weight && singleWeight) {
  859. weight = singleWeight * measureQuantity;
  860. }
  861. return {
  862. index,
  863. categoryId: item.id,
  864. categoryName: item.name,
  865. categoryCode: item.code,
  866. categoryModel: item.modelType || "",
  867. specification: item.specification || "",
  868. brandNum: item.brandNum || "",
  869. batchNo: this.isDetail
  870. ? detail.batchNo || batchNo
  871. : this.arrayIncludes([1, 3, 6], this.bizType)
  872. ? detailList[0]?.batchNo || batchNo
  873. : batchNo,
  874. packingQuantity,
  875. packingUnit: packUnit,
  876. packingQuantityDisplay:
  877. packingQuantity !== 0 ? `${packingQuantity}${packUnit}` : "",
  878. measureQuantity,
  879. measureUnit: measureUnit,
  880. measuringUnit: measureUnit,
  881. measureQuantityDisplay:
  882. measureQuantity !== 0 ? `${measureQuantity}${measureUnit}` : "",
  883. measureType: item.measureType,
  884. weight,
  885. weightUnit,
  886. weightDisplay: weight !== 0 ? `${weight}${weightUnit}` : "",
  887. singleWeight,
  888. warehouseId,
  889. warehouseName,
  890. warehouseIds,
  891. warehouseNames,
  892. supplierName: detail.supplierName || item.supplierName || "",
  893. supplierCode: detail.supplierCode || item.supplierCode || "",
  894. supplierId: detail.supplierId || this.form.supplierId || "",
  895. productionRequirements: detail.productionRequirements || "",
  896. packingSpecification:
  897. item.packingSpecification || packingSpecLabel || "",
  898. packingSpecificationOption: itemPackingSpecs,
  899. packingUnitId,
  900. modelKey,
  901. colorKey,
  902. netWeight: item.netWeight > -1 ? item.netWeight : 0,
  903. isUnpack: item.isUnpack,
  904. qualityControl: detail.qualityControl,
  905. extField: item.extField || {},
  906. isSave: true,
  907. outInDetailRecordRequestList: [],
  908. };
  909. });
  910. await this.buildPackingList(batchNo);
  911. console.log("this.productList", this.productList);
  912. this.formData.outInDetailList = this.productList;
  913. } catch (e) {
  914. console.warn("初始化产品数据失败", e);
  915. this.buildFromDetailList(detailList);
  916. }
  917. },
  918. buildFromDetailList(detailList) {
  919. this.productList = detailList.map((item, index) => {
  920. const packUnit = item.packingUnit || "";
  921. const measureUnit = item.measuringUnit || "";
  922. const pQty = item.packingCount || item.quantity || 0;
  923. const mQty = item.quantity || item.measureQuantity || 0;
  924. return {
  925. index,
  926. categoryId: item.categoryId || item.id || "",
  927. categoryName: item.categoryName || "",
  928. categoryCode: item.categoryCode || "",
  929. categoryModel: item.modelType || "",
  930. specification: item.specification || "",
  931. brandNum: item.brandNum || "",
  932. batchNo: item.batchNo || "",
  933. packingQuantity: pQty,
  934. packingUnit: packUnit,
  935. packingQuantityDisplay: pQty ? `${pQty}${packUnit}` : "",
  936. measureQuantity: mQty,
  937. measureUnit: measureUnit,
  938. measuringUnit: measureUnit,
  939. measureQuantityDisplay: mQty ? `${mQty}${measureUnit}` : "",
  940. weight: item.weight || 0,
  941. weightUnit: item.weightUnit || "",
  942. weightDisplay: item.weight
  943. ? `${item.weight}${item.weightUnit || ""}`
  944. : "",
  945. singleWeight: item.singleWeight || 0,
  946. warehouseId: item.warehouseId || "",
  947. warehouseName: item.warehouseName || "",
  948. warehouseIds: item.warehouseId ? [item.warehouseId] : [],
  949. warehouseNames: item.warehouseName ? [item.warehouseName] : [],
  950. supplierName: item.supplierName || "",
  951. supplierCode: item.supplierCode || "",
  952. supplierId: item.supplierId || "",
  953. productionRequirements: item.productionRequirements || "",
  954. packingSpecification: item.packingSpecification || "",
  955. isSave: true,
  956. outInDetailRecordRequestList: [],
  957. };
  958. });
  959. this.productList.forEach((product) => {
  960. product.outInDetailRecordRequestList = [
  961. this.buildDefaultPackingEntry(product),
  962. ];
  963. });
  964. this.packingList = this.productList.reduce((list, product) => {
  965. return list.concat(product.outInDetailRecordRequestList || []);
  966. }, []);
  967. this.formData.outInDetailList = this.productList;
  968. },
  969. buildDefaultPackingEntry(product) {
  970. const detail =
  971. (this.form.detailList || []).find(
  972. (d) => (d.productCode || d.categoryCode) === product.categoryCode,
  973. ) || {};
  974. return {
  975. packageNo: "",
  976. categoryCode: product.categoryCode,
  977. categoryName: product.categoryName,
  978. batchNo: product.batchNo,
  979. packingQuantity: product.packingQuantity,
  980. packingUnit: product.packingUnit,
  981. packingQuantityDisplay: product.packingQuantityDisplay,
  982. measureQuantity: product.measureQuantity,
  983. measureUnit: product.measureUnit,
  984. measureQuantityDisplay: product.measureQuantityDisplay,
  985. weight: product.weight,
  986. weightUnit: product.weightUnit,
  987. weightDisplay: product.weightDisplay,
  988. warehouseId: product.warehouseId,
  989. warehouseName: product.warehouseName,
  990. materielDesignation: "",
  991. clientCode: "",
  992. barcodes: "",
  993. engrave: "",
  994. supplierName: product.supplierName,
  995. supplierCode: product.supplierCode,
  996. result: 0,
  997. status: 0,
  998. resultLabel: QUALITY_RESULTS[0],
  999. statusLabel: QUALITY_STATUS[0],
  1000. productionDate: "",
  1001. purchaseDate: "",
  1002. modelKey: product.modelKey || "",
  1003. colorKey: product.colorKey || "",
  1004. workOrderId: detail.workOrderId || "",
  1005. taskId: detail.taskId || "",
  1006. };
  1007. },
  1008. _getNowDateStr() {
  1009. const now = new Date();
  1010. const pad = (n) => this.padNumber(n);
  1011. return `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
  1012. },
  1013. _isNonSplitUnit(unit) {
  1014. if (!unit) return false;
  1015. const u = unit.toUpperCase();
  1016. return this.arrayIncludes(["KG", "G", "L", "ML"], u) || unit === "立方";
  1017. },
  1018. async buildPackingList(batchNo) {
  1019. const detailList = this.form.detailList || [];
  1020. const isMoreProduct = this.productList.length > 1;
  1021. let productionDate = "";
  1022. let purchaseDate = "";
  1023. if (this.bizType == 1) {
  1024. productionDate = this._getNowDateStr();
  1025. }
  1026. if (this.isDetail) {
  1027. // isAllPackageData == 1: 对齐PC端 saleProductList → batchSave → generateWrappers 路径
  1028. // 从 productList 生成包装明细
  1029. try {
  1030. for (const product of this.productList) {
  1031. if (!product.packingQuantity || product.packingQuantity <= 0)
  1032. continue;
  1033. const packingSpecOption = product.packingSpecificationOption || [];
  1034. const packingBoolen = this._isNonSplitUnit(product.packingUnit);
  1035. const measureBoolen = this._isNonSplitUnit(product.measureUnit);
  1036. let packingNum = Number(product.packingQuantity);
  1037. let filterArr = [];
  1038. if (packingBoolen) {
  1039. if (!product.isUnpack && product.packingUnit === "立方") {
  1040. packingNum = 1;
  1041. } else {
  1042. filterArr = packingSpecOption.filter(
  1043. (s) =>
  1044. s.packageUnit === product.packingUnit &&
  1045. s.packageUnit !== s.conversionUnit,
  1046. );
  1047. if (filterArr.length) {
  1048. packingNum = Math.ceil(
  1049. product.packingQuantity / filterArr[0].packageCell,
  1050. );
  1051. }
  1052. }
  1053. } else {
  1054. if (product.isUnpack) {
  1055. if (measureBoolen) {
  1056. let splitIndex = packingSpecOption.findIndex(
  1057. (s) =>
  1058. s.conversionUnit === product.packingUnit &&
  1059. s.packageUnit !== s.conversionUnit,
  1060. );
  1061. let num = product.packingQuantity;
  1062. for (; splitIndex > 1; splitIndex--) {
  1063. num = num * packingSpecOption[splitIndex].packageCell;
  1064. }
  1065. packingNum = Math.ceil(num);
  1066. } else {
  1067. if (product.packingUnitId) {
  1068. let splitIndex = packingSpecOption.findIndex(
  1069. (s) => s.id == product.packingUnitId,
  1070. );
  1071. if (splitIndex == 0) {
  1072. packingNum = Math.ceil(
  1073. product.measureQuantity /
  1074. (packingSpecOption[1]?.packageCell || 1),
  1075. );
  1076. } else if (splitIndex == 1) {
  1077. packingNum = product.packingQuantity;
  1078. } else {
  1079. for (; splitIndex > 1; splitIndex--) {
  1080. packingNum = Math.ceil(
  1081. product.packingQuantity *
  1082. packingSpecOption[splitIndex].packageCell,
  1083. );
  1084. }
  1085. }
  1086. } else if (packingSpecOption[1]?.packageCell) {
  1087. packingNum = Math.ceil(
  1088. product.measureQuantity /
  1089. packingSpecOption[1].packageCell,
  1090. );
  1091. filterArr = packingSpecOption.filter(
  1092. (s) =>
  1093. s.packageUnit === product.packingUnit &&
  1094. s.packageUnit !== s.conversionUnit,
  1095. );
  1096. }
  1097. }
  1098. } else {
  1099. if (product.measureUnit === product.packingUnit) {
  1100. packingNum = 0;
  1101. } else {
  1102. packingNum = Number(product.packingQuantity);
  1103. }
  1104. }
  1105. }
  1106. if (packingNum <= 0) packingNum = 1;
  1107. let packageNos = [];
  1108. try {
  1109. const assetNumRes = await getAssetNum([
  1110. {
  1111. assetCode: product.categoryCode + product.index,
  1112. batchNum: product.batchNo,
  1113. num: packingNum,
  1114. },
  1115. ]);
  1116. packageNos = assetNumRes?.data || [];
  1117. } catch (e) {
  1118. console.warn("获取包装编码失败", e);
  1119. }
  1120. const qualityStatus = product.qualityControl == 1 ? 0 : 2;
  1121. const packingEntries = [];
  1122. for (let i = 0; i < packageNos.length; i++) {
  1123. let measureQuantity = 1;
  1124. let packingQuantity = 1;
  1125. if (packingBoolen) {
  1126. const cell = filterArr[0]?.packageCell || 1;
  1127. measureQuantity =
  1128. Number(product.packingQuantity) > cell * (i + 1)
  1129. ? cell
  1130. : Number(product.packingQuantity) - cell * i;
  1131. } else {
  1132. if (
  1133. product.weightUnit === product.measureUnit &&
  1134. product.weight
  1135. ) {
  1136. measureQuantity =
  1137. Math.trunc((product.weight / packageNos.length) * 10000) /
  1138. 10000;
  1139. } else if (measureBoolen) {
  1140. let splitIndex = packingSpecOption.findIndex(
  1141. (s) =>
  1142. s.conversionUnit === product.packingUnit &&
  1143. s.packageUnit !== s.conversionUnit,
  1144. );
  1145. measureQuantity = 1;
  1146. for (; splitIndex > 0; splitIndex--) {
  1147. measureQuantity =
  1148. measureQuantity *
  1149. packingSpecOption[splitIndex].packageCell;
  1150. }
  1151. } else {
  1152. measureQuantity = packingSpecOption[1]?.packageCell || 1;
  1153. }
  1154. }
  1155. let clientCode = "";
  1156. if (this.bizType == 2) {
  1157. clientCode = product.customerMark || "";
  1158. } else {
  1159. clientCode = product.extInfo?.clientCode || "";
  1160. }
  1161. let packingUnit = product.packingUnit;
  1162. if (product.isUnpack) {
  1163. if (packingBoolen) {
  1164. packingUnit =
  1165. packingSpecOption[1]?.conversionUnit || product.packingUnit;
  1166. } else if (measureBoolen) {
  1167. packingUnit =
  1168. (packingSpecOption[1] || packingSpecOption[0])
  1169. ?.conversionUnit || product.packingUnit;
  1170. } else {
  1171. packingUnit =
  1172. packingSpecOption[1]?.conversionUnit || product.packingUnit;
  1173. }
  1174. }
  1175. let measureUnit = product.isUnpack
  1176. ? measureBoolen
  1177. ? (packingSpecOption[1] || packingSpecOption[0])
  1178. ?.packageUnit || product.measureUnit
  1179. : product.measureUnit
  1180. : product.measureUnit;
  1181. let weight = 0;
  1182. if (product.weightUnit === product.measureUnit) {
  1183. weight = measureQuantity ? Number(measureQuantity) : 0;
  1184. } else if (product.singleWeight && measureQuantity) {
  1185. weight = Number(measureQuantity) * Number(product.singleWeight);
  1186. }
  1187. packingEntries.push({
  1188. index: product.index + "-" + i,
  1189. warehouseId: product.warehouseId || "",
  1190. warehouseName: product.warehouseName || "",
  1191. categoryName: product.categoryName || "",
  1192. categoryCode: product.categoryCode || "",
  1193. categoryModel: product.categoryModel || "",
  1194. specification: product.specification || "",
  1195. supplierCode: product.supplierCode || "",
  1196. supplierName: product.supplierName || "",
  1197. brandNum: product.brandNum || "",
  1198. parentIndex: product.index,
  1199. batchNo: product.batchNo || batchNo,
  1200. packageNo: packageNos[i]?.onlyCode || "",
  1201. packingQuantity: packingQuantity,
  1202. modelKey: product.modelKey || "",
  1203. colorKey: product.colorKey || "",
  1204. packingUnit: packingUnit,
  1205. packingQuantityDisplay: this.formatValueWithUnit(
  1206. "",
  1207. packingQuantity,
  1208. packingUnit,
  1209. ),
  1210. measureQuantity: measureQuantity,
  1211. measureUnit: measureUnit,
  1212. measureQuantityDisplay: this.formatValueWithUnit(
  1213. "",
  1214. measureQuantity,
  1215. measureUnit,
  1216. ),
  1217. weight: weight,
  1218. weightDisplay: this.formatValueWithUnit(
  1219. "",
  1220. weight,
  1221. product.weightUnit || "",
  1222. ),
  1223. packingSpecificationOption:
  1224. product.packingSpecificationOption || [],
  1225. weightUnit: product.weightUnit || "",
  1226. netWeight: product.netWeight || 0,
  1227. barcodes: "",
  1228. clientCode: clientCode,
  1229. materielDesignation: product.extInfo?.materielCode || "",
  1230. engrave: "",
  1231. isUnpack: product.isUnpack,
  1232. productionDate: productionDate,
  1233. purchaseDate: "",
  1234. result: 1,
  1235. qualityControl: product.qualityControl,
  1236. status: qualityStatus,
  1237. resultLabel: QUALITY_RESULTS[1] || "合格",
  1238. statusLabel: QUALITY_STATUS[qualityStatus] || "未质检",
  1239. workOrderId: "",
  1240. taskId: "",
  1241. });
  1242. }
  1243. // 处理尾包余数
  1244. if (
  1245. product.weightUnit !== product.measureUnit &&
  1246. packingSpecOption[1]?.packageCell
  1247. ) {
  1248. const remainder =
  1249. product.measureQuantity % packingSpecOption[1].packageCell;
  1250. if (remainder > 0 && packingEntries.length > 0) {
  1251. const lastEntry = packingEntries[packingEntries.length - 1];
  1252. lastEntry.measureQuantity = remainder;
  1253. lastEntry.measureQuantityDisplay = this.formatValueWithUnit(
  1254. "",
  1255. remainder,
  1256. lastEntry.measureUnit,
  1257. );
  1258. if (product.singleWeight) {
  1259. lastEntry.weight = product.singleWeight * remainder;
  1260. lastEntry.weightDisplay = this.formatValueWithUnit(
  1261. "",
  1262. lastEntry.weight,
  1263. lastEntry.weightUnit,
  1264. );
  1265. }
  1266. }
  1267. }
  1268. product.outInDetailRecordRequestList = packingEntries;
  1269. this.packingList.push(...packingEntries);
  1270. }
  1271. } catch (e) {
  1272. console.warn("生成包装明细失败", e);
  1273. }
  1274. } else {
  1275. // isAllPackageData != 1: 对齐PC端 detailList 路径
  1276. // detailList 每条记录即是一个包装, 直接映射
  1277. const product0 = this.productList[0] || {};
  1278. let getAssetNumPr = isMoreProduct
  1279. ? detailList.map((val) => ({
  1280. assetCode: val.productCode,
  1281. batchNum: val.productBrand ? val.productBrand : val.batchNo,
  1282. num: 1,
  1283. }))
  1284. : [
  1285. {
  1286. assetCode:
  1287. (product0.categoryCode || "") + (product0.index ?? 0),
  1288. batchNum: product0.batchNo || "",
  1289. num: detailList.length,
  1290. },
  1291. ];
  1292. let packingCodeList = [];
  1293. try {
  1294. const assetNumRes = await getAssetNum(getAssetNumPr);
  1295. packingCodeList = assetNumRes?.data || [];
  1296. } catch (e) {
  1297. console.warn("获取包装编码失败", e);
  1298. }
  1299. this.packingList = detailList.map((item, index) => {
  1300. const matchProduct = isMoreProduct
  1301. ? this.productList.find(
  1302. (val) => val.categoryCode === item.productCode,
  1303. ) || product0
  1304. : product0;
  1305. let clientCode = "";
  1306. if (this.bizType == 2) {
  1307. clientCode = item.customerMark || "";
  1308. } else {
  1309. clientCode = item.clientCode || item.extInfo?.clientCode || "";
  1310. }
  1311. return {
  1312. index:
  1313. (isMoreProduct ? matchProduct.index : product0.index) +
  1314. "-" +
  1315. index,
  1316. warehouseId:
  1317. item.warehouseId || (product0.warehouseIds || [])[index] || "",
  1318. warehouseName:
  1319. item.warehouseName ||
  1320. (product0.warehouseNames || [])[index] ||
  1321. "",
  1322. categoryName: item.productName || product0.categoryName || "",
  1323. categoryCode: item.productCode || product0.categoryCode || "",
  1324. categoryModel: item.modelType || product0.categoryModel || "",
  1325. specification: item.specification || product0.specification || "",
  1326. brandNum: item.productBrand || product0.brandNum || "",
  1327. colorKey:
  1328. (item.colorKey ? item.colorKey.split(",") : "") ||
  1329. product0.colorKey ||
  1330. "",
  1331. modelKey:
  1332. (item.modelKey ? item.modelKey.split(",") : "") ||
  1333. product0.modelKey ||
  1334. "",
  1335. parentIndex: isMoreProduct ? matchProduct.index : product0.index,
  1336. batchNo: product0.batchNo || batchNo,
  1337. packageNo:
  1338. item.packageNo ||
  1339. item.packingCode ||
  1340. packingCodeList[index]?.onlyCode ||
  1341. "",
  1342. packingQuantity: 1,
  1343. packingUnit: item.packingUnit || "",
  1344. packingQuantityDisplay: this.formatValueWithUnit(
  1345. "",
  1346. 1,
  1347. item.packingUnit || "",
  1348. ),
  1349. measureQuantity: item.quantity || item.measureQuantity || 0,
  1350. measureUnit: item.measuringUnit || item.measureUnit || "",
  1351. measureQuantityDisplay: this.formatValueWithUnit(
  1352. "",
  1353. item.quantity || item.measureQuantity || 0,
  1354. item.measuringUnit || item.measureUnit || "",
  1355. ),
  1356. supplierCode: item.supplierCode || "",
  1357. supplierId: item.supplierId || "",
  1358. supplierName: item.supplierName || "",
  1359. weight: item.packingWeight || 0,
  1360. weightDisplay: this.formatValueWithUnit(
  1361. "",
  1362. item.packingWeight || 0,
  1363. item.weightUnit || product0.weightUnit || "",
  1364. ),
  1365. singleWeight: item.singleWeight || 0,
  1366. pricingWay: item.pricingWay || "",
  1367. weightUnit: item.weightUnit || product0.weightUnit || "",
  1368. packingSpecificationOption: isMoreProduct
  1369. ? matchProduct.packingSpecificationOption || []
  1370. : product0.packingSpecificationOption || [],
  1371. netWeight: product0.netWeight || 0,
  1372. barcodes: item.barcodes || item.sendCode || "",
  1373. clientCode: clientCode,
  1374. materielDesignation:
  1375. item.materielDesignation || item.extInfo?.materielCode || "",
  1376. engrave: item.engrave || item.extInfo?.engrave || "",
  1377. isUnpack: product0.isUnpack,
  1378. productionDate: productionDate,
  1379. purchaseDate: purchaseDate,
  1380. result: 1,
  1381. status: 2,
  1382. resultLabel: QUALITY_RESULTS[1] || "合格",
  1383. statusLabel: QUALITY_STATUS[2] || "已质检",
  1384. serialNumber: item.productSequence || "",
  1385. workOrderId: item.workOrderId || "",
  1386. taskId: item.taskId || "",
  1387. };
  1388. });
  1389. this.productList.forEach((product) => {
  1390. product.outInDetailRecordRequestList = this.packingList.filter(
  1391. (p) => p.categoryCode === product.categoryCode,
  1392. );
  1393. });
  1394. }
  1395. },
  1396. async getReturnStorage() {
  1397. if (!this.productList.length) {
  1398. uni.showToast({ title: "暂无产品信息!", icon: "none" });
  1399. return null;
  1400. }
  1401. const detailList = this.form.detailList || [];
  1402. const _packingList = this.packingList.map((packingItem) => {
  1403. let _workOrderId = null;
  1404. let _taskId = null;
  1405. if (this.arrayIncludes([1], this.bizType)) {
  1406. _workOrderId = detailList[0]?.workOrderId;
  1407. _taskId = detailList[0]?.taskId;
  1408. }
  1409. const processed = { ...packingItem };
  1410. if (processed.modelKey) {
  1411. processed.modelKey = processed.modelKey.toString();
  1412. }
  1413. if (processed.colorKey) {
  1414. processed.colorKey = processed.colorKey.toString();
  1415. }
  1416. return {
  1417. ...processed,
  1418. workOrderId: _workOrderId,
  1419. taskId: _taskId,
  1420. materialDetailList: [],
  1421. };
  1422. });
  1423. const processedProductList = this.productList.map((productItem) => {
  1424. const processed = { ...productItem };
  1425. if (processed.modelKey) {
  1426. processed.modelKey = processed.modelKey.toString();
  1427. }
  1428. if (processed.colorKey) {
  1429. processed.colorKey = processed.colorKey.toString();
  1430. }
  1431. return {
  1432. ...processed,
  1433. outInDetailRecordRequestList: _packingList.filter(
  1434. (item) => item.parentIndex === productItem.index,
  1435. ),
  1436. };
  1437. });
  1438. const obj = JSON.parse(JSON.stringify(this.formData));
  1439. obj.type = 1;
  1440. if (Array.isArray(obj.extInfo.assetType)) {
  1441. obj.extInfo.assetType = obj.extInfo.assetType.join(",");
  1442. }
  1443. obj.extInfo.documentSource = obj.sourceBizNo;
  1444. obj.extInfo.deptName = this.formData.extInfo.deptName || "";
  1445. obj.extInfo.supplierName = this.form.supplierName || "";
  1446. const warehouseId = [];
  1447. const warehouseName = [];
  1448. processedProductList.forEach((item) => {
  1449. const ids = item.warehouseIds || [];
  1450. const names = item.warehouseNames || [];
  1451. ids.forEach((id, idx) => {
  1452. if (id && warehouseId.indexOf(id) === -1) {
  1453. warehouseId.push(id);
  1454. warehouseName.push(names[idx] || "");
  1455. }
  1456. });
  1457. });
  1458. obj.warehouseIds = warehouseId;
  1459. obj.warehouseNames = warehouseName;
  1460. obj.outInDetailList = processedProductList;
  1461. obj._packingList = _packingList;
  1462. try {
  1463. const isVerifyData = await isVerifyRepeatIsStock({
  1464. categoryCodes: this.productList.map((item) => item.categoryCode),
  1465. batchNos: this.productList.map((item) => item.batchNo),
  1466. });
  1467. if (isVerifyData?.length) {
  1468. return new Promise((resolve) => {
  1469. uni.showModal({
  1470. title: "提示",
  1471. content: `当前批次:${isVerifyData[0].batchNo},物品${isVerifyData
  1472. .map((item) => item.categoryName)
  1473. .join(",")}已有入库记录,是否继续入库!`,
  1474. confirmText: "是",
  1475. cancelText: "否",
  1476. success: (modalRes) => {
  1477. if (modalRes.confirm) {
  1478. resolve(obj);
  1479. } else {
  1480. resolve(false);
  1481. }
  1482. },
  1483. });
  1484. });
  1485. }
  1486. } catch (e) {
  1487. console.warn("验证重复入库失败", e);
  1488. }
  1489. return obj;
  1490. },
  1491. async getTableValue() {
  1492. const returnStorageData = await this.getReturnStorage();
  1493. return {
  1494. form: this.form,
  1495. returnStorageData: returnStorageData || {},
  1496. };
  1497. },
  1498. },
  1499. };
  1500. </script>
  1501. <style lang="scss">
  1502. .sticky-subsection {
  1503. position: fixed;
  1504. left: 0;
  1505. right: 0;
  1506. z-index: 99;
  1507. width: 100%;
  1508. box-sizing: border-box;
  1509. background: #f5f7fa;
  1510. }
  1511. .sticky-subsection-placeholder {
  1512. width: 100%;
  1513. }
  1514. .subsection-wrap {
  1515. background: #f5f7fa;
  1516. padding: 0 16rpx 12rpx;
  1517. width: 100%;
  1518. box-sizing: border-box;
  1519. }
  1520. .basic_info {
  1521. box-sizing: border-box;
  1522. padding: 0 20rpx;
  1523. }
  1524. .info_header {
  1525. margin-top: 10rpx;
  1526. }
  1527. .info_title {
  1528. position: relative;
  1529. padding: 16rpx 50rpx;
  1530. font-size: 36rpx;
  1531. color: #606266;
  1532. }
  1533. .info_title::after {
  1534. content: "";
  1535. position: absolute;
  1536. top: 16rpx;
  1537. left: 0px;
  1538. width: 16rpx;
  1539. height: 50rpx;
  1540. background: #1890ff;
  1541. }
  1542. .info_content {
  1543. .label {
  1544. padding: 20rpx 0;
  1545. text-align: right;
  1546. font-size: 28rpx;
  1547. font-weight: 700;
  1548. color: #6e6e6e;
  1549. }
  1550. .value {
  1551. padding: 20rpx 0;
  1552. font-size: 28rpx;
  1553. color: #606266;
  1554. }
  1555. }
  1556. .card_box {
  1557. box-sizing: border-box;
  1558. padding: 20rpx;
  1559. margin: 20rpx;
  1560. width: calc(100% - 40rpx);
  1561. border-radius: 20rpx;
  1562. box-shadow: 0 0 12rpx -6rpx #000;
  1563. .card_title {
  1564. font-size: 32rpx;
  1565. font-weight: 700;
  1566. color: #666;
  1567. margin-bottom: 10rpx;
  1568. }
  1569. .label {
  1570. padding: 18rpx 0;
  1571. text-align: right;
  1572. font-size: 28rpx;
  1573. font-weight: 700;
  1574. color: #6e6e6e;
  1575. }
  1576. .value {
  1577. padding: 18rpx 0;
  1578. font-size: 28rpx;
  1579. color: #606266;
  1580. }
  1581. }
  1582. .empty_text {
  1583. text-align: center;
  1584. color: #909399;
  1585. font-size: 28rpx;
  1586. padding: 80rpx 0;
  1587. }
  1588. </style>