index.vue 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. <template>
  2. <div v-loading="loading">
  3. <div class="white-box">
  4. <div class="filter-box">
  5. <filter-user :filter-types="filterTypes" @select-value="handleFilterUser"></filter-user>
  6. </div>
  7. <el-table class="table-box" ref="multipleTable" :data="tableData" stripe style="width: 100%;" :height="tool.getTableHeight()" @selection-change="handleSelectionChange">
  8. <el-table-column fixed type="selection" width="55" v-if="tableHeaders" :selectable="checkSelectable"></el-table-column>
  9. <el-table-column v-for="(tableHeader, key) in tableHeaders" :key="key" :label="tableHeader.header" :width="tableHeader.other.width ? tableHeader.other.width : ''" :prop="tableHeader.other.prop ? tableHeader.other.prop : null">
  10. <template slot-scope="scope">
  11. <template v-if="scope.row[tableHeader.index].other.tag" >
  12. <el-tag :type="scope.row[tableHeader.index].other.tag.type ? scope.row[tableHeader.index].other.tag.type : null" :size="scope.row[tableHeader.index].other.tag.size ? scope.row[tableHeader.index].other.tag.size : null" :class="scope.row[tableHeader.index].other.tag.class ? scope.row[tableHeader.index].other.tag.class : null" >{{scope.row[tableHeader.index].value}}</el-tag>
  13. </template>
  14. <template v-else>
  15. <div v-html="scope.row[tableHeader.index].value"></div>
  16. </template>
  17. </template>
  18. </el-table-column>
  19. <el-table-column fixed="right" label="操作" width="180">
  20. <template slot-scope="scope">
  21. <el-dropdown size="small" trigger="click" v-if="permission.hasPermission(`shop/goods-edit`) || permission.hasPermission(`shop/goods-delete`)">
  22. <el-button type="primary" size="small" @click.stop="">
  23. 操作该数据<i class="el-icon-arrow-down el-icon--right"></i>
  24. </el-button>
  25. <el-dropdown-menu slot="dropdown">
  26. <el-dropdown-item command="goods-edit" @click.native="handleEditShow(scope.row)">修改数据 </el-dropdown-item>
  27. <el-dropdown-item command="del" @click.native="handleDel(scope.row.ID)"
  28. v-show="permission.hasPermission(`shop/goods-delete`)">删除数据
  29. </el-dropdown-item>
  30. <el-dropdown-item command="goods-edit" @click.native="handleGoodUp(scope.row.ID)">商品上架 </el-dropdown-item>
  31. <el-dropdown-item command="goods-edit" @click.native="handleGoodDown(scope.row.ID)">商品下架 </el-dropdown-item>
  32. <el-dropdown-item command="goods-edit" @click.native="handleEditShowGoodsTimes(scope.row)">商品限时 </el-dropdown-item>
  33. </el-dropdown-menu>
  34. </el-dropdown>
  35. </template>
  36. </el-table-column>
  37. <!-- <el-table-column label="操作">
  38. <template slot-scope="scope">
  39. <el-button type="success" size="small" @click="handleGroupManage(scope.row)" >
  40. 状态管理
  41. </el-button>
  42. </template></el-table-column>-->
  43. </el-table>
  44. <div class="white-box-footer">
  45. <!-- <el-dropdown size="small" trigger="click">
  46. <el-button type="primary" size="small">
  47. 所选数据<i class="el-icon-arrow-down el-icon&#45;&#45;right"></i>
  48. </el-button>
  49. <el-dropdown-menu slot="dropdown">
  50. <el-dropdown-item command="delete" @click.native="handleMuliDel()">上架</el-dropdown-item>
  51. </el-dropdown-menu>
  52. </el-dropdown>-->
  53. <el-button type="primary" size="small" @click="handlestate" icon="el-icon-plus"
  54. v-if="permission.hasPermission(`shop/goods-add`)">商品添加
  55. </el-button>
  56. <el-button type="success" size="small" @click="handleExport" v-show="permission.hasPermission(`shop/goods-list-export`)">导出Excel</el-button>
  57. <!-- <el-button-group>
  58. <el-button type="success" size="mini" @click.native="handleup(scope.row.ID)">上架</el-button>
  59. <el-button type="danger" size="mini">下架</el-button>
  60. </el-button-group> -->
  61. <pagination :total="totalCount" :page_size="pageSize" @size-change="handleSizeChange" @current-change="handleCurrentChange"></pagination>
  62. </div>
  63. </div>
  64. <el-dialog title="修改套餐" :visible.sync="dialogEditFormVisible">
  65. <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoading">
  66. <el-form-item label="商品名称">
  67. <el-input v-model="form.goodsName"></el-input>
  68. </el-form-item>
  69. <el-form-item label="商品来源">
  70. <el-select v-model="form.type">
  71. <el-option v-for="(item,index) in goodsType" :key="index" :label="item.name" :value="index"></el-option>
  72. </el-select>
  73. </el-form-item>
  74. <el-form-item label="会员折扣">
  75. <el-input v-model="form.sellDiscount"></el-input>
  76. </el-form-item>
  77. <el-form-item label="商品类型">
  78. <el-checkbox v-for="(value,index) in GiftTypeArr" v-model="value.checked" :key="index" v-show="(index%2)!=0">{{value.name}}</el-checkbox>
  79. </el-form-item>
  80. <el-form-item label="报单类型">
  81. <el-radio-group v-model="form.reconsumeType">
  82. <el-radio v-for="(value,index) in GiftTypeArr" :label="index" :key="index" v-show="(index%2)==0">{{value.name}}</el-radio>
  83. <el-radio :label="null">无</el-radio>
  84. </el-radio-group>
  85. </el-form-item>
  86. <!-- <el-form-item label="复消购买方式">
  87. <el-checkbox v-for="(value,index) in sell_type" v-model="value.checked" :key="index" >{{value.name}}</el-checkbox>
  88. </el-form-item> -->
  89. <el-form-item label="PV分期">
  90. <!-- <el-checkbox v-model="form.pvSplit" :checked="form.pvSplit">Yes</el-checkbox>-->
  91. <el-select v-model="form.pvSplit" placeholder="">
  92. <el-option
  93. v-for="item in pvSplitOptions"
  94. :key="item.value"
  95. :label="item.label"
  96. :value="item.value">
  97. </el-option>
  98. </el-select>
  99. </el-form-item>
  100. <el-form-item label="商品编号">
  101. <el-input v-model="form.goodsNo"></el-input>
  102. </el-form-item>
  103. <el-form-item label="单位">
  104. <el-input v-model="form.unit"></el-input>
  105. </el-form-item>
  106. <el-form-item label="市场价格">
  107. <el-input v-model="form.marketPrice"></el-input>
  108. </el-form-item>
  109. <el-form-item label="销售价格" >
  110. <el-input v-model="form.sellPrice"></el-input>
  111. </el-form-item>
  112. <el-form-item label="价格PV">
  113. <el-input v-model="form.pricePv"></el-input>
  114. </el-form-item>
  115. <el-form-item label="兑换积分" v-show="false">
  116. <el-input v-model="form.point"></el-input>
  117. </el-form-item>
  118. <el-form-item label="库存">
  119. <el-input v-model="form.storeNums"></el-input>
  120. </el-form-item>
  121. <el-form-item label="商品详情">
  122. <el-input
  123. type="textarea"
  124. :rows="2"
  125. placeholder="请输入内容"
  126. v-model="form.content">
  127. </el-input>
  128. </el-form-item>
  129. <el-form-item label="排序">
  130. <el-input v-model="form.sort"></el-input>
  131. </el-form-item>
  132. <el-form-item label="上传图片">
  133. <div class='up_load'>
  134. <!-- <img v-if="form.cover&&img_show" :src="form.cover" alt=""> -->
  135. <leo-uploader
  136. @on-success='upLoadSuccess'
  137. :request-route="'shop/upload'"
  138. ref='up_load'
  139. :defaultImageUrl='form.cover'
  140. ></leo-uploader>
  141. </div>
  142. </el-form-item>
  143. </el-form>
  144. <div slot="footer" class="dialog-footer">
  145. <el-button @click="dialogEditFormVisible = false">取 消</el-button>
  146. <el-button type="primary" @click.native="handleEdit">修 改</el-button>
  147. </div>
  148. </el-dialog>
  149. <el-dialog title="商品限时" :visible.sync="dialogEditFormVisibleGoodsTimes">
  150. <el-form :model="form" label-width="250px" class="form-dialog" v-loading="dialogEditLoadingGoodsTimes">
  151. <el-form-item label="是否限时">
  152. <el-switch
  153. v-model="form.statusdate"
  154. active-value="1"
  155. inactive-value="0">
  156. </el-switch>
  157. </el-form-item>
  158. <transition name="el-zoom-in-top">
  159. <el-form-item label="限时时间" v-show='form.statusdate==1?true:false'>
  160. <el-date-picker
  161. v-model="form.goodsdate"
  162. type="datetime"
  163. placeholder="选择日期时间"
  164. value-format="timestamp"
  165. popper-class='goodsdate'>
  166. </el-date-picker>
  167. </el-form-item>
  168. </transition>
  169. <transition name="el-zoom-in-top">
  170. <el-form-item label="限时类型" v-show='form.statusdate==1?true:false'>
  171. <el-radio v-model="form.goodsstatusdate" label="0" border>下架</el-radio>
  172. <el-radio v-model="form.goodsstatusdate" label="1" border>上架</el-radio>
  173. </el-form-item>
  174. </transition>
  175. </el-form>
  176. <div slot="footer" class="dialog-footer">
  177. <el-button @click="dialogEditFormVisibleGoodsTimes = false">取 消</el-button>
  178. <el-button type="primary" @click.native="handleEdit">修 改</el-button>
  179. </div>
  180. </el-dialog>
  181. </div>
  182. </template>
  183. <script>
  184. import network from '@/utils/network'
  185. import tool from '@/utils/tool'
  186. import baseInfo from '@/utils/baseInfo'
  187. import FilterUser from '../../components/FilterUser'
  188. import permission from '@/utils/permission'
  189. import Pagination from '@/components/Pagination'
  190. import filterHelper from '@/utils/filterHelper'
  191. import {FRONTEND_SERVER} from '@/utils/config'
  192. import store from './../../utils/vuexStore'
  193. import LeoUploader from '@/components/Uploader'
  194. export default {
  195. name: 'index',
  196. components: {FilterUser,Pagination,LeoUploader},
  197. mounted () {
  198. this.getData()
  199. // this.$refs.up_load.successImageUrl='';
  200. },
  201. data () {
  202. return {
  203. tableHeaders: null,
  204. tableData: null,
  205. loading: true,
  206. currentPage: 1,
  207. totalPages: 1,
  208. totalCount: 1,
  209. pageSize: 20,
  210. multipleSelection: [],
  211. tool: tool,
  212. permission: permission,
  213. baseDecLevels: baseInfo.decLevels(),
  214. baseEmpLevels: baseInfo.empLevels(),
  215. filterTypes: null,
  216. dialogVisible: false,
  217. dialogLoading: false,
  218. filterModel: {},
  219. value: [],
  220. selectedIds: '',
  221. dialogEditFormVisible: false,
  222. dialogEditLoading: false,
  223. dialogEditFormVisibleGoodsTimes: false,
  224. dialogEditLoadingGoodsTimes: false,
  225. pvSplitOptions: [
  226. {
  227. value: '0',
  228. label: 'No'
  229. },
  230. {
  231. value: '1',
  232. label: 'Yes'
  233. }],
  234. form: {
  235. sellType: [],
  236. goodsName: '',
  237. type: '',
  238. giftType: [],
  239. goodsNo: '',
  240. unit: '',
  241. marketPrice: '',
  242. sellPrice: '',
  243. pricePv: '',
  244. point: '',
  245. storeNums: '',
  246. content: '',
  247. sort: '',
  248. discount: '',
  249. cover: '',
  250. textarea: '',
  251. sellDiscount: '',
  252. pvSplit: '',
  253. statusdate: '',
  254. goodsstatusdate: '',
  255. goodsdate: '',
  256. reconsumeType: null
  257. },
  258. submitButtonStat: false,
  259. goodsType: [],
  260. GiftTypeArr: [],
  261. sell_type: [],
  262. img_show: true
  263. }
  264. },
  265. methods: {
  266. handleSelectionChange (val) {
  267. this.multipleSelection = val
  268. },
  269. handleCurrentChange (page) {
  270. this.getData(page, this.pageSize)
  271. },
  272. handleSizeChange (pageSize) {
  273. this.getData(this.currentPage, pageSize)
  274. },
  275. handleFilterUser (filterData) {
  276. filterHelper.handleFilterUser(this, filterData)
  277. },
  278. checkSelectable (row) {
  279. return row.DONT_DEL !== '1'
  280. },
  281. handleFilter () {
  282. this.getData()
  283. },
  284. handlestate () {
  285. this.$router.push({path: `/shop/goods-add`})
  286. },
  287. upLoadSuccess (file) {
  288. this.form.cover = tool.getLocaleLink(file, '/files/')
  289. this.form.coverOrigin = file
  290. this.img_show = false
  291. },
  292. handleEditShow (row) {
  293. this.dialogEditLoading = true
  294. this.auditId = row.ID
  295. this.dialogEditFormVisible = true
  296. let vueObj = this
  297. network.getData('shop/goods-edit', {id: this.auditId}).then(response => {
  298. vueObj.dialogEditLoading = false
  299. vueObj.goodsType = response.goodsType
  300. let gift = response.goodsInfo.GIFT_TYPE
  301. let gift_type = response.giftType
  302. let giftType = []
  303. if (gift.length > 0) {
  304. for (let i in gift_type) {
  305. giftType.push({key: i, name: gift_type[i].name, checked: false})
  306. gift.map((v, k) => {
  307. if (v == i) {
  308. giftType[i - 1].checked = true
  309. }
  310. })
  311. }
  312. for (let j in gift) {
  313. if (gift[j] % 2 != 0) {
  314. vueObj.form.reconsumeType = gift[j] - 1
  315. } else {
  316. vueObj.form.reconsumeType = null
  317. }
  318. }
  319. }
  320. vueObj.GiftTypeArr = giftType
  321. let sell = response.goodsInfo.SELL_TYPE
  322. let sell_type = response.sellType
  323. let sellType = []
  324. if (sell.length > 0) {
  325. for (let i in sell_type) {
  326. sellType.push({key: i, name: sell_type[i].name, checked: false})
  327. sell.map((item, index) => {
  328. if (item == i) {
  329. sellType[i - 1].checked = true
  330. }
  331. })
  332. }
  333. }
  334. vueObj.sell_type = sellType
  335. vueObj.form.goodsName = response.goodsInfo.GOODS_NAME
  336. vueObj.form.sellDiscount = response.goodsInfo.SELL_DISCOUNT
  337. vueObj.form.goodsNo = response.goodsInfo.GOODS_NO
  338. vueObj.form.type = response.goodsInfo.CATE_ID
  339. vueObj.form.unit = response.goodsInfo.UNIT
  340. vueObj.form.marketPrice = response.goodsInfo.MARKET_PRICE
  341. vueObj.form.sellPrice = response.goodsInfo.SELL_PRICE
  342. vueObj.form.pricePv = response.goodsInfo.PRICE_PV
  343. vueObj.form.point = response.goodsInfo.POINT
  344. vueObj.form.storeNums = response.goodsInfo.STORE_NUMS
  345. vueObj.form.content = response.goodsInfo.CONTENT
  346. vueObj.form.sort = response.goodsInfo.SORT
  347. vueObj.form.id = response.goodsInfo.ID
  348. vueObj.form.statusdate = response.goodsInfo.STATUS_DATE
  349. vueObj.form.pvSplit = response.goodsInfo.PV_SPLIT
  350. vueObj.form.goodsstatusdate = response.goodsInfo.GOODS_STATUS_DATE
  351. vueObj.form.goodsdate = response.goodsInfo.GOODS_DATE * 1000
  352. // vueObj.form.sellType=vueObj.form.sellType.map((item,index)=>{
  353. // return response.goodsInfo.SELL_TYPE.some(val=>(index+1).toString()==val)
  354. // })
  355. vueObj.form.coverOrigin = response.goodsInfo.COVER
  356. vueObj.form.cover = tool.getLocaleLink(response.goodsInfo.COVER, '/files/')
  357. this.$forceUpdate()
  358. })
  359. },
  360. /**
  361. * 2022-05-09
  362. * York
  363. * 限时商品
  364. */
  365. handleEditShowGoodsTimes (row) {
  366. this.dialogEditLoadingGoodsTimes = true
  367. this.auditId = row.ID
  368. this.dialogEditFormVisibleGoodsTimes = true
  369. let vueObj = this
  370. network.getData('shop/goods-edit', {id: this.auditId}).then(response => {
  371. vueObj.dialogEditLoadingGoodsTimes = false
  372. vueObj.goodsType = response.goodsType
  373. let gift = response.goodsInfo.GIFT_TYPE
  374. let gift_type = response.giftType
  375. let giftType = []
  376. if (gift.length > 0) {
  377. for (let i in gift_type) {
  378. giftType.push({key: i, name: gift_type[i].name, checked: false})
  379. gift.map((v, k) => {
  380. if (v == i) {
  381. giftType[i - 1].checked = true
  382. }
  383. })
  384. }
  385. }
  386. vueObj.GiftTypeArr = giftType
  387. let sell = response.goodsInfo.SELL_TYPE
  388. let sell_type = response.sellType
  389. let sellType = []
  390. if (sell.length > 0) {
  391. for (let i in sell_type) {
  392. sellType.push({key: i, name: sell_type[i].name, checked: false})
  393. sell.map((item, index) => {
  394. if (item == i) {
  395. sellType[i - 1].checked = true
  396. }
  397. })
  398. }
  399. }
  400. vueObj.sell_type = sellType
  401. vueObj.form.goodsName = response.goodsInfo.GOODS_NAME
  402. vueObj.form.sellDiscount = response.goodsInfo.SELL_DISCOUNT
  403. vueObj.form.goodsNo = response.goodsInfo.GOODS_NO
  404. vueObj.form.type = response.goodsInfo.CATE_ID
  405. vueObj.form.unit = response.goodsInfo.UNIT
  406. vueObj.form.marketPrice = response.goodsInfo.MARKET_PRICE
  407. vueObj.form.sellPrice = response.goodsInfo.SELL_PRICE
  408. vueObj.form.pricePv = response.goodsInfo.PRICE_PV
  409. vueObj.form.point = response.goodsInfo.POINT
  410. vueObj.form.storeNums = response.goodsInfo.STORE_NUMS
  411. vueObj.form.content = response.goodsInfo.CONTENT
  412. vueObj.form.sort = response.goodsInfo.SORT
  413. vueObj.form.id = response.goodsInfo.ID
  414. vueObj.form.statusdate = response.goodsInfo.STATUS_DATE
  415. vueObj.form.goodsstatusdate = response.goodsInfo.GOODS_STATUS_DATE
  416. vueObj.form.goodsdate = response.goodsInfo.GOODS_DATE * 1000
  417. vueObj.form.coverOrigin = response.goodsInfo.COVER
  418. vueObj.form.cover = tool.getLocaleLink(response.goodsInfo.COVER, '/files/')
  419. this.$forceUpdate()
  420. })
  421. },
  422. handleEdit () {
  423. this.dialogEditFormVisible = false
  424. this.dialogEditFormVisibleGoodsTimes = false
  425. this.$message({
  426. message: '正在修改数据',
  427. type: 'info'
  428. })
  429. let path = 'shop/goods-edit'
  430. let sen_sell = []
  431. this.sell_type.map((item, index) => {
  432. if (item.checked) {
  433. sen_sell.push(item.key)
  434. }
  435. })
  436. this.form.sellType = sen_sell
  437. let sen_gift = []
  438. this.GiftTypeArr.map((item, index) => {
  439. if (item.checked && (index % 2 != 0)) {
  440. sen_gift.push(item.key)
  441. }
  442. })
  443. if (this.form.reconsumeType == 0 || this.form.reconsumeType == 2){ // 复消类型,单选
  444. sen_gift.push((this.form.reconsumeType + 1).toString())
  445. }
  446. this.form.giftType = sen_gift
  447. this.form.cover = this.form.coverOrigin
  448. delete this.form.coverOrigin
  449. network.postData(path, {...this.form}).then(response => {
  450. this.$message({
  451. message: response,
  452. type: 'success'
  453. })
  454. this.getData(this.currentPage, this.pageSize)
  455. }).catch(response => {
  456. })
  457. },
  458. handleDel (id = null) {
  459. let obj = this
  460. this.$confirm('确定删除选定的数据?', '提示', {
  461. confirmButtonText: '确定',
  462. cancelButtonText: '取消',
  463. type: 'warning'
  464. }).then(() => {
  465. let selectedIds = []
  466. if (id === null) {
  467. for (let val of obj.multipleSelection) {
  468. selectedIds.push(val.ID)
  469. }
  470. } else {
  471. selectedIds.push(id)
  472. }
  473. return network.postData(`shop/goods-delete`, {
  474. selected: selectedIds
  475. })
  476. }).then(response => {
  477. this.$message({
  478. message: response,
  479. type: 'success'
  480. })
  481. obj.getData(obj.currentPage, obj.pageSize)
  482. }).catch(response => {
  483. })
  484. },
  485. getData (page, pageSize) {
  486. let filterData = this.filterModel
  487. /* this.allData = response */
  488. network.getPageData(this, 'shop/index', page, pageSize, this.filterModel, response => {
  489. // console.log(response)
  490. this.filterTypes = response.filterTypes
  491. })
  492. },
  493. handleGoodUp (id) {
  494. // console.log(id)
  495. network.postData('shop/goods-status', {selectedIds: id, status: 1})
  496. .then(response => {
  497. this.$message({
  498. message: response,
  499. type: 'success'
  500. })
  501. this.getData(this.currentPage, this.pageSize)
  502. })
  503. },
  504. handleGoodDown (id) {
  505. network.postData('shop/goods-status', {selectedIds: id, status: 0})
  506. .then(response => {
  507. this.$message({
  508. message: response,
  509. type: 'success'
  510. })
  511. this.getData(this.currentPage, this.pageSize)
  512. })
  513. },
  514. handleExport () {
  515. this.$confirm(`确定要导出当前数据吗?`, '提示', {
  516. confirmButtonText: '确定',
  517. cancelButtonText: '取消',
  518. type: 'warning'
  519. }).then(() => {
  520. return network.getData(`shop/goods-list-export`, this.filterModel)
  521. }).then(response => {
  522. this.$message({
  523. message: response,
  524. type: 'success'
  525. })
  526. }).catch(response => {
  527. })
  528. }
  529. }
  530. }
  531. </script>
  532. <style scoped>
  533. .table-box .el-form-item__label {
  534. width: 100px;
  535. color: #99a9bf;
  536. }
  537. .table-box .el-form-item {
  538. width: 30%;
  539. margin-right: 0;
  540. margin-bottom: 0;
  541. }
  542. </style>
  543. <!-- <style>
  544. .goodsdate{
  545. top: 286px !important;
  546. }
  547. </style> -->