Edit.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525
  1. <!--
  2. * @Author: liuzhenlin 461480418@qq.ocm
  3. * @Date: 2023-01-09 15:49:34
  4. * @LastEditors: liuzhenlin
  5. * @LastEditTime: 2023-01-11 16:05:02
  6. * @Description: file content
  7. * @FilePath: \订单全流程管理系统\src\views\contract\components\Edit.vue
  8. -->
  9. <template>
  10. <el-dialog class="edit-container" :title="title" top="5vh" :visible.sync="editVisible" @close="handleClose">
  11. <div class="setp-wrap">
  12. <el-steps :active="stepActive" :align-center="true" finish-status="success">
  13. <el-step title="基础信息" />
  14. <el-step title="产品列表" />
  15. </el-steps>
  16. </div>
  17. <el-form v-show="stepActive == 0" ref="editForm" :model="editForm" :rules="editRules">
  18. <el-row :gutter="20">
  19. <el-col :span="12">
  20. <el-form-item label="合同编号" prop="contractCode">
  21. <el-input v-model="editForm.contractCode" disabled placeholder="根据编号规则自动生产" />
  22. </el-form-item>
  23. </el-col>
  24. <el-col :span="12">
  25. <el-form-item label="合同名称" prop="contractName">
  26. <el-input v-model="editForm.contractName" placeholder="请输入合同名称" />
  27. </el-form-item>
  28. </el-col>
  29. </el-row>
  30. <el-row :gutter="20">
  31. <el-col :span="12">
  32. <el-form-item label="关联项目" prop="nboName">
  33. <el-select
  34. v-model="editForm.nboName"
  35. placeholder="请选择关联项目"
  36. readonly
  37. style="width: 100%"
  38. @focus="openProject" />
  39. </el-form-item>
  40. </el-col>
  41. <el-col :span="12">
  42. <el-form-item label="客户名称" prop="nboId">
  43. <el-input v-model="editForm.custName" disabled />
  44. </el-form-item>
  45. </el-col>
  46. </el-row>
  47. <el-row :gutter="20">
  48. <el-col :span="12">
  49. <el-form-item label="合同开始时间" prop="contractStartTime">
  50. <el-date-picker
  51. v-model="editForm.contractStartTime"
  52. :picker-options="pickerOptionsStart"
  53. placeholder="选择开始日期"
  54. style="width: 100%"
  55. type="date"
  56. value-format="yyyy-MM-dd" />
  57. </el-form-item>
  58. </el-col>
  59. <el-col :span="12">
  60. <el-form-item label="合同结束时间" prop="contractEndTime">
  61. <el-date-picker
  62. v-model="editForm.contractEndTime"
  63. :picker-options="pickerOptionsEnd"
  64. placeholder="选择结束日期"
  65. style="width: 100%"
  66. type="date"
  67. value-format="yyyy-MM-dd" />
  68. </el-form-item>
  69. </el-col>
  70. </el-row>
  71. <el-row :gutter="20">
  72. <el-col :span="12">
  73. <el-form-item label="销售工程师" prop="inchargeName">
  74. <el-select
  75. v-model="editForm.inchargeName"
  76. placeholder="请选择销售工程师"
  77. readonly
  78. style="width: 100%"
  79. @focus="openUser(false, 'inchargeId', 'inchargeName')" />
  80. </el-form-item>
  81. </el-col>
  82. <el-col :span="12">
  83. <el-form-item label="公司签约人" prop="signatoryName">
  84. <el-select
  85. ref="signatoryName"
  86. v-model="editForm.signatoryName"
  87. placeholder="请选择公司签约人"
  88. readonly
  89. style="width: 100%"
  90. @focus="openUser(false, 'signatoryId', 'signatoryName')" />
  91. </el-form-item>
  92. </el-col>
  93. </el-row>
  94. <el-row :gutter="20">
  95. <el-col :span="12">
  96. <el-form-item label="经销商" prop="distributorName">
  97. <el-select
  98. v-model="editForm.distributorName"
  99. placeholder="请选择经销商"
  100. readonly
  101. style="width: 100%"
  102. @focus="openDistributor" />
  103. </el-form-item>
  104. </el-col>
  105. <el-col :span="12">
  106. <el-form-item label="合同类型" prop="contractType">
  107. <el-select v-model="editForm.contractType" placeholder="合同类型" style="width: 100%">
  108. <el-option v-for="item in contractOptions" :key="item.value" :label="item.value" :value="item.value" />
  109. </el-select>
  110. </el-form-item>
  111. </el-col>
  112. </el-row>
  113. <el-row :gutter="20">
  114. <el-col :span="12">
  115. <el-form-item label="客户签约人" prop="custSignatoryName">
  116. <el-select
  117. v-model="editForm.custSignatoryName"
  118. :disabled="!businessUserQueryParams.busId"
  119. placeholder="请选择客户签约人"
  120. readonly
  121. style="width: 100%"
  122. @focus="openContact" />
  123. </el-form-item>
  124. </el-col>
  125. <el-col :span="12">
  126. <el-form-item label="备注" prop="remark">
  127. <el-input v-model="editForm.remark" placeholder="请输入备注" :rows="4" type="textarea" />
  128. </el-form-item>
  129. </el-col>
  130. </el-row>
  131. </el-form>
  132. <!-- 产品分类 -->
  133. <el-row v-show="stepActive == 1">
  134. <el-row class="mb10" :gutter="20">
  135. <el-col :span="12">
  136. <p>产品:</p>
  137. </el-col>
  138. <el-col class="proj-col" :span="12">
  139. <el-button type="primary" @click="$refs.product.open()">选择产品</el-button>
  140. </el-col>
  141. </el-row>
  142. <el-row>
  143. <el-col :span="24">
  144. <product-table
  145. ref="productTable"
  146. :product-data="productData"
  147. @changeProductData="changeProductData"
  148. @delProductData="delProductData" />
  149. </el-col>
  150. </el-row>
  151. </el-row>
  152. <span slot="footer">
  153. <el-button v-show="stepActive == 0" type="primary" @click="setStep(1)">下一步</el-button>
  154. <el-button v-show="stepActive == 1" type="primary" @click="setStep(0)">上一步</el-button>
  155. <el-button v-show="!editForm.id && stepActive == 1" type="primary" @click="contractSave">保存</el-button>
  156. <el-button v-show="editForm.id && stepActive == 1" type="primary" @click="contractEdit">保存</el-button>
  157. <el-button @click="editVisible = false">取消</el-button>
  158. </span>
  159. <!-- 选择项目 -->
  160. <select-business ref="project" :multiple="false" @save="getBusinessInfo" />
  161. <!-- 选择经销商 -->
  162. <select-distributor ref="distributor" :multiple="false" @save="getDistributor" />
  163. <!-- 选择用户 -->
  164. <select-user ref="user" :label="label" :multiple="multiple" :property="property" @save="getUser" />
  165. <!-- 选择产品 -->
  166. <select-product ref="product" :multiple="true" @save="getProduct" />
  167. <!-- 选择联系人 -->
  168. <select-business-contact
  169. ref="contact"
  170. :multiple="false"
  171. :query-params="businessUserQueryParams"
  172. @save="getContact" />
  173. </el-dialog>
  174. </template>
  175. <script>
  176. import { mapGetters } from 'vuex'
  177. import to from 'await-to-js'
  178. import contractApi from '@/api/contract'
  179. import businessApi from '@/api/proj/business'
  180. import ProductTable from './ProductTable'
  181. import SelectBusiness from '@/components/select/SelectBusiness'
  182. import SelectDistributor from '@/components/select/SelectDistributor'
  183. import SelectUser from '@/components/select/SelectUser'
  184. import SelectProduct from '@/components/select/SelectProduct'
  185. import SelectBusinessContact from '@/components/select/SelectBusinessContact'
  186. export default {
  187. components: {
  188. ProductTable,
  189. SelectBusiness,
  190. SelectDistributor,
  191. SelectUser,
  192. SelectProduct,
  193. SelectBusinessContact,
  194. },
  195. data() {
  196. return {
  197. stepActive: 0, //步骤
  198. title: '新增客户信息',
  199. editVisible: false,
  200. editForm: {
  201. contractCode: '', //合同编号
  202. contractName: '', //合同名称
  203. contractType: '', //合同类型
  204. nboId: null, //项目id
  205. nboName: '', //项目名称
  206. custName: '', // 客户名称
  207. inchargeId: null, //销售工程师
  208. inchargeName: '', //销售工程师姓名
  209. contractStartTime: '', //合同开始时间
  210. contractEndTime: '', //合同结束时间
  211. signatoryName: '', //公司签约人
  212. signatoryId: null, //公司签约人id
  213. distributorId: null, //经销商id
  214. distributorName: '', //经销商name
  215. custSignatoryId: null, //客户签约人id
  216. custSignatoryName: '', //客户签约人name
  217. remark: '', //备注
  218. },
  219. editRules: {
  220. contractName: [{ required: true, trigger: 'blur', message: '请输入合同名称' }],
  221. contractType: [{ required: true, trigger: 'change', message: '请选择合同类型' }],
  222. nboName: [{ required: true, trigger: 'change', message: '请选择关联项目' }],
  223. contractStartTime: [
  224. { required: true, trigger: 'change', validator: this.pickerOptionsStart, message: '请选择开始时间' },
  225. ],
  226. contractEndTime: [
  227. { required: true, trigger: 'change', validator: this.pickerOptionsEnd, message: '请选择结束时间' },
  228. ],
  229. inchargeId: [{ required: true, trigger: 'change', message: '请选择销售工程师' }],
  230. signatoryName: [{ required: true, trigger: 'change', message: '请选择公司签约人' }],
  231. distributorName: [{ required: true, trigger: 'change', message: '请选择经销商' }],
  232. },
  233. pickerOptionsStart: {
  234. disabledDate: (time) => {
  235. let endDateVal = this.editForm.contractEndTime
  236. if (endDateVal) {
  237. return time.getTime() > new Date(endDateVal).getTime()
  238. }
  239. },
  240. },
  241. pickerOptionsEnd: {
  242. disabledDate: (time) => {
  243. let beginDateVal = this.editForm.contractStartTime
  244. if (beginDateVal) {
  245. return time.getTime() < new Date(beginDateVal).getTime() - 1 * 24 * 60 * 60 * 1000
  246. }
  247. },
  248. },
  249. contractOptions: [], //合同类型
  250. productData: [],
  251. multiple: false,
  252. property: '',
  253. label: '',
  254. businessUserQueryParams: {}, //查询客户签约人参数
  255. }
  256. },
  257. computed: {
  258. ...mapGetters({
  259. userId: 'user/id',
  260. username: 'user/username',
  261. }),
  262. },
  263. mounted() {
  264. this.getOptions()
  265. },
  266. methods: {
  267. getOptions() {
  268. Promise.all([this.getDicts('contract_type')])
  269. .then(([contract]) => {
  270. this.contractOptions = contract.data.values || []
  271. })
  272. .catch((err) => console.log(err))
  273. },
  274. async init(id) {
  275. if (!id) {
  276. this.title = '新增合同信息'
  277. // 设置销售工程师默认为当前用户
  278. this.editForm.inchargeId = this.userId
  279. this.editForm.inchargeName = this.username
  280. this.editForm.signatoryId = this.userId
  281. this.editForm.signatoryName = this.username
  282. console.log(this.editForm.signatoryName)
  283. } else {
  284. this.title = '编辑合同'
  285. const [err, res] = await to(contractApi.getDetails({ id }))
  286. if (err) return
  287. if (res.data) {
  288. // eslint-disable-next-line no-unused-vars
  289. let { product, ...data } = res.data
  290. this.editForm = data
  291. this.businessUserQueryParams = { busId: data.nboId, custId: data.custId }
  292. this.productData =
  293. product.length > 0
  294. ? product.map((item) => ({
  295. id: item.prodId,
  296. prodName: item.prodName,
  297. prodClass: item.prodClass,
  298. guidPrice: item.sugSalesPrice,
  299. price: item.tranPrice,
  300. count: item.prodNum,
  301. }))
  302. : []
  303. }
  304. }
  305. this.editVisible = true
  306. },
  307. // 修改步骤
  308. async setStep(step) {
  309. if (step == 1) {
  310. const [valid] = await to(this.$refs.editForm.validate())
  311. if (valid == false) return
  312. }
  313. this.stepActive = step
  314. },
  315. // 打开选择项目
  316. openProject() {
  317. this.$refs.project.open()
  318. },
  319. // 关闭选择项目获取项目信息
  320. getBusinessInfo(data) {
  321. let business = data[0] || null
  322. if (!business) return
  323. this.editForm.custName = business.custName
  324. this.editForm.nboId = business.id
  325. this.editForm.nboName = business.nboName
  326. this.editForm.custSignatoryId = business.contactId
  327. this.editForm.custSignatoryName = business.contactName
  328. this.businessUserQueryParams = { busId: business.id, custId: business.custId }
  329. console.log('项目信息', data)
  330. // 获取产品信息
  331. this.getProjectInfo(business.id)
  332. },
  333. // 打开选择经销商
  334. openDistributor() {
  335. this.$refs.distributor.open()
  336. },
  337. // 关闭经销商获取经销商信息
  338. getDistributor(data) {
  339. let distributor = data[0] || null
  340. if (!distributor) return
  341. this.editForm.distributorName = distributor.distName
  342. this.editForm.distributorId = distributor.id
  343. },
  344. // 打开选择公司签约人
  345. openUser(multiple, property, label) {
  346. this.multiple = multiple
  347. this.property = property
  348. this.label = label
  349. if (this.editForm[property].length) {
  350. this.$refs.user.ids = this.editForm[property]
  351. } else if (this.editForm[property]) {
  352. this.$refs.user.ids = [this.editForm[property]]
  353. } else {
  354. this.$refs.user.ids = []
  355. }
  356. this.$refs.user.open()
  357. },
  358. // 获取签约人信息
  359. getUser(userList, property, label) {
  360. console.log(userList, property, label)
  361. this.editForm[label] = userList.map((item) => item.nickName).join()
  362. if (this.multiple) {
  363. this.editForm[property] = userList.map((item) => item.id)
  364. } else {
  365. this.editForm[property] = userList[0] ? userList[0].id : ''
  366. }
  367. this.$forceUpdate()
  368. },
  369. // 打开选择公司签约人
  370. openContact() {
  371. this.$refs.contact.open()
  372. },
  373. // 获取签约人信息
  374. getContact(data) {
  375. let user = data[0] || null
  376. if (!user) return
  377. this.editForm['custSignatoryName'] = user.userName
  378. this.editForm['custSignatoryId'] = user.id
  379. },
  380. // 获取产品信息
  381. getProduct(data) {
  382. // 重构产品数据结构
  383. if (data.length > 0) this.setProductData(data)
  384. },
  385. // 根据项目id获取产品信息
  386. async getProjectInfo(id) {
  387. let params = { id }
  388. const [err, res] = await to(businessApi.getProductByBusinessId(params))
  389. console.log(res)
  390. if (err) return
  391. if (res.data && res.data.length > 0) this.setProductData(res.data)
  392. },
  393. setProductData(data) {
  394. let projData = data.map((item) => ({
  395. id: item.prodId ? item.prodId : item.id,
  396. prodName: item.prodName,
  397. prodClass: item.prodClass,
  398. guidPrice: item.guidPrice,
  399. price: item.prodPrice ? item.prodPrice : item.guidPrice,
  400. count: 1,
  401. }))
  402. this.productData.push(...projData)
  403. this.productData = this.removeDuplicateObj(this.productData)
  404. },
  405. // 数组对象去重
  406. removeDuplicateObj(arr) {
  407. let obj = {}
  408. arr = arr.reduce((newArr, next) => {
  409. obj[next.id] ? '' : (obj[next.id] = true && newArr.push(next))
  410. return newArr
  411. }, [])
  412. return arr
  413. },
  414. // 修改产品列表数据
  415. changeProductData(data) {
  416. this.productData = this.productData.map((item) => {
  417. return item.id === data.id ? data : item
  418. })
  419. },
  420. delProductData(data) {
  421. this.productData = this.productData.filter((item) => item.id != data.id)
  422. },
  423. // 保存合同
  424. async contractSave() {
  425. let product = this.productData.map((item) => ({
  426. prodId: item.id,
  427. prodNum: item.count,
  428. maintTerm: 1,
  429. sugSalesPrice: item.guidPrice,
  430. tranPrice: this.delcommafy(item.price),
  431. remark: '',
  432. }))
  433. let params = Object.assign({ ...this.editForm }, { product })
  434. if (product.length == 0) return this.$message.warning('请选择产品信息')
  435. const [err, res] = await to(contractApi.addContract(params))
  436. if (err) return
  437. if (res.code == 200) this.$message.success(res.msg)
  438. else return
  439. this.editVisible = false
  440. this.$emit('contractSave')
  441. },
  442. // 编辑合同
  443. async contractEdit() {
  444. let product = this.productData.map((item) => ({
  445. prodId: item.id,
  446. prodNum: item.count,
  447. maintTerm: 1,
  448. sugSalesPrice: item.guidPrice,
  449. tranPrice: this.delcommafy(item.price),
  450. remark: '',
  451. }))
  452. let params = Object.assign({ ...this.editForm }, { product })
  453. if (product.length == 0) return this.$message.warning('请选择产品信息')
  454. const [err, res] = await to(contractApi.updateContract(params))
  455. if (err) return
  456. if (res.code == 200) this.$message.success(res.msg)
  457. else return
  458. this.editVisible = false
  459. this.$emit('contractSave')
  460. },
  461. handleClose() {
  462. this.editForm = {
  463. contractCode: '', //合同编号
  464. contractName: '', //合同名称
  465. contractType: '', //合同类型
  466. nboId: null, //项目id
  467. nboName: '', //项目名称
  468. custName: '', // 客户名称
  469. inchargeId: null, //销售工程师
  470. inchargeName: '', //销售工程师名称
  471. contractStartTime: '', //合同开始时间
  472. contractEndTime: '', //合同结束时间
  473. signatoryName: '', //公司签约人
  474. signatoryId: null, //公司签约人id
  475. distributorId: null, //经销商id
  476. distributorName: '', //经销商name
  477. remark: '', //备注
  478. }
  479. this.productData = []
  480. this.stepActive = 0
  481. this.businessUserQueryParams = {}
  482. this.$refs.editForm.resetFields()
  483. },
  484. delcommafy(num) {
  485. if (!num) return 0
  486. num = num.toString()
  487. num = num.replace(/,/gi, '')
  488. if (num.indexOf('.00') > 0) num = parseInt(num)
  489. return Number(num)
  490. },
  491. },
  492. }
  493. </script>
  494. <style lang="scss" scoped>
  495. $base: '.edit-container';
  496. #{$base} {
  497. .mb10 {
  498. margin-bottom: 10px;
  499. }
  500. .proj-col {
  501. text-align: right;
  502. }
  503. // 进度条样式
  504. // ::v-deep .el-steps {
  505. // .el-step__line {
  506. // top: 17px;
  507. // }
  508. // .el-step__icon {
  509. // width: 35px;
  510. // height: 35px;
  511. // font-size: 18px;
  512. // }
  513. // .is-process {
  514. // .el-step__icon {
  515. // background: #2e51ff;
  516. // color: #fff;
  517. // border-color: #2e51ff;
  518. // }
  519. // }
  520. // }
  521. }
  522. </style>