商品分类

main
fanfan 8 months ago
parent 89aa484150
commit 45951256e2
  1. 23
      package-lock.json
  2. 9
      package.json
  3. 239
      src/views/dataCenter/goods/Index.vue
  4. 30
      yarn.lock

23
package-lock.json generated

@ -50,6 +50,7 @@
"git-revision-webpack-plugin": "^3.0.6",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"node": "^10.24.1",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2",
"vue-svg-icon-loader": "^2.1.1",
@ -14044,12 +14045,34 @@
"lower-case": "^1.1.1"
}
},
"node_modules/node": {
"version": "10.24.1",
"resolved": "https://registry.npmjs.org/node/-/node-10.24.1.tgz",
"integrity": "sha512-3VQ/FYdesUorecUrJAB2ZxeE9E/3Lm1/g0A5Y3jdnDgu/nK9G7pFBgDUlrLkb9FKWPd4pa3ieOAjvlwLSa4F1w==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
"node-bin-setup": "^1.0.0"
},
"bin": {
"node": "bin/node"
},
"engines": {
"npm": ">=5.0.0"
}
},
"node_modules/node-addon-api": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
"dev": true
},
"node_modules/node-bin-setup": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.1.3.tgz",
"integrity": "sha512-opgw9iSCAzT2+6wJOETCpeRYAQxSopqQ2z+N6BXwIMsQQ7Zj5M8MaafQY8JMlolRR6R1UXg2WmhKp0p9lSOivg==",
"dev": true
},
"node_modules/node-cache": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.2.1.tgz",

@ -3,12 +3,10 @@
"version": "3.0.0",
"private": true,
"scripts": {
"serve": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
"start": "vue-cli-service serve",
"build": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
"build:default": "vue-cli-service build",
"serve": "vue-cli-service serve",
"build": "set NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint",
"lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint",
"build:preview": "vue-cli-service build --mode preview",
"lint:nofix": "vue-cli-service lint --no-fix"
},
@ -55,6 +53,7 @@
"git-revision-webpack-plugin": "^3.0.6",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"node": "^10.24.1",
"opencollective": "^1.0.3",
"opencollective-postinstall": "^2.0.2",
"vue-svg-icon-loader": "^2.1.1",

