product-add-or-update.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. <template>
  2. <div>
  3. <el-dialog
  4. :title="!id ? '新增': display ? '详情' : '修改'"
  5. width="70%"
  6. :close-on-click-modal="false"
  7. :visible.sync="visible">
  8. <!-- 工作流 -->
  9. <div v-show="display && dataForm.workFlowBusinessExt">
  10. <el-steps :active="dataForm.workFlowBusinessExt?dataForm.workFlowBusinessExt.workFlowProcessStepList.length + 2:0" align-center style="margin-bottom: 20px">
  11. <template v-for="(item, i) in stepList">
  12. <el-step :icon="item.icon" :title="item.title" :description="item.description"></el-step>
  13. </template>
  14. </el-steps>
  15. <el-collapse style="margin-bottom: 20px">
  16. <el-collapse-item>
  17. <template slot="title">
  18. <span style="color: red">审批日志(展开查看更多):</span>
  19. </template>
  20. <template v-for="(item, i) in logList">
  21. <div>{{++i}}:{{item.approverName}} {{item.createTime}} {{item.approvalValue}}</div>
  22. </template>
  23. </el-collapse-item>
  24. </el-collapse>
  25. </div>
  26. <!-- 表单 -->
  27. <el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="auto">
  28. <el-row class="my-row">
  29. <el-col :span="8">
  30. <el-form-item label="产品名称" prop="productName">
  31. <el-input v-model="dataForm.productName" :disabled="display" placeholder="产品名称"></el-input>
  32. </el-form-item>
  33. </el-col>
  34. <el-col :span="8">
  35. <el-form-item label="产品规格" prop="productSpec">
  36. <el-input v-model="dataForm.productSpec" :disabled="display" placeholder="产品规格"></el-input>
  37. </el-form-item>
  38. </el-col>
  39. <el-col :span="8">
  40. <el-form-item label="产品类别" prop="productType">
  41. <el-select
  42. v-model="dataForm.productType"
  43. :disabled="display"
  44. remote
  45. placeholder="请选择">
  46. <el-option
  47. v-for="item in optionsType"
  48. :key="item.code"
  49. :label="item.value"
  50. :value="item.code">
  51. </el-option>
  52. </el-select>
  53. </el-form-item>
  54. </el-col>
  55. </el-row>
  56. <el-row class="my-row">
  57. <el-col :span="8">
  58. <el-form-item label="产品来源" prop="source">
  59. <el-input v-if="display" v-model="dataForm.sourceName" disabled></el-input>
  60. <el-select v-else
  61. v-model="dataForm.source"
  62. :disabled="display"
  63. filterable
  64. remote
  65. :remote-method="remoteCusList"
  66. placeholder="请选择">
  67. <el-option
  68. v-for="item in optionsSource"
  69. :key="item.code"
  70. :label="item.value"
  71. :value="item.code">
  72. </el-option>
  73. </el-select>
  74. </el-form-item>
  75. </el-col>
  76. <el-col :span="16">
  77. <el-form-item label="产品图纸" prop="drawingIdList">
  78. <upload-component v-if="display" :display="display" :title="'产品图纸'" :accept="'*'" :file-obj-list="fileList" @uploadSuccess="uploadSuccess"/>
  79. <el-select v-else
  80. v-model="dataForm.drawingIdList"
  81. filterable
  82. multiple
  83. remote
  84. :remote-method="remoteDraw"
  85. placeholder="请选择"
  86. style="width: 100%">
  87. <el-option
  88. v-for="item in optionsDraw"
  89. :key="item.code"
  90. :label="item.value"
  91. :value="item.code">
  92. </el-option>
  93. </el-select>
  94. </el-form-item>
  95. </el-col>
  96. </el-row>
  97. <el-row class="my-row">
  98. <el-form-item label="备注" prop="notes">
  99. <el-input type="textarea" v-model="dataForm.notes" :disabled="display"></el-input>
  100. </el-form-item>
  101. </el-row>
  102. <el-row class="my-row">
  103. <el-form-item label="是否组合产品" prop="displayProductList">
  104. <el-switch
  105. v-model="dataForm.displayProductList"
  106. :disabled="display"
  107. active-color="#13ce66"
  108. inactive-color="#ff4949"
  109. active-text="是"
  110. inactive-text="否">
  111. </el-switch>
  112. </el-form-item>
  113. </el-row>
  114. <el-row v-if="dataForm.displayProductList">
  115. <div class="title"><span style="color: red">*</span> 组合小产品</div>
  116. <el-table
  117. :data="productDetails"
  118. border
  119. style="width: 100%;">
  120. <el-table-column
  121. label="序号"
  122. type="index"
  123. width="50"
  124. align="center">
  125. </el-table-column>
  126. <el-table-column
  127. prop="productName"
  128. header-align="center"
  129. align="center"
  130. label="产品名称">
  131. </el-table-column>
  132. <el-table-column
  133. prop="productSpec"
  134. header-align="center"
  135. align="center"
  136. label="规格">
  137. </el-table-column>
  138. <el-table-column
  139. prop="cnt"
  140. header-align="center"
  141. align="center"
  142. label="数量"
  143. width="170">
  144. <template slot-scope="scope">
  145. <el-input-number v-model="scope.row.cnt" :disabled="display" :min="1" style="width: 140px;"/>
  146. </template>
  147. </el-table-column>
  148. <el-table-column
  149. prop="notes"
  150. header-align="center"
  151. align="center"
  152. label="备注">
  153. </el-table-column>
  154. </el-table>
  155. <el-row style="text-align: center; margin-top: 10px;">
  156. <el-button v-show="!display" type="primary" icon="el-icon-plus" @click="addProduct"></el-button>
  157. </el-row>
  158. </el-row>
  159. <el-row>
  160. <div class="title"><span style="color: red">*</span> 产品配料清单</div>
  161. <el-table
  162. :data="materialList"
  163. border
  164. style="width: 100%;">
  165. <el-table-column
  166. label="序号"
  167. type="index"
  168. width="50"
  169. align="center">
  170. </el-table-column>
  171. <el-table-column
  172. prop="materialName"
  173. header-align="center"
  174. align="center"
  175. label="物品名称">
  176. </el-table-column>
  177. <el-table-column
  178. prop="specifications"
  179. header-align="center"
  180. align="center"
  181. label="规格">
  182. </el-table-column>
  183. <el-table-column
  184. prop="cnt"
  185. header-align="center"
  186. align="center"
  187. label="数量"
  188. width="170">
  189. <template slot-scope="scope">
  190. <el-input-number v-model="scope.row.cnt" :disabled="display" :min="1" style="width: 140px;"/>
  191. </template>
  192. </el-table-column>
  193. <el-table-column
  194. prop="unitName"
  195. header-align="center"
  196. align="center"
  197. label="单位">
  198. </el-table-column>
  199. <el-table-column
  200. prop="notes"
  201. header-align="center"
  202. align="center"
  203. label="备注">
  204. </el-table-column>
  205. </el-table>
  206. <el-row style="text-align: center; margin-top: 10px;">
  207. <el-button v-show="!display" type="primary" icon="el-icon-plus" @click="addMaterial"></el-button>
  208. </el-row>
  209. </el-row>
  210. </el-form>
  211. <span slot="footer" class="dialog-footer">
  212. <el-button @click="visible = false">取消</el-button>
  213. <el-button v-if="!display" type="primary" @click="dataFormSubmit()">确定</el-button>
  214. </span>
  215. </el-dialog>
  216. <template-chose v-if="productListVisible" ref="productList" @addItems="addProductItems" />
  217. <templateChoseMaterial v-if="materialListVisible" ref="materialList" @addItems="addMaterialItems"/>
  218. </div>
  219. </template>
  220. <script>
  221. import templateChose from '../product/template-chose'
  222. import templateChoseMaterial from '../product/template-chose-material'
  223. import { getDictList } from '@/api/dict'
  224. import { getProductDetail, getTechList, getDrawList } from '@/api/product'
  225. import { getCusList } from '@/api/cus'
  226. import UploadComponent from '../common/upload-component'
  227. import { dealStepData, dealStepLogs } from '@/api/util'
  228. export default {
  229. name: 'product-add-or-update',
  230. components: {UploadComponent, templateChose, templateChoseMaterial},
  231. computed: {
  232. orgId: {
  233. get () { return this.$store.state.user.orgId }
  234. }
  235. },
  236. watch: {
  237. 'dataForm.isCompose' (value) {
  238. this.dataForm.displayProductList = value === '1'
  239. }
  240. },
  241. data () {
  242. return {
  243. productListVisible: false,
  244. materialListVisible: false,
  245. visible: false,
  246. display: false,
  247. optionsType: [],
  248. optionsTech: [],
  249. optionsSource: [],
  250. optionsDraw: [],
  251. fileList: [],
  252. dataList: [],
  253. id: 0,
  254. productDetails: [],
  255. materialList: [],
  256. dataForm: {
  257. displayProductList: false
  258. },
  259. dataRule: {
  260. productName: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
  261. productSpec: [{ required: true, message: '产品规格不能为空', trigger: 'blur' }],
  262. productType: [{ required: true, message: '产品类别不能为空', trigger: 'change' }],
  263. source: [{ required: true, message: '产品来源不能为空', trigger: 'change' }],
  264. drawingIdList: [{ required: true, message: '产品图纸不能为空', trigger: 'blur' }]
  265. },
  266. stepList: [],
  267. logList: []
  268. }
  269. },
  270. methods: {
  271. async init (id, display) {
  272. this.fileList = []
  273. this.stepList = []
  274. this.logList = []
  275. this.dataForm = {}
  276. this.productDetails = []
  277. this.materialList = []
  278. this.optionsSource = []
  279. this.optionsTech = []
  280. this.optionsDraw = []
  281. this.visible = true
  282. this.id = id || 0
  283. this.display = display
  284. // 获取产品类别
  285. await getDictList({type: 'product_type'}).then(({data}) => {
  286. if (data) {
  287. this.optionsType = data
  288. }
  289. })
  290. // 产品工艺
  291. if (!id) return
  292. await getProductDetail(this.id).then(({data}) => {
  293. if (data && data.code === '200') {
  294. this.dataForm = data.data
  295. // 流程图展示
  296. if (data.data.workFlowBusinessExt) {
  297. dealStepData(data.data.workFlowBusinessExt.workFlowProcessStepList, this.stepList)
  298. dealStepLogs(data.data.workFlowBusinessExt.processLogList, this.logList)
  299. }
  300. // 组合小产品
  301. data.data.composeProductMaterialList.forEach((item) => {
  302. this.productDetails.push(item)
  303. })
  304. // 产品配料清单
  305. data.data.productMaterialList.forEach((item) => {
  306. this.materialList.push(item)
  307. })
  308. // 产品来源
  309. if (data.data.source) {
  310. this.optionsSource = [{
  311. code: data.data.source,
  312. value: data.data.sourceName
  313. }]
  314. }
  315. // 产品工艺
  316. if (data.data.techId) {
  317. this.optionsTech = [{
  318. code: data.data.techId,
  319. value: data.data.techName
  320. }]
  321. }
  322. // 产品图纸
  323. if (data.data.proDrawings) {
  324. this.dataForm.drawingIdList = []
  325. data.data.proDrawings.forEach((item) => {
  326. if (item.attachList) {
  327. item.attachList.forEach((item1) => {
  328. this.fileList.push({
  329. name: item1.fileName,
  330. url: item1.url,
  331. id: item1.url
  332. })
  333. })
  334. }
  335. this.optionsDraw.push({
  336. code: item.drawingId,
  337. value: item.drawingName
  338. })
  339. this.dataForm.drawingIdList.push(item.drawingId)
  340. })
  341. }
  342. }
  343. })
  344. },
  345. uploadSuccess (fileList) {
  346. this.fileList = fileList
  347. },
  348. // 产品来源(客户)列表
  349. async remoteCusList (query) {
  350. if (!query) {
  351. query = ''
  352. }
  353. await getCusList({'customerName': query}).then(({data}) => {
  354. if (data && data.code === '200') {
  355. this.optionsSource = []
  356. data.data.records.forEach((item) => {
  357. this.optionsSource.push({
  358. code: item.customerId,
  359. value: item.customerName
  360. })
  361. })
  362. }
  363. }
  364. )
  365. },
  366. // 产品工艺
  367. async remoteTech (query) {
  368. if (!query) {
  369. query = ''
  370. }
  371. await getTechList().then(({data}) => {
  372. if (data && data.code === '200') {
  373. this.optionsTech = []
  374. data.data.records.forEach((item) => {
  375. this.optionsTech.push({
  376. code: item.customerId,
  377. value: item.customerName
  378. })
  379. })
  380. }
  381. })
  382. },
  383. // 图纸
  384. async remoteDraw (query) {
  385. if (!query) {
  386. query = ''
  387. }
  388. await getDrawList({'keyword': query}).then(({data}) => {
  389. if (data && data.code === '200') {
  390. this.optionsDraw = []
  391. data.data.records.forEach((item) => {
  392. this.optionsDraw.push({
  393. code: item.drawingId,
  394. value: item.drawingName
  395. })
  396. })
  397. }
  398. })
  399. },
  400. // 添加组合产品
  401. addProduct () {
  402. this.productListVisible = true
  403. this.$nextTick(() => {
  404. this.$refs.productList.init()
  405. })
  406. },
  407. addProductItems (items) {
  408. this.productDetails = []
  409. items.forEach((item) => {
  410. this.addProductItem(item)
  411. })
  412. },
  413. addProductItem (item) {
  414. this.productDetails.push({
  415. productId: item.productId,
  416. productName: item.productName,
  417. productSpec: item.productSpec,
  418. cnt: 1,
  419. notes: item.notes
  420. })
  421. },
  422. addMaterial () {
  423. this.materialListVisible = true
  424. this.$nextTick(() => {
  425. this.$refs.materialList.init()
  426. })
  427. },
  428. addMaterialItems (items) {
  429. this.materialList = []
  430. items.forEach((item) => {
  431. this.addMaterialItem(item)
  432. })
  433. },
  434. addMaterialItem (item) {
  435. this.materialList.push({
  436. materialId: item.materialId,
  437. materialName: item.materialName,
  438. specifications: item.specifications,
  439. cnt: item.cnt,
  440. unitName: item.unitName,
  441. notes: item.notes
  442. })
  443. },
  444. validateField (type) {
  445. this.$refs.dataForm.validateField(type)
  446. },
  447. // 表单提交
  448. dataFormSubmit () {
  449. this.$refs['dataForm'].validate((valid) => {
  450. if (valid) {
  451. // 组合小产品
  452. this.dataForm.composeProductMaterialList = []
  453. const b1 = this.dataForm.displayProductList
  454. this.dataForm.isCompose = b1 === true ? '1' : '0'
  455. if (this.dataForm.isCompose === '1' && this.productDetails.length > 0) {
  456. this.productDetails.forEach((item) => {
  457. this.dataForm.composeProductMaterialList.push({
  458. cnt: item.cnt,
  459. materialId: item.productId,
  460. notes: item.notes
  461. })
  462. })
  463. }
  464. // 产品配料清单
  465. this.dataForm.productMaterialList = []
  466. if (this.materialList.length > 0) {
  467. this.materialList.forEach((item) => {
  468. this.dataForm.productMaterialList.push({
  469. cnt: item.cnt,
  470. materialId: item.materialId,
  471. notes: item.notes
  472. })
  473. })
  474. }
  475. this.$http({
  476. url: this.$http.adornUrl(`/biz-service/product/save`),
  477. method: 'post',
  478. data: this.$http.adornData({...this.dataForm, orgId: this.orgId})
  479. }).then(({data}) => {
  480. if (data && data.code === '200') {
  481. this.$message({
  482. message: '操作成功',
  483. type: 'success',
  484. duration: 1500,
  485. onClose: () => {
  486. this.visible = false
  487. this.$emit('refreshDataList')
  488. }
  489. })
  490. } else {
  491. this.$message.error(data.msg)
  492. }
  493. })
  494. }
  495. })
  496. }
  497. }
  498. }
  499. </script>
  500. <style scoped>
  501. </style>