chooseCustomModal.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. <template>
  2. <div v-if="opened">
  3. <a-modal
  4. v-model="opened"
  5. :title="title"
  6. centered
  7. :maskClosable="false"
  8. :confirmLoading="confirmLoading"
  9. :width="960"
  10. :footer="null"
  11. @cancel="cancel"
  12. >
  13. <a-spin :spinning="spinning" tip="Loading...">
  14. <a-form-model
  15. id="chooseCustom-form"
  16. ref="ruleForm"
  17. :model="form"
  18. :rules="rules"
  19. :label-col="formItemLayout.labelCol"
  20. :wrapper-col="formItemLayout.wrapperCol"
  21. >
  22. <a-row :gutter="15">
  23. <a-col :span="16">
  24. <a-form-model-item label="客户名称" prop="buyerSn" :labelCol="{ span: 3 }" :wrapperCol="{ span: 20 }">
  25. <selectCust ref="custList" :isValidateEnabled="true" id="chooseCustom-buyerSn" @change="custChange" v-model="form.buyerSn"></selectCust>
  26. </a-form-model-item>
  27. </a-col>
  28. <a-col :span="8" v-if="$hasPermissions('B_customer_customerInfo_add')">
  29. <a-form-model-item :labelCol="{ span: 0 }" :wrapperCol="{ span: 24 }">
  30. <a-button type="primary" id="chooseCustom-add" class="button-primary" @click="openNewCust" icon="plus">新增</a-button>
  31. (点击新增按钮新增客户)
  32. </a-form-model-item>
  33. </a-col>
  34. </a-row>
  35. <a-row :gutter="15">
  36. <a-col :span="24">
  37. <a-form-model-item label="客户地址" required style="margin: 0;" :labelCol="{ span: 2 }" :wrapperCol="{ span: 22 }">
  38. <a-row :gutter="15">
  39. <!-- 客户地址 -->
  40. <a-col span="8">
  41. <a-form-model-item prop="shippingAddressProvinceSn">
  42. <a-select id="chooseCustom-provinceSn" allowClear @change="getCityList" v-model="form.shippingAddressProvinceSn" placeholder="请选择省">
  43. <a-select-option v-for="item in addrProvinceList" :value="item.areaSn" :key="item.areaSn + 'a'">{{ item.name }}</a-select-option>
  44. </a-select>
  45. </a-form-model-item>
  46. </a-col>
  47. <a-col span="8">
  48. <a-form-model-item prop="shippingAddressCitySn">
  49. <a-select id="chooseCustom-citySn" allowClear @change="getAreaList" v-model="form.shippingAddressCitySn" placeholder="请选择市">
  50. <a-select-option v-for="item in addrCityList" :value="item.areaSn" :key="item.areaSn + 'b'">{{ item.name }}</a-select-option>
  51. </a-select>
  52. </a-form-model-item>
  53. </a-col>
  54. <a-col span="8">
  55. <a-form-model-item prop="shippingAddressCountySn">
  56. <a-select id="chooseCustom-countySn" allowClear @change="areaCharged" v-model="form.shippingAddressCountySn" placeholder="请选择区/县">
  57. <a-select-option v-for="item in addrDistrictList" :value="item.areaSn" :key="item.areaSn + 'c'">{{ item.name }}</a-select-option>
  58. </a-select>
  59. </a-form-model-item>
  60. </a-col>
  61. </a-row>
  62. </a-form-model-item>
  63. </a-col>
  64. <a-col :span="24">
  65. <a-form-model-item label="详细地址" prop="shippingAddress" :labelCol="{ span: 2 }" :wrapperCol="{ span: 22 }">
  66. <a-input
  67. id="chooseCustom-shippingAddress"
  68. :maxLength="60"
  69. v-model.trim="form.shippingAddress"
  70. placeholder="请输入详细地址(最多60个字符)"
  71. allowClear />
  72. </a-form-model-item>
  73. </a-col>
  74. </a-row>
  75. <a-row :gutter="15">
  76. <a-col :span="8">
  77. <a-form-model-item label="联系人" prop="consigneeName">
  78. <a-input
  79. id="chooseCustom-consigneeName"
  80. :maxLength="30"
  81. v-model.trim="form.consigneeName"
  82. placeholder="请输入联系人(最多30个字符)"
  83. allowClear />
  84. </a-form-model-item>
  85. </a-col>
  86. <a-col :span="8">
  87. <a-form-model-item label="联系电话" prop="consigneeTel">
  88. <a-input
  89. id="chooseCustom-consigneeTel"
  90. :maxLength="15"
  91. v-model.trim="form.consigneeTel"
  92. placeholder="请输入联系电话(最多15个字符)"
  93. allowClear />
  94. </a-form-model-item>
  95. </a-col>
  96. <a-col :span="8">
  97. <a-form-model-item label="联系手机" prop="consigneeMobile">
  98. <a-input
  99. id="chooseCustom-consigneeMobile"
  100. :maxLength="11"
  101. v-model.trim="form.consigneeMobile"
  102. placeholder="请输入联系电话(最多11个字符)"
  103. allowClear />
  104. </a-form-model-item>
  105. </a-col>
  106. </a-row>
  107. <a-row :gutter="15">
  108. <a-col :span="8">
  109. <a-form-model-item label="价格类型" prop="priceType">
  110. <a-row :gutter="15">
  111. <a-col :span="20">
  112. <v-select
  113. code="PRICE_TYPE"
  114. :disabled="priceTypeDisabled"
  115. id="chooseCustom-priceType"
  116. v-model="form.priceType"
  117. @change="changePriceType"
  118. allowClear
  119. placeholder="请选择价格类型" ></v-select>
  120. </a-col>
  121. <a-col :span="4">
  122. <a-popover>
  123. <template slot="content">(选择后在当前工单不可修改)</template>
  124. <a-icon type="question-circle" />
  125. </a-popover>
  126. </a-col>
  127. </a-row>
  128. </a-form-model-item>
  129. </a-col>
  130. <a-col :span="8">
  131. <a-form-model-item label="收款方式" prop="settleStyleSn">
  132. <settleStyle
  133. id="chooseCustom-settleStyleSn"
  134. v-model="form.settleStyleSn"
  135. placeholder="请选择收款方式">
  136. </settleStyle>
  137. </a-form-model-item>
  138. </a-col>
  139. <a-col :span="8">
  140. <a-form-model-item label="配送方式" prop="dispatchType">
  141. <v-select code="DISPATCH_TYPE" id="chooseCustom-dispatchType" v-model="form.dispatchType" allowClear placeholder="请选择配送方式"></v-select>
  142. </a-form-model-item>
  143. </a-col>
  144. </a-row>
  145. <a-row :gutter="15">
  146. <a-col :span="8">
  147. <a-form-model-item label="业务员" prop="salesManSn">
  148. <a-select id="chooseCustom-salesManSn" allowClear @change="salesManChange" v-model="form.salesManSn" placeholder="请选择业务员">
  149. <a-select-option v-for="item in userList" :value="item.employeeSn" :key="item.id + 'c'">{{ item.name }}</a-select-option>
  150. </a-select>
  151. </a-form-model-item>
  152. </a-col>
  153. <a-col :span="8">
  154. <a-form-model-item label="铺货出库" prop="distributionFlag">
  155. <v-select code="FLAG" id="chooseCustom-distributionFlag" v-model="form.distributionFlag" allowClear placeholder="请选择是否铺货出库"></v-select>
  156. </a-form-model-item>
  157. </a-col>
  158. </a-row>
  159. <a-row :gutter="15">
  160. <a-col :span="8">
  161. <a-form-model-item label="备注" prop="remarks">
  162. <a-input
  163. id="chooseCustom-remarks"
  164. type="textarea"
  165. :maxLength="100"
  166. v-model.trim="form.remarks"
  167. placeholder="请输入备注(最多100个字符)"
  168. allowClear />
  169. </a-form-model-item>
  170. </a-col>
  171. <a-col :span="8">
  172. <a-form-model-item label="开单人">{{ $store.state.user.info.userNameCN }}</a-form-model-item>
  173. </a-col>
  174. </a-row>
  175. <a-form-model-item :wrapper-col="{ span: 12, offset: 6 }" style="text-align: center;">
  176. <a-button type="primary" size="large" :loading="confirmLoading" @click="handleSubmit" id="chooseCustom-btn-submit">保存</a-button>
  177. <a-button @click="cancel" size="large" style="margin-left: 15px" id="chooseCustom-btn-back">取消</a-button>
  178. </a-form-model-item>
  179. </a-form-model>
  180. <!-- 新增客户 -->
  181. <a-modal
  182. v-model="isNewCust"
  183. title="新增客户"
  184. centered
  185. :width="960"
  186. :maskClosable="false"
  187. @cancel="cancelNewCust"
  188. :footer="null"
  189. id="chooseCustom-newCustModal"
  190. >
  191. <CustomerManagementEdit ref="newCust" model="modal" @ok="newCustFun"></CustomerManagementEdit>
  192. </a-modal>
  193. </a-spin>
  194. </a-modal>
  195. </div>
  196. </template>
  197. <script>
  198. // 接口
  199. import { getArea } from '@/api/data'
  200. import { custFindById, updateByCustomerSn } from '@/api/customer'
  201. import { salesSave } from '@/api/sales'
  202. import { employeeAllList } from '@/api/salesman'
  203. // 组件
  204. import settleStyle from '@/views/common/settleStyle'
  205. import { VSelect } from '@/components'
  206. import selectCust from '@/views/common/selectCust.vue'
  207. import CustomerManagementEdit from '@/views/customerManagement/customerInfo/edit.vue'
  208. export default {
  209. name: 'ChooseCustomModal',
  210. components: { VSelect, CustomerManagementEdit, selectCust, settleStyle },
  211. props: {
  212. show: [Boolean], // 是否显示弹框
  213. distributionFlag: { // 是否铺货出库
  214. type: [String, Number],
  215. default: '0'
  216. }
  217. },
  218. data () {
  219. return {
  220. spinning: false,
  221. opened: this.show, // 是否显示弹框
  222. title: '选择客户', // 弹框标题
  223. confirmLoading: false, // 确认按钮loading
  224. formItemLayout: {
  225. labelCol: { span: 6 },
  226. wrapperCol: { span: 18 }
  227. },
  228. buyerSnBak: '', // 更改前客户sn备份
  229. priceTypeBak: '', // 更改前客户价格类型备份
  230. form: {
  231. buyerName: '', // 客户名称
  232. buyerSn: undefined, // 客户sn
  233. consigneeTel: '', // 联系电话
  234. consigneeMobile: '', // 联系电话1
  235. consigneeName: '', // 联系人
  236. shippingAddressProvinceSn: undefined, // 省
  237. shippingAddressProvinceName: '',
  238. shippingAddressCitySn: undefined, // 市
  239. shippingAddressCityName: '',
  240. shippingAddressCountySn: undefined, // 区
  241. shippingAddressCountyName: '',
  242. shippingAddress: '', // 详细地址
  243. fax: '', // 客户传真
  244. dispatchType: undefined, // 配送方式
  245. satelliteFlag: 0, // 是否卫星仓客户
  246. priceType: undefined, // 价格类型
  247. settleStyleSn: undefined, // 收款方式
  248. salesManSn: undefined, // 业务员
  249. salesManName: '', // 业务员名称
  250. distributionFlag: undefined, // 铺货出库
  251. salesTragetType: 'CUSTOMER', // 销售目标类型
  252. remarks: '' // 备注
  253. },
  254. rules: {
  255. buyerSn: [
  256. { required: true, message: '请选择客户', trigger: ['change', 'blur'] }
  257. ],
  258. consigneeMobile: [{ required: false, pattern: /^\d{11}$/, message: '请输入正确的手机号', trigger: 'blur' }],
  259. shippingAddressProvinceSn: [
  260. { required: true, message: '请选择省', trigger: 'change' }
  261. ],
  262. shippingAddressCitySn: [
  263. { required: true, message: '请选择市', trigger: 'change' }
  264. ],
  265. shippingAddressCountySn: [
  266. { required: true, message: '请选择区/县', trigger: 'change' }
  267. ],
  268. priceType: [
  269. { required: true, message: '请选择价格类型', trigger: ['change', 'blur'] }
  270. ],
  271. settleStyleSn: [
  272. { required: true, message: '请选择收款方式', trigger: ['change', 'blur'] }
  273. ],
  274. distributionFlag: [
  275. { required: true, message: '请选择是否铺货出库', trigger: 'change' }
  276. ]
  277. // salesManSn: [
  278. // { required: true, message: '请选择业务员', trigger: 'change' }
  279. // ]
  280. },
  281. addrProvinceList: [], // 省下拉
  282. addrCityList: [], // 市下拉
  283. addrDistrictList: [], // 区下拉
  284. userList: [], // 业务员 下拉
  285. custId: undefined, // 客户id
  286. isEdit: false, // 是否编辑状态
  287. priceTypeDisabled: false, // 价格类型可编辑
  288. isChangeCust: false, // 是否更换客户
  289. interId: null,
  290. isNewCust: false // 是否新增客户
  291. }
  292. },
  293. methods: {
  294. // 选择价格类型
  295. changePriceType (v) {
  296. this.form.priceType = v
  297. this.$refs.ruleForm.clearValidate('priceType')
  298. },
  299. // 打开新增客户弹框
  300. openNewCust () {
  301. this.isNewCust = true
  302. setTimeout(() => {
  303. this.$refs.newCust.getBaseData()
  304. }, 500)
  305. },
  306. // 新建客户成功后
  307. newCustFun (data) {
  308. // console.log(data, this.isEdit)
  309. this.isNewCust = false
  310. // 更新客户信息
  311. this.$refs.custList.setData({ key: data.customerSn, label: data.customerName, row: data })
  312. this.custChange({ key: data.customerSn, label: data.customerName, row: data })
  313. },
  314. // 业务员变更
  315. salesManChange (employeeSn) {
  316. if (employeeSn) {
  317. this.form.salesManName = this.userList.find(item => item.employeeSn == employeeSn).name
  318. } else {
  319. this.form.salesManName = ''
  320. }
  321. },
  322. // 客户变更 change
  323. custChange (obj) {
  324. const _this = this
  325. if (obj && obj.key) {
  326. const cust = obj.row
  327. this.form.buyerSn = cust.customerSn
  328. // 编辑
  329. if (this.isEdit) {
  330. this.$confirm({
  331. title: '提示',
  332. content: '更换客户后信息需要重新完善,确认要更换吗?',
  333. centered: true,
  334. onOk () {
  335. _this.custId = cust.id
  336. _this.form.buyerName = cust.customerName
  337. _this.priceTypeDisabled = false
  338. _this.getDetail()
  339. },
  340. onCancel () {
  341. _this.form.buyerSn = _this.buyerSnBak
  342. }
  343. })
  344. } else {
  345. _this.custId = cust.id
  346. _this.form.buyerName = cust.customerName
  347. _this.getDetail()
  348. }
  349. } else {
  350. this.$refs.ruleForm.resetFields()
  351. this.$refs.custList.resetForm()
  352. }
  353. },
  354. // 编辑客户信息
  355. editCust (data) {
  356. // console.log(data)
  357. this.title = '编辑客户信息'
  358. this.isEdit = true
  359. this.priceTypeDisabled = true
  360. if (data.shippingAddressProvinceSn) { this.getArea('city', data.shippingAddressProvinceSn) }
  361. if (data.shippingAddressCitySn) { this.getArea('district', data.shippingAddressCitySn) }
  362. this.form = Object.assign(this.form, data)
  363. this.form.buyerName = data.buyerNameCurrent || data.buyerName
  364. this.buyerSnBak = this.form.buyerSn
  365. this.priceTypeBak = this.form.priceType
  366. this.$nextTick(() => {
  367. // 客户组件赋值
  368. this.$refs.custList.setData({ key: data.buyerSn, label: data.buyerNameCurrent || data.buyerName, row: data })
  369. })
  370. },
  371. // 获取详情
  372. getDetail () {
  373. this.spinning = true
  374. custFindById({ id: this.custId }).then(res => {
  375. const data = res.data
  376. if (res.status == 200 && data) {
  377. if (data.provinceSn) { this.getArea('city', data.provinceSn) }
  378. if (data.citySn) { this.getArea('district', data.citySn) }
  379. this.form = Object.assign(this.form, {
  380. buyerName: data.customerName, // 客户名称
  381. buyerSn: data.customerSn, // 客户sn
  382. consigneeTel: data.contactTel, // 联系电话
  383. consigneeMobile: data.contactMobile,
  384. consigneeName: data.contactName, // 联系人
  385. shippingAddressProvinceSn: data.provinceSn, // 省
  386. shippingAddressProvinceName: data.provinceName,
  387. shippingAddressCitySn: data.citySn, // 市
  388. shippingAddressCityName: data.cityName,
  389. shippingAddressCountySn: data.countySn, // 区
  390. shippingAddressCountyName: data.countyName,
  391. shippingAddress: data.customerAddr, // 详细地址
  392. fax: data.fax, // 客户传真
  393. dispatchType: data.dispatchType, // 配送方式
  394. satelliteFlag: data.satelliteFlag, // 是否卫星仓客户
  395. priceType: data.priceType, // 价格类型
  396. settleStyleSn: data.settleStyleSn // 收款方式
  397. })
  398. // this.buyerSnBak = this.form.buyerSn
  399. // this.priceTypeBak = this.form.priceType
  400. } else {
  401. this.$message.error('获取客户信息失败')
  402. this.$refs.ruleForm.resetFields()
  403. }
  404. this.$refs.ruleForm.clearValidate()
  405. this.spinning = false
  406. })
  407. },
  408. // 保存更新客户信息
  409. handleSaveCust () {
  410. const params = {
  411. customerName: this.form.buyerName, // 客户名称
  412. customerSn: this.form.buyerSn,
  413. contactTel: this.form.consigneeTel, // 联系电话
  414. contactMobile: this.form.consigneeMobile,
  415. contactName: this.form.consigneeName, // 联系人
  416. provinceSn: this.form.shippingAddressProvinceSn, // 省
  417. provinceName: this.form.shippingAddressProvinceName,
  418. citySn: this.form.shippingAddressCitySn, // 市
  419. cityName: this.form.shippingAddressCityName,
  420. countySn: this.form.shippingAddressCountySn, // 区
  421. countyName: this.form.shippingAddressCountyName,
  422. customerAddr: this.form.shippingAddress, // 详细地址
  423. dispatchType: this.form.dispatchType, // 配送方式
  424. priceType: this.form.priceType, // 价格类型
  425. settleStyleSn: this.form.settleStyleSn // 收款方式
  426. }
  427. this.spinning = true
  428. updateByCustomerSn(params).then(res => {
  429. this.spinning = false
  430. if (res.status == 200) {
  431. // 保存销售单
  432. this.salesSaveFun()
  433. this.spinning = false
  434. } else {
  435. this.spinning = false
  436. }
  437. })
  438. },
  439. // 保存销售单客户信息
  440. handleSubmit (e) {
  441. e.preventDefault()
  442. const _this = this
  443. // console.log(_this.form, '------save')
  444. this.$refs.ruleForm.validate(valid => {
  445. if (valid) {
  446. // 如果价格类型改变,提示
  447. if (_this.priceTypeBak != _this.form.priceType && this.isEdit) {
  448. this.$confirm({
  449. title: '提示',
  450. content: '价格类型变更,确认提交吗?',
  451. centered: true,
  452. onOk () {
  453. // 保存客户信息
  454. _this.handleSaveCust()
  455. }
  456. })
  457. } else {
  458. // 保存客户信息
  459. _this.handleSaveCust()
  460. }
  461. } else {
  462. return false
  463. }
  464. })
  465. },
  466. // 新建或编辑销售单
  467. salesSaveFun () {
  468. const _this = this
  469. const form = this.form
  470. _this.spinning = true
  471. salesSave(form).then(res => {
  472. if (res.status == 200) {
  473. _this.$message.success(res.message)
  474. _this.$emit('ok', res.data)
  475. if (_this.form.id) {
  476. _this.$emit('updateData', form.priceType)
  477. }
  478. _this.cancel()
  479. _this.spinning = false
  480. } else {
  481. _this.spinning = false
  482. }
  483. })
  484. },
  485. // 取消新建销售单
  486. cancel () {
  487. this.opened = false
  488. this.$emit('cancel')
  489. this.$refs.ruleForm.resetFields()
  490. this.$refs.custList.resetForm()
  491. },
  492. // 取消新增客户弹框
  493. cancelNewCust () {
  494. this.isNewCust = false
  495. this.$refs.newCust.getBaseData()
  496. },
  497. // 获取业务员列表数据
  498. getUserAllList () {
  499. employeeAllList({}).then(res => {
  500. if (res.status == 200) {
  501. this.userList = res.data || []
  502. } else {
  503. this.userList = []
  504. }
  505. })
  506. },
  507. // 获取城市列表
  508. getCityList (val) {
  509. this.addrCityList = []
  510. this.addrDistrictList = []
  511. this.form.shippingAddressCitySn = undefined
  512. this.form.shippingAddressCityName = ''
  513. this.form.shippingAddressCountySn = undefined
  514. this.form.shippingAddressCountyName = ''
  515. if (val) {
  516. this.getArea('city', val)
  517. this.form.shippingAddressProvinceName = this.addrProvinceList.find(item => item.areaSn == val).name
  518. } else {
  519. this.form.shippingAddressProvinceName = ''
  520. }
  521. },
  522. // 获取区县列表
  523. getAreaList (val) {
  524. this.addrDistrictList = []
  525. this.form.shippingAddressCountySn = undefined
  526. this.form.shippingAddressCountyName = ''
  527. if (val) {
  528. this.getArea('district', val)
  529. this.form.shippingAddressCityName = this.addrCityList.find(item => item.areaSn == val).name
  530. } else {
  531. this.form.shippingAddressCityName = ''
  532. }
  533. },
  534. // 区县变更
  535. areaCharged (val) {
  536. if (val) {
  537. this.form.shippingAddressCountyName = this.addrDistrictList.find(item => item.areaSn == val).name
  538. } else {
  539. this.form.shippingAddressCountyName = ''
  540. }
  541. },
  542. // 省/市/区
  543. getArea (leve, sn) {
  544. let params
  545. if (leve == 'province') {
  546. params = { type: '2' }
  547. } else {
  548. params = { parentId: sn, type: leve == 'city' ? '3' : '4' }
  549. }
  550. getArea(params).then(res => {
  551. if (res.status == 200) {
  552. if (leve == 'province') {
  553. this.addrProvinceList = res.data || []
  554. } else if (leve == 'city') {
  555. this.addrCityList = res.data || []
  556. } else if (leve == 'district') {
  557. this.addrDistrictList = res.data || []
  558. }
  559. } else {
  560. if (leve == 'province') {
  561. this.addrProvinceList = []
  562. } else if (leve == 'city') {
  563. this.addrCityList = []
  564. } else if (leve == 'district') {
  565. this.addrDistrictList = []
  566. }
  567. }
  568. })
  569. }
  570. },
  571. watch: {
  572. show (newValue, oldValue) {
  573. this.opened = newValue
  574. if (newValue) {
  575. this.getArea('province')
  576. this.getUserAllList()
  577. }
  578. },
  579. // 是否铺货出库
  580. distributionFlag (newValue, oldValue) {
  581. this.form.distributionFlag = newValue.toString()
  582. }
  583. }
  584. }
  585. </script>