taskForm.vue 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438
  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="list"
  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. <view v-show="curNow === 0" class="out-info-wrap">
  20. <view class="out-info-title">
  21. <text class="out-info-title-bar"></text>
  22. <text class="out-info-title-text">领料信息</text>
  23. </view>
  24. <view class="out-info-divider"></view>
  25. <view class="out-info-card">
  26. <view
  27. v-for="(item, index) in pickInfoItems"
  28. :key="index"
  29. class="out-info-row"
  30. >
  31. <text class="out-info-label">{{ item.label }}</text>
  32. <text class="out-info-value">{{ item.value || "—" }}</text>
  33. </view>
  34. </view>
  35. </view>
  36. <view v-show="curNow === 1" class="pick-list-wrap">
  37. <view class="out-info-title">
  38. <text class="out-info-title-bar"></text>
  39. <text class="out-info-title-text">领料清单</text>
  40. </view>
  41. <view class="out-info-divider"></view>
  42. <view
  43. v-if="!form.detailList || !form.detailList.length"
  44. class="pick-list-empty"
  45. >
  46. 暂无领料明细
  47. </view>
  48. <view
  49. v-for="(row, idx) in form.detailList"
  50. :key="idx"
  51. class="pick-list-card"
  52. >
  53. <view class="pick-list-card-head">
  54. <text class="pick-list-index">序号 {{ idx + 1 }}</text>
  55. </view>
  56. <view class="pick-list-card-body">
  57. <view
  58. v-for="(field, fieldIdx) in pickListFieldItems"
  59. :key="`${idx}-${fieldIdx}`"
  60. class="pick-list-row"
  61. >
  62. <text class="out-info-label">{{ field.label }}</text>
  63. <text class="out-info-value">{{
  64. formatPickListField(row, field.key)
  65. }}</text>
  66. </view>
  67. </view>
  68. </view>
  69. </view>
  70. <view v-show="curNow === 2" class="out-info-wrap">
  71. <view class="out-info-title">
  72. <text class="out-info-title-bar"></text>
  73. <text class="out-info-title-text">出库信息</text>
  74. </view>
  75. <view class="out-info-divider"></view>
  76. <view class="out-info-card">
  77. <view
  78. v-for="(item, index) in outboundInfoItems"
  79. :key="index"
  80. class="out-info-row"
  81. >
  82. <text class="out-info-label">{{ item.label }}</text>
  83. <text class="out-info-value">{{ item.value || "—" }}</text>
  84. </view>
  85. </view>
  86. </view>
  87. <view v-show="curNow === 3" class="outbound-wrap">
  88. <view class="outbound-title">
  89. <text class="outbound-title-bar"></text>
  90. <text class="outbound-title-text">出库物品清单</text>
  91. </view>
  92. <view class="out-info-divider"></view>
  93. <view v-if="!outboundItemRows.length" class="outbound-empty">
  94. 暂无出库物品明细
  95. </view>
  96. <view
  97. v-for="(row, index) in outboundItemRows"
  98. :key="index"
  99. class="outbound-card"
  100. >
  101. <view class="outbound-card-head">
  102. <text class="outbound-index">序号 {{ row.seq }}</text>
  103. </view>
  104. <view
  105. v-for="(line, li) in outboundItemGrid"
  106. :key="li"
  107. class="outbound-grid"
  108. :class="{
  109. 'outbound-grid-last': li === outboundItemGrid.length - 1,
  110. 'outbound-grid--full': !line.right,
  111. }"
  112. >
  113. <block v-if="line.right">
  114. <view class="outbound-col">
  115. <text class="outbound-label">{{ line.left[0] }}</text>
  116. <text class="outbound-value">{{ dash(row[line.left[1]]) }}</text>
  117. </view>
  118. <view class="outbound-col outbound-col-right">
  119. <text class="outbound-label">{{ line.right[0] }}</text>
  120. <text class="outbound-value">{{ dash(row[line.right[1]]) }}</text>
  121. </view>
  122. </block>
  123. </view>
  124. </view>
  125. </view>
  126. <view v-show="curNow === 4" class="outbound-wrap">
  127. <view class="outbound-title">
  128. <text class="outbound-title-bar"></text>
  129. <text class="outbound-title-text">包装清单</text>
  130. </view>
  131. <view class="out-info-divider"></view>
  132. <view v-if="!packingListRows.length" class="outbound-empty">
  133. 暂无包装明细
  134. </view>
  135. <view
  136. v-for="(row, index) in packingListRows"
  137. :key="index"
  138. class="outbound-card"
  139. >
  140. <view class="outbound-card-head">
  141. <text class="outbound-index">序号 {{ row.seq }}</text>
  142. </view>
  143. <view
  144. v-for="(line, li) in packingItemGrid"
  145. :key="li"
  146. class="outbound-grid"
  147. :class="{
  148. 'outbound-grid-last': li === packingItemGrid.length - 1,
  149. 'outbound-grid--full': !line.right,
  150. }"
  151. >
  152. <block v-if="line.right">
  153. <view class="outbound-col">
  154. <text class="outbound-label">{{ line.left[0] }}</text>
  155. <text class="outbound-value">{{ dash(row[line.left[1]]) }}</text>
  156. </view>
  157. <view class="outbound-col outbound-col-right">
  158. <text class="outbound-label">{{ line.right[0] }}</text>
  159. <text class="outbound-value">{{ dash(row[line.right[1]]) }}</text>
  160. </view>
  161. </block>
  162. <!-- <block v-if="line.right">
  163. <view class="outbound-col">
  164. <text class="outbound-label">{{ line.left[0] }}</text>
  165. <text
  166. class="outbound-value"
  167. :class="{ 'outbound-value--mono': line.mono }"
  168. >{{ dash(row[line.left[1]]) }}</text
  169. >
  170. </view>
  171. <view class="outbound-col outbound-col-right">
  172. <text class="outbound-label">{{ line.right[0] }}</text>
  173. <text
  174. class="outbound-value"
  175. :class="{ 'outbound-value--mono': line.mono }"
  176. >{{ dash(row[line.right[1]]) }}</text
  177. >
  178. </view>
  179. </block>
  180. <view v-else class="outbound-col outbound-col--full">
  181. <text class="outbound-label">{{ line.left[0] }}</text>
  182. <text class="outbound-value outbound-highlight">{{
  183. dash(row[line.left[1]])
  184. }}</text>
  185. </view> -->
  186. </view>
  187. </view>
  188. </view>
  189. </view>
  190. </template>
  191. <script>
  192. import {
  193. getPickOrderById,
  194. getOutInBySourceBizNo,
  195. allCategoryLevel,
  196. getLoginUser,
  197. getGroupList,
  198. getUserPageByGroupId,
  199. getUserById,
  200. } from "@/api/wt/index.js";
  201. import { getHierarchyFifo } from "@/api/warehouseManagement/index.js";
  202. const OUTPUT_SCENE_STATE = [
  203. { code: 1, label: "退供出库" },
  204. { code: 2, label: "调拨出库" },
  205. { code: 3, label: "销售出库" },
  206. { code: 4, label: "领用出库" },
  207. { code: 5, label: "报废出库" },
  208. { code: 6, label: "外协出库" },
  209. { code: 7, label: "委外出库" },
  210. { code: 8, label: "受托退货出库" },
  211. { code: 9, label: "仓库委外出库" },
  212. { code: 10, label: "采购退货出库" },
  213. { code: 11, label: "自选领用出库" },
  214. { code: 12, label: "配料出库" },
  215. { code: 13, label: "质检出库" },
  216. { code: 14, label: "物料需求清单出库" },
  217. { code: 99, label: "其他出库" },
  218. ];
  219. const qualityResults = {
  220. 0: "无",
  221. 1: "合格",
  222. 2: "不合格",
  223. 3: "让步接收",
  224. };
  225. const qualityStatus = {
  226. 0: "未质检",
  227. 1: "待检",
  228. 2: "已质检",
  229. };
  230. /** 出库物品卡片:每行左右两列的字段 key(与 outboundItemRows 一致) */
  231. const OUTBOUND_ITEM_GRID = [
  232. { left: ["名称", "name"], right: ["编码", "code"] },
  233. { left: ["批次号", "batchNo"], right: ["型号", "categoryModel"] },
  234. { left: ["规格", "specification"], right: ["包装数量", "packQtyDisplay"] },
  235. { left: ["计量数量", "countDisplay"], right: ["重量", "weightDisplay"] },
  236. { left: ["库存数量", "stockDisplay"], right: ["锁库数", "lockDisplay"] },
  237. { left: ["仓库", "warehouse"], right: ["包装规格", "packingSpecification"] },
  238. { left: ["供应商", "supplierName"], right: ["供应商编号", "supplierCode"] },
  239. ];
  240. /** 包装清单卡片:字段 key 与 packingListRows 一致 */
  241. const PACKING_ITEM_GRID = [
  242. { left: ["名称", "name"], right: ["编码", "code"] },
  243. {
  244. left: ["批次号", "batchNo"],
  245. right: ["发货条码", "shipBarcode"],
  246. mono: true,
  247. },
  248. {
  249. left: ["包装编码", "packageCode"],
  250. right: ["客户代号", "customerCode"],
  251. mono: true,
  252. },
  253. {
  254. left: ["包装数量", "packageQtyDisplay"],
  255. right: ["计量数量", "measureQtyDisplay"],
  256. },
  257. { left: ["重量", "weightDisplay"], right: ["刻码", "engrave"] },
  258. { left: ["质检结果", "resultLabel"], right: ["质检状态", "statusLabel"] },
  259. { left: ["生产日期", "productionDate"], right: ["采购日期", "purchaseDate"] },
  260. { left: ["供应商", "supplierName"], right: ["供应商代号", "supplierCode"] },
  261. // { left: ["物料代号", "materialAlias"], right: ["客户代号", "customerCode"] },
  262. ];
  263. export default {
  264. props: {
  265. businessId: {
  266. default: "",
  267. },
  268. taskDefinitionKey: {
  269. default: "",
  270. },
  271. },
  272. data() {
  273. return {
  274. form: {},
  275. list: ["领料信息", "领料清单", "出库信息", "出库物品", "包装清单"],
  276. curNow: 0,
  277. isStorage: false,
  278. outFormData: {
  279. bizType: "",
  280. sourceBizNo: "",
  281. fromId: "",
  282. fromUser: "",
  283. fromUserPhone: "",
  284. storageTime: "",
  285. type: 2,
  286. createUserId: "",
  287. remark: "",
  288. clientName: "",
  289. outInDetailList: [],
  290. extInfo: {
  291. assetType: [],
  292. assetTypeName: "",
  293. deptCode: "",
  294. deptName: "",
  295. verifyDeptCode: "",
  296. verifyDeptName: "",
  297. createUserName: "",
  298. createUserId: "",
  299. fromUserPhone: "",
  300. sourceBizNo: "",
  301. },
  302. },
  303. warehousingMaterialList: [],
  304. batchDetailsVOList: [],
  305. assetTypeMapping: {},
  306. extractedList: [],
  307. productList: [],
  308. packingList: [],
  309. wwType: null,
  310. outboundItemGrid: OUTBOUND_ITEM_GRID,
  311. packingItemGrid: PACKING_ITEM_GRID,
  312. stickyPlaceholderHeight: 0,
  313. stickyTop: 44,
  314. };
  315. },
  316. computed: {
  317. typeOptions() {
  318. return [
  319. { label: "自建领料", value: 1 },
  320. { label: "工单领料", value: 2 },
  321. { label: "委外领料", value: 3 },
  322. ];
  323. },
  324. typeLabel() {
  325. const current = this.typeOptions.find(
  326. (item) => item.value === Number(this.form.type),
  327. );
  328. return current ? current.label : "";
  329. },
  330. typeIndex() {
  331. const index = this.typeOptions.findIndex(
  332. (item) => item.value === Number(this.form.type),
  333. );
  334. return index > -1 ? index : 0;
  335. },
  336. pickInfoItems() {
  337. return [
  338. { label: "领料单名称", value: this.form.name || "" },
  339. { label: "领料单号", value: this.form.code || "" },
  340. { label: "物品编码", value: this.form.categoryCode || "" },
  341. { label: "物品名称", value: this.form.categoryName || "" },
  342. { label: "型号", value: this.form.modelType || "" },
  343. { label: "规格", value: this.form.specification || "" },
  344. { label: "数量", value: this.form.formingNum || "" },
  345. { label: "计量单位", value: this.form.unit || "" },
  346. { label: "机型", value: this.form.modelKey || "" },
  347. { label: "颜色", value: this.form.colorKey || "" },
  348. { label: "领料时间", value: this.form.createTime || "" },
  349. { label: "领料部门", value: this.form.executorDeptName || "" },
  350. { label: "领料人", value: this.form.executorName || "" },
  351. { label: "类型", value: this.typeLabel || "" },
  352. ];
  353. },
  354. pickListFieldItems() {
  355. return [
  356. { label: "工单编号", key: "workOrderCode" },
  357. { label: "物品编码", key: "categoryCode" },
  358. { label: "物品名称", key: "categoryName" },
  359. { label: "数量", key: "demandQuantity" },
  360. { label: "领料仓库", key: "warehouseName" },
  361. ];
  362. },
  363. outboundSceneLabel() {
  364. const code = Number(this.outFormData.bizType);
  365. const item = OUTPUT_SCENE_STATE.find((s) => s.code === code);
  366. return item ? item.label : "";
  367. },
  368. assetTypeLabel() {
  369. const assetType = this.outFormData.extInfo.assetType;
  370. if (Array.isArray(assetType)) {
  371. return assetType
  372. .map((id) => this.assetTypeMapping[id] || "")
  373. .filter(Boolean)
  374. .join("、");
  375. }
  376. if (typeof assetType === "string" && assetType.includes(",")) {
  377. return assetType
  378. .split(",")
  379. .map((id) => this.assetTypeMapping[id.trim()] || "")
  380. .filter(Boolean)
  381. .join("、");
  382. }
  383. return this.assetTypeMapping[assetType] || "";
  384. },
  385. outboundInfoItems() {
  386. const fd = this.outFormData;
  387. const ext = fd.extInfo || {};
  388. return [
  389. { label: "出库场景", value: this.outboundSceneLabel },
  390. { label: "领料单", value: fd.sourceBizNo || this.form.code || "" },
  391. { label: "出库物品类型", value: this.assetTypeLabel },
  392. { label: "出库时间", value: fd.storageTime || "" },
  393. { label: "出库登记人", value: ext.createUserName || "" },
  394. { label: "领料人部门", value: ext.verifyDeptName || "" },
  395. { label: "领料人", value: fd.fromUser || "" },
  396. { label: "客户名称", value: fd.clientName || "" },
  397. { label: "备注", value: fd.remark || "" },
  398. ];
  399. },
  400. outboundItemRows() {
  401. return this.warehousingMaterialList.map((item, i) => {
  402. const countUnit = item.measuringUnit || "";
  403. const wu = item.weightUnit || "";
  404. const packUnit = item.packingUnit || item.minUnit || "";
  405. const pb = item.packingCountBase;
  406. return {
  407. seq: i + 1,
  408. code: item.assetCode || item.categoryCode || item.code || "",
  409. name: item.assetName || item.name || "",
  410. manualBatchNo: item.manualBatchNo || "",
  411. batchNo: item.batchNo || "",
  412. minPacking:
  413. item.minPackingCount != null
  414. ? `${item.minPackingCount}${countUnit}/${item.minUnit || ""}`
  415. : "",
  416. packQtyDisplay: pb != null && pb !== "" ? `${pb}${packUnit}` : "",
  417. countDisplay:
  418. item.availableCountBase !== "" && item.availableCountBase != null
  419. ? `${item.availableCountBase}${countUnit}`
  420. : "",
  421. weightDisplay:
  422. item.weight !== "" && item.weight != null
  423. ? `${item.weight}${wu}`
  424. : "",
  425. stockDisplay:
  426. item.stockNum !== "" && item.stockNum != null
  427. ? `${item.stockNum}${countUnit}`
  428. : "",
  429. lockDisplay:
  430. item.lockQuantity !== "" && item.lockQuantity != null
  431. ? `${item.lockQuantity}${countUnit}`
  432. : "",
  433. warehouse: item.warehouseName || item.position || "",
  434. supplierName: item.supplierName || "",
  435. supplierCode: item.supplierCode || "",
  436. stockNum: item.stockNum ?? "",
  437. categoryModel: item.categoryModel || "",
  438. specification: item.specification || "",
  439. brandNum: item.brandNum || "",
  440. lockQuantity: item.lockQuantity ?? "",
  441. packingSpecification: item.packingSpecification || "",
  442. };
  443. });
  444. },
  445. packingListRows() {
  446. return this.batchDetailsVOList.map((item, i) => {
  447. const packUnit = item.packingUnit || item.minUnit || "";
  448. const measureUnit = item.measuringUnit || "";
  449. const weightUnit = item.weightUnit || "";
  450. return {
  451. seq: i + 1,
  452. code: item.categoryCode || item.onlyCode || "",
  453. name: item.name || item.assetName || "",
  454. manualBatchNo: item.manualBatchNo || "",
  455. batchNo: item.batchNo || "",
  456. shipBarcode: item.barcodes || "",
  457. packageCode:
  458. item.packageNo ||
  459. item.code ||
  460. item.onlyCode ||
  461. item.packageCode ||
  462. "",
  463. packageQtyDisplay:
  464. item.packingCountBase !== "" && item.packingCountBase != null
  465. ? `${item.packingCountBase}${packUnit}`
  466. : "",
  467. measureQtyDisplay:
  468. item.availableCountBase !== "" && item.availableCountBase != null
  469. ? `${item.availableCountBase}${measureUnit}`
  470. : "",
  471. materialAlias: item.materielCode || "",
  472. customerCode: item.clientCode || "",
  473. weightDisplay:
  474. item.weight !== "" && item.weight != null
  475. ? `${item.weight}${weightUnit}`
  476. : "",
  477. engrave: item.engrave || "",
  478. resultLabel: qualityResults[item.result] || "无",
  479. statusLabel: qualityStatus[item.status] || "未质检",
  480. productionDate: item.productionDate || "",
  481. purchaseDate: item.purchaseDate || "",
  482. supplierName: item.supplierName || "",
  483. supplierCode: item.supplierCode || "",
  484. };
  485. });
  486. },
  487. },
  488. async mounted() {
  489. this.initStickyTop();
  490. await this.loadAssetTypeMapping();
  491. await this.getDetailData(this.businessId);
  492. await this.getLoginUserData();
  493. this.updateStickyPlaceholderHeight();
  494. },
  495. methods: {
  496. initStickyTop() {
  497. try {
  498. const systemInfo = uni.getSystemInfoSync();
  499. const statusBarHeight = Number(systemInfo.statusBarHeight || 0);
  500. // `uni-nav-bar` 开启 statusBar 后,内容区高度默认约为 44px。
  501. this.stickyTop = statusBarHeight + 44;
  502. } catch (error) {
  503. this.stickyTop = 50;
  504. }
  505. },
  506. updateStickyPlaceholderHeight() {
  507. this.$nextTick(() => {
  508. const query = uni.createSelectorQuery().in(this);
  509. query
  510. .select(".sticky-subsection")
  511. .boundingClientRect((rect) => {
  512. if (rect && rect.height) {
  513. this.stickyPlaceholderHeight = rect.height;
  514. }
  515. })
  516. .exec();
  517. });
  518. },
  519. dash(val) {
  520. if (val === null || val === undefined) return "—";
  521. if (typeof val === "string" && val.trim() === "") return "—";
  522. return val;
  523. },
  524. formatPickListField(row, key) {
  525. if (key === "demandQuantity") {
  526. const qty = row?.demandQuantity ?? "";
  527. const unit = row?.unit ?? "";
  528. return qty !== "" || unit !== "" ? `${qty}${unit}` : "";
  529. }
  530. return row?.[key] ?? "";
  531. },
  532. async loadAssetTypeMapping() {
  533. try {
  534. const data = await allCategoryLevel();
  535. const list = Array.isArray(data) ? data : data?.data || [];
  536. const obj = {};
  537. list.forEach((item) => {
  538. obj[item.id] = item.name;
  539. });
  540. this.assetTypeMapping = obj;
  541. } catch (e) {
  542. console.warn("加载物品分类失败", e);
  543. }
  544. },
  545. async getDetailData(id) {
  546. const data = await getPickOrderById(id);
  547. this.form = data;
  548. this.extractedList = this.form.detailList.map((item) => {
  549. return {
  550. taskId: item.taskId,
  551. workOrderId: item.workOrderId,
  552. };
  553. });
  554. console.log(this.extractedList, "this.extractedList");
  555. await this.loadOutboundData(data);
  556. },
  557. async loadOutboundData(pickData) {
  558. const code = pickData.code;
  559. if (!code) return;
  560. const categoryLevelTopIds = (pickData.detailList || [])
  561. .map((item) => item.rootCategoryLevelId)
  562. .filter(Boolean);
  563. const uniqueAssetTypes = [...new Set(categoryLevelTopIds)];
  564. const rootCategoryLevelId =
  565. Array.isArray(this.form.detailList) && this.form.detailList[0]
  566. ? this.form.detailList[0].rootCategoryLevelId
  567. : "";
  568. try {
  569. const outData = await getOutInBySourceBizNo(code);
  570. if (!outData || !outData.id) {
  571. throw new Error("No outbound data");
  572. }
  573. this.isStorage = true;
  574. this.outFormData = {
  575. bizType: outData.bizType || "11",
  576. sourceBizNo:
  577. outData.sourceBizNo || outData.extInfo?.sourceBizNo || code,
  578. fromId: outData.fromId || "",
  579. fromUser: outData.fromUser || "",
  580. fromUserPhone: outData.fromUserPhone || "",
  581. storageTime: outData.storageTime || "",
  582. type: outData.type || 2,
  583. createUserId: outData.createUserId || "",
  584. clientName: outData.clientName || "",
  585. remark: outData.remark || "",
  586. outInDetailList: outData.outInDetailVOList || [],
  587. extInfo: {
  588. ...(outData.extInfo || {}),
  589. createUserName:
  590. outData.extInfo?.createUserName ||
  591. this.outFormData.extInfo?.createUserName ||
  592. "",
  593. assetType:
  594. uniqueAssetTypes.length > 0
  595. ? uniqueAssetTypes
  596. : rootCategoryLevelId || outData.extInfo?.assetType || "",
  597. },
  598. };
  599. this.parseOutInDetailList(outData.outInDetailVOList || []);
  600. } catch (e) {
  601. this.isStorage = false;
  602. const savedCreateUserName =
  603. this.outFormData.extInfo?.createUserName || "";
  604. this.outFormData = {
  605. bizType: "11",
  606. sourceBizNo: code,
  607. fromId: "",
  608. fromUser: "",
  609. fromUserPhone: "",
  610. storageTime: "",
  611. type: 2,
  612. createUserId: "",
  613. clientName: "",
  614. remark: "",
  615. outInDetailList: [],
  616. extInfo: {
  617. assetType:
  618. uniqueAssetTypes.length > 0
  619. ? uniqueAssetTypes
  620. : rootCategoryLevelId || "",
  621. assetTypeName: "",
  622. deptCode: "",
  623. deptName: "",
  624. verifyDeptCode: "",
  625. verifyDeptName: "",
  626. createUserName: savedCreateUserName,
  627. createUserId: "",
  628. fromUserPhone: "",
  629. sourceBizNo: "",
  630. },
  631. };
  632. this.warehousingMaterialList = [];
  633. this.batchDetailsVOList = [];
  634. if (
  635. this.taskDefinitionKey === "storeman" ||
  636. this.taskDefinitionKey === "storemanAudit"
  637. ) {
  638. await this.initOutboundFromHierarchy(pickData);
  639. }
  640. }
  641. },
  642. parseOutInDetailList(list) {
  643. const materials = [];
  644. const packages = [];
  645. list.forEach((goodsItem) => {
  646. materials.push({
  647. ...goodsItem,
  648. assetName: goodsItem.name || goodsItem.assetName,
  649. assetCode: goodsItem.categoryCode || goodsItem.assetCode,
  650. outInNum: goodsItem.packingCount,
  651. });
  652. const records = goodsItem.outInDetailRecordVOList || [];
  653. records.forEach((wrapItem) => {
  654. packages.push({
  655. ...wrapItem,
  656. assetName: goodsItem.name || goodsItem.assetName,
  657. assetCode: goodsItem.categoryCode || goodsItem.assetCode,
  658. });
  659. });
  660. });
  661. this.warehousingMaterialList = materials;
  662. this.batchDetailsVOList = packages;
  663. },
  664. onTypeChange(e) {
  665. const index = e?.detail?.value;
  666. const selected = this.typeOptions[index];
  667. this.form.type = selected ? selected.value : this.form.type;
  668. },
  669. async getLoginUserData() {
  670. try {
  671. const data = await getLoginUser();
  672. if (!this.outFormData.extInfo) {
  673. this.$set(this.outFormData, "extInfo", {});
  674. }
  675. this.$set(this.outFormData.extInfo, "createUserName", data.name || "");
  676. } catch (e) {
  677. console.warn("获取登录用户数据失败", e);
  678. }
  679. },
  680. getNowFormatDate() {
  681. const now = new Date();
  682. const pad = (n) => String(n).padStart(2, "0");
  683. this.outFormData.storageTime = `${now.getFullYear()}-${pad(now.getMonth() + 1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
  684. },
  685. async getStaffList(groupId) {
  686. try {
  687. const res = await getUserPageByGroupId({
  688. groupId,
  689. size: 9999,
  690. page: 1,
  691. });
  692. return res.list || [];
  693. } catch (e) {
  694. console.warn("获取员工列表失败", e);
  695. return [];
  696. }
  697. },
  698. async initOutboundFromHierarchy(pickData) {
  699. const code = pickData.code;
  700. this.wwType = pickData.type;
  701. const categoryLevelTopIds = (pickData.detailList || [])
  702. .map((item) => item.rootCategoryLevelId)
  703. .filter(Boolean);
  704. const uniqueAssetTypes = [...new Set(categoryLevelTopIds)];
  705. this.outFormData.bizType = 11;
  706. this.outFormData.sourceBizNo = code;
  707. this.outFormData.type = 2;
  708. this.outFormData.extInfo.assetType = uniqueAssetTypes;
  709. this.outFormData.extInfo.sourceBizNo = code;
  710. this.getNowFormatDate();
  711. try {
  712. const userData = await getLoginUser();
  713. this.outFormData.extInfo.createUserName = userData.name || "";
  714. this.outFormData.extInfo.createUserId = userData.userId || "";
  715. this.outFormData.createUserId = userData.userId || "";
  716. } catch (e) {
  717. console.warn("获取登录用户失败", e);
  718. }
  719. if (pickData.executorDeptId) {
  720. try {
  721. const staffList = await this.getStaffList(pickData.executorDeptId);
  722. this.outFormData.fromId = pickData.executorId || "";
  723. this.outFormData.fromUser = pickData.executorName || "";
  724. this.outFormData.extInfo.verifyDeptCode =
  725. pickData.executorDeptId || "";
  726. this.outFormData.extInfo.verifyDeptName =
  727. pickData.executorDeptName || "";
  728. } catch (e) {
  729. console.warn("设置领料人信息失败", e);
  730. }
  731. } else if (pickData.createUserId) {
  732. this.outFormData.fromId = pickData.createUserId;
  733. try {
  734. const userInfo = await getUserById(pickData.createUserId);
  735. this.outFormData.fromUser = userInfo.name || "";
  736. this.outFormData.extInfo.verifyDeptCode = userInfo.groupId || "";
  737. this.outFormData.extInfo.verifyDeptName = userInfo.groupName || "";
  738. } catch (e) {
  739. console.warn("获取领料人部门信息失败", e);
  740. }
  741. }
  742. if (pickData.makerId) {
  743. try {
  744. const makerInfo = await getUserById(pickData.makerId);
  745. this.outFormData.extInfo.verifyDeptCode =
  746. this.outFormData.extInfo.verifyDeptCode || makerInfo.groupId || "";
  747. this.outFormData.extInfo.verifyDeptName =
  748. this.outFormData.extInfo.verifyDeptName ||
  749. makerInfo.groupName ||
  750. "";
  751. } catch (e) {
  752. console.warn("获取makerId部门失败", e);
  753. }
  754. }
  755. const detailList = pickData.detailList || [];
  756. if (!detailList.length) return;
  757. let requestData;
  758. if (Number(this.wwType) === 3) {
  759. requestData = {
  760. type: this.wwType,
  761. deliveryNo: code,
  762. taskIds: this.extractedList.map((item) => item.taskId),
  763. workOrderIds: this.extractedList.map((item) => item.workOrderId),
  764. };
  765. } else {
  766. requestData = {
  767. type: "1",
  768. deliveryNo: code,
  769. builders: detailList.map((item) => ({
  770. categoryId:
  771. item.categoryId || item.instanceId || item.productId || "",
  772. num: item.demandQuantity || item.measurementCount || 0,
  773. warehouseId: item.warehouseId || "",
  774. batchNo: item.batchNo || "",
  775. })),
  776. };
  777. }
  778. try {
  779. const data = await getHierarchyFifo(requestData);
  780. this.processHierarchyData(data, pickData);
  781. } catch (err) {
  782. console.warn("获取出库物品数据失败", err);
  783. }
  784. },
  785. processHierarchyData(data, pickData) {
  786. if (!Array.isArray(data) || !data.length) return;
  787. const firstDetail =
  788. Array.isArray(pickData?.detailList) && pickData.detailList[0]
  789. ? pickData.detailList[0]
  790. : {};
  791. this.productList = data.map((productItem) => ({
  792. ...productItem,
  793. suspendBatchNo: productItem.batchNo || "",
  794. outInDetailRecordRequestList: (
  795. productItem.outInDetailRecordRequestList || []
  796. ).map((packingItem) => ({
  797. ...packingItem,
  798. workOrderId: firstDetail.workOrderId || "",
  799. pickOrderId: firstDetail.pickOrderId || "",
  800. taskId: firstDetail.taskId || "",
  801. categoryName: productItem.categoryName || packingItem.categoryName,
  802. categoryCode: productItem.categoryCode || packingItem.categoryCode,
  803. supplierCode:
  804. productItem.supplierCode || packingItem.supplierCode || "",
  805. supplierName:
  806. productItem.supplierName || packingItem.supplierName || "",
  807. materialDetailList: (packingItem.materialDetailList || []).map(
  808. (materialItem) => ({
  809. ...materialItem,
  810. categoryName:
  811. productItem.categoryName || materialItem.categoryName,
  812. categoryCode:
  813. productItem.categoryCode || materialItem.categoryCode,
  814. supplierCode:
  815. productItem.supplierCode ||
  816. packingItem.supplierCode ||
  817. materialItem.supplierCode ||
  818. "",
  819. supplierName:
  820. productItem.supplierName ||
  821. packingItem.supplierName ||
  822. materialItem.supplierName ||
  823. "",
  824. }),
  825. ),
  826. })),
  827. }));
  828. console.log(this.productList, "productList");
  829. this.productList.sort((a, b) =>
  830. (a.categoryCode || "").localeCompare(b.categoryCode || ""),
  831. );
  832. const materials = [];
  833. const packages = [];
  834. console.log(this.productList, "productList1111");
  835. this.productList.forEach((item) => {
  836. materials.push({
  837. assetCode: item.categoryCode,
  838. assetName: item.categoryName,
  839. categoryCode: item.categoryCode,
  840. categoryName: item.categoryName,
  841. name: item.categoryName,
  842. manualBatchNo: item.manualBatchNo || "",
  843. batchNo: item.batchNo || "",
  844. packingCountBase: item.packingQuantity,
  845. minPackingCount: item.minPackingCount,
  846. minUnit: item.packingUnit,
  847. availableCountBase: item.measureQuantity,
  848. measuringUnit: item.measureUnit,
  849. weight: item.weight,
  850. weightUnit: item.weightUnit,
  851. warehouseName: item.warehouseName,
  852. warehouseId: item.warehouseId,
  853. outInNum: item.packingQuantity,
  854. stockNum: item.stockNum,
  855. categoryModel: item.categoryModel,
  856. specification: item.specification,
  857. brandNum: item.brandNum,
  858. lockQuantity: item.lockQuantity,
  859. packingSpecification: item.extField?.packingSpecification || "",
  860. supplierName:
  861. item.supplierName ||
  862. (item.outInDetailRecordRequestList &&
  863. item.outInDetailRecordRequestList[0] &&
  864. item.outInDetailRecordRequestList[0].supplierName) ||
  865. "",
  866. supplierCode:
  867. item.supplierCode ||
  868. (item.outInDetailRecordRequestList &&
  869. item.outInDetailRecordRequestList[0] &&
  870. item.outInDetailRecordRequestList[0].supplierCode) ||
  871. "",
  872. });
  873. console.log(materials, "materialsmaterialsmaterials");
  874. const records = item.outInDetailRecordRequestList || [];
  875. records.forEach((record) => {
  876. packages.push({
  877. code: record.packageNo,
  878. onlyCode: record.packageNo,
  879. assetName: item.categoryName,
  880. name: item.categoryName,
  881. categoryCode: item.categoryCode,
  882. categoryName: item.categoryName,
  883. manualBatchNo: record.manualBatchNo || "",
  884. batchNo: record.batchNo || "",
  885. barcodes: record.barcodes || "",
  886. packingCountBase: record.packingQuantity,
  887. packingUnit: record.packingUnit,
  888. minUnit: record.packingUnit,
  889. availableCountBase: record.measureQuantity,
  890. measuringUnit: record.measureUnit,
  891. materielCode: record.materielDesignation || "",
  892. clientCode: record.clientCode || "",
  893. weight: record.weight,
  894. weightUnit: record.weightUnit,
  895. supplierCode: item.supplierCode || record.supplierCode || "",
  896. supplierName: item.supplierName || record.supplierName || "",
  897. modelKey: record.modelKey || "",
  898. colorKey: record.colorKey || "",
  899. result: record.result,
  900. status: record.status,
  901. productionDate: record.productionDate || "",
  902. purchaseDate: record.purchaseDate || "",
  903. engrave: record.engrave || "",
  904. });
  905. });
  906. });
  907. this.warehousingMaterialList = materials;
  908. this.batchDetailsVOList = packages;
  909. this.packingList = packages;
  910. this.outFormData.outInDetailList = this.productList;
  911. },
  912. async getReturnStorage() {
  913. if (!this.productList || !this.productList.length) {
  914. uni.showToast({ title: "请添加出库明细!", icon: "none" });
  915. return null;
  916. }
  917. const obj = JSON.parse(JSON.stringify({ ...this.outFormData, type: 2 }));
  918. obj.extInfo.sourceBizNo = obj.sourceBizNo;
  919. obj.fromType = obj.type;
  920. if (Array.isArray(obj.extInfo.assetType)) {
  921. obj.extInfo.assetType = obj.extInfo.assetType.join(",");
  922. }
  923. const warehouseId = [];
  924. const warehouseName = [];
  925. this.productList.forEach((item) => {
  926. if (item.warehouseId && !warehouseId.includes(item.warehouseId)) {
  927. warehouseId.push(item.warehouseId);
  928. warehouseName.push(item.warehouseName || "");
  929. }
  930. });
  931. obj.warehouseIds = warehouseId;
  932. obj.warehouseNames = warehouseName;
  933. obj.outInDetailList = this.productList;
  934. return obj;
  935. },
  936. async getTableValue() {
  937. const outboundData = {
  938. // 原始数据(接口/提交更稳定)
  939. warehousingMaterialList: this.warehousingMaterialList || [],
  940. batchDetailsVOList: this.batchDetailsVOList || [],
  941. // 展示映射数据(便于前端直接渲染)
  942. outboundItemRows: this.outboundItemRows || [],
  943. packingListRows: this.packingListRows || [],
  944. };
  945. if (!this.isStorage && this.productList.length > 0) {
  946. const returnStorageData = await this.getReturnStorage();
  947. return {
  948. form: this.form,
  949. returnStorageData: returnStorageData || {},
  950. ...outboundData,
  951. };
  952. }
  953. return {
  954. form: this.form,
  955. returnStorageData: {},
  956. ...outboundData,
  957. };
  958. },
  959. sectionChange(index) {
  960. this.curNow = index;
  961. },
  962. },
  963. };
  964. </script>
  965. <style scoped>
  966. .btnConcel {
  967. margin-top: 20rpx;
  968. }
  969. .sticky-subsection {
  970. position: fixed;
  971. left: 0;
  972. right: 0;
  973. z-index: 99;
  974. width: 100%;
  975. box-sizing: border-box;
  976. background: #f5f7fa;
  977. }
  978. .sticky-subsection-placeholder {
  979. width: 100%;
  980. }
  981. .subsection-wrap {
  982. background: #f5f7fa;
  983. padding: 0 16rpx 12rpx;
  984. width: 100%;
  985. box-sizing: border-box;
  986. }
  987. .pick-info-wrap {
  988. padding: 0 0 24rpx;
  989. }
  990. .pick-info-title {
  991. display: flex;
  992. align-items: center;
  993. margin: 20rpx 24rpx 12rpx;
  994. }
  995. .pick-info-title-bar {
  996. width: 8rpx;
  997. height: 30rpx;
  998. background: #157a2c;
  999. border-radius: 4rpx;
  1000. margin-right: 14rpx;
  1001. flex-shrink: 0;
  1002. }
  1003. .pick-info-title-text {
  1004. font-size: 30rpx;
  1005. font-weight: 600;
  1006. color: #303133;
  1007. }
  1008. .pick-info-form {
  1009. background: #ffffff;
  1010. border-radius: 16rpx;
  1011. padding: 6rpx 20rpx;
  1012. box-sizing: border-box;
  1013. box-shadow: 0 6rpx 18rpx rgba(0, 0, 0, 0.04);
  1014. }
  1015. .pick-info-form :deep(.u-form-item) {
  1016. padding: 8rpx 0;
  1017. }
  1018. .pick-info-form :deep(.u-form-item__body) {
  1019. min-height: 88rpx;
  1020. }
  1021. .pick-info-form :deep(.u-form-item__body__left__content__label) {
  1022. font-size: 28rpx;
  1023. color: #303133;
  1024. }
  1025. .pick-info-form :deep(.u-border-bottom::after) {
  1026. border-color: #ebeef5 !important;
  1027. }
  1028. .pick-info-form :deep(.u-input) {
  1029. background: #f6f8fc !important;
  1030. border: 1rpx solid #e7ebf1 !important;
  1031. border-radius: 12rpx !important;
  1032. padding: 12rpx 16rpx !important;
  1033. }
  1034. .pick-info-form :deep(.u-input__content__field-wrapper__field) {
  1035. font-size: 28rpx !important;
  1036. color: #4a4f57 !important;
  1037. }
  1038. .pick-list-wrap {
  1039. padding: 0 24rpx 32rpx;
  1040. box-sizing: border-box;
  1041. }
  1042. .pick-list-section-title {
  1043. display: flex;
  1044. align-items: center;
  1045. padding: 24rpx 0 16rpx;
  1046. }
  1047. .pick-list-section-bar {
  1048. width: 8rpx;
  1049. height: 32rpx;
  1050. background: #1890ff;
  1051. border-radius: 4rpx;
  1052. margin-right: 16rpx;
  1053. flex-shrink: 0;
  1054. }
  1055. .pick-list-section-text {
  1056. font-size: 32rpx;
  1057. font-weight: 600;
  1058. color: #303133;
  1059. }
  1060. .pick-list-divider {
  1061. height: 2rpx;
  1062. background: linear-gradient(
  1063. 90deg,
  1064. rgba(24, 144, 255, 0.35) 0%,
  1065. rgba(24, 144, 255, 0.08) 100%
  1066. );
  1067. margin-bottom: 8rpx;
  1068. }
  1069. .pick-list-empty {
  1070. text-align: center;
  1071. color: #909399;
  1072. font-size: 28rpx;
  1073. padding: 80rpx 0;
  1074. }
  1075. .pick-list-card {
  1076. background: #fff;
  1077. border-radius: 16rpx;
  1078. margin-top: 24rpx;
  1079. box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06);
  1080. border: 1rpx solid #eef0f4;
  1081. overflow: hidden;
  1082. }
  1083. .pick-list-card-head {
  1084. background: #f5f7fa;
  1085. padding: 20rpx 24rpx;
  1086. border-bottom: 1rpx solid #eef0f4;
  1087. }
  1088. .pick-list-index {
  1089. font-size: 26rpx;
  1090. font-weight: 600;
  1091. color: #606266;
  1092. }
  1093. .pick-list-card-body {
  1094. padding: 8rpx 24rpx 20rpx;
  1095. }
  1096. .pick-list-row {
  1097. display: flex;
  1098. align-items: flex-start;
  1099. justify-content: space-between;
  1100. padding: 18rpx 0;
  1101. border-bottom: 1rpx solid #f0f2f5;
  1102. }
  1103. .pick-list-row:last-child {
  1104. border-bottom: none;
  1105. }
  1106. .pick-list-row--highlight .pick-list-value {
  1107. color: #157a2c;
  1108. font-weight: 600;
  1109. }
  1110. .pick-list-row--two {
  1111. display: flex;
  1112. gap: 24rpx;
  1113. align-items: flex-start;
  1114. }
  1115. .pick-list-cell {
  1116. flex: 1;
  1117. min-width: 0;
  1118. display: flex;
  1119. flex-direction: column;
  1120. gap: 8rpx;
  1121. }
  1122. .pick-list-cell--right {
  1123. align-items: flex-end;
  1124. text-align: right;
  1125. }
  1126. .pick-list-cell--right .pick-list-label,
  1127. .pick-list-cell--right .pick-list-value {
  1128. text-align: right;
  1129. }
  1130. .pick-list-label {
  1131. font-size: 24rpx;
  1132. color: #909399;
  1133. flex-shrink: 0;
  1134. margin-right: 16rpx;
  1135. min-width: 140rpx;
  1136. }
  1137. .pick-list-row--two .pick-list-label {
  1138. margin-right: 0;
  1139. min-width: 0;
  1140. }
  1141. .pick-list-value {
  1142. font-size: 28rpx;
  1143. color: #303133;
  1144. word-break: break-all;
  1145. flex: 1;
  1146. text-align: right;
  1147. }
  1148. .pick-list-row--two .pick-list-value {
  1149. text-align: left;
  1150. }
  1151. .pick-list-cell--right .pick-list-value {
  1152. text-align: right;
  1153. }
  1154. .pick-list-value--mono {
  1155. font-family: ui-monospace, monospace;
  1156. font-size: 26rpx;
  1157. }
  1158. .out-info-wrap {
  1159. padding: 0 24rpx 32rpx;
  1160. box-sizing: border-box;
  1161. }
  1162. .out-info-title {
  1163. display: flex;
  1164. align-items: center;
  1165. padding: 24rpx 0 12rpx;
  1166. }
  1167. .out-info-title-bar {
  1168. width: 8rpx;
  1169. height: 32rpx;
  1170. background: #1890ff;
  1171. border-radius: 4rpx;
  1172. margin-right: 16rpx;
  1173. flex-shrink: 0;
  1174. }
  1175. .out-info-title-text {
  1176. font-size: 32rpx;
  1177. font-weight: 600;
  1178. color: #303133;
  1179. }
  1180. .out-info-divider {
  1181. height: 2rpx;
  1182. background: linear-gradient(
  1183. 90deg,
  1184. rgba(24, 144, 255, 0.35) 0%,
  1185. rgba(24, 144, 255, 0.08) 100%
  1186. );
  1187. margin-bottom: 8rpx;
  1188. }
  1189. .out-info-card {
  1190. margin-top: 20rpx;
  1191. background: #fff;
  1192. border: 1rpx solid #eef0f4;
  1193. border-radius: 16rpx;
  1194. box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
  1195. overflow: hidden;
  1196. }
  1197. .out-info-row {
  1198. display: flex;
  1199. align-items: flex-start;
  1200. justify-content: space-between;
  1201. padding: 22rpx;
  1202. border-bottom: 1rpx solid #f0f2f5;
  1203. gap: 16rpx;
  1204. }
  1205. .out-info-row:last-child {
  1206. border-bottom: none;
  1207. }
  1208. .out-info-label {
  1209. font-size: 28rpx;
  1210. color: #303133;
  1211. min-width: 160rpx;
  1212. word-break: break-all;
  1213. }
  1214. .out-info-value {
  1215. flex: 1;
  1216. text-align: right;
  1217. color: #303133;
  1218. font-size: 28rpx;
  1219. word-break: break-all;
  1220. }
  1221. .outbound-wrap {
  1222. padding: 0 24rpx 32rpx;
  1223. }
  1224. .outbound-title {
  1225. display: flex;
  1226. align-items: center;
  1227. padding: 24rpx 0 14rpx;
  1228. }
  1229. .outbound-title-bar {
  1230. width: 8rpx;
  1231. height: 32rpx;
  1232. background: #1890ff;
  1233. border-radius: 4rpx;
  1234. margin-right: 14rpx;
  1235. }
  1236. .outbound-title-text {
  1237. font-size: 32rpx;
  1238. font-weight: 600;
  1239. color: #303133;
  1240. }
  1241. .outbound-empty {
  1242. text-align: center;
  1243. color: #909399;
  1244. font-size: 28rpx;
  1245. padding: 80rpx 0;
  1246. }
  1247. .outbound-card {
  1248. margin-top: 20rpx;
  1249. background: #fff;
  1250. border: 1rpx solid #eef0f4;
  1251. border-radius: 16rpx;
  1252. box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
  1253. overflow: hidden;
  1254. }
  1255. .outbound-card-head {
  1256. background: #f7f9fc;
  1257. border-bottom: 1rpx solid #eef0f4;
  1258. padding: 18rpx 22rpx;
  1259. display: flex;
  1260. align-items: center;
  1261. justify-content: space-between;
  1262. }
  1263. .outbound-index {
  1264. font-size: 25rpx;
  1265. color: #606266;
  1266. font-weight: 600;
  1267. }
  1268. .outbound-code {
  1269. font-size: 25rpx;
  1270. color: #303133;
  1271. font-family: ui-monospace, monospace;
  1272. }
  1273. .outbound-grid {
  1274. padding: 18rpx 22rpx;
  1275. border-bottom: 1rpx solid #f0f2f5;
  1276. display: flex;
  1277. gap: 20rpx;
  1278. }
  1279. .outbound-grid-last {
  1280. border-bottom: none;
  1281. }
  1282. .outbound-grid--full {
  1283. flex-wrap: wrap;
  1284. }
  1285. .outbound-col--full {
  1286. flex: 1;
  1287. min-width: 0;
  1288. width: 100%;
  1289. display: flex;
  1290. flex-direction: column;
  1291. gap: 10rpx;
  1292. }
  1293. .outbound-col {
  1294. flex: 1;
  1295. min-width: 0;
  1296. display: flex;
  1297. flex-direction: column;
  1298. gap: 10rpx;
  1299. }
  1300. .outbound-col-right {
  1301. align-items: flex-end;
  1302. text-align: right;
  1303. }
  1304. .outbound-label {
  1305. font-size: 24rpx;
  1306. color: #303133;
  1307. }
  1308. .outbound-value {
  1309. font-size: 28rpx;
  1310. color: #205dd9;
  1311. word-break: break-all;
  1312. }
  1313. .outbound-col-right .outbound-value {
  1314. text-align: right;
  1315. }
  1316. .outbound-value--mono {
  1317. font-family: ui-monospace, monospace;
  1318. font-size: 26rpx;
  1319. }
  1320. .outbound-highlight {
  1321. color: #157a2c;
  1322. font-weight: 600;
  1323. }
  1324. </style>