edit.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. <template>
  2. <div class="productInfoEdit-wrap">
  3. <a-spin :spinning="spinning" tip="Loading...">
  4. <a-page-header :ghost="false" :backIcon="false" class="productInfoEdit-back" v-if="pageType=='pages'">
  5. <!-- 自定义的二级文字标题 -->
  6. <template slot="subTitle">
  7. <a id="productInfoEdit-back-btn" href="javascript:;" @click="handleBack"><a-icon type="left" /> 返回列表</a>
  8. </template>
  9. </a-page-header>
  10. <a-card size="small" :bordered="false" class="productInfoEdit-table-page-wrapper">
  11. <a-form-model
  12. id="productInfoEdit-form"
  13. ref="ruleForm"
  14. :model="form"
  15. :rules="rules"
  16. :label-col="formItemLayout.labelCol"
  17. :wrapper-col="formItemLayout.wrapperCol"
  18. >
  19. <a-form-model-item label="供应商" v-if="pageType=='modal'">
  20. <a-input
  21. disabled
  22. v-model.trim="formData.supplierName"
  23. />
  24. </a-form-model-item>
  25. <a-form-model-item label="产品名称" prop="name">
  26. <a-input
  27. id="productInfoEdit-name"
  28. :maxLength="100"
  29. v-model.trim="form.name"
  30. placeholder="请输入产品名称(最多100个字符)"
  31. ref="name"
  32. @keydown.enter.native="nextFocus('name', 'code', $event)"
  33. allowClear />
  34. </a-form-model-item>
  35. <a-form-model-item label="产品编码" prop="code">
  36. <a-input
  37. id="productInfoEdit-code"
  38. :maxLength="100"
  39. :disabled="isEdit"
  40. v-model.trim="form.code"
  41. placeholder="请输入产品编码(最多100个字符)"
  42. ref="code"
  43. @keydown.enter.native="nextFocus('code', 'origCode', $event)"
  44. allowClear />
  45. </a-form-model-item>
  46. <a-form-model-item label="原厂编码" prop="origCode">
  47. <a-input
  48. id="productInfoEdit-origCode"
  49. :maxLength="200"
  50. v-model.trim="form.origCode"
  51. placeholder="请输入原厂编码(最多200个字符,多个编码用逗号隔开)"
  52. ref="origCode"
  53. @keydown.enter.native="nextFocus('origCode', 'unit', $event)"
  54. allowClear />
  55. </a-form-model-item>
  56. <a-form-model-item label="基本单位" prop="unit">
  57. <a-input-group compact>
  58. <a-input
  59. style="width: 80%"
  60. v-model.trim="form.unit"
  61. id="productInfoEdit-unit-input"
  62. placeholder="请输入基本单位"
  63. ref="unit"
  64. @keydown.enter.native="nextFocus('unit', 'UNIT', $event, 'vSelect')"
  65. allowClear/>
  66. <v-select
  67. style="width: 20%"
  68. code="UNIT"
  69. @change="unitChange"
  70. id="productInfoEdit-unit"
  71. ref="UNIT"
  72. @keydown.enter.native="nextFocus('UNIT', 'productBrandSn', $event)"
  73. placeholder="快速选择单位"></v-select>
  74. </a-input-group>
  75. </a-form-model-item>
  76. <a-form-model-item label="产品品牌" prop="productBrandSn">
  77. <a-select
  78. show-search
  79. id="productInfoEdit-productBrand"
  80. v-model="form.productBrandSn"
  81. placeholder="请输入名称或拼音查询,如果没有请点击 '+' 新增"
  82. :disabled="isEdit"
  83. :filter-option="false"
  84. :not-found-content="fetching ? undefined : null"
  85. @search="fetchUser"
  86. style="width: 90%;"
  87. ref="productBrandSn"
  88. @keydown.enter.native="nextFocus('productBrandSn', 'productType', $event)"
  89. >
  90. <a-spin v-if="fetching" slot="notFoundContent" size="small" />
  91. <a-select-option v-for="item in productBrandList" :key="item.brandSn" :value="item.brandSn" :disabled="item.enabledFlag==0">{{ item.brandName }}</a-select-option>
  92. </a-select>
  93. <a-button
  94. v-if="$hasPermissions('B_product_dealerProductBrand_add')"
  95. @click="openModal=true"
  96. :disabled="isEdit"
  97. icon="plus"
  98. size="small"
  99. id="productInfoEdit-add-btn"
  100. style="margin-left: 5px;"></a-button>
  101. </a-form-model-item>
  102. <a-form-model-item label="产品分类" prop="productType">
  103. <a-cascader
  104. :disabled="isEdit"
  105. @change="changeProductType"
  106. expand-trigger="hover"
  107. :options="productTypeList"
  108. :fieldNames="{ label: 'productTypeName', value: 'productTypeSn', children: 'children' }"
  109. id="productInfoEdit-productType"
  110. placeholder="请选择产品分类"
  111. allowClear
  112. v-model="form.productType"
  113. ref="productType"
  114. @keydown.enter.native="nextFocus('productType', 'specialPrice', $event)" />
  115. </a-form-model-item>
  116. <a-form-model-item label="成本价" v-if="pageType=='modal'" prop="putCost">
  117. <a-input-number
  118. id="productInfoEdit-putCost"
  119. v-model="form.putCost"
  120. :min="0"
  121. :max="999999"
  122. :precision="2"
  123. style="width: 90%;margin-right: 5px;"
  124. placeholder="请输入成本价(1~999999)"
  125. ref="putCost"
  126. @keydown.enter.native="nextFocus('putCost', 'putQty', $event)"
  127. allowClear /><span>元</span>
  128. </a-form-model-item>
  129. <a-form-model-item label="数量" v-if="pageType=='modal'" prop="putQty">
  130. <a-input-number
  131. id="productInfoEdit-specialPrice"
  132. v-model="form.putQty"
  133. :precision="0"
  134. :min="1"
  135. :max="999999"
  136. style="width: 90%;"
  137. placeholder="请输入数量(1~999999)"
  138. ref="putQty"
  139. allowClear />
  140. </a-form-model-item>
  141. <a-form-model-item v-if="pageType=='pages'" label="经销批发价" prop="specialPrice">
  142. <a-input-number
  143. id="productInfoEdit-specialPrice"
  144. v-model="form.specialPrice"
  145. :min="0"
  146. :max="999999"
  147. :precision="2"
  148. style="width: 90%;margin-right: 5px;"
  149. placeholder="请输入经销批发价(1~999999)"
  150. ref="specialPrice"
  151. @keydown.enter.native="nextFocus('specialPrice', 'terminalPrice', $event)"
  152. allowClear /><span>元</span>
  153. </a-form-model-item>
  154. <a-form-model-item v-if="pageType=='pages'" label="终端价" prop="terminalPrice">
  155. <a-input-number
  156. id="productInfoEdit-terminalPrice"
  157. v-model="form.terminalPrice"
  158. :min="0"
  159. :max="999999"
  160. :precision="2"
  161. style="width: 90%;margin-right: 5px;"
  162. placeholder="请输入终端价(1~999999)"
  163. ref="terminalPrice"
  164. @keydown.enter.native="nextFocus('terminalPrice', 'carOwnersPrice', $event)"
  165. allowClear /><span>元</span>
  166. </a-form-model-item>
  167. <a-form-model-item v-if="pageType=='pages'" label="车主价" prop="carOwnersPrice">
  168. <a-input-number
  169. id="productInfoEdit-carOwnersPrice"
  170. v-model="form.carOwnersPrice"
  171. :min="0"
  172. :max="999999"
  173. :precision="2"
  174. style="width: 90%;margin-right: 5px;"
  175. placeholder="请输入车主价(1~999999)"
  176. ref="carOwnersPrice"
  177. @keydown.enter.native="nextFocus('carOwnersPrice', '', $event)"
  178. allowClear /><span>元</span>
  179. </a-form-model-item>
  180. <a-form-model-item :wrapper-col="{ span: 12, offset: 6 }" style="text-align: center;">
  181. <a-button
  182. type="primary"
  183. :loading="saveing"
  184. @click="handleSubmit"
  185. size="large"
  186. id="productInfoEdit-btn-submit"
  187. style="padding: 0 60px;">保存</a-button>
  188. </a-form-model-item>
  189. </a-form-model>
  190. <!-- 新增/编辑产品品牌 -->
  191. <product-brand-edit-modal :openModal="openModal" @ok="handleOk" @close="openModal=false" />
  192. </a-card>
  193. </a-spin>
  194. </div>
  195. </template>
  196. <script>
  197. import { commonMixin } from '@/utils/mixin'
  198. import { STable, VSelect } from '@/components'
  199. import productBrandEditModal from '../productBrand/editModal.vue'
  200. import { dealerProductBrandQuery } from '@/api/dealerProductBrand'
  201. import { dealerProductTypeList } from '@/api/dealerProductType'
  202. import { dealerProductSave, dealerProductDetail } from '@/api/dealerProduct'
  203. export default {
  204. name: 'ProductInfoEdit',
  205. components: { STable, VSelect, productBrandEditModal },
  206. mixins: [commonMixin],
  207. props: {
  208. pageType: { // 页面表现形式,pages 新页签打开的页面,modal 弹框里的页面
  209. type: String,
  210. default: 'pages'
  211. },
  212. paramsData: {
  213. type: Object,
  214. default: function () {
  215. return null
  216. }
  217. },
  218. saveing: {
  219. type: Boolean,
  220. default: false
  221. }
  222. },
  223. computed: {
  224. isEdit () {
  225. return this.pageType == 'pages' ? !!this.$route.params.id : false
  226. }
  227. },
  228. data () {
  229. return {
  230. spinning: false,
  231. formItemLayout: {
  232. labelCol: { span: 4 },
  233. wrapperCol: { span: 16 }
  234. },
  235. formData: this.paramsData,
  236. form: {
  237. name: '', // 产品名称
  238. code: '', // 产品编码
  239. origCode: '', // 原厂编码
  240. unit: '', // 基本单位
  241. productBrandSn: undefined, // 产品品牌
  242. productTypeSn3: '', // 产品三级分类
  243. productType: [], // 产品分类
  244. specialPrice: '', // 经销价
  245. terminalPrice: '', // 终端价
  246. carOwnersPrice: '', // 车主价
  247. putCost: '',
  248. putQty: ''
  249. },
  250. rules: {
  251. name: [
  252. { required: true, message: '请输入产品名称', trigger: 'blur' }
  253. ],
  254. code: [
  255. { required: true, message: '请输入产品编码', trigger: 'blur' }
  256. ],
  257. productBrandSn: [
  258. { required: true, message: '请选择产品品牌', trigger: 'change' }
  259. ],
  260. productType: [
  261. { required: true, message: '请选择产品分类', trigger: 'change' }
  262. ],
  263. putCost: [
  264. { required: true, type: 'number', message: '请输入成本价', trigger: 'change' }
  265. ],
  266. putQty: [
  267. { required: true, type: 'number', message: '请输入数量', trigger: 'change' }
  268. ]
  269. },
  270. fetching: false,
  271. productBrandList: [], // 品牌下拉数据
  272. productTypeList: [], // 分类下拉数据
  273. openModal: false // 新增编辑 弹框
  274. }
  275. },
  276. methods: {
  277. // 搜索品牌
  278. fetchUser (value) {
  279. console.log('fetching user', value)
  280. this.fetching = true
  281. dealerProductBrandQuery({ 'queryWord': value }).then(res => {
  282. if (res.status == 200) {
  283. this.productBrandList = res.data || []
  284. this.fetching = false
  285. } else {
  286. this.productBrandList = []
  287. this.fetching = false
  288. }
  289. })
  290. },
  291. filterEmpty () {
  292. let str = this.form.name
  293. str = str.replace(/\ +/g, '')
  294. str = str.replace(/[ ]/g, '')
  295. str = str.replace(/[\r\n]/g, '')
  296. this.form.name = str
  297. },
  298. // 选择单位
  299. unitChange (a, b) {
  300. this.form.unit = b.dispName
  301. },
  302. // 获取产品信息
  303. getGoodsDetail () {
  304. dealerProductDetail({ id: this.$route.params.id }).then(res => {
  305. if (res.status == 200) {
  306. this.form = Object.assign(this.form, res.data)
  307. const productTypeSn1 = res.data.productTypeSn1 ? res.data.productTypeSn1 : ''
  308. const productTypeSn2 = res.data.productTypeSn2 ? res.data.productTypeSn2 : ''
  309. const productTypeSn3 = res.data.productTypeSn3 ? res.data.productTypeSn3 : ''
  310. this.form.productType = [productTypeSn1, productTypeSn2, productTypeSn3]
  311. if (res.data.productBrandName) {
  312. this.fetchUser(res.data.productBrandName)
  313. }
  314. } else {
  315. this.$refs.ruleForm.resetFields()
  316. }
  317. })
  318. },
  319. // 保存
  320. handleSubmit (e) {
  321. e.preventDefault()
  322. const _this = this
  323. this.$refs.ruleForm.validate(valid => {
  324. if (valid) {
  325. const form = JSON.parse(JSON.stringify(_this.form))
  326. if (!form.productTypeSn3) {
  327. this.$message.warning('产品分类未选到第三级,请修改后再提交!')
  328. return false
  329. }
  330. // 编辑
  331. if (this.isEdit) {
  332. form.id = _this.$route.params.id ? _this.$route.params.id : undefined
  333. }
  334. delete form.productType
  335. _this.spinning = true
  336. dealerProductSave(form).then(res => {
  337. if (res.status == 200) {
  338. _this.$message.success(res.message)
  339. if (_this.pageType == 'pages') {
  340. _this.$router.push({ path: '/productManagement/productInfo/list' })
  341. _this.spinning = false
  342. } else {
  343. _this.$emit('saveOk', _this.form)
  344. }
  345. } else {
  346. _this.spinning = false
  347. }
  348. })
  349. } else {
  350. console.log('error submit!!')
  351. return false
  352. }
  353. })
  354. },
  355. // 回车键快捷定位表单下一项
  356. nextFocus (nowRef, nextRef, event, isComponent) {
  357. const _this = this
  358. if (_this.$refs[nowRef]) {
  359. _this.$nextTick(() => {
  360. if (_this.$refs[nextRef]) {
  361. event.target.blur()
  362. if (isComponent == 'vSelect') {
  363. _this.$refs[nextRef].$children[0].focus()
  364. } else {
  365. _this.$refs[nextRef].focus()
  366. }
  367. }
  368. })
  369. }
  370. },
  371. // 产品分类 change
  372. changeProductType (val, opt) {
  373. this.form.productTypeSn3 = val[2] ? val[2] : ''
  374. },
  375. // 新增品牌 成功
  376. handleOk () {
  377. // 获取品牌数据列表,并赋值
  378. this.getProductBrand('val')
  379. },
  380. filterOption (input, option) {
  381. return (
  382. option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
  383. )
  384. },
  385. // 返回
  386. handleBack () {
  387. this.$router.push({ path: '/productManagement/productInfo/list' })
  388. },
  389. // 产品品牌 列表
  390. getProductBrand (val) {
  391. dealerProductBrandQuery({}).then(res => {
  392. if (res.status == 200) {
  393. this.productBrandList = res.data
  394. if (val) { // 需将新增加的品牌回填到产品品牌的地方,即不需要用户再选一下
  395. this.form.productBrandSn = this.productBrandList[0].brandSn
  396. this.$refs.ruleForm.clearValidate('productBrandSn')
  397. }
  398. }
  399. })
  400. },
  401. // 产品分类 列表
  402. getProductType () {
  403. dealerProductTypeList({}).then(res => {
  404. if (res.status == 200) {
  405. this.productTypeList = res.data
  406. } else {
  407. this.productTypeList = []
  408. }
  409. })
  410. },
  411. pageInit () {
  412. this.getProductType()
  413. this.$refs.ruleForm.resetFields()
  414. // 默认首项获取焦点
  415. const _this = this
  416. setTimeout(() => {
  417. if (_this.$refs['name']) {
  418. _this.$refs['name'].focus()
  419. }
  420. }, 300)
  421. if (this.$route.params.id) { // 编辑页
  422. this.getGoodsDetail()
  423. }
  424. // 如果是其它页面新建产品
  425. if (this.pageType == 'modal') {
  426. this.form = Object.assign(this.form, this.formData)
  427. }
  428. }
  429. },
  430. mounted () {
  431. if (!this.$store.state.app.isNewTab) { // 页签刷新时调用
  432. this.pageInit()
  433. }
  434. },
  435. activated () {
  436. // 如果是新页签打开或者进入新的子页(例:存在列表第2条数据编辑页页签时再打开第4条数据的编辑页),则重置当前页面
  437. if (this.$store.state.app.isNewTab || !this.$store.state.app.isNewSubTab) {
  438. this.pageInit()
  439. }
  440. },
  441. beforeRouteEnter (to, from, next) {
  442. next(vm => {})
  443. }
  444. }
  445. </script>
  446. <style lang="less">
  447. .productInfoEdit-wrap{
  448. height: 100%;
  449. >.ant-spin-nested-loading{
  450. height: 100%;
  451. .ant-spin-container{
  452. height: 90%;
  453. }
  454. }
  455. .productInfoEdit-table-page-wrapper{
  456. height: 100%;
  457. }
  458. .productInfoEdit-back{
  459. margin-bottom: 10px;
  460. }
  461. }
  462. </style>