@ -7,7 +7,14 @@
<a-form class="search-form" :form="searchForm" layout="inline" @submit="handleSearch">
<a-form-item label="渠道">
<a-select @change="getChannel" style="width: 120px" placeholder="请选择">
<a-select-option :value="item.id" v-for="(item) in checkList" :key="item.id">
<a-select-option :value="item.id" v-for="item in checkList" :key="item.id">
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="数据类型">
<a-select @change="getDataType" style="width: 120px" placeholder="请选择">
<a-select-option :value="item.val" v-for="item in dataType" :key="item.val">
{{ item.name }}
</a-select-option>
</a-select>
@ -26,12 +33,50 @@
v-decorator="['categoryId', { initialValue: 0 }]"
></a-tree-select>
</a-form-item>
<a-form-item label="类型">
<a-select @change="getGoodsType" style="width: 120px" placeholder="请选择">
<a-select-option :value="item.val" v-for="item in goodsType" :key="item.val">
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="状态">
<a-select @change="getGoodsStarus" style="width: 120px" placeholder="请选择">
<a-select-option :value="item.val" v-for="item in goodsStatus" :key="item.val">
{{ item.name }}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="前台价">
<div style="display: flex" class="goodsType">
<a-input v-decorator="['goods_price_min']" placeholder="请输入" />-
<a-input style="margin-left: 5px" v-decorator="['goods_price_max']" placeholder="请输入" />
</div>
</a-form-item>
<a-form-item label="利润率">
<div style="display: flex" class="goodsType">
<a-input v-decorator="['profit_rate_min']" placeholder="请输入" />-
<a-input style="margin-left: 5px" v-decorator="['profit_rate_max']" placeholder="请输入" />
</div>
</a-form-item>
<a-form-item class="search-btn">
<a-button type="primary" icon="search" html-type="submit">搜索</a-button>
</a-form-item>
</a-form>
</a-row>
<!-- 操作板块 -->
<a-modal v-model:visible="visible" title="商品分类" @ok="handleUpdateClassify(selectedRowKeys, categoryIds)">
<a-tree-select
style="min-width: 400px"
placeholder="请选择商品分类"
:dropdownStyle="{ maxHeight: '500px', overflow: 'auto' }"
:treeData="categoryListTree"
treeCheckable
treeCheckStrictly
allowClear
@change="onChangeCategory"
></a-tree-select>
</a-modal>
<div class="row-item-tab clearfix">
<div class="tab-list fl-l">
<a-radio-group :defaultValue="queryParam.listType" @change="handleTabs">
@ -41,26 +86,25 @@
<a-radio-button value="sold_out">已售罄</a-radio-button>
</a-radio-group>
</div>
<a-button
class="fl-l"
type="primary"
icon="plus"
@click="handleCreate()"
>创建商品</a-button
>
<a-button
class="fl-l"
icon="arrow-up"
@click="handleImport()"
>批量导入</a-button
>
<a-button class="fl-l" type="primary" icon="plus" @click="handleCreate()">创建商品</a-button>
<a-button class="fl-l" icon="arrow-up" @click="handleImport()">批量导入</a-button>
<div v-if="selectedRowKeys.length" class="button-group">
<a-button-group class="ml-10">
<a-button icon="arrow-up" @click="handleUpdateStatus(selectedRowKeys, true)">上架</a-button>
<a-button
icon="arrow-up"
style="background-color: red; color: #fff"
@click="handleUpdateStatus(selectedRowKeys, 1)"
>上架</a-button
>
<a-button
icon="arrow-down"
@click="handleUpdateStatus(selectedRowKeys, false)"
>下架</a-button
style="background-color: gray; color: #fff"
@click="handleUpdateStatus(selectedRowKeys, 2)"
>移除</a-button
>
<a-button style="background-color: green; color: #fff" @click="visible = true">归类</a-button>
<a-button style="background-color: blue; color: #fff" @click="handleUpdateSales(selectedRowKeys, false)"
>停售</a-button
>
<a-button icon="delete" @click="handleDelete(selectedRowKeys)">删除</a-button>
</a-button-group>
@ -92,19 +136,13 @@
class="cur-p"
:color="text == 10 ? 'green' : 'red'"
@click="handleUpdateStatus([item.goods_id], text != 10)"
>{{ text == 10 ? '上架' : '下架' }}</a-tag
>{{ text == 10 ? '上架' : '下架' }}</a-tag
>
</span>
<!-- 操作项 -->
<div class="actions" slot="action" slot-scope="text, item">
<router-link
:to="{ path: '/goods/update', query: { goodsId: item.goods_id } }"
>编辑</router-link
>
<router-link
:to="{ path: '/goods/copy', query: { goodsId: item.goods_id } }"
>复制</router-link
>
<router-link :to="{ path: '/goods/update', query: { goodsId: item.goods_id } }">编辑</router-link>
<router-link :to="{ path: '/goods/copy', query: { goodsId: item.goods_id } }">复制</router-link>
<a @click="handleDelete([item.goods_id])">删除</a>
</div>
</s-table>
@ -115,79 +153,80 @@
import * as GoodsApi from '@/api/goods'
import { ContentHeader, STable } from '@/components'
import CategoryModel from '@/common/model/Category'
import * as Api from '@/api/store'
import * as Api from '@/api/store'
//
const columns = [
{
title: '商品ID',
dataIndex: 'goods_id',
sorter: true
sorter: true,
},
{
title: '渠道',
dataIndex: 'channel_name',
width: '60px'
width: '60px',
},
{
title: '商品图片',
dataIndex: 'goods_image',
scopedSlots: { customRender: 'goods_image' }
scopedSlots: { customRender: 'goods_image' },
},
{
title: '商品名称',
dataIndex: 'goods_name',
width: '270px',
scopedSlots: { customRender: 'goods_name' }
scopedSlots: { customRender: 'goods_name' },
},
{
title: '商品价格',
dataIndex: 'goods_price_min',
scopedSlots: { customRender: 'goods_price_min' },
sorter: true
sorter: true,
},
{
title: '商品利润',
dataIndex: 'profit',
sorter: true
sorter: true,
},
{
title: '商品利润率',
dataIndex: 'profit_rate',
sorter: true
sorter: true,
},
{
title: '库存总量',
dataIndex: 'stock_total',
sorter: true
sorter: true,
},
{
title: '状态',
dataIndex: 'status',
scopedSlots: { customRender: 'status' }
scopedSlots: { customRender: 'status' },
},
{
title: '添加时间',
width: '180px',
dataIndex: 'create_time',
sorter: true
sorter: true,
},
{
title: '操作',
dataIndex: 'action',
width: '150px',
scopedSlots: { customRender: 'action' }
}
scopedSlots: { customRender: 'action' },
},
]
export default {
name: 'Index',
components: {
ContentHeader,
STable
STable,
},
data () {
data() {
return {
visible: false,
//
searchForm: this.$form.createForm(this),
//
@ -195,7 +234,10 @@ export default {
//
queryParam: {
listType: 'all',
channel: ''
channel: '',
is_self: '',
is_pool: '',
date_type: '',
},
//
isLoading: false,
@ -208,7 +250,7 @@ export default {
const data = { ...param, ...this.queryParam }
const orderEnum = {
ascend: 'asc',
descend: 'desc'
descend: 'desc',
}
if (data.sortField && data.sortOrder && orderEnum[data.sortOrder]) {
@ -226,10 +268,26 @@ export default {
})
},
checkList: []
checkList: [],
goodsType: [
{ name: '自营', val: 1 },
{ name: 'POP', val: 2 },
{ name: '其他', val: 0 },
],
goodsStatus: [
{ name: '待处理', val: 0 },
{ name: '已入池', val: 1 },
{ name: '未入池', val: 2 },
],
dataType: [
{ name: 'API数据', val: 0 },
{ name: '人工数据', val: 1 },
{ name: '商品池', val: 2 },
],
categoryIds: [],
}
},
created () {
created() {
this.getDataList()
//
@ -240,27 +298,27 @@ export default {
this.getCategoryList()
},
computed: {
rowSelection () {
rowSelection() {
return {
selectedRowKeys: this.selectedRowKeys,
onChange: this.onSelectChange
onChange: this.onSelectChange,
}
}
},
},
methods: {
//
onSelectChange (selectedRowKeys) {
onSelectChange(selectedRowKeys) {
this.selectedRowKeys = selectedRowKeys
},
// tab
handleTabs (e) {
handleTabs(e) {
this.queryParam.listType = e.target.value
this.handleRefresh(true)
},
//
handleSearch (e) {
handleSearch(e) {
e.preventDefault()
this.searchForm.validateFields((error, values) => {
if (!error) {
@ -271,25 +329,33 @@ export default {
},
//
handleReset () {
handleReset() {
this.searchForm.resetFields()
},
getDataList () {
return Api.getDataList().then(result => {
getDataList() {
return Api.getDataList().then((result) => {
const obj = result.data
Object.keys(obj).forEach(item => {
this.checkList.push({ id: item, name: obj[item] })
Object.keys(obj).forEach((item) => {
this.checkList.push({ id: item, name: obj[item] })
})
})
},
getChannel (val) {
getChannel(val) {
this.queryParam.channel = val
},
getDataType(val) {
this.queryParam.date_type = val
},
getGoodsType(val) {
this.queryParam.is_self = val
},
getGoodsStarus(val) {
this.queryParam.is_pool = val
},
//
getCategoryList () {
getCategoryList() {
this.isLoading = true
CategoryModel.getListFromScreen()
.then((selectList) => {
@ -299,9 +365,9 @@ export default {
},
// ()
handleUpdateStatus (goodsIds, state = true) {
handleUpdateStatus(goodsIds, is_pool) {
this.isLoading = true
GoodsApi.state({ goodsIds, state })
GoodsApi.state({ goodsIds, is_pool })
.then((result) => {
//
this.$message.success(result.message, 1.5)
@ -311,31 +377,57 @@ export default {
this.isLoading = false
})
},
//
onChangeCategory(list) {
this.categoryIds = []
list.forEach((item) => {
this.categoryIds.push(item.value)
})
},
handleUpdateClassify(goodsIds, categoryIds) {
console.log(goodsIds, categoryIds)
if (categoryIds.length == 0) {
this.$message.warn('请至少选择1个商品分类', 1.5)
return
}
return
this.isLoading = true
GoodsApi.state({ goodsIds, categoryIds })
.then((result) => {
//
this.$message.success(result.message, 1.5)
this.handleRefresh()
})
.finally((result) => {
this.isLoading = false
})
},
//
handleUpdateSales() {},
//
handleDelete (goodsIds) {
handleDelete(goodsIds) {
const app = this
const modal = this.$confirm({
title: '您确定要删除该记录吗?',
content: '删除后不可恢复',
onOk () {
onOk() {
return GoodsApi.deleted({ goodsIds })
.then((result) => {
app.$message.success(result.message, 1.5)
app.handleRefresh()
})
.finally((result) => modal.destroy())
}
},
})
},
//
handleCreate () {
handleCreate() {
this.$router.push('/goods/create')
},
//
handleImport () {
handleImport() {
this.$router.push('/goods/import/batch')
},
@ -343,11 +435,11 @@ export default {
* 刷新列表
* @param Boolean bool 强制刷新到第一页
*/
handleRefresh (bool = false) {
handleRefresh(bool = false) {
this.selectedRowKeys = []
this.$refs.table.refresh(bool)
}
}
},
},
}
</script>
<style lang="less" scoped>
@ -365,4 +457,11 @@ export default {
align-items: center;
margin-top: 10px;
}
.goodsType {
display: flex;
input {
width: 100px;
margin-right: 5px;
}
}
</style>

@ -5805,19 +5805,6 @@
"resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
"version" "1.0.0"
"fsevents@^1.2.7":
"integrity" "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw=="
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz"
"version" "1.2.13"
dependencies:
"bindings" "^1.5.0"
"nan" "^2.12.1"
"fsevents@~2.3.2":
"integrity" "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="
"resolved" "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz"
"version" "2.3.2"
"function-bind@^1.1.1":
"integrity" "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
"resolved" "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz"
@ -8353,11 +8340,6 @@
"object-assign" "^4.0.1"
"thenify-all" "^1.0.0"
"nan@^2.12.1":
"integrity" "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
"resolved" "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz"
"version" "2.17.0"
"nanoid@^3.3.7":
"integrity" "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="
"resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz"
@ -8422,6 +8404,11 @@
"resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz"
"version" "1.7.2"
"node-bin-setup@^1.0.0":
"integrity" "sha512-opgw9iSCAzT2+6wJOETCpeRYAQxSopqQ2z+N6BXwIMsQQ7Zj5M8MaafQY8JMlolRR6R1UXg2WmhKp0p9lSOivg=="
"resolved" "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.1.3.tgz"
"version" "1.1.3"
"node-cache@^4.1.1":
"integrity" "sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A=="
"resolved" "https://registry.npmjs.org/node-cache/-/node-cache-4.2.1.tgz"
@ -8500,6 +8487,13 @@
"resolved" "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz"
"version" "2.0.10"
"node@^10.24.1":
"integrity" "sha512-3VQ/FYdesUorecUrJAB2ZxeE9E/3Lm1/g0A5Y3jdnDgu/nK9G7pFBgDUlrLkb9FKWPd4pa3ieOAjvlwLSa4F1w=="
"resolved" "https://registry.npmjs.org/node/-/node-10.24.1.tgz"
"version" "10.24.1"
dependencies:
"node-bin-setup" "^1.0.0"
"nopt@^6.0.0":
"integrity" "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g=="
"resolved" "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz"

Loading…
Cancel
Save