product-add-or-update.vue 18 KB

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