edit.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <template>
  2. <view class="mainBox">
  3. <uni-nav-bar
  4. fixed="true"
  5. statusBar="true"
  6. left-icon="back"
  7. title="新增报损报溢"
  8. @clickLeft="back"
  9. >
  10. </uni-nav-bar>
  11. <u-form
  12. labelPosition="left"
  13. :model="formData"
  14. :rules="rules"
  15. ref="formRef"
  16. labelWidth="260"
  17. labelAlign="right"
  18. class="baseForm"
  19. >
  20. <u-form-item label="报损报溢编码" borderBottom prop="code">
  21. <u-input
  22. :value="formData.code"
  23. disableColor="#ffffff"
  24. placeholder="请选择"
  25. disabled
  26. type="select"
  27. />
  28. </u-form-item>
  29. <u-form-item label="名称" class="required-form" borderBottom prop="name">
  30. <u-input v-model="formData.name" placeholder="请输入" type="text" />
  31. </u-form-item>
  32. <u-form-item
  33. label="报损报溢部门"
  34. class="required-form"
  35. prop="bizScene"
  36. borderBottom
  37. >
  38. <u-input
  39. v-model="formData.reportDeptName"
  40. disableColor="#ffffff"
  41. placeholder="请选择"
  42. disabled
  43. type="select"
  44. />
  45. </u-form-item>
  46. <u-form-item
  47. label="报损报溢人"
  48. class="required-form"
  49. prop="reportName"
  50. borderBottom
  51. >
  52. <u-input
  53. :value="formData.reportName"
  54. disableColor="#ffffff"
  55. placeholder="请选择"
  56. disabled
  57. type="select"
  58. />
  59. </u-form-item>
  60. <u-form-item label="审核人部门" prop="verifyDeptName" borderBottom>
  61. <u-input
  62. :value="formData.verifyDeptName"
  63. disableColor="#ffffff"
  64. placeholder="请选择"
  65. disabled
  66. type="select"
  67. @click.native="$refs.treePicker._show()"
  68. />
  69. <u-icon slot="right" name="arrow-right"></u-icon>
  70. </u-form-item>
  71. <u-form-item label="审核人" prop="auditId" borderBottom>
  72. <picker
  73. @change="(e) => handlePicker(e, userList, 'auditId', 'auditName')"
  74. :value="pickerIndex"
  75. :range="userList"
  76. range-key="name"
  77. >
  78. <u-input
  79. :value="formData.auditName"
  80. disableColor="#ffffff"
  81. placeholder="请选择"
  82. disabled
  83. type="select"
  84. />
  85. </picker>
  86. <u-icon slot="right" name="arrow-right"></u-icon>
  87. </u-form-item>
  88. <u-form-item label="备注" prop="remark" borderBottom>
  89. <u-textarea
  90. confirmType="done"
  91. :maxlength="-1"
  92. height="80"
  93. v-model="formData.remark"
  94. placeholder="请输入"
  95. ></u-textarea>
  96. </u-form-item>
  97. </u-form>
  98. <uni-section title="报损报溢明细" type="line">
  99. <template v-slot:right>
  100. <text class="text-primary" @click="workorderSelect">选择盘点工单</text>
  101. </template>
  102. <view class="order-box">盘点工单{{ formData.workOrderCode }}</view>
  103. <view
  104. v-for="(item, index) in formData.list"
  105. :key="index"
  106. class="list-card"
  107. >
  108. <view class="status" :style="{ color: _getStatus(item.status).color }">
  109. <text>{{ _getStatus(item.status).name }}</text>
  110. <text
  111. >数量:{{
  112. [1, 2].includes(item.status) ? "-1" : `+${item.checkNum || 0}`
  113. }}</text
  114. >
  115. </view>
  116. <view class="row first">
  117. <view class="col" style="width: 100%">
  118. <text class="main">{{ item.name }}</text>
  119. {{ item.code }}
  120. </view>
  121. <view class="col" style="width: 100%">
  122. <text class="main">货位:</text>
  123. {{ item.warehouseName }}-{{ item.reservoirName }}-{{
  124. item.goodsShelfName
  125. }}-{{ item.goodsAllocationName }}
  126. </view>
  127. </view>
  128. <view class="row">
  129. <view class="col">
  130. <text class="label">批次号:</text>
  131. {{ item.batchNo }}
  132. </view>
  133. <view class="col">
  134. <text class="label">类型:</text>
  135. {{ getDictValue("物品类型", item.productType) }}
  136. </view>
  137. <view class="col" v-for="(itm, index) in tableHeader" :key="index">
  138. <text class="label">{{ itm.label }}:</text>
  139. {{ item[itm.prop] }}
  140. </view>
  141. <view class="col" v-if="!item.isUnpack">
  142. <text class="label">最小单元:</text>
  143. {{ item.unit }}/{{ item.minPackUnit }}
  144. </view>
  145. </view>
  146. <uni-icons
  147. type="trash"
  148. size="30"
  149. class="del"
  150. @click="delRow(index)"
  151. ></uni-icons>
  152. </view>
  153. </uni-section>
  154. <view class="footBox">
  155. <u-button type="success" @click="handleSubmit">提交</u-button>
  156. </view>
  157. <ba-tree-picker
  158. ref="treePicker"
  159. :multiple="false"
  160. @select-change="deptConfirm"
  161. key="dept"
  162. title="选择部门"
  163. :localdata="deptList"
  164. valueKey="code"
  165. textKey="name"
  166. childrenKey="children"
  167. />
  168. </view>
  169. </template>
  170. <script>
  171. import { post, postJ, get, getJ } from "@/utils/api.js";
  172. import {
  173. getDict,
  174. wh_equStatus,
  175. getDictName,
  176. warehousingType,
  177. } from "../enum.js";
  178. import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue";
  179. import { getRuleNo } from "@/utils/utils.js";
  180. import dictMxins from "@/mixins/dictMixins";
  181. export default {
  182. components: { baTreePicker },
  183. mixins: [dictMxins],
  184. data() {
  185. return {
  186. warehousingType,
  187. getDictName,
  188. pickerIndex: 0,
  189. deptList: [],
  190. userList: [],
  191. formData: {
  192. code: getRuleNo("BS"),
  193. auditId: "",
  194. auditName: "",
  195. verifyDeptCode: "",
  196. verifyDeptName: "",
  197. workOrderCode: "",
  198. list: [],
  199. },
  200. isMaterial: true,
  201. rules: {
  202. // name: {
  203. // type: 'string',
  204. // required: true,
  205. // message: '请输入名称',
  206. // trigger: ['blur']
  207. // }
  208. },
  209. };
  210. },
  211. onLoad({ id }) {
  212. this.requestDict("物品类型");
  213. if (id) {
  214. this.getDetail(id);
  215. } else {
  216. const userInfo = uni.getStorageSync("userInfo");
  217. this.formData.reportName = userInfo.name;
  218. this.formData.reportId = userInfo.id;
  219. this.formData.reportDeptName = userInfo.dept.name;
  220. this.formData.reportDeptId = userInfo.dept.code;
  221. }
  222. this.getDept();
  223. uni.$off("getWorkorder");
  224. uni.$on("getWorkorder", (data) => {
  225. if (data?.id) {
  226. this.formData.workOrderCode = data.workOrderCode;
  227. this.isMaterial = data.assetDict?.code === 3;
  228. this._getAbnormaldetailList(data.id);
  229. }
  230. });
  231. },
  232. computed: {
  233. tableHeader() {
  234. if (this.formData.list?.length) {
  235. return this.getTableHeader(this.formData.list[0].assetTypeDict);
  236. }
  237. return [];
  238. },
  239. },
  240. methods: {
  241. getTableHeader(selectEquiType) {
  242. switch (+selectEquiType) {
  243. case 3:
  244. return [{ label: "牌号", prop: "assetBrand" }];
  245. case 8:
  246. return [
  247. { label: "型号", prop: "assetSku" },
  248. { label: "规格", prop: "specification" },
  249. ];
  250. case 4:
  251. return [
  252. { label: "牌号", prop: "assetBrand" },
  253. { label: "型号", prop: "assetSku" },
  254. ];
  255. case 5: //'周转车'
  256. return [
  257. { label: "规格", prop: "specification" },
  258. {
  259. label: "材质",
  260. prop: "texture",
  261. formatter(row) {
  262. if (!row?.extendField) return "";
  263. const extendField = JSON.parse(row.extendField);
  264. return extendField.texture;
  265. },
  266. },
  267. {
  268. label: "长宽高",
  269. prop: "",
  270. formatter(row) {
  271. if (!row?.extendField) return "";
  272. const extendField = JSON.parse(row.extendField);
  273. return `${extendField.length || "-"}*${
  274. extendField.width || "-"
  275. }*${extendField.high || "-"}`;
  276. },
  277. },
  278. ];
  279. case 2: //'舟皿'
  280. return [
  281. { label: "规格", prop: "specification" },
  282. { label: "型号", prop: "assetSku" },
  283. {
  284. label: "长宽高",
  285. prop: "",
  286. formatter(row) {
  287. if (!row?.extendField) return "";
  288. const extendField = JSON.parse(row.extendField);
  289. return `${extendField.length || "-"}*${
  290. extendField.width || "-"
  291. }*${extendField.high || "-"}`;
  292. },
  293. },
  294. ];
  295. case 1: //'设备'
  296. return [
  297. { label: "型号", prop: "assetSku" },
  298. { label: "规格", prop: "specification" },
  299. ];
  300. case 6: //'模具'
  301. return [
  302. { label: "牌号", prop: "assetBrand" },
  303. { label: "型号", prop: "assetSku" },
  304. {
  305. label: "收缩系数",
  306. prop: "",
  307. formatter(row) {
  308. if (!row?.extendField) return "";
  309. const extendField = JSON.parse(row.extendField);
  310. return extendField.shrinkageCoefficient;
  311. },
  312. },
  313. ];
  314. case 7: //'备品备件'
  315. return [
  316. { label: "规格", prop: "specification" },
  317. { label: "型号", prop: "assetSku" },
  318. ];
  319. }
  320. return [];
  321. },
  322. _getStatus: getDict(wh_equStatus),
  323. workorderSelect() {
  324. uni.navigateTo({
  325. url: "/pages/warehouse/reportLoss/workorderSelected",
  326. });
  327. },
  328. async getDetail(id) {
  329. const res = await get(this.apiUrl + `/breakag/info/${id}`);
  330. if (res?.success) {
  331. this.formData = res.data;
  332. }
  333. },
  334. // 工单详情
  335. async _getAbnormaldetailList(workOrderId) {
  336. const res = await postJ(
  337. this.apiUrl +
  338. `/repertoryCheck/getAbnormaldetailList?workOrderId=${workOrderId}`
  339. );
  340. if (res?.success) {
  341. this.formData.list = (res.data || []).map((itm) => {
  342. delete itm.id;
  343. if ([1, 2].includes(itm.equStatus)) {
  344. itm.checkNum = 1;
  345. }
  346. return {
  347. ...itm,
  348. amount: itm.checkNum,
  349. model: itm.assetSku,
  350. name: itm.assetName,
  351. productType: itm.assetTypeDict,
  352. code: itm.assetCode,
  353. batch: itm.batchNo,
  354. num: itm.bucketNum,
  355. bizTypeId: itm.bizTypeId,
  356. bizTypeName: itm.bizTypeName,
  357. status: itm.equStatus,
  358. unitPrice: itm.univalence,
  359. minimumUnit: itm.minPackUnit,
  360. };
  361. });
  362. }
  363. },
  364. delRow(index) {
  365. this.formData.list.splice(index, 1);
  366. },
  367. async handleSubmit() {
  368. // this.$refs.formRef.validate().then(async () => {
  369. if (!this.formData.list?.length) {
  370. uni.showToast({
  371. title: "请选择工单!",
  372. icon: "none",
  373. });
  374. return;
  375. }
  376. const res = await postJ(this.apiUrl + `/breakag/save`, this.formData);
  377. if (res?.success) {
  378. uni.showToast({
  379. title: "提交成功!",
  380. icon: "success",
  381. });
  382. uni.navigateBack({
  383. delta: 1,
  384. });
  385. }
  386. // })
  387. },
  388. // 抬头下拉信息保存
  389. handlePicker(e, list, idKey, nameKey) {
  390. if (idKey) {
  391. this.formData[idKey] = list[e.detail.value].id;
  392. }
  393. if (nameKey) {
  394. this.formData[nameKey] = list[e.detail.value].name;
  395. }
  396. },
  397. // 部门确认
  398. deptConfirm(data, name) {
  399. this.formData.verifyDeptCode = data[0];
  400. this.formData.verifyDeptName = name;
  401. this.formData.auditId = "";
  402. this.formData.auditName = "";
  403. this.getUser(data[0]);
  404. },
  405. // 获取部门
  406. getDept() {
  407. get(this.apiUrl + "/main/org/dept/effectiveTree").then((res) => {
  408. if (res?.success) {
  409. this.deptList = res.data;
  410. }
  411. });
  412. },
  413. // 获取人员
  414. getUser(deptCode) {
  415. post(this.apiUrl + "/main/user/list", {
  416. deptCode,
  417. page: 1,
  418. size: 9999,
  419. }).then((res) => {
  420. if (res?.success) {
  421. this.userList = res.data.items.map((item) => {
  422. item.name = item.trueName;
  423. item.id = item.userId;
  424. return item;
  425. });
  426. }
  427. });
  428. },
  429. },
  430. };
  431. </script>
  432. <style lang="scss" scoped>
  433. .footBox {
  434. position: fixed;
  435. bottom: 0;
  436. left: 0;
  437. right: 0;
  438. }
  439. .mainBox {
  440. padding-bottom: 90rpx;
  441. .order-box {
  442. color: #7f7f7f;
  443. background-color: rgba(215, 215, 215, 0.729411764705882);
  444. line-height: 44rpx;
  445. border-radius: 44rpx;
  446. text-align: center;
  447. font-size: 28rpx;
  448. margin: 0 20rpx;
  449. }
  450. .list-card {
  451. border-bottom: 6rpx solid #f2f2f2;
  452. position: relative;
  453. .status {
  454. padding: 6rpx 20rpx;
  455. font-weight: bold;
  456. font-size: 28rpx;
  457. display: flex;
  458. justify-content: space-between;
  459. align-items: center;
  460. border-bottom: 1rpx solid #f2f2f2;
  461. }
  462. .del {
  463. position: absolute;
  464. color: $uni-color-order-error !important;
  465. bottom: 5rpx;
  466. right: 10rpx;
  467. font-size: 50rpx !important;
  468. }
  469. .row {
  470. display: flex;
  471. justify-content: flex-start;
  472. align-items: center;
  473. flex-wrap: wrap;
  474. font-size: 28rpx;
  475. padding: 10rpx 20rpx;
  476. color: #7d7d7d;
  477. &.first {
  478. color: #000;
  479. font-size: 28rpx;
  480. border-bottom: 1rpx solid #f2f2f2;
  481. .col {
  482. min-width: 0%;
  483. }
  484. }
  485. .col {
  486. min-width: 45%;
  487. }
  488. .label {
  489. margin-right: 10rpx;
  490. display: inline-block;
  491. width: 180rpx;
  492. text-align: right;
  493. }
  494. .main {
  495. margin-right: 10rpx;
  496. }
  497. }
  498. }
  499. }
  500. </style>