basicInfoModal.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. <template>
  2. <a-modal
  3. centered
  4. class="allocateBill-basicInfo-modal"
  5. :footer="null"
  6. :maskClosable="false"
  7. :title="isEdit?'编辑':'新增'"
  8. v-model="isShow"
  9. @cancel="isShow = false"
  10. :width="900">
  11. <a-spin :spinning="spinning" tip="Loading...">
  12. <a-form-model
  13. id="allocateBill-basicInfo-form"
  14. ref="ruleForm"
  15. :model="form"
  16. :rules="rules"
  17. :label-col="formItemLayout.labelCol"
  18. :wrapper-col="formItemLayout.wrapperCol"
  19. >
  20. <a-row :gutter="15">
  21. <a-col :md="12" :sm="24" v-if="!isEdit">
  22. <a-form-model-item label="调往对象" prop="targetType">
  23. <a-radio-group v-model="form.targetType" @change="targetTypeChange">
  24. <a-radio v-for="(item,index) in targetTypeList" :key="index" :value="item.code">{{ item.dispName }}</a-radio>
  25. </a-radio-group>
  26. </a-form-model-item>
  27. </a-col>
  28. <a-col :md="12" :sm="24" v-if="!isEdit">
  29. <a-form-model-item label="调往对象名称" :prop="isDealer||isDepartment ? 'targetSn' : 'targetName'">
  30. <a-select
  31. v-if="isDealer"
  32. show-search
  33. id="allocateBill-basicInfo-dealerName"
  34. v-model="form.targetSn"
  35. placeholder="请选择经销商"
  36. :filter-option="false"
  37. :not-found-content="fetching ? undefined : null"
  38. @search="fetchUser"
  39. @change="handleChange"
  40. >
  41. <a-spin v-if="fetching" slot="notFoundContent" size="small" />
  42. <a-select-option v-for="item in dealerData" :key="item.dealerSn" :value="item.dealerSn">{{ item.dealerName }}</a-select-option>
  43. </a-select>
  44. <department v-else-if="isDepartment" style="width: 100%;" placeholder="请选择部门" @change="departementChange" v-model="form.targetSn"></department>
  45. <a-input v-else v-model="form.targetName" placeholder="请输入调往对象名称(最多30个字符)" :maxLength="30"></a-input>
  46. </a-form-model-item>
  47. </a-col>
  48. <a-col :md="12" :sm="24" v-if="!isEdit">
  49. <a-form-model-item label="调出仓库" prop="warehouseSn">
  50. <warehouse
  51. isPermission
  52. v-model="form.warehouseSn"
  53. ref="warehouse"
  54. id="allocateBill-basicInfo-warehouseSn"
  55. placeholder="请选择调出仓库"
  56. />
  57. </a-form-model-item>
  58. </a-col>
  59. <a-col :md="12" :sm="24">
  60. <a-form-model-item label="费用/调拨类型" prop="costTypeSn">
  61. <AllocateType id="allocateBill-basicInfo-allocateTypeSn" v-model="allocateTypeVal" placeholder="请选择费用/调拨类型" @change="allocateTypeChange"></AllocateType>
  62. </a-form-model-item>
  63. </a-col>
  64. <a-col :md="12" :sm="24">
  65. <a-form-model-item
  66. label="费用归属品牌"
  67. prop="productBrandSn"
  68. :required="form.costTypeName=='促销费用'"
  69. >
  70. <ProductBrand id="allocateBill-basicInfo-productBrandSn" @change="changeBrand" showAllBrand v-model="form.productBrandSn" placeholder="请选择费用归属品牌(单选)"></ProductBrand>
  71. </a-form-model-item>
  72. </a-col>
  73. <a-col :md="12" :sm="24">
  74. <a-form-model-item
  75. label="费用归属品类"
  76. prop="productTypeSn2"
  77. :required="form.costTypeName=='促销费用'"
  78. >
  79. <productTypeAll
  80. :isAll="true"
  81. placeholder="请选择费用归属品类(单选,至少选到二级或三级)"
  82. showAllType
  83. @change="changeProductType"
  84. v-model="productType"
  85. id="allocateBill-basicInfo-productType"></productTypeAll>
  86. </a-form-model-item>
  87. </a-col>
  88. <a-col :md="12" :sm="24">
  89. <a-form-model-item label="起止时间" prop="time">
  90. <a-range-picker
  91. style="width:100%"
  92. v-model="form.time"
  93. :format="dateFormat"
  94. @change="dateChange"
  95. :placeholder="['开始时间', '结束时间']" />
  96. </a-form-model-item>
  97. </a-col>
  98. <a-col :md="24" :sm="24">
  99. <a-form-model-item style="margin-bottom:10px;" label="备注" prop="remark" :wrapperCol="{ span: 20 }" :labelCol="{ span: 4 }">
  100. <a-textarea id="allocateBill-basicInfo-remark" :maxLength="100" v-model="form.remark" placeholder="请输入备注(最多100个字符)" allowClear />
  101. </a-form-model-item>
  102. </a-col>
  103. <a-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  104. <a-form-model-item label="附件" help="(支持图片、word、excel、PDF等格式,最多10个附件)" :label-col="{span:4}" :wrapper-col="{span:18}">
  105. <Upload
  106. style="height: 100%;"
  107. id="allocateBill-attachList"
  108. v-model="form.attachmentList"
  109. ref="attachList"
  110. :fileSize="10"
  111. :maxNums="10"
  112. fileType="*"
  113. uploadType="attach"
  114. :action="attachAction"
  115. @change="changeAttach"
  116. upText="上传附件"></Upload>
  117. </a-form-model-item>
  118. </a-col>
  119. </a-row>
  120. </a-form-model>
  121. <div class="btn-cont">
  122. <a-button type="primary" :loading="spinning" id="allocateBill-basicInfo-modal-save" @click="handleSave">保存</a-button>
  123. <a-button id="allocateBill-basicInfo-modal-back" @click="isShow = false" style="margin-left: 15px;">取消</a-button>
  124. </div>
  125. </a-spin>
  126. </a-modal>
  127. </template>
  128. <script>
  129. import { commonMixin } from '@/utils/mixin'
  130. import debounce from 'lodash/debounce'
  131. import { VSelect, Upload } from '@/components'
  132. import { allocateBillSave } from '@/api/allocateBill'
  133. import { dealerSubareaScopeList } from '@/api/dealer'
  134. import { getLookUpData } from '@/api/data'
  135. import ProductBrand from '@/views/common/productBrand.js'
  136. import productTypeAll from '@/views/common/productTypeAll.js'
  137. import AllocateType from '@/views/common/allocateType.js'
  138. import warehouse from '@/views/common/chooseWarehouse.js'
  139. import department from '@/views/expenseManagement/expenseReimbursement/department.js'
  140. export default {
  141. name: 'TransferOutBasicInfoModal',
  142. mixins: [commonMixin],
  143. components: { VSelect, Upload, ProductBrand, productTypeAll, AllocateType, department, warehouse },
  144. props: {
  145. openModal: {
  146. // 弹框显示状态
  147. type: Boolean,
  148. default: false
  149. },
  150. detailData: Object
  151. },
  152. data () {
  153. this.lastFetchId = 0
  154. this.fetchUser = debounce(this.fetchUser, 800)
  155. return {
  156. isShow: this.openModal, // 是否打开弹框
  157. spinning: false,
  158. formItemLayout: {
  159. labelCol: { span: 8 },
  160. wrapperCol: { span: 16 }
  161. },
  162. productType: [],
  163. attachList: [],
  164. attachAction: process.env.VUE_APP_API_BASE_URL + '/uploadGetFileInfo',
  165. form: {
  166. targetType: 'DEALER',
  167. targetSn: undefined,
  168. targetName: '',
  169. costTypeSn: '',
  170. allocateTypeSn: '',
  171. allocateSortSn: '',
  172. warehouseSn: undefined, // 仓库
  173. productBrandSn: undefined, // 产品品牌
  174. productTypeSn1: '', // 产品一级分类
  175. productTypeSn2: '', // 产品二级分类
  176. productTypeSn3: '', // 产品三级分类
  177. time: [],
  178. promoStartDate: '',
  179. promoEndDate: '',
  180. remark: '',
  181. attachmentList: ''
  182. },
  183. rules: {
  184. targetType: [{ required: true, message: '请选择调往对象', trigger: 'change' }],
  185. targetSn: [{ required: true, message: '请选择调往对象名称', trigger: 'change' }],
  186. costTypeSn: [{ required: true, message: '请选择费用/调拨类型', trigger: 'change' }],
  187. warehouseSn: [{ required: true, message: '请选择调出仓库', trigger: 'change' }],
  188. targetName: [{ required: true, message: '请输入调往对象名称', trigger: 'blur' }]
  189. },
  190. fetching: false,
  191. dealerData: [], // 经销商 下拉数据
  192. targetTypeList: [], // 调往对象类型
  193. allocateTypeVal: [],
  194. dateFormat: 'YYYY-MM-DD',
  195. isEdit: false
  196. }
  197. },
  198. computed: {
  199. // 当前所选调往对象是否为经销商
  200. isDealer () {
  201. return this.form.targetType == 'DEALER'
  202. },
  203. isDepartment () {
  204. return this.form.targetType == 'DEPARTMENT'
  205. }
  206. },
  207. methods: {
  208. // 日期 change
  209. dateChange (date, dateStrings) {
  210. console.log(date, dateStrings)
  211. this.form.time = dateStrings
  212. this.form.promoStartDate = date.length ? dateStrings[0] : ''
  213. this.form.promoEndDate = date.length ? dateStrings[1] : ''
  214. },
  215. // 附件上传
  216. changeAttach (file) {
  217. this.attachList = JSON.parse(file)
  218. this.attachList.map(item => {
  219. item.fileType = item.extName
  220. })
  221. },
  222. departementChange (v, row) {
  223. console.log(v, row)
  224. this.form.targetName = row.name
  225. },
  226. // 调拨类别 change
  227. allocateTypeChange (val, opt) {
  228. console.log(val, opt, '------------')
  229. this.allocateTypeVal = val || ''
  230. this.form.costTypeSn = val && val[0] ? val[0] : ''
  231. this.form.allocateSortSn = val && val[1] ? val[1] : ''
  232. this.form.allocateTypeSn = val && val[2] ? val[2] : ''
  233. // 名称
  234. this.form.costTypeName = opt && opt[0] ? opt[0].name : ''
  235. this.form.allocateSortName = opt && opt[1] ? opt[1].name : ''
  236. this.form.allocateTypeName = opt && opt[2] ? opt[2].name : ''
  237. // 校验规则
  238. this.$refs.ruleForm.clearValidate()
  239. this.valiadBranType()
  240. },
  241. valiadBranType () {
  242. if (this.form.costTypeName == '促销费用') {
  243. this.rules.productBrandSn = [{ required: true, message: '请选择归属品牌', trigger: 'change' }]
  244. this.rules.productTypeSn2 = [{ required: true, message: '请选择归属分类(至少选择到2级或3级分类)', trigger: 'change' }]
  245. } else {
  246. this.rules.productBrandSn = []
  247. this.rules.productTypeSn2 = []
  248. }
  249. },
  250. // 产品分类 change
  251. changeProductType (val, id, opt) {
  252. console.log(val, opt, '------------')
  253. this.form.productTypeSn1 = val && val[0] ? val[0] : ''
  254. this.form.productTypeSn2 = val && val[1] ? val[1] : ''
  255. this.form.productTypeSn3 = val && val[2] ? val[2] : ''
  256. // 名称
  257. this.form.productTypeName1 = opt && opt[0] ? opt[0].productTypeName : ''
  258. this.form.productTypeName2 = opt && opt[1] ? opt[1].productTypeName : ''
  259. this.form.productTypeName3 = opt && opt[2] ? opt[2].productTypeName : ''
  260. },
  261. // 品牌
  262. changeBrand (val, id, opt) {
  263. this.form.productBrandName = opt ? opt.brandName : ''
  264. },
  265. fetchUser (dealerName) {
  266. if (dealerName == '') return
  267. this.lastFetchId += 1
  268. const fetchId = this.lastFetchId
  269. this.dealerData = []
  270. this.fetching = true
  271. dealerSubareaScopeList({ nameLike: dealerName.replace(/\s+/g, ''), pageNo: 1, pageSize: 20 }).then(res => {
  272. if (fetchId !== this.lastFetchId) {
  273. return
  274. }
  275. this.dealerData = res.data && res.data.list ? res.data.list : []
  276. this.fetching = false
  277. })
  278. },
  279. // 调往对象名称经销商 change
  280. handleChange (value) {
  281. const ind = this.dealerData.findIndex(item => item.dealerSn == value)
  282. this.form.targetName = this.dealerData[ind].dealerName
  283. const wsn = this.dealerData[ind].defaultWarehouseSn
  284. if (this.$refs.warehouse.hasWarehouse(wsn)) {
  285. this.form.warehouseSn = wsn
  286. } else {
  287. this.form.warehouseSn = undefined
  288. }
  289. },
  290. // 保存
  291. handleSave () {
  292. const _this = this
  293. this.$refs.ruleForm.validate(valid => {
  294. if (valid) {
  295. const form = JSON.parse(JSON.stringify(_this.form))
  296. if (!form.productBrandName) {
  297. form.productBrandSn = ''
  298. }
  299. form.attachmentList = this.attachList
  300. // 判断费用归属品类 最少要选择到2级或3级分类
  301. if (_this.form.productTypeSn1 && !_this.form.productTypeSn2) {
  302. _this.$message.warning('请选择归属分类(至少选择到2级或3级分类)')
  303. return false
  304. }
  305. _this.spinning = true
  306. allocateBillSave(form).then(res => {
  307. if (res.status == 200) {
  308. _this.$message.success(res.message)
  309. _this.isShow = false
  310. _this.$emit('ok', res.data)
  311. }
  312. _this.spinning = false
  313. })
  314. } else {
  315. _this.spinning = false
  316. return false
  317. }
  318. })
  319. },
  320. // 调往对象 change
  321. targetTypeChange (e) {
  322. this.form.targetSn = undefined
  323. this.form.targetName = ''
  324. this.form.warehouseSn = undefined
  325. this.form.targetType = e.target.value
  326. },
  327. // 调往对象类型
  328. getTargetTypeList () {
  329. const _this = this
  330. getLookUpData({
  331. pageNo: 1,
  332. pageSize: 1000,
  333. lookupCode: 'TARGET_TYPE'
  334. }).then(res => {
  335. if (res.status == 200) {
  336. _this.targetTypeList = res.data.list
  337. } else {
  338. _this.targetTypeList = []
  339. }
  340. })
  341. }
  342. },
  343. watch: {
  344. // 父页面传过来的弹框状态
  345. openModal (newValue, oldValue) {
  346. this.isShow = newValue
  347. },
  348. // 重定义的弹框状态
  349. isShow (newValue, oldValue) {
  350. if (!newValue) {
  351. this.$emit('close')
  352. this.$refs.ruleForm.resetFields()
  353. this.allocateTypeVal = []
  354. this.productType = []
  355. this.attachList = []
  356. this.rules.productBrandSn = []
  357. this.rules.productTypeSn2 = []
  358. this.form.attachmentList = ''
  359. this.$refs.attachList.setFileList('')
  360. this.form = {
  361. targetType: 'DEALER',
  362. targetSn: undefined,
  363. targetName: '',
  364. costTypeSn: '',
  365. allocateTypeSn: '',
  366. allocateSortSn: '',
  367. warehouseSn: undefined,
  368. productBrandSn: undefined, // 产品品牌
  369. productTypeSn1: '', // 产品一级分类
  370. productTypeSn2: '', // 产品二级分类
  371. productTypeSn3: '', // 产品三级分类
  372. time: [],
  373. promoStartDate: '',
  374. promoEndDate: '',
  375. remark: ''
  376. }
  377. } else {
  378. this.getTargetTypeList()
  379. // 编辑
  380. if (this.detailData) {
  381. this.isEdit = true
  382. this.form = Object.assign(this.form, this.detailData)
  383. // 获取附件列表
  384. this.form.attachmentList = ''
  385. this.attachList = this.detailData.attachmentList
  386. this.$nextTick(() => {
  387. this.$refs.attachList.setFileList(this.attachList)
  388. })
  389. this.allocateTypeVal = [this.detailData.costTypeSn, this.detailData.allocateSortSn, this.detailData.allocateTypeSn]
  390. if (this.detailData.productTypeSn1) {
  391. this.productType = [this.detailData.productTypeSn1, this.detailData.productTypeSn2, this.detailData.productTypeSn3]
  392. }
  393. if (this.form.promoStartDate && this.form.promoEndDate) {
  394. this.form.time = [this.form.promoStartDate, this.form.promoEndDate]
  395. }
  396. if (!this.form.productBrandSn) {
  397. this.form.productBrandSn = undefined
  398. }
  399. this.valiadBranType()
  400. }
  401. }
  402. }
  403. }
  404. }
  405. </script>
  406. <style lang="less">
  407. .allocateBill-basicInfo-modal {
  408. .ant-modal-body {
  409. padding: 40px 40px 24px;
  410. }
  411. .btn-cont {
  412. text-align: center;
  413. margin: 35px 0 10px;
  414. }
  415. }
  416. </style>