Edit.vue 19 KB

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