product-add-or-update.vue 16 KB

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