edit.vue 18 KB

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