sparepartApply.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. <template>
  2. <el-dialog :visible.sync="visible" title="备品备件申请单" width="90%">
  3. <div class="sparepart-apply">
  4. <div class="select-box">
  5. <el-row :gutter="40">
  6. <el-col :span="8">
  7. <el-form label-position="left" label-width="50px">
  8. <el-form-item label="仓库" required>
  9. <el-select
  10. filterable
  11. ref="selectRef"
  12. class="w100"
  13. size="small"
  14. v-model="warehouseId"
  15. placeholder="请选择"
  16. @change="handleWarehouseChange"
  17. >
  18. <el-option
  19. :key="item.id"
  20. :value="item.id"
  21. :label="item.name"
  22. v-for="(item, index) in warehouseList"
  23. ></el-option>
  24. </el-select>
  25. </el-form-item>
  26. </el-form>
  27. </el-col>
  28. <el-col :span="6">
  29. <el-button type="primary" @click="addGoods">添加物品</el-button>
  30. </el-col>
  31. </el-row>
  32. </div>
  33. <div class="list-box">
  34. <div
  35. class="material-item"
  36. v-for="(item, index) in registerlist"
  37. :key="index"
  38. >
  39. <el-descriptions
  40. title=""
  41. :column="3"
  42. :labelStyle="{ width: '10%' }"
  43. size="medium"
  44. border
  45. >
  46. <el-descriptions-item label="物品编码">
  47. {{ item.informationCode }}
  48. </el-descriptions-item>
  49. <el-descriptions-item label="物品名称">
  50. {{ item.informationName }}
  51. </el-descriptions-item>
  52. <el-descriptions-item label="规格型号">
  53. {{ item.specification }}\{{ item.modelType }}
  54. </el-descriptions-item>
  55. <el-descriptions-item label="单位">
  56. <!-- :label="item.isUnpack ? '包装单位' : '计量单位'" `${item.measuringUnit}/${item.minPackUnit}` -->
  57. {{ item.isUnpack ? item.measuringUnit : item.minPackUnit }}
  58. </el-descriptions-item>
  59. <el-descriptions-item label="所需数量" :span="2">
  60. <div class="flex-between">
  61. {{ item.selectNum || 0 }}{{ item.measuringUnit
  62. }}{{
  63. sourceType == 1 ? `/${item.num}${item.measuringUnit}` : ''
  64. }}
  65. <el-link @click="addSparepart(item)" type="primary">
  66. 添加备品备件</el-link
  67. >
  68. </div>
  69. </el-descriptions-item>
  70. <!-- <el-descriptions-item label=""> 添加备品备件 </el-descriptions-item> -->
  71. </el-descriptions>
  72. <el-table
  73. border
  74. :data="item.tableData"
  75. :header-cell-style="{ background: '#F0F3F3' }"
  76. >
  77. <el-table-column
  78. label="序号"
  79. type="index"
  80. width="80"
  81. ></el-table-column>
  82. <el-table-column
  83. width="160"
  84. show-overflow-tooltip
  85. label="备品备件编码"
  86. prop="onlyCode"
  87. ></el-table-column>
  88. <el-table-column label="批次号" prop="batchNum"></el-table-column>
  89. <el-table-column
  90. label="生产日期"
  91. width="160"
  92. prop="manufactureTime"
  93. ></el-table-column>
  94. <el-table-column
  95. label="采购日期"
  96. width="160"
  97. prop="procurementTime"
  98. ></el-table-column>
  99. <el-table-column label="最小包装单元" prop="" v-if="!item.isUnpack"
  100. ><template slot-scope="{ row }">
  101. {{ row.measurementUnit }}{{ row.unit }}/{{ row.minPackUnit }}
  102. </template></el-table-column
  103. >
  104. <el-table-column label="包装编码" prop="num"></el-table-column>
  105. <el-table-column
  106. label="货位"
  107. prop=""
  108. show-overflow-tooltip
  109. width="300"
  110. >
  111. <template slot-scope="{ row }">
  112. {{ row.warehouseName }}-{{ row.areaName }}-{{
  113. row.shelfCode
  114. }}-{{ row.cargoSpaceCode }}
  115. </template></el-table-column
  116. >
  117. <el-table-column label="操作">
  118. <template slot-scope="{ row, $index }">
  119. <el-link type="danger" @click="handleDelete(item, row, $index)"
  120. >删除</el-link
  121. >
  122. </template>
  123. </el-table-column>
  124. </el-table>
  125. </div>
  126. </div>
  127. </div>
  128. <div slot="footer" class="footer">
  129. <el-button @click="cancel">取消</el-button>
  130. <el-button type="primary" @click="submit">提交</el-button>
  131. </div>
  132. <AssetsDialog
  133. ref="assetsDialogRef"
  134. title="备品备件"
  135. :warehousingMaterialList="registerlist"
  136. :assetType="7"
  137. :warehouseId="warehouseId"
  138. @selectTableData="onSelectTableData"
  139. />
  140. <detailSelect ref="detailSelectRef" :warehouseId="warehouseId" />
  141. </el-dialog>
  142. </template>
  143. <script>
  144. // import detailSelect from './detailSelect.vue'
  145. // import {
  146. // getSparePartsApplyDetail,
  147. // sparePartsApplySave
  148. // } from '@/api/stockManagement/stocking'
  149. // import { warehouseListValuable } from '@/api/stockManagement/warehouseDefinition'
  150. // import AssetsDialog from '@/views/warehouseManagement/components/AssetsDialog.vue'
  151. // import { deepClone } from '@/utils'
  152. export default {
  153. components: { detailSelect, AssetsDialog },
  154. props: {
  155. sourceType: {
  156. type: Number, //1,保养工单;2,维修工单
  157. required: true
  158. }
  159. },
  160. data () {
  161. return {
  162. visible: false,
  163. registerlist: [],
  164. warehouseIdOld: '',
  165. warehouseId: '',
  166. warehouseList: [],
  167. row: {},
  168. planList: []
  169. };
  170. },
  171. methods: {
  172. open (row) {
  173. this.row = row;
  174. this.warehouseId = '';
  175. this.warehouseIdOld = '';
  176. this.registerlist = [];
  177. this._getWarehouse();
  178. if (this.sourceType == 1) {
  179. this._getSparePartsApplyDetail(row.planCode);
  180. }
  181. this.visible = true;
  182. },
  183. async submit () {
  184. const params = {
  185. sparePartsApplyDetailList: this.registerlist
  186. .filter((i) => i.tableData.length)
  187. .map((i) => i.tableData)
  188. .flat()
  189. .map((i) => {
  190. delete i.id;
  191. return {
  192. informationCode: i.assetCode,
  193. informationName: i.assetName,
  194. assetCode: i.onlyCode
  195. };
  196. }),
  197. sourceCode: this.row.workOrderCode,
  198. sourceId: this.row.id,
  199. sourceType: this.sourceType
  200. };
  201. if (!params.sparePartsApplyDetailList.length) {
  202. return this.$message.error('请添加备品备件!');
  203. }
  204. const res = await sparePartsApplySave(params);
  205. if (res?.success) {
  206. this.$message.success('提交成功!');
  207. this.visible = false;
  208. this.$emit('success');
  209. }
  210. },
  211. cancel () {
  212. this.visible = false;
  213. },
  214. addSparepart (item) {
  215. if (!this.warehouseId) {
  216. return this.$message.error('请选择仓库!');
  217. }
  218. this.$refs.detailSelectRef.open(item, item.tableData).then((res) => {
  219. item.tableData = res;
  220. const obj = this.planList.find((i) => i.curId === item.curId);
  221. item.selectNum = item.tableData.reduce((next, pre) => {
  222. next += pre.isUnpack ? 1 : pre.measurementUnit || 0;
  223. return next;
  224. }, 0);
  225. if (!obj) {
  226. // 非计划
  227. item.num = item.selectNum;
  228. }
  229. });
  230. },
  231. // 切换仓库清空选择
  232. handleWarehouseChange () {
  233. if (
  234. this.registerlist.length > this.planList.length ||
  235. this.registerlist.some((i) => i.tableData.length)
  236. ) {
  237. Promise.resolve().then(() => {
  238. this.$refs.selectRef.blur();
  239. if (this.warehouseIdOld) {
  240. this.$confirm(
  241. '仓库修改后,已添加的备品备件信息将会被清空,是否要继续修改仓库?'
  242. )
  243. .then(() => {
  244. this.registerlist = deepClone(this.planList);
  245. this.warehouseIdOld = this.warehouseId;
  246. })
  247. .catch(() => {
  248. this.warehouseId = this.warehouseIdOld;
  249. });
  250. } else {
  251. this.registerlist = deepClone(this.planList);
  252. this.warehouseIdOld = this.warehouseId;
  253. }
  254. });
  255. }
  256. },
  257. handleDelete (item, row, index) {
  258. this.$confirm(`确定删除${row.onlyCode}?`).then(() => {
  259. item.tableData.splice(index, 1);
  260. });
  261. },
  262. async _getSparePartsApplyDetail (planCode) {
  263. const res = await getSparePartsApplyDetail({ planCode });
  264. if (res?.success) {
  265. this.registerlist = res.data.map((item) => ({
  266. ...item,
  267. selectNum: 0,
  268. curId: item.informationCode,
  269. tableData: []
  270. }));
  271. this.planList = deepClone(this.registerlist);
  272. }
  273. },
  274. addGoods () {
  275. if (!this.warehouseId) {
  276. return this.$message.error('请选择仓库!');
  277. }
  278. this.$refs.assetsDialogRef.open();
  279. },
  280. // 选择物品
  281. onSelectTableData (selectList) {
  282. this.registerlist = this.registerlist.filter((item) => {
  283. const index = selectList.findIndex((i) => i.curId === item.curId);
  284. if (index > -1) {
  285. selectList.splice(index, 1);
  286. }
  287. return index > -1;
  288. });
  289. this.registerlist.push(
  290. ...selectList.map((item) => {
  291. return {
  292. curId: item.curId,
  293. isUnpack: item.isUnpack,
  294. informationCode: item.assetCode || item.informationCode,
  295. informationName: item.assetName || item.informationName,
  296. specification: item.specification,
  297. minPackUnit: item.minPackUnit,
  298. modelType: item.modelType,
  299. measuringUnit: item.unit || item.measuringUnit,
  300. tableData: item.tableData || [],
  301. num: 0,
  302. selectNum: 0
  303. };
  304. })
  305. );
  306. },
  307. async _getWarehouse () {
  308. if (this.warehouseList.length) return;
  309. const res = await warehouseListValuable();
  310. if (res?.success) {
  311. this.warehouseList = res.data.filter((i) => !!i.status);
  312. }
  313. }
  314. }
  315. };
  316. </script>
  317. <style lang="scss" scoped>
  318. .sparepart-apply {
  319. min-height: 40vh;
  320. .select-box {
  321. margin-bottom: 10px;
  322. }
  323. .material-item {
  324. width: 100%;
  325. }
  326. .material-item + .material-item {
  327. margin-top: 10px;
  328. }
  329. }
  330. .flex-between {
  331. display: flex;
  332. justify-content: space-between;
  333. padding-right: 20%;
  334. }
  335. .list-box {
  336. max-height: 60vh;
  337. overflow-y: auto;
  338. overflow-x: hidden;
  339. }
  340. .footer {
  341. padding: 10px;
  342. text-align: right;
  343. background: #fff;
  344. }
  345. </style>