edit.vue 18 KB

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