Index.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. <template>
  2. <a-card :bordered="false">
  3. <div class="card-title">{{ $route.meta.title }}</div>
  4. <div class="table-operator">
  5. <!-- 搜索板块 -->
  6. <a-row class="row-item-search">
  7. <a-form class="search-form" :form="searchForm" layout="inline" @submit="handleSearch">
  8. <a-form-item label="商品名称">
  9. <a-input v-decorator="['goodsName']" placeholder="请输入商品名称" />
  10. </a-form-item>
  11. <a-form-item label="商品编码">
  12. <a-input v-decorator="['goodsNo']" placeholder="请输入商品编码" />
  13. </a-form-item>
  14. <a-form-item label="商品分类">
  15. <a-tree-select
  16. :treeData="categoryListTree"
  17. :dropdownStyle="{ maxHeight: '500px', overflow: 'auto' }"
  18. allowClear
  19. v-decorator="['categoryId', { initialValue: 0 }]"
  20. ></a-tree-select>
  21. </a-form-item>
  22. <a-form-item class="search-btn">
  23. <a-button type="primary" icon="search" html-type="submit">搜索</a-button>
  24. </a-form-item>
  25. <!-- <a-form-item class="search-btn">
  26. <a-button @click="handleReset">重置</a-button>
  27. </a-form-item>-->
  28. </a-form>
  29. </a-row>
  30. <!-- 操作板块 -->
  31. <div class="row-item-tab clearfix">
  32. <div class="tab-list fl-l">
  33. <a-radio-group :defaultValue="queryParam.listType" @change="handleTabs">
  34. <a-radio-button value="all">全部</a-radio-button>
  35. <a-radio-button value="on_sale">出售中</a-radio-button>
  36. <a-radio-button value="off_sale">已下架</a-radio-button>
  37. <a-radio-button value="sold_out">已售罄</a-radio-button>
  38. </a-radio-group>
  39. </div>
  40. <a-button
  41. v-if="$auth('/goods/create')"
  42. class="fl-l"
  43. type="primary"
  44. icon="plus"
  45. @click="handleCreate"
  46. >创建商品</a-button>
  47. <div v-if="selectedRowKeys.length" class="button-group">
  48. <a-button-group class="ml-10">
  49. <a-button icon="arrow-up" @click="handleUpdateStatus(selectedRowKeys, true)">上架</a-button>
  50. <a-button icon="arrow-down" @click="handleUpdateStatus(selectedRowKeys, false)">下架</a-button>
  51. <a-button icon="delete" @click="handleDelete(selectedRowKeys)">删除</a-button>
  52. </a-button-group>
  53. </div>
  54. </div>
  55. </div>
  56. <s-table
  57. ref="table"
  58. rowKey="goods_id"
  59. :loading="isLoading"
  60. :columns="columns"
  61. :data="loadData"
  62. :rowSelection="rowSelection"
  63. :pageSize="15"
  64. >
  65. <!-- 商品图片 -->
  66. <span slot="goods_image" slot-scope="text">
  67. <a title="点击查看原图" :href="text" target="_blank">
  68. <img width="50" height="50" :src="text" alt="商品图片" />
  69. </a>
  70. </span>
  71. <!-- 商品名称 -->
  72. <span slot="goods_name" slot-scope="text">
  73. <p class="twoline-hide" style="width: 270px;">{{ text }}</p>
  74. </span>
  75. <!-- 商品状态 -->
  76. <span slot="status" slot-scope="text, item">
  77. <a-tag
  78. class="cur-p"
  79. :color="text == 10 ? 'green' : 'red'"
  80. @click="handleUpdateStatus([item.goods_id], text != 10)"
  81. >{{ text == 10 ? '上架' : '下架' }}</a-tag>
  82. </span>
  83. <!-- 操作项 -->
  84. <div class="actions" slot="action" slot-scope="text, item">
  85. <a v-if="$auth('/goods/update')" @click="handleEdit(item)">编辑</a>
  86. <a v-action:delete @click="handleDelete([item.goods_id])">删除</a>
  87. </div>
  88. </s-table>
  89. </a-card>
  90. </template>
  91. <script>
  92. import * as GoodsApi from '@/api/goods'
  93. import { ContentHeader, STable } from '@/components'
  94. import CategoryModel from '@/common/model/Category'
  95. // 表格表头
  96. const columns = [
  97. {
  98. title: '商品ID',
  99. dataIndex: 'goods_id'
  100. },
  101. {
  102. title: '商品图片',
  103. dataIndex: 'goods_image',
  104. scopedSlots: { customRender: 'goods_image' }
  105. },
  106. {
  107. title: '商品名称',
  108. dataIndex: 'goods_name',
  109. scopedSlots: { customRender: 'goods_name' }
  110. },
  111. {
  112. title: '商品价格',
  113. dataIndex: 'goods_price_min',
  114. scopedSlots: { customRender: 'goods_price_min' }
  115. },
  116. {
  117. title: '总销量',
  118. dataIndex: 'sales_actual'
  119. },
  120. {
  121. title: '库存总量',
  122. dataIndex: 'stock_total'
  123. },
  124. {
  125. title: '状态',
  126. dataIndex: 'status',
  127. scopedSlots: { customRender: 'status' }
  128. },
  129. {
  130. title: '排序',
  131. dataIndex: 'sort'
  132. },
  133. {
  134. title: '添加时间',
  135. dataIndex: 'create_time'
  136. },
  137. {
  138. title: '操作',
  139. dataIndex: 'action',
  140. width: '180px',
  141. scopedSlots: { customRender: 'action' }
  142. }
  143. ]
  144. export default {
  145. name: 'Index',
  146. components: {
  147. ContentHeader,
  148. STable
  149. },
  150. data () {
  151. return {
  152. // 当前表单元素
  153. searchForm: this.$form.createForm(this),
  154. // 商品分类列表
  155. categoryListTree: [],
  156. // 查询参数
  157. queryParam: {
  158. listType: 'all'
  159. },
  160. // 正在加载
  161. isLoading: false,
  162. // 表头
  163. columns,
  164. // 选择的元素
  165. selectedRowKeys: [],
  166. // 加载数据方法 必须为 Promise 对象
  167. loadData: param => {
  168. return GoodsApi.list({ ...param, ...this.queryParam })
  169. .then(response => {
  170. return response.data.list
  171. })
  172. }
  173. }
  174. },
  175. created () {
  176. // 默认的查询参数
  177. if (this.$route.query.listType) {
  178. this.queryParam.listType = this.$route.query.listType
  179. }
  180. // 获取商品分类列表
  181. this.getCategoryList()
  182. },
  183. computed: {
  184. rowSelection () {
  185. return {
  186. selectedRowKeys: this.selectedRowKeys,
  187. onChange: this.onSelectChange
  188. }
  189. }
  190. },
  191. methods: {
  192. /**
  193. * 选中项发生变化时的回调
  194. */
  195. onSelectChange (selectedRowKeys) {
  196. this.selectedRowKeys = selectedRowKeys
  197. },
  198. // 切换tab
  199. handleTabs (e) {
  200. this.queryParam.listType = e.target.value
  201. this.handleRefresh(true)
  202. },
  203. // 确认搜索
  204. handleSearch (e) {
  205. e.preventDefault()
  206. this.searchForm.validateFields((error, values) => {
  207. if (!error) {
  208. this.queryParam = { ...this.queryParam, ...values }
  209. this.handleRefresh(true)
  210. }
  211. })
  212. },
  213. // 重置搜索表单
  214. handleReset () {
  215. this.searchForm.resetFields()
  216. },
  217. // 获取分类列表
  218. getCategoryList () {
  219. this.isLoading = true
  220. CategoryModel.getListFromScreen()
  221. .then(selectList => {
  222. this.categoryListTree = selectList
  223. })
  224. .finally(result => {
  225. this.isLoading = false
  226. })
  227. },
  228. // 修改商品状态(上下架)
  229. handleUpdateStatus (goodsIds, state = true) {
  230. this.isLoading = true
  231. GoodsApi.state({ goodsIds, state })
  232. .then(result => {
  233. // 显示成功
  234. this.$message.success(result.message, 1.5)
  235. this.handleRefresh()
  236. })
  237. .finally(result => { this.isLoading = false })
  238. },
  239. /**
  240. * 删除记录
  241. */
  242. handleDelete (goodsIds) {
  243. const app = this
  244. const modal = this.$confirm({
  245. title: '您确定要删除该记录吗?',
  246. content: '删除后不可恢复',
  247. onOk () {
  248. return GoodsApi.deleted({ goodsIds })
  249. .then(result => {
  250. app.$message.success(result.message, 1.5)
  251. app.handleRefresh()
  252. })
  253. .finally(result => {
  254. modal.destroy()
  255. })
  256. }
  257. })
  258. },
  259. /**
  260. * 新增记录
  261. */
  262. handleCreate () {
  263. this.$router.push('/goods/create')
  264. },
  265. /**
  266. * 编辑记录
  267. */
  268. handleEdit (item) {
  269. this.$router.push({ path: '/goods/update', query: { goodsId: item.goods_id } })
  270. },
  271. /**
  272. * 刷新列表
  273. * @param Boolean bool 强制刷新到第一页
  274. */
  275. handleRefresh (bool = false) {
  276. this.selectedRowKeys = []
  277. this.$refs.table.refresh(bool)
  278. }
  279. }
  280. }
  281. </script>
  282. <style lang="less" scoped>
  283. .ant-card-body {
  284. padding: 22px 29px 25px;
  285. }
  286. // 筛选tab
  287. .tab-list {
  288. margin-right: 20px;
  289. }
  290. </style>