MaterialAdd.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. <template>
  2. <ele-modal width="1160px" :visible="visible" v-if="visible" :append-to-body="true" :close-on-click-modal="true"
  3. custom-class="ele-dialog-form" title="物料BOM" @update:visible="updateVisible">
  4. <el-form ref="form" :model="form" :rules="rules" label-width="120px">
  5. <header-title title="物料BOM"> </header-title>
  6. <el-row>
  7. <el-col :span="8">
  8. <el-form-item label="BOM编码:" prop="code">
  9. <el-input v-model="form.code" disabled />
  10. </el-form-item>
  11. </el-col>
  12. <el-col :span="8">
  13. <el-form-item label="BOM名称:" prop="name">
  14. <el-input placeholder="请输入BOM名称" v-model="form.name" />
  15. </el-form-item>
  16. </el-col>
  17. <el-col :span="8">
  18. <el-form-item label="版本号:" prop="version">
  19. <el-input placeholder="请输入BOM版本号" v-model="form.version" />
  20. </el-form-item>
  21. </el-col>
  22. <el-col :span="8">
  23. <el-form-item label="状态:" prop="status">
  24. <el-select v-model="form.status" placeholder="" filterable>
  25. <el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value">
  26. </el-option>
  27. </el-select>
  28. </el-form-item>
  29. </el-col>
  30. <el-col :span="8">
  31. <el-form-item label="所属工厂" prop="factoryId">
  32. <factorySelect v-model="form.factoryId" />
  33. </el-form-item>
  34. </el-col>
  35. <el-col :span="8">
  36. <el-form-item label="基本数量" prop="baseCount">
  37. <el-row>
  38. <el-col :span="12">
  39. <el-input placeholder="请输入" v-model.number="form.baseCount">
  40. </el-input></el-col>
  41. <el-col :span="2">&nbsp;</el-col>
  42. <el-col :span="10">
  43. <DictSelection dictName="计量单位" v-model="form.baseCountUnit" />
  44. </el-col>
  45. </el-row>
  46. </el-form-item>
  47. </el-col>
  48. </el-row>
  49. <el-row>
  50. <div class="ele-body">
  51. <ele-pro-table ref="table" :columns="columns" :datasource="tableData" height="calc(100vh - 550px)"
  52. :need-page="false">
  53. <!-- 表头工具栏 -->
  54. <template v-slot:toolbar>
  55. <el-button type="primary" @click="add">添加</el-button>
  56. </template>
  57. <template v-slot:action="{ row, $index }">
  58. <el-link type="primary" @click="handleDel(row, $index)">删除</el-link>
  59. </template>
  60. <template v-slot:subCode="{ row }">
  61. <el-input v-model="row.subCode" placeholder="请输入"></el-input>
  62. </template>
  63. <template v-slot:isReworkBom="{ row }">
  64. <el-select v-model="row.isReworkBom">
  65. <el-option v-for="item in isReworkBomList" :key="item.value" :label="item.label"
  66. :value="item.value">
  67. </el-option>
  68. </el-select>
  69. </template>
  70. <template v-slot:unit="{ row }">
  71. <DictSelection dictName="计量单位" v-model="row.unit"></DictSelection>
  72. </template>
  73. <template v-slot:count="{ row }">
  74. <el-input v-model="row.count" placeholder="请输入" @input="(value) =>
  75. (row.count = value.replace(
  76. /^(-)*(\d+)\.(\d\d\d\d\d\d).*$/,
  77. '$1$2.$3'
  78. ))
  79. "></el-input>
  80. </template>
  81. <template v-slot:categoryName="{ row, $index }">
  82. <el-input :value="row.categoryName" placeholder="请选择"
  83. @click.native="categorySelect(row, $index)"></el-input>
  84. </template>
  85. </ele-pro-table>
  86. </div>
  87. </el-row>
  88. <el-row class="rx-cc">
  89. <el-button type="primary" size="small" class="ele-btn-icon" @click="save">
  90. 保存
  91. </el-button>
  92. </el-row>
  93. </el-form>
  94. <ProductModal ref="productRefs" @changeProduct='determineChoose' />
  95. </ele-modal>
  96. </template>
  97. <script>
  98. import factorySelect from '@/components/CommomSelect/factory-select.vue';
  99. import { pageList } from '@/api/technology/version/version.js';
  100. import { getCode } from '@/api/codeManagement/index.js';
  101. import { bomSave, bomUpdate } from '@/api/material/BOM';
  102. import ProductModal from '@/components/select/bom/ProductModal.vue'
  103. export default {
  104. components: {
  105. factorySelect,
  106. ProductModal
  107. },
  108. props: {
  109. // 弹窗是否打开
  110. visible: Boolean,
  111. // 修改回显的数据
  112. categoryId: [String, Number],
  113. data: Object,
  114. taskId: [String, Number],
  115. },
  116. data() {
  117. var baseCountVa = (rule, value, callback) => {
  118. if (value == '') {
  119. callback(new Error('请输入基本数量'));
  120. } else if (this.form.baseCountUnit == '') {
  121. callback(new Error('请选择基本数量单位'));
  122. } else {
  123. callback();
  124. }
  125. };
  126. const defaultForm = {
  127. id: null,
  128. code: '',
  129. name: '',
  130. version: '1.0',
  131. factoryId: '',
  132. type: 0,
  133. status: '',
  134. isReworkBom: 0,
  135. baseCount: '',
  136. baseCountUnit: '',
  137. taskId: '',
  138. };
  139. return {
  140. defaultForm,
  141. // 表单数据
  142. form: {
  143. ...defaultForm
  144. },
  145. removeSubBomIdList: [],
  146. versionList: [],
  147. // 表单验证规则
  148. rules: {
  149. code: [
  150. { required: true, message: '请输入BOM编码', trigger: 'blur' }
  151. ],
  152. name: [
  153. { required: true, message: '请输入BOM名称', trigger: 'blur' }
  154. ],
  155. version: [
  156. { required: true, message: '请输入BOM版本号', trigger: 'blur' }
  157. ],
  158. status: [
  159. { required: true, message: '请选择状态', trigger: 'change' }
  160. ],
  161. factoryId: [
  162. { required: true, message: '请输入所属工厂', trigger: 'change' }
  163. ],
  164. baseCount: [
  165. { validator: baseCountVa, trigger: 'blur' }
  166. ]
  167. },
  168. columns: [
  169. {
  170. type: 'index',
  171. width: 55,
  172. align: 'center'
  173. },
  174. {
  175. label: '子项编号',
  176. prop: 'subCode',
  177. slot: 'subCode',
  178. action: 'subCode'
  179. },
  180. {
  181. label: '物料名称',
  182. prop: 'categoryName',
  183. slot: 'categoryName',
  184. action: 'categoryName'
  185. },
  186. {
  187. label: '是否反工料',
  188. prop: 'isReworkBom',
  189. slot: 'isReworkBom',
  190. action: 'isReworkBom'
  191. },
  192. {
  193. label: '物料编码',
  194. prop: 'categoryCode'
  195. },
  196. {
  197. label: '牌号',
  198. prop: 'brandNum'
  199. },
  200. {
  201. label: '型号',
  202. prop: 'modelType'
  203. },
  204. {
  205. label: '数量',
  206. slot: 'count',
  207. action: 'count'
  208. },
  209. {
  210. label: '单位',
  211. slot: 'unit',
  212. action: 'unit'
  213. },
  214. {
  215. action: 'action',
  216. slot: 'action',
  217. label: '操作'
  218. }
  219. ],
  220. tableData: [],
  221. statusList: [
  222. { label: '草稿', value: -1 },
  223. { label: '失效', value: 0 },
  224. { label: '生效', value: 1 }
  225. ],
  226. isReworkBomList: [
  227. { label: '否', value: 0 },
  228. { label: '是', value: 1 }
  229. ],
  230. // 提交状态
  231. loading: false,
  232. // 是否是修改
  233. isUpdate: false,
  234. };
  235. },
  236. computed: {
  237. // 是否开启响应式布局
  238. styleResponsive() {
  239. return this.$store.state.theme.styleResponsive;
  240. }
  241. },
  242. methods: {
  243. handleDel(row, index) {
  244. this.tableData.splice(index, 1);
  245. if (row?.id) {
  246. this.removeSubBomIdList.push(row.id)
  247. }
  248. },
  249. add() {
  250. let subCode = '0010';
  251. if (this.tableData.length) {
  252. let max = Math.max(...this.tableData.map((i) => i.subCode)) + 10 + '';
  253. if (max.length < 4) {
  254. max = new Array(4 - max.length).fill('0').join('') + max;
  255. }
  256. subCode = max.substring(0, max.length - 1) + '0';
  257. }
  258. this.tableData.push({
  259. subCode,
  260. categoryId: '',
  261. categoryName: '',
  262. isReworkBom: 0,
  263. brandNum: '',
  264. count: '',
  265. modelType: '',
  266. unit: '',
  267. netWeight: '',
  268. weightUnit: ''
  269. });
  270. },
  271. async _getCode() {
  272. const code = await getCode('bom_code');
  273. this.form.code = code;
  274. },
  275. /* 保存编辑 */
  276. save() {
  277. this.$refs.form.validate((valid) => {
  278. if (!valid) {
  279. return false;
  280. }
  281. if (this.tableData.length == 0) {
  282. this.$message.info('请至少添加一条物料');
  283. return;
  284. }
  285. if (!this.isUpdate) {
  286. delete this.form.id;
  287. this.form['taskId'] = this.taskId
  288. }
  289. const data = {
  290. ...this.form,
  291. removeSubBomIdList: this.removeSubBomIdList,
  292. subDetailList: this.tableData,
  293. categoryId: this.categoryId,
  294. };
  295. this.loading = true;
  296. const saveOrUpdate = this.isUpdate ? bomUpdate : bomSave;
  297. saveOrUpdate(data)
  298. .then((msg) => {
  299. this.loading = false;
  300. this.$message.success(msg);
  301. this.$emit('done', this.form['taskId']);
  302. this.visible = false
  303. })
  304. .catch((e) => {
  305. this.loading = false;
  306. });
  307. });
  308. },
  309. categorySelect(row, idx) {
  310. // 3 type: 物料组
  311. this.$refs.productRefs.open(row, '选择物料', 3, idx)
  312. },
  313. determineChoose(title, row, idx) {
  314. if (title == '选择物料') {
  315. this.$set(this.tableData[idx], 'categoryName', row.name)
  316. this.$set(this.tableData[idx], 'categoryId', row.id)
  317. this.$set(this.tableData[idx], 'categoryCode', row.code)
  318. this.$set(this.tableData[idx], 'unit', row.measuringUnit)
  319. this.$set(this.tableData[idx], 'weightUnit', row.weightUnit)
  320. this.$set(this.tableData[idx], 'brandNum', row.brandNum)
  321. this.$set(this.tableData[idx], 'modelType', row.modelType)
  322. }
  323. },
  324. /* 更新visible */
  325. updateVisible(value) {
  326. this.$emit('update:visible', value);
  327. }
  328. },
  329. watch: {
  330. async visible(visible) {
  331. if (visible) {
  332. this._getCode()
  333. this.removeSubBomIdList = []
  334. if (this.data) {
  335. this.tableData = this.data.subDetailList
  336. this.$util.assignObject(this.form, {
  337. ...this.data
  338. });
  339. this.isUpdate = true
  340. } else {
  341. this.isUpdate = false
  342. }
  343. } else {
  344. this.$refs.form.clearValidate();
  345. this.form = { ...this.defaultForm };
  346. }
  347. }
  348. }
  349. };
  350. </script>