BusinessEdit.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. <template>
  2. <el-dialog append-to-body :title="title" :visible.sync="dialogFormVisible" @close="close">
  3. <el-steps :active="activeSteps" align-center style="margin: -15px 0 15px 0">
  4. <el-step title="创建项目" />
  5. <el-step title="添加产品" />
  6. <el-step title="跟进日程" />
  7. </el-steps>
  8. <el-form ref="form" :model="form" :rules="rules">
  9. <el-row v-if="activeSteps === 1" :gutter="20">
  10. <el-col :span="12">
  11. <el-form-item label="项目名称" prop="nboName">
  12. <el-input v-model="form.nboName" />
  13. </el-form-item>
  14. </el-col>
  15. <el-col :span="12">
  16. <el-form-item label="关联客户" prop="custName">
  17. <el-input
  18. v-model="form.custName"
  19. :disabled="Boolean(custInfo.custName)"
  20. readonly
  21. @focus="handleSelectCustomer" />
  22. </el-form-item>
  23. </el-col>
  24. <el-col :span="12">
  25. <el-form-item label="获取日期" prop="obtainTime">
  26. <el-date-picker v-model="form.obtainTime" placeholder="选择日期" style="width: 100%" type="datetime" />
  27. </el-form-item>
  28. </el-col>
  29. <el-col :span="12">
  30. <el-form-item label="项目来源" prop="nboSource">
  31. <el-select v-model="form.nboSource" clearable placeholder="项目来源" style="width: 100%">
  32. <el-option v-for="dict in nboSourceOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
  33. </el-select>
  34. </el-form-item>
  35. </el-col>
  36. <el-col :span="12">
  37. <el-form-item label="主要联系人" prop="contactName">
  38. <el-input v-model="form.contactName" readonly @focus="handleSelectContact" />
  39. </el-form-item>
  40. </el-col>
  41. <el-col :span="12">
  42. <el-form-item label="职位" prop="contactPostion">
  43. <el-input v-model="form.contactPostion" />
  44. </el-form-item>
  45. </el-col>
  46. <el-col :span="12">
  47. <el-form-item label="联系电话" prop="contactTelephone">
  48. <el-input v-model="form.contactTelephone" />
  49. </el-form-item>
  50. </el-col>
  51. <el-col :span="12">
  52. <el-form-item label="销售工程师" prop="saleName">
  53. <el-input v-model="form.saleName" readonly @focus="handleSelectSale" />
  54. </el-form-item>
  55. </el-col>
  56. <el-col :span="12">
  57. <el-form-item label="销售模式" prop="salesModel">
  58. <el-select v-model="form.salesModel" clearable placeholder="销售模式" style="width: 100%">
  59. <el-option v-for="dict in salesModelOptions" :key="dict.key" :label="dict.value" :value="dict.key" />
  60. </el-select>
  61. </el-form-item>
  62. </el-col>
  63. <el-col :span="12">
  64. <el-form-item label="经销商/代理商" prop="distributorName">
  65. <el-input
  66. v-model="form.distributorName"
  67. :disabled="form.salesModel === '10'"
  68. readonly
  69. @focus="handleSelectDistributor" />
  70. </el-form-item>
  71. </el-col>
  72. <el-col :span="24">
  73. <el-form-item label="备注信息" prop="remark">
  74. <el-input v-model="form.remark" placeholder="请输入备注信息" rows="5" show-word-limit type="textarea" />
  75. </el-form-item>
  76. </el-col>
  77. </el-row>
  78. <el-row v-if="activeSteps === 2" :gutter="20">
  79. <el-col :span="24">
  80. <el-button size="mini" type="primary" @click="handleSelectProduct">添加产品</el-button>
  81. <product-table
  82. ref="productTable"
  83. :product-data="productData"
  84. @changeProductData="changeProductData"
  85. @delProductData="delProductData" />
  86. </el-col>
  87. </el-row>
  88. <el-row v-if="activeSteps === 3" :gutter="20">
  89. <el-col :span="12">
  90. <el-form-item label="跟进时间" prop="followTime">
  91. <el-date-picker v-model="form.followTime" placeholder="选择时间" style="width: 100%" type="datetime" />
  92. </el-form-item>
  93. </el-col>
  94. <el-col :span="12">
  95. <el-form-item label="负责人员" prop="followUserName">
  96. <el-input v-model="form.followUserName" readonly @focus="handleSelectFollowUser" />
  97. </el-form-item>
  98. </el-col>
  99. <el-col :span="24">
  100. <el-form-item label="跟进内容" prop="followContent">
  101. <el-input
  102. v-model="form.followContent"
  103. placeholder="请输入跟进内容"
  104. rows="5"
  105. show-word-limit
  106. type="textarea" />
  107. </el-form-item>
  108. </el-col>
  109. </el-row>
  110. </el-form>
  111. <div slot="footer" class="dialog-footer">
  112. <el-button v-if="activeSteps !== 1" type="primary" @click="activeSteps--">上一步</el-button>
  113. <el-button v-if="activeSteps !== 3" type="primary" @click="nextStep">下一步</el-button>
  114. <el-button v-if="activeSteps === 3" type="primary" @click="save">提 交</el-button>
  115. </div>
  116. <!-- 选择客户弹窗 -->
  117. <select-customer ref="selectCustomer" @save="selectCustomer" />
  118. <!-- 选择客户联系人弹窗 -->
  119. <select-contact
  120. ref="selectContact"
  121. :default-customer="customerInfo"
  122. :query-params="queryContact"
  123. @save="selectContact" />
  124. <!-- 选择销售工程师弹窗 -->
  125. <select-user ref="selectSales" :query-params="{ roles: ['Sales', 'SalesManager'] }" @save="selectSales" />
  126. <!-- 选择经销商弹窗 -->
  127. <select-distributor ref="selectDistributor" @save="selectDistributor" />
  128. <!-- 选择产品弹窗 -->
  129. <select-product ref="selectProduct" multiple @save="selectProduct" />
  130. <!-- 选择跟进负责人弹窗 -->
  131. <select-user ref="selectFollowUser" @save="selectFollowUser" />
  132. </el-dialog>
  133. </template>
  134. <script>
  135. import businessApi from '@/api/proj/business'
  136. import ProductTable from './ProductTable'
  137. import SelectContact from '@/components/select/SelectCustomerContact'
  138. import SelectCustomer from '@/components/select/SelectCustomer'
  139. import SelectUser from '@/components/select/SelectUser'
  140. import SelectDistributor from '@/components/select/SelectDistributor'
  141. import SelectProduct from '@/components/select/SelectProduct'
  142. export default {
  143. name: 'BusinessEdit',
  144. components: { ProductTable, SelectContact, SelectProduct, SelectDistributor, SelectCustomer, SelectUser },
  145. props: {
  146. // 客户信息{ custId: id, custName: custName}
  147. custInfo: {
  148. type: Object,
  149. default() {
  150. return {}
  151. },
  152. },
  153. },
  154. data() {
  155. const validateDistributor = (rule, value, callback) => {
  156. if ('' === value && this.form.salesModel !== '10')
  157. callback(new Error(this.translateTitle('请选择经销商/代理商')))
  158. else callback()
  159. }
  160. return {
  161. activeSteps: 1,
  162. form: {
  163. nboName: undefined,
  164. custId: undefined,
  165. custName: undefined,
  166. obtainTime: undefined,
  167. nboSource: undefined,
  168. contactId: undefined,
  169. contactName: undefined,
  170. contactPostion: undefined,
  171. contactTelephone: undefined,
  172. saleId: undefined,
  173. saleName: undefined,
  174. distributorId: undefined,
  175. distributorName: undefined,
  176. remark: undefined,
  177. products: undefined,
  178. // 跟进
  179. followTime: undefined,
  180. followUserId: undefined,
  181. followUserName: undefined,
  182. followContent: undefined,
  183. },
  184. rules: {
  185. nboName: [{ required: true, trigger: ['blur', 'change'], message: '请输入项目名称' }],
  186. custName: [{ required: true, trigger: ['blur', 'change'], message: '请选择关联客户' }],
  187. nboSource: [{ required: true, trigger: ['blur', 'change'], message: '请选择项目来源' }],
  188. contactName: [{ required: true, trigger: ['blur', 'change'], message: '请选择主要联系人' }],
  189. saleName: [{ required: true, trigger: ['blur', 'change'], message: '请选择销售工程师' }],
  190. salesModel: [{ required: true, trigger: ['blur', 'change'], message: '请选择销售模式' }],
  191. distributorName: [
  192. { validator: validateDistributor, trigger: ['blur', 'change'], message: '请选择经销商/代理商' },
  193. ],
  194. // 跟进
  195. followTime: [{ required: true, trigger: ['blur', 'change'], message: '请输入跟进时间' }],
  196. followContent: [{ required: true, trigger: ['blur', 'change'], message: '请输入跟进内容' }],
  197. },
  198. title: '',
  199. dialogFormVisible: false,
  200. nboSourceOptions: [],
  201. salesModelOptions: [],
  202. queryContact: {},
  203. customerInfo: {},
  204. productData: [],
  205. }
  206. },
  207. watch: {
  208. custInfo: function (val) {
  209. this.form.custId = val.custId
  210. this.queryContact.custId = val.custId
  211. this.form.custName = val.custName
  212. this.customerInfo = val
  213. },
  214. },
  215. created() {},
  216. mounted() {
  217. this.getDicts('proj_nbo_source').then((response) => {
  218. this.nboSourceOptions = response.data.values || []
  219. })
  220. this.getDicts('proj_sales_model').then((response) => {
  221. this.salesModelOptions = response.data.values || []
  222. })
  223. },
  224. methods: {
  225. nextStep() {
  226. if (this.activeSteps === 1) {
  227. this.$refs['form'].validate(async (valid) => {
  228. if (valid) {
  229. this.activeSteps++
  230. }
  231. })
  232. } else if (this.activeSteps === 2) {
  233. this.form.products = this.productData
  234. this.activeSteps++
  235. }
  236. },
  237. handleSelectCustomer() {
  238. this.$refs.selectCustomer.open()
  239. },
  240. handleSelectContact() {
  241. if (!this.queryContact.custId) {
  242. this.$message.warning('请先选择客户')
  243. return
  244. }
  245. this.$refs.selectContact.open()
  246. },
  247. handleSelectSale() {
  248. this.$refs.selectSales.open()
  249. },
  250. handleSelectDistributor() {
  251. this.$refs.selectDistributor.open()
  252. },
  253. handleSelectProduct() {
  254. this.$refs.selectProduct.open()
  255. },
  256. handleSelectFollowUser() {
  257. this.$refs.selectFollowUser.open()
  258. },
  259. selectCustomer(val) {
  260. if (val && val.length > 0) {
  261. this.queryContact.custId = val[0].id
  262. this.customerInfo = {
  263. custId: val[0].id,
  264. custName: val[0].custName,
  265. }
  266. this.form.custId = val[0].id
  267. this.form.custName = val.map((item) => item.custName).join()
  268. }
  269. },
  270. selectContact(val) {
  271. if (val && val.length > 0) {
  272. this.form.contactId = val[0].id
  273. this.form.contactName = val.map((item) => item.cuctName).join()
  274. this.form.contactPostion = val.map((item) => item.postion).join()
  275. this.form.contactTelephone = val.map((item) => item.telephone).join()
  276. }
  277. },
  278. selectSales(val) {
  279. if (val && val.length > 0) {
  280. this.form.saleId = val[0].id
  281. this.form.saleName = val.map((item) => item.userName).join()
  282. }
  283. },
  284. selectDistributor(val) {
  285. if (val && val.length > 0) {
  286. this.form.distributorId = val[0].id
  287. this.form.distributorName = val.map((item) => item.distName).join()
  288. }
  289. },
  290. selectFollowUser(val) {
  291. this.form.followUserName = val.map((item) => item.userName).join()
  292. },
  293. selectProduct(data) {
  294. let projData = data.map((item) => ({
  295. prodId: item.id,
  296. prodCode: item.prodCode,
  297. prodName: item.prodName,
  298. prodClass: item.prodClass,
  299. guidPrice: item.guidPrice,
  300. prodPrice: item.marketPrice,
  301. prodNum: 1,
  302. }))
  303. this.productData.push(...projData)
  304. this.productData = this.removeDuplicateObj(this.productData)
  305. },
  306. // 数组对象去重
  307. removeDuplicateObj(arr) {
  308. let obj = {}
  309. arr = arr.reduce((newArr, next) => {
  310. obj[next.prodId] ? '' : (obj[next.prodId] = true && newArr.push(next))
  311. return newArr
  312. }, [])
  313. return arr
  314. },
  315. // 修改产品列表数据
  316. changeProductData(data) {
  317. this.productData = this.productData.map((item) => {
  318. return item.prodId === data.prodId ? data : item
  319. })
  320. },
  321. delProductData(data) {
  322. this.productData = this.productData.filter((item) => item.prodId !== data.prodId)
  323. },
  324. async getProductData(busId) {
  325. const { data } = await businessApi.getProductByBusinessId({ id: busId })
  326. this.productData = data
  327. },
  328. showEdit(row) {
  329. this.activeSteps = 1
  330. if (!row) {
  331. this.title = '添加'
  332. } else {
  333. this.title = '编辑'
  334. this.form = Object.assign({}, row)
  335. this.getProductData(row.id)
  336. }
  337. this.dialogFormVisible = true
  338. },
  339. close() {
  340. this.$refs['form'].resetFields()
  341. this.form = this.$options.data().form
  342. this.dialogFormVisible = false
  343. },
  344. save() {
  345. this.$refs['form'].validate(async (valid) => {
  346. if (valid) {
  347. let res
  348. if (this.form.id) {
  349. res = await businessApi.doEdit(this.form)
  350. } else {
  351. res = await businessApi.doAdd(this.form)
  352. }
  353. this.$baseMessage(res.msg, 'success')
  354. this.$emit('fetch-data')
  355. this.close()
  356. } else {
  357. return false
  358. }
  359. })
  360. },
  361. },
  362. }
  363. </script>