Browse Source

mallplus相关

master
liupopo 1 year ago
parent
commit
3659ed34d1
  1. 7
      src/api/oss.js
  2. 113
      src/api/product.js
  3. 52
      src/api/productAttr.js
  4. 37
      src/api/productAttrCate.js
  5. 76
      src/api/productCate.js
  6. 16
      src/api/skuStock.js
  7. 109
      src/components/Upload/multiUpload.vue
  8. 107
      src/components/Upload/singleUpload-oss.vue
  9. 120
      src/components/Upload/singleUpload.vue
  10. 33
      src/layout/components/Sidebar/index.vue
  11. 64
      src/router/index.js
  12. 43
      src/utils/date.js
  13. 7
      src/views/pms/brand/add.vue
  14. 166
      src/views/pms/brand/components/BrandDetail.vue
  15. 367
      src/views/pms/brand/index.vue
  16. 12
      src/views/pms/product/add.vue
  17. 609
      src/views/pms/product/components/ProductAttrDetail.vue
  18. 201
      src/views/pms/product/components/ProductDetail.vue
  19. 434
      src/views/pms/product/components/ProductInfoDetail.vue
  20. 145
      src/views/pms/product/components/ProductRelationDetail.vue
  21. 322
      src/views/pms/product/components/ProductSaleDetail.vue
  22. 1017
      src/views/pms/product/index.vue
  23. 795
      src/views/pms/product/productBySku.vue
  24. 12
      src/views/pms/product/update.vue
  25. 15
      src/views/pms/productAttr/addProductAttr.vue
  26. 147
      src/views/pms/productAttr/components/ProductAttrDetail.vue
  27. 224
      src/views/pms/productAttr/index.vue
  28. 255
      src/views/pms/productAttr/productAttrList.vue
  29. 15
      src/views/pms/productAttr/updateProductAttr.vue
  30. 14
      src/views/pms/productCate/add.vue
  31. 291
      src/views/pms/productCate/components/ProductCateDetail.vue
  32. 269
      src/views/pms/productCate/index.vue
  33. 14
      src/views/pms/productCate/update.vue

7
src/api/oss.js

@ -0,0 +1,7 @@
import request from '@/utils/request'
export function policy() {
return request({
url:'/aliyun/oss/policy',
method:'get',
})
}

113
src/api/product.js

@ -0,0 +1,113 @@
import request from '@/utils/request'
export function fetchList(params) {
return request({
url:'/pms/PmsProduct/list',
method:'get',
params:params
})
}
export function fetchSimpleList(params) {
return request({
url:'/pms/PmsProduct/simpleList',
method:'get',
params:params
})
}
export function updateDeleteStatus(params) {
return request({
url:'/pms/PmsProduct/update/deleteStatus',
method:'post',
params:params
})
}
export function deleteProduct(id) {
return request({
url:'/pms/PmsProduct/delete/'+id,
method:'get',
})
}
export function updateNewStatus(params) {
return request({
url:'/pms/PmsProduct/update/newStatus',
method:'post',
params:params
})
}
export function updateRecommendStatus(params) {
return request({
url:'/pms/PmsProduct/update/recommendStatus',
method:'post',
params:params
})
}
export function updateVerifyStatus(params) {
return request({
url:'/pms/PmsProduct/update/verifyStatus',
method:'post',
params:params
})
}
export function updatePublishStatus(params) {
return request({
url:'/pms/PmsProduct/update/publishStatus',
method:'post',
params:params
})
}
export function updatePaiMai(params) {
return request({
url:'/pms/PmsProduct/update/updatePaiMai',
method:'post',
params:params
})
}
export function updateFenxiao(params) {
return request({
url:'/pms/PmsProduct/update/isFenxiao',
method:'post',
params:params
})
}
export function updateVip(params) {
return request({
url:'/pms/PmsProduct/update/isVip',
method:'post',
params:params
})
}
export function createProduct(data) {
return request({
url:'/pms/PmsProduct/create',
method:'post',
data:data
})
}
export function updateProduct(id,data) {
return request({
url:'/pms/PmsProduct/update/'+id,
method:'post',
data:data
})
}
export function fetchVList(id) {
return request({
url:'/pms/PmsProduct/fetchVList/'+id,
method:'get',
})
}
export function getProduct(id) {
return request({
url:'/pms/PmsProduct/updateInfo/'+id,
method:'get',
})
}

52
src/api/productAttr.js

@ -0,0 +1,52 @@
import request from '@/utils/request'
export function fetchList(cid,params) {
return request({
url:'/pms/PmsProductAttribute/list/'+cid,
method:'get',
params:params
})
}
export function fetchAllList(params) {
return request({
url:'/pms/PmsProductAttribute/listAll',
method:'get',
params:params
})
}
export function deleteProductAttr(id) {
return request({
url:'/pms/PmsProductAttribute/delete/'+id,
method:'get'
})
}
export function createProductAttr(data) {
return request({
url:'/pms/PmsProductAttribute/create',
method:'post',
data:data
})
}
export function updateProductAttr(id,data) {
return request({
url:'/pms/PmsProductAttribute/update/'+id,
method:'post',
data:data
})
}
export function getProductAttr(id) {
return request({
url:'/pms/PmsProductAttribute/'+id,
method:'get'
})
}
export function getProductAttrInfo(productCategoryId) {
return request({
url:'/pms/PmsProductAttribute/attrInfo/'+productCategoryId,
method:'get'
})
}

37
src/api/productAttrCate.js

@ -0,0 +1,37 @@
import request from '@/utils/request'
export function fetchList(params) {
return request({
url:'/pms/PmsProductAttributeCategory/list',
method:'get',
params:params
})
}
export function createProductAttrCate(data) {
return request({
url:'/pms/PmsProductAttributeCategory/create',
method:'post',
data:data
})
}
export function deleteProductAttrCate(id) {
return request({
url:'/pms/PmsProductAttributeCategory/delete/'+id,
method:'get'
})
}
export function updateProductAttrCate(id,data) {
return request({
url:'/pms/PmsProductAttributeCategory/update/'+id,
method:'post',
data:data
})
}
export function fetchListWithAttr() {
return request({
url:'/pms/PmsProductAttributeCategory/list/withAttr',
method:'get'
})
}

76
src/api/productCate.js

@ -0,0 +1,76 @@
import request from '@/utils/request'
export function fetchListAll(params) {
return request({
url:'/pms/PmsProductCategory/list',
method:'get',
params:params
})
}
export function fetchList(parentId,params) {
return request({
url:'/pms/PmsProductCategory/list/'+parentId,
method:'get',
params:params
})
}
export function deleteProductCate(id) {
return request({
url:'/pms/PmsProductCategory/delete/'+id,
method:'get'
})
}
export function createProductCate(data) {
return request({
url:'/pms/PmsProductCategory/create',
method:'post',
data:data
})
}
export function updateProductCate(id,data) {
return request({
url:'/pms/PmsProductCategory/update/'+id,
method:'post',
data:data
})
}
export function getProductCate(id) {
return request({
url:'/pms/PmsProductCategory/'+id,
method:'get',
})
}
export function updateShowStatus(data) {
return request({
url:'/pms/PmsProductCategory/update/showStatus',
method:'post',
data:data
})
}
export function updateIndexStatus(data) {
return request({
url:'/pms/PmsProductCategory/update/indexStatus',
method:'post',
data:data
})
}
export function updateNavStatus(data) {
return request({
url:'/pms/PmsProductCategory/update/navStatus',
method:'post',
data:data
})
}
export function fetchListWithChildren() {
return request({
url:'/pms/PmsProductCategory/list/withChildren',
method:'get'
})
}

16
src/api/skuStock.js

@ -0,0 +1,16 @@
import request from '@/utils/request'
export function fetchList(pid,params) {
return request({
url:'/pms/PmsSkuStock/select/'+pid,
method:'get',
params:params
})
}
export function update(pid,data) {
return request({
url:'/pms/PmsSkuStock/updatePid/'+pid,
method:'post',
data:data
})
}

109
src/components/Upload/multiUpload.vue

@ -0,0 +1,109 @@
<template> 
<div>
<el-upload
action="http://yxt-sc.oss-cn-huhehaote.aliyuncs.com/"
:data="dataObj"
list-type="picture-card"
:file-list="fileList"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:on-preview="handlePreview"
:limit="maxCount"
:on-exceed="handleExceed"
>
<i class="el-icon-plus"></i>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
<script>
import {policy} from '@/api/oss'
export default {
name: 'multiUpload',
props: {
//
value: Array,
//
maxCount:{
type:Number,
default:5
}
},
data() {
return {
dataObj: {
policy: '',
signature: '',
key: '',
ossaccessKeyId: '',
dir: '',
host: ''
},
dialogVisible: false,
dialogImageUrl:null
};
},
computed: {
fileList() {
let fileList=[];
for(let i=0;i<this.value.length;i++){
fileList.push({url:this.value[i]});
}
return fileList;
}
},
methods: {
emitInput(fileList) {
let value=[];
for(let i=0;i<fileList.length;i++){
value.push(fileList[i].url);
}
this.$emit('input', value)
},
handleRemove(file, fileList) {
this.emitInput(fileList);
},
handlePreview(file) {
this.dialogVisible = true;
this.dialogImageUrl=file.url;
},
beforeUpload(file) {
let _self = this;
return new Promise((resolve, reject) => {
policy().then(response => {
_self.dataObj.policy = response.data.policy;
_self.dataObj.signature = response.data.signature;
_self.dataObj.ossaccessKeyId = response.data.accessKeyId;
_self.dataObj.key = response.data.dir + '/${filename}';
_self.dataObj.dir = response.data.dir;
_self.dataObj.host = response.data.host;
resolve(true)
}).catch(err => {
console.log(err)
reject(false)
})
})
},
handleUploadSuccess(res, file) {
this.fileList.push({url: file.name,url:this.dataObj.host + '/' + this.dataObj.dir + '/' + file.name});
this.emitInput(this.fileList);
},
handleExceed(files, fileList) {
this.$message({
message: '最多只能上传'+this.maxCount+'张图片',
type: 'warning',
duration:1000
});
},
}
}
</script>
<style>
</style>

107
src/components/Upload/singleUpload-oss.vue

@ -0,0 +1,107 @@
<template> 
<div>
<el-upload
action="http://yxt-sc.oss-cn-huhehaote.aliyuncs.com/"
:data="dataObj"
list-type="picture"
:multiple="false" :show-file-list="showFileList"
:file-list="fileList"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:on-preview="handlePreview">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过10MB</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="fileList[0].url" alt="">
</el-dialog>
</div>
</template>
<script>
import {policy} from '@/api/oss'
export default {
name: 'singleUpload',
props: {
value: String
},
computed: {
imageUrl() {
return this.value;
},
imageName() {
if (this.value != null && this.value !== '') {
return this.value.substr(this.value.lastIndexOf("/") + 1);
} else {
return null;
}
},
fileList() {
return [{
name: this.imageName,
url: this.imageUrl
}]
},
showFileList: {
get: function () {
return this.value !== null && this.value !== ''&& this.value!==undefined;
},
set: function (newValue) {
}
}
},
data() {
return {
dataObj: {
policy: '',
signature: '',
key: '',
ossaccessKeyId: '',
dir: '',
host: ''
},
dialogVisible: false
};
},
methods: {
emitInput(val) {
this.$emit('input', val)
},
handleRemove(file, fileList) {
this.emitInput('');
},
handlePreview(file) {
this.dialogVisible = true;
},
beforeUpload(file) {
let _self = this;
return new Promise((resolve, reject) => {
policy().then(response => {
_self.dataObj.policy = response.data.policy;
_self.dataObj.signature = response.data.signature;
_self.dataObj.ossaccessKeyId = response.data.accessKeyId;
_self.dataObj.key = response.data.dir + '/${filename}';
_self.dataObj.dir = response.data.dir;
_self.dataObj.host = response.data.host;
resolve(true)
}).catch(err => {
console.log(err)
reject(false)
})
})
},
handleUploadSuccess(res, file) {
this.showFileList = true;
this.fileList.pop();
this.fileList.push({name: file.name, url: this.dataObj.host + '/' + this.dataObj.dir + '/' + file.name});
this.emitInput(this.fileList[0].url);
}
}
}
</script>
<style>
</style>

120
src/components/Upload/singleUpload.vue

@ -0,0 +1,120 @@
<template>
<div>
<el-upload
:action="uploadAction"
:headers="accessToken"
:data="dataObj"
list-type="picture"
:multiple="false"
:show-file-list="showFileList"
:file-list="fileList"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:on-preview="handlePreview"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过10MB</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="fileList[0].url" alt="">
</el-dialog>
</div>
</template>
<script>
import { policy } from '@/api/oss'
import { getStorage } from '@/utils/auth.js'
export default {
name: 'SingleUpload',
props: {
value: String
},
data() {
return {
uploadAction: process.env.VUE_APP_BASE_API + '/file/upload',
accessToken: null,
dataObj: {
policy: '',
signature: '',
key: '',
ossaccessKeyId: '',
dir: '',
host: ''
},
dialogVisible: false
}
},
computed: {
imageUrl() {
return this.value
},
imageName() {
if (this.value != null && this.value !== '') {
return this.value.substr(this.value.lastIndexOf('/') + 1)
} else {
return null
}
},
fileList() {
return [{
name: this.imageName,
url: this.imageUrl
}]
},
showFileList: {
get: function() {
return this.value !== null && this.value !== '' && this.value !== undefined
},
set: function(newValue) {
}
}
},
created() {
this.accessToken = {
token: getStorage()
}
},
methods: {
emitInput(val) {
this.$emit('input', val)
},
handleRemove(file, fileList) {
this.emitInput('')
},
handlePreview(file) {
this.dialogVisible = true
},
beforeUpload(file) {
const _self = this
// return new Promise((resolve, reject) => {
// policy().then(response => {
// _self.dataObj.policy = response.data.policy;
// _self.dataObj.signature = response.data.signature;
// _self.dataObj.ossaccessKeyId = response.data.accessKeyId;
// _self.dataObj.key = response.data.dir + '/${filename}';
// _self.dataObj.dir = response.data.dir;
// _self.dataObj.host = response.data.host;
// resolve(true)
// }).catch(err => {
// console.log(err)
// reject(false)
// })
// })
},
handleUploadSuccess(res, file) {
console.log('LLLLL', res)
console.log('FFFFF', file)
this.showFileList = true
this.fileList.pop()
// this.fileList.push({ name: file.name, url: this.dataObj.host + '/' + this.dataObj.dir + '/' + file.name })
this.fileList.push({ name: file.name, url: res.data.fullUrl })
this.emitInput(this.fileList[0].url)
}
}
}
</script>
<style>
</style>

33
src/layout/components/Sidebar/index.vue

@ -55,40 +55,49 @@
path: '/userInfo/index'
}, {
alwaysShow: true,
component: 'brand',
component: 'pms',
meta: {
icon: 'el-icon-menu',
title: '商品管理'
},
name: '/brand',
path: '/brand',
name: '/pms',
path: '/pms',
children: [{
alwaysShow: true,
component: 'index',
component: 'product',
meta: {
icon: 'el-icon-help',
title: '商品列表'
},
name: '/pms/product',
path: '/pms/product'
}, {
alwaysShow: true,
component: 'brand',
meta: {
icon: 'el-icon-help',
title: '品牌管理'
},
name: '/brand/index',
path: '/brand/index'
name: '/pms/brand',
path: '/pms/brand'
}, {
alwaysShow: true,
component: 'enterprise',
component: 'productCate',
meta: {
icon: 'el-icon-help',
title: '商品分类'
},
name: '/cardManage/enterprise',
path: '/cardManage/enterprise'
name: '/pms/productCate',
path: '/pms/productCate'
}, {
alwaysShow: true,
component: 'giftCard',
component: 'productAttr',
meta: {
icon: 'el-icon-help',
title: '商品类型'
},
name: '/cardManage/giftCard',
path: '/cardManage/giftCard'
name: '/pms/productAttr',
path: '/pms/productAttr'
}
]
},

64
src/router/index.js

@ -30,7 +30,7 @@ export const constantRoutes = [{
// component: () => import('@/views/userInfo/index.vue'),
// name: 'index'
// },
// },
{
path: '/index',
@ -67,34 +67,78 @@ export const constantRoutes = [{
}
}, ]
}, {
path: '/brand',
path: '/pms',
component: Layout,
redirect: null,
meta: {
title: '商品管理'
},
children: [{
path: '/brand/index',
path: 'product',
name: 'product',
component: () => import('@/views/pms/product/index'),
meta: {
title: '商品列表',
icon: 'product-list'
}
},{
path: 'brand',
component: () =>
import('@/views/pms/brand/index.vue'),
name: 'index',
name: 'brand',
meta: {
title: '品牌管理'
}
},
{
path: '/cardManage/enterprise',
path: 'addBrand',
name: 'addBrand',
component: () => import('@/views/pms/brand/add'),
meta: {
title: '添加品牌'
},
hidden: true
},
{
path: 'updateBrand',
name: 'updateBrand',
component: () => import('@/views/pms/brand/update'),
meta: {
title: '编辑品牌'
},
hidden: true
},
{
path: 'productCate',
component: () =>
import('@/views/cardManage/enterprise.vue'),
name: 'enterprise',
import('@/views/pms/productCate/index'),
name: 'productCate',
meta: {
title: '商品分类'
}
},
{
path: '/cardManage/giftCard',
path: 'addProductCate',
name: 'addProductCate',
component: () => import('@/views/pms/productCate/add'),
meta: {
title: '添加商品分类'
},
hidden: true
},
{
path: 'updateProductCate',
name: 'updateProductCate',
component: () => import('@/views/pms/productCate/update'),
meta: {
title: '修改商品分类'
},
hidden: true
},
{
path: 'productAttr',
component: () =>
import('@/views/cardManage/giftCard.vue'),
import('@/views/pms/productAttr/index'),
name: 'giftCard',
meta: {
title: '商品类型'
@ -362,4 +406,4 @@ export function resetRouter() {
router.matcher = newRouter.matcher // reset router
}
export default router
export default router

43
src/utils/date.js

@ -0,0 +1,43 @@
// date.js
export function formatDate(date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
};
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + '';
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
}
}
return fmt;
}
function padLeftZero(str) {
return ('00' + str).substr(str.length);
}
export function str2Date(dateStr, separator) {
if (!separator) {
separator = "-";
}
let dateArr = dateStr.split(separator);
let year = parseInt(dateArr[0]);
let month;
//处理月份为04这样的情况
if (dateArr[1].indexOf("0") == 0) {
month = parseInt(dateArr[1].substring(1));
} else {
month = parseInt(dateArr[1]);
}
let day = parseInt(dateArr[2]);
let date = new Date(year, month - 1, day);
return date;
}

7
src/views/pms/brand/add.vue

@ -1,14 +1,13 @@
<template> 
<brand-detail :is-edit='false'></brand-detail>
<template>
<brand-detail :is-edit="false" />
</template>
<script>
import BrandDetail from './components/BrandDetail'
export default {
name: 'addBrand',
name: 'AddBrand',
components: { BrandDetail }
}
</script>
<style>
</style>

166
src/views/pms/brand/components/BrandDetail.vue

@ -1,51 +1,53 @@
<template> 
<el-card class="form-container" shadow="never">
<el-form :model="brand" :rules="rules" ref="brandFrom" label-width="150px">
<el-form-item label="品牌名称:" prop="name">
<el-input v-model="brand.name"></el-input>
</el-form-item>
<el-form-item label="品牌首字母:">
<el-input v-model="brand.firstLetter"></el-input>
</el-form-item>
<el-form-item label="品牌LOGO:" prop="logo">
<single-upload v-model="brand.logo"></single-upload>
</el-form-item>
<el-form-item label="品牌专区大图:">
<single-upload v-model="brand.bigPic"></single-upload>
</el-form-item>
<el-form-item label="品牌故事:">
<el-input
placeholder="请输入内容"
type="textarea"
v-model="brand.brandStory"
:autosize="true"></el-input>
</el-form-item>
<el-form-item label="排序:" prop="sort">
<el-input v-model.number="brand.sort"></el-input>
</el-form-item>
<el-form-item label="是否显示:">
<el-radio-group v-model="brand.showStatus">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="品牌制造商:">
<el-radio-group v-model="brand.factoryStatus">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('brandFrom')">提交</el-button>
<el-button v-if="!isEdit" @click="resetForm('brandFrom')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<template>
<div class="main-content">
<el-card class="form-container" shadow="never">
<el-form ref="brandFrom" :model="brand" :rules="rules" label-width="150px">
<el-form-item label="品牌名称:" prop="name">
<el-input v-model="brand.name" />
</el-form-item>
<el-form-item label="品牌首字母:">
<el-input v-model="brand.firstLetter" />
</el-form-item>
<el-form-item label="品牌LOGO:" prop="logo">
<single-upload v-model="brand.logo" />
</el-form-item>
<el-form-item label="品牌专区大图:">
<single-upload v-model="brand.bigPic" />
</el-form-item>
<el-form-item label="品牌故事:">
<el-input v-model="brand.brandStory" placeholder="请输入内容" type="textarea" :autosize="true" />
</el-form-item>
<el-form-item label="排序:" prop="sort">
<el-input v-model.number="brand.sort" />
</el-form-item>
<el-form-item label="是否显示:">
<el-radio-group v-model="brand.showStatus">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="品牌制造商:">
<el-radio-group v-model="brand.factoryStatus">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('brandFrom')">提交</el-button>
<el-button v-if="!isEdit" @click="resetForm('brandFrom')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import {createBrand, getBrand, updateBrand} from '@/api/brand'
import {
createBrand,
getBrand,
updateBrand
} from '@/api/brand'
import SingleUpload from '@/components/Upload/singleUpload'
const defaultBrand={
const defaultBrand = {
bigPic: '',
brandStory: '',
factoryStatus: 0,
@ -54,10 +56,12 @@
name: '',
showStatus: 0,
sort: 0
};
}
export default {
name: 'BrandDetail',
components:{SingleUpload},
components: {
SingleUpload
},
props: {
isEdit: {
type: Boolean,
@ -66,26 +70,35 @@
},
data() {
return {
brand:Object.assign({}, defaultBrand),
brand: Object.assign({}, defaultBrand),
rules: {
name: [
{required: true, message: '请输入品牌名称', trigger: 'blur'},
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
name: [{
required: true,
message: '请输入品牌名称',
trigger: 'blur'
},
{
min: 2,
max: 140,
message: '长度在 2 到 140 个字符',
trigger: 'blur'
}
],
sort: [
{type: 'number', message: '排序必须为数字'}
],
sort: [{
type: 'number',
message: '排序必须为数字'
}]
}
}
},
created() {
if (this.isEdit) {
getBrand(this.$route.query.id).then(response => {
this.brand = response.data;
});
}else{
this.brand = Object.assign({},defaultBrand);
this.brand = response.data
})
} else {
this.brand = Object.assign({}, defaultBrand)
}
},
methods: {
@ -99,45 +112,42 @@
}).then(() => {
if (this.isEdit) {
updateBrand(this.$route.query.id, this.brand).then(response => {
this.$refs[formName].resetFields();
this.$refs[formName].resetFields()
this.$message({
message: '修改成功',
type: 'success',
duration:1000
});
this.$router.back();
});
duration: 1000
})
this.$router.back()
})
} else {
createBrand(this.brand).then(response => {
this.$refs[formName].resetFields();
this.brand = Object.assign({},defaultBrand);
this.$refs[formName].resetFields()
this.brand = Object.assign({}, defaultBrand)
this.$message({
message: '提交成功',
type: 'success',
duration:1000
});
});
duration: 1000
})
})
}
});
})
} else {
this.$message({
message: '验证失败',
type: 'error',
duration:1000
});
return false;
duration: 1000
})
return false
}
});
})
},
resetForm(formName) {
this.$refs[formName].resetFields();
this.brand = Object.assign({},defaultBrand);
this.$refs[formName].resetFields()
this.brand = Object.assign({}, defaultBrand)
}
}
}
</script>
<style>
</style>

367
src/views/pms/brand/index.vue

@ -1,145 +1,158 @@
<template> 
<template>
<div class="app-container">
<el-card class="filter-container" shadow="never">
<div class="main-content">
<el-card class="filter-container" shadow="never">
<div>
<i class="el-icon-search"></i>
<i class="el-icon-search" />
<span>筛选搜索</span>
<el-button
style="float: right"
@click="searchBrandList()"
type="primary"
size="small">
size="small"
@click="searchBrandList()"
>
查询结果
</el-button>
</div>
<div style="margin-top: 15px">
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<el-form-item label="输入搜索:">
<el-input style="width: 203px" v-model="listQuery.name" placeholder="品牌名称/关键字"></el-input>
<el-input v-model="listQuery.name" style="width: 203px" placeholder="品牌名称/关键字" />
</el-form-item>
</el-form>
</div>
</el-card>
<el-card class="operate-container" shadow="never">
<i class="el-icon-tickets"></i>
<span>数据列表</span>
<el-button
class="btn-add"
@click="addBrand()"
size="mini">
添加
</el-button>
</el-card>
<div class="table-container">
<el-table ref="brandTable"
:data="list"
style="width: 100%"
@selection-change="handleSelectionChange"
v-loading="listLoading"
border>
<el-table-column type="selection" width="60" align="center"></el-table-column>
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<el-table-column label="品牌名称" align="center">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column label="品牌首字母" width="100" align="center">
<template slot-scope="scope">{{scope.row.firstLetter}}</template>
</el-table-column>
<el-table-column label="排序" width="100" align="center">
<template slot-scope="scope">{{scope.row.sort}}</template>
</el-table-column>
<el-table-column label="品牌制造商" width="100" align="center">
<template slot-scope="scope">
<el-switch
@change="handleFactoryStatusChange(scope.$index, scope.row)"
:active-value="1"
:inactive-value="0"
v-model="scope.row.factoryStatus">
</el-switch>
</template>
</el-table-column>
<el-table-column label="是否显示" width="100" align="center">
<template slot-scope="scope">
<el-switch
@change="handleShowStatusChange(scope.$index, scope.row)"
:active-value="1"
:inactive-value="0"
v-model="scope.row.showStatus">
</el-switch>
</template>
</el-table-column>
<el-table-column label="相关" width="220" align="center">
<template slot-scope="scope">
<span>商品</span>
<el-button
size="mini"
type="text"
@click="getProductList(scope.$index, scope.row)">100
</el-button>
<span>评价</span>
<el-button
size="mini"
type="text"
@click="getProductCommentList(scope.$index, scope.row)">1000
</el-button>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleUpdate(scope.$index, scope.row)">编辑
</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="batch-operate-container">
<el-select
size="small"
v-model="operateType" placeholder="批量操作">
<el-option
v-for="item in operates"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button
style="margin-left: 20px"
class="search-button"
@click="handleBatchOperate()"
type="primary"
size="small">
确定
</el-button>
</div>
<div class="pagination-container">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes,prev, pager, next,jumper"
:page-size="listQuery.pageSize"
:page-sizes="[5,10,15]"
:current-page.sync="listQuery.pageNum"
:total="total">
</el-pagination>
</el-card>
<el-card class="operate-container" shadow="never">
<i class="el-icon-tickets" />
<span>数据列表</span>
<el-button
class="btn-add"
size="mini"
@click="addBrand()"
>
添加
</el-button>
</el-card>
<div class="table-container">
<el-table
ref="brandTable"
v-loading="listLoading"
:data="list"
style="width: 100%"
border
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="60" align="center" />
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{ scope.row.id }}</template>
</el-table-column>
<el-table-column label="品牌名称" align="center">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="品牌首字母" width="100" align="center">
<template slot-scope="scope">{{ scope.row.firstLetter }}</template>
</el-table-column>
<el-table-column label="排序" width="100" align="center">
<template slot-scope="scope">{{ scope.row.sort }}</template>
</el-table-column>
<el-table-column label="品牌制造商" width="100" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.factoryStatus"
:active-value="1"
:inactive-value="0"
@change="handleFactoryStatusChange(scope.$index, scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="是否显示" width="100" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.showStatus"
:active-value="1"
:inactive-value="0"
@change="handleShowStatusChange(scope.$index, scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="相关" width="220" align="center">
<template slot-scope="scope">
<span>商品</span>
<el-button
size="mini"
type="text"
@click="getProductList(scope.$index, scope.row)"
>100
</el-button>
<span>评价</span>
<el-button
size="mini"
type="text"
@click="getProductCommentList(scope.$index, scope.row)"
>1000
</el-button>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleUpdate(scope.$index, scope.row)"
>编辑
</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="batch-operate-container">
<el-select
v-model="operateType"
size="small"
placeholder="批量操作"
>
<el-option
v-for="item in operates"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-button
style="margin-left: 20px"
class="search-button"
type="primary"
size="small"
@click="handleBatchOperate()"
>
确定
</el-button>
</div>
<div class="pagination-container">
<el-pagination
background
layout="total, sizes,prev, pager, next,jumper"
:page-size="listQuery.pageSize"
:page-sizes="[5,10,15]"
:current-page.sync="listQuery.pageNum"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
</template>
<script>
import {fetchList, updateShowStatus, updateFactoryStatus, deleteBrand} from '@/api/brand'
import { fetchList, updateShowStatus, updateFactoryStatus, deleteBrand } from '@/api/brand'
export default {
name: 'brandList',
name: 'BrandList',
data() {
return {
operates: [
@ -158,24 +171,24 @@
}
},
created() {
this.getList();
this.getList()
},
methods: {
getList() {
this.listLoading = true;
this.listLoading = true
fetchList(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.records;
this.total = response.data.total;
this.totalPage = response.data.pages;
this.pageSize = response.data.size;
});
this.listLoading = false
this.list = response.data.records
this.total = response.data.total
this.totalPage = response.data.pages
this.pageSize = response.data.size
})
},
handleSelectionChange(val) {
this.multipleSelection = val;
this.multipleSelection = val
},
handleUpdate(index, row) {
this.$router.push({path: '/pms/updateBrand', query: {id: row.id}})
this.$router.push({ path: '/pms/updateBrand', query: { id: row.id }})
},
handleDelete(index, row) {
this.$confirm('是否要删除该品牌', '提示', {
@ -188,115 +201,113 @@
message: '删除成功',
type: 'success',
duration: 1000
});
this.getList();
});
});
})
this.getList()
})
})
},
getProductList(index, row) {
console.log(index, row);
console.log(index, row)
},
getProductCommentList(index, row) {
console.log(index, row);
console.log(index, row)
},
handleFactoryStatusChange(index, row) {
var data = new URLSearchParams();
data.append("ids", row.id);
data.append("factoryStatus", row.factoryStatus);
var data = new URLSearchParams()
data.append('ids', row.id)
data.append('factoryStatus', row.factoryStatus)
updateFactoryStatus(data).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
})
}).catch(error => {
if (row.factoryStatus === 0) {
row.factoryStatus = 1;
row.factoryStatus = 1
} else {
row.factoryStatus = 0;
row.factoryStatus = 0
}
});
})
},
handleShowStatusChange(index, row) {
let data = new URLSearchParams();
;
data.append("ids", row.id);
data.append("showStatus", row.showStatus);
const data = new URLSearchParams()
data.append('ids', row.id)
data.append('showStatus', row.showStatus)
updateShowStatus(data).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
})
}).catch(error => {
if (row.showStatus === 0) {
row.showStatus = 1;
row.showStatus = 1
} else {
row.showStatus = 0;
row.showStatus = 0
}
});
})
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
this.listQuery.pageNum = 1
this.listQuery.pageSize = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
this.listQuery.pageNum = val
this.getList()
},
searchBrandList() {
this.listQuery.pageNum = 1;
this.getList();
this.listQuery.pageNum = 1
this.getList()
},
handleBatchOperate() {
console.log(this.multipleSelection);
console.log(this.multipleSelection)
if (this.multipleSelection < 1) {
this.$message({
message: '请选择一条记录',
type: 'warning',
duration: 1000
});
return;
})
return
}
let showStatus = 0;
let showStatus = 0
if (this.operateType === 'showBrand') {
showStatus = 1;
showStatus = 1
} else if (this.operateType === 'hideBrand') {
showStatus = 0;
showStatus = 0
} else {
this.$message({
message: '请选择批量操作类型',
type: 'warning',
duration: 1000
});
return;
})
return
}
let ids = [];
const ids = []
for (let i = 0; i < this.multipleSelection.length; i++) {
ids.push(this.multipleSelection[i].id);
ids.push(this.multipleSelection[i].id)
}
let data = new URLSearchParams();
data.append("ids", ids);
data.append("showStatus", showStatus);
const data = new URLSearchParams()
data.append('ids', ids)
data.append('showStatus', showStatus)
updateShowStatus(data).then(response => {
this.getList();
this.getList()
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
})
})
},
addBrand() {
this.$router.push({path: '/pms/addBrand'})
this.$router.push({ path: '/pms/addBrand' })
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
</style>

12
src/views/pms/product/add.vue

@ -0,0 +1,12 @@
<template> 
<product-detail :is-edit='false'></product-detail>
</template>
<script>
import ProductDetail from './components/ProductDetail'
export default {
name: 'addProduct',
components: { ProductDetail }
}
</script>
<style>
</style>

609
src/views/pms/product/components/ProductAttrDetail.vue

@ -0,0 +1,609 @@
<template>
<div style="margin-top: 50px">
<el-form :model="value" ref="productAttrForm" label-width="150px" style="width: 720px" size="small">
<el-form-item label="商品类型:">
<el-select v-model="value.productAttributeCategoryId"
placeholder="请选择属性类型"
@change="handleProductAttrChange">
<el-option
v-for="item in productAttributeCategoryOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="商品规格:">
<el-card shadow="never" class="cardBg">
<div v-for="(productAttr,idx) in selectProductAttr">
{{productAttr.name}}
<el-checkbox-group v-if="productAttr.handAddStatus===0" v-model="selectProductAttr[idx].values">
<el-checkbox v-for="item in getInputListArr(productAttr.inputList)" :label="item" :key="item"
class="littleMarginLeft"></el-checkbox>
</el-checkbox-group>
<div v-else>
<el-checkbox-group v-model="selectProductAttr[idx].values">
<div v-for="(item,index) in selectProductAttr[idx].options" style="display: inline-block"
class="littleMarginLeft">
<el-checkbox :label="item" :key="item"></el-checkbox>
<el-button type="text" class="littleMarginLeft" @click="handleRemoveProductAttrValue(idx,index)">删除
</el-button>
</div>
</el-checkbox-group>
<el-input v-model="addProductAttrValue" style="width: 160px;margin-left: 10px" clearable></el-input>
<el-button class="littleMarginLeft" @click="handleAddProductAttrValue(idx)">增加</el-button>
</div>
</div>
</el-card>
<el-table style="width: 100%;margin-top: 20px"
:data="value.skuStockList"
border>
<el-table-column
v-for="(item,index) in selectProductAttr"
:label="item.name"
:key="item.id"
align="center">
<template slot-scope="scope">
{{getProductSkuSp(scope.row,index)}}
</template>
</el-table-column>
<el-table-column
label="销售价格"
width="80"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.price"></el-input>
</template>
</el-table-column>
<el-table-column
label="商品库存"
width="80"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.stock"></el-input>
</template>
</el-table-column>
<el-table-column
label="库存预警值"
width="80"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.lowStock"></el-input>
</template>
</el-table-column>
<el-table-column
label="SKU编号"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.skuCode"></el-input>
</template>
</el-table-column>
<el-table-column label="属性图片:" align="left">
<template slot-scope="scope">
<single-upload v-model="scope.row.pic"
style="width: 300px;display: inline-block;margin-left: 10px"></single-upload>
</template>
</el-table-column>
<el-table-column
label="操作"
width="80"
align="center">
<template slot-scope="scope">
<el-button
type="text"
@click="handleRemoveProductSku(scope.$index, scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-button
type="primary"
style="margin-top: 20px"
@click="handleRefreshProductSkuList">刷新列表
</el-button>
<el-button
type="primary"
style="margin-top: 20px"
@click="handleSyncProductSkuPrice">同步价格
</el-button>
</el-form-item> -->
<!--<el-form-item label="属性图片:" v-if="hasAttrPic">
<el-card shadow="never" class="cardBg">
<div v-for="(item,index) in selectProductAttrPics">
<span>{{item.name}}:</span>
<single-upload v-model="item.pic"
style="width: 300px;display: inline-block;margin-left: 10px"></single-upload>
</div>
</el-card>
</el-form-item>-->
<!-- <el-form-item label="商品参数:">
<el-card shadow="never" class="cardBg">
<div v-for="(item,index) in selectProductParam" :class="{littleMarginTop:index!==0}">
<div class="paramInputLabel">{{item.name}}:</div>
<el-select v-if="item.inputType===1" class="paramInput" v-model="selectProductParam[index].value">
<el-option
v-for="item in getParamInputList(item.inputList)"
:key="item"
:label="item"
:value="item">
</el-option>
</el-select>
<el-input v-else class="paramInput" v-model="selectProductParam[index].value"></el-input>
</div>
</el-card>
</el-form-item> -->
<el-form-item label="商品相册:">
<multi-upload v-model="selectProductPics"></multi-upload>
</el-form-item>
<el-form-item label="规格参数:">
<el-tabs v-model="activeHtmlName" type="card">
<!-- <el-tab-pane label="电脑端详情" name="pc">
<tinymce :width="595" :height="300" v-model="value.detailHtml"></tinymce>
</el-tab-pane> -->
<el-tab-pane label="移动端详情" name="mobile">
<!-- <tinymce :width="595" :height="300" v-model="value.detailMobileHtml"></tinymce> -->
<tinymce :width="595" :height="300" v-model="value.detailHtml"></tinymce>
</el-tab-pane>
</el-tabs>
</el-form-item>
<el-form-item style="text-align: center">
<el-button size="medium" @click="handlePrev">上一步</el-button>
<!-- <el-button type="primary" size="medium" @click="handleNext">下一步选择商品关联</el-button> -->
<el-button type="primary" size="medium" @click="handleFinishCommit">保存商品</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {fetchList as fetchProductAttrCateList} from '@/api/productAttrCate'
import {fetchList as fetchProductAttrList} from '@/api/productAttr'
import SingleUpload from '@/components/Upload/singleUpload'
import MultiUpload from '@/components/Upload/multiUpload'
import Tinymce from '@/components/Tinymce'
export default {
name: "ProductAttrDetail",
components: {SingleUpload, MultiUpload, Tinymce},
props: {
value: Object,
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
//
hasEditCreated:false,
//
productAttributeCategoryOptions: [],
//
selectProductAttr: [],
//
selectProductParam: [],
//
selectProductAttrPics: [],
//
addProductAttrValue: '',
//
activeHtmlName: 'mobile'
}
},
computed: {
//
hasAttrPic() {
if (this.selectProductAttrPics.length < 1) {
return false;
}
return true;
},
//
productId(){
return this.value.id;
},
//
selectProductPics:{
get:function () {
let pics=[];
if(this.value.pic===undefined||this.value.pic==null||this.value.pic===''){
return pics;
}
pics.push(this.value.pic);
if(this.value.albumPics===undefined||this.value.albumPics==null||this.value.albumPics===''){
return pics;
}
let albumPics = this.value.albumPics.split(',');
for(let i=0;i<albumPics.length;i++){
pics.push(albumPics[i]);
}
return pics;
},
set:function (newValue) {
if (newValue == null || newValue.length === 0) {
this.value.pic = null;
this.value.albumPics = null;
} else {
this.value.pic = newValue[0];
this.value.albumPics = '';
if (newValue.length > 1) {
for (let i = 1; i < newValue.length; i++) {
this.value.albumPics += newValue[i];
if (i !== newValue.length - 1) {
this.value.albumPics += ',';
}
}
}
}
}
}
},
created() {
this.getProductAttrCateList();
},
watch: {
productId:function (newValue) {
if(!this.isEdit)return;
if(this.hasEditCreated)return;
if(newValue===undefined||newValue==null||newValue===0)return;
this.handleEditCreated();
}
},
methods: {
handleEditCreated() {
//id
if(this.value.productAttributeCategoryId!=null){
this.handleProductAttrChange(this.value.productAttributeCategoryId);
}
this.hasEditCreated=true;
},
getProductAttrCateList() {
let param = {pageNum: 1, pageSize: 100};
fetchProductAttrCateList(param).then(response => {
this.productAttributeCategoryOptions = [];
let list = response.data.records;
for (let i = 0; i < list.length; i++) {
this.productAttributeCategoryOptions.push({label: list[i].name, value: list[i].id});
}
});
},
getProductAttrList(type, cid) {
let param = {pageNum: 1, pageSize: 3, type: type};
fetchProductAttrList(cid, param).then(response => {
let list = response.data.records;
if (type === 0) {
this.selectProductAttr = [];
for (let i = 0; i < list.length; i++) {
let options = [];
let values = [];
if (this.isEdit) {
if (list[i].handAddStatus === 1) {
//
options = this.getEditAttrOptions(list[i].id);
}
//
values = this.getEditAttrValues(i);
}
this.selectProductAttr.push({
id: list[i].id,
name: list[i].name,
handAddStatus: list[i].handAddStatus,
inputList: list[i].inputList,
values: values,
options: options
});
}
if(this.isEdit){
//
this.refreshProductAttrPics();
}
} else {
this.selectProductParam = [];
for (let i = 0; i < list.length; i++) {
let value=null;
if(this.isEdit){
//
value= this.getEditParamValue(list[i].id);
}
this.selectProductParam.push({
id: list[i].id,
name: list[i].name,
value: value,
inputType: list[i].inputType,
inputList: list[i].inputList
});
}
}
});
},
//
getEditAttrOptions(id) {
let options = [];
for (let i = 0; i < this.value.productAttributeValueList.length; i++) {
let attrValue = this.value.productAttributeValueList[i];
if (attrValue.productAttributeId === id) {
let strArr = attrValue.value.split(',');
for (let j = 0; j < strArr.length; j++) {
options.push(strArr[j]);
}
break;
}
}
return options;
},
//
getEditAttrValues(index) {
let values = [];
if (index === 0) {
for (let i = 0; i < this.value.skuStockList.length; i++) {
let sku = this.value.skuStockList[i];
if (sku.sp1 != null && values.indexOf(sku.sp1) === -1) {
values.push(sku.sp1);
}
}
} else if (index === 1) {
for (let i = 0; i < this.value.skuStockList.length; i++) {
let sku = this.value.skuStockList[i];
if (sku.sp2 != null && values.indexOf(sku.sp2) === -1) {
values.push(sku.sp2);
}
}
} else {
for (let i = 0; i < this.value.skuStockList.length; i++) {
let sku = this.value.skuStockList[i];
if (sku.sp3 != null && values.indexOf(sku.sp3) === -1) {
values.push(sku.sp3);
}
}
}
return values;
},
//
getEditParamValue(id){
for(let i=0;i<this.value.productAttributeValueList.length;i++){
if(id===this.value.productAttributeValueList[i].productAttributeId){
return this.value.productAttributeValueList[i].value;
}
}
},
handleProductAttrChange(value) {
this.getProductAttrList(0, value);
this.getProductAttrList(1, value);
},
getInputListArr(inputList) {
return inputList.split(',');
},
handleAddProductAttrValue(idx) {
let options = this.selectProductAttr[idx].options;
if (this.addProductAttrValue == null || this.addProductAttrValue == '') {
this.$message({
message: '属性值不能为空',
type: 'warning',
duration: 1000
});
return
}
if (options.indexOf(this.addProductAttrValue) !== -1) {
this.$message({
message: '属性值不能重复',
type: 'warning',
duration: 1000
});
return;
}
this.selectProductAttr[idx].options.push(this.addProductAttrValue);
this.addProductAttrValue = null;
},
handleRemoveProductAttrValue(idx, index) {
this.selectProductAttr[idx].options.splice(index, 1);
},
getProductSkuSp(row, index) {
if (index === 0) {
return row.sp1;
} else if (index === 1) {
return row.sp2;
} else {
return row.sp3;
}
},
handleRefreshProductSkuList() {
this.$confirm('刷新列表将导致sku信息重新生成,是否要刷新', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// this.refreshProductAttrPics();
this.refreshProductSkuList();
});
},
handleSyncProductSkuPrice(){
this.$confirm('将同步第一个sku的价格到所有sku,是否继续', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if(this.value.skuStockList!==null&&this.value.skuStockList.length>0){
let price=this.value.skuStockList[0].price;
for(let i=0;i<this.value.skuStockList.length;i++){
this.value.skuStockList[i].price=price;
}
}
});
},
refreshProductSkuList() {
this.value.skuStockList = [];
let skuList = this.value.skuStockList;
//
if (this.selectProductAttr.length === 1) {
let values = this.selectProductAttr[0].values;
for (let i = 0; i < values.length; i++) {
skuList.push({
sp1: values[i]
});
}
} else if (this.selectProductAttr.length === 2) {
let values0 = this.selectProductAttr[0].values;
let values1 = this.selectProductAttr[1].values;
for (let i = 0; i < values0.length; i++) {
if (values1.length === 0) {
skuList.push({
sp1: values0[i]
});
continue;
}
for (let j = 0; j < values1.length; j++) {
skuList.push({
sp1: values0[i],
sp2: values1[j]
});
}
}
} else {
let values0 = this.selectProductAttr[0].values;
let values1 = this.selectProductAttr[1].values;
let values2 = this.selectProductAttr[2].values;
for (let i = 0; i < values0.length; i++) {
if (values1.length === 0) {
skuList.push({
sp1: values0[i]
});
continue;
}
for (let j = 0; j < values1.length; j++) {
if (values2.length === 0) {
skuList.push({
sp1: values0[i],
sp2: values1[j]
});
continue;
}
for (let k = 0; k < values2.length; k++) {
skuList.push({
sp1: values0[i],
sp2: values1[j],
sp3: values2[k]
});
}
}
}
}
},
refreshProductAttrPics() {
this.selectProductAttrPics = [];
if (this.selectProductAttr.length >= 1) {
let values = this.selectProductAttr[0].values;
for (let i = 0; i < values.length; i++) {
let pic=null;
if(this.isEdit){
//
pic=this.getProductSkuPic(values[i]);
}
this.selectProductAttrPics.push({name: values[i], pic: pic})
}
}
},
//
getProductSkuPic(name){
for(let i=0;i<this.value.skuStockList.length;i++){
if(name===this.value.skuStockList[i].sp1){
return this.value.skuStockList[i].pic;
}
}
return null;
},
//
mergeProductAttrValue() {
this.value.productAttributeValueList = [];
for (let i = 0; i < this.selectProductAttr.length; i++) {
let attr = this.selectProductAttr[i];
if (attr.handAddStatus === 1 && attr.options != null && attr.options.length > 0) {
this.value.productAttributeValueList.push({
productAttributeId: attr.id,
name: attr.name,
type:1,
value: this.getOptionStr(attr.options)
});
}
}
for (let i = 0; i < this.selectProductParam.length; i++) {
let param = this.selectProductParam[i];
this.value.productAttributeValueList.push({
productAttributeId: param.id,
name: param.name,
type:2,
value: param.value
});
}
},
//
mergeProductAttrPics() {
for (let i = 0; i < this.selectProductAttrPics.length; i++) {
for (let j = 0; j < this.value.skuStockList.length; j++) {
if (this.value.skuStockList[j].sp1 === this.selectProductAttrPics[i].name) {
this.value.skuStockList[j].pic = this.selectProductAttrPics[i].pic;
}
}
}
},
getOptionStr(arr) {
let str = '';
for (let i = 0; i < arr.length; i++) {
str += arr[i];
if (i != arr.length - 1) {
str += ',';
}
}
return str;
},
handleRemoveProductSku(index, row) {
let list = this.value.skuStockList;
if (list.length === 1) {
list.pop();
} else {
list.splice(index, 1);
}
},
getParamInputList(inputList) {
return inputList.split(',');
},
handlePrev() {
this.$emit('prevStep')
},
handleNext() {
this.mergeProductAttrValue();
this.mergeProductAttrPics();
this.$emit('nextStep')
},
handleFinishCommit(){
this.$emit('finishCommit',this.isEdit);
}
}
}
</script>
<style scoped>
.littleMarginLeft {
margin-left: 10px;
}
.littleMarginTop {
margin-top: 10px;
}
.paramInput {
width: 250px;
}
.paramInputLabel {
display: inline-block;
width: 100px;
text-align: right;
padding-right: 10px
}
.cardBg {
background: #F8F9FC;
}
</style>

201
src/views/pms/product/components/ProductDetail.vue

@ -0,0 +1,201 @@
<template> 
<el-card class="form-container" shadow="never">
<el-steps :active="active" finish-status="success" align-center>
<el-step title="商品息信"></el-step>
<el-step title="商品展示"></el-step>
<el-step title="图片及详情"></el-step>
</el-steps>
<product-info-detail v-show="showStatus[0]" v-model="productParam" :is-edit="isEdit" @nextStep="nextStep">
</product-info-detail>
<product-sale-detail v-show="showStatus[1]" v-model="productParam" :is-edit="isEdit" @nextStep="nextStep"
@prevStep="prevStep">
</product-sale-detail>
<product-attr-detail v-show="showStatus[2]" v-model="productParam" :is-edit="isEdit"
@finishCommit="finishCommit" @nextStep="nextStep" @prevStep="prevStep">
</product-attr-detail>
<!-- <product-relation-detail
v-show="showStatus[3]"
v-model="productParam"
:is-edit="isEdit"
@prevStep="prevStep"
@finishCommit="finishCommit">
</product-relation-detail> -->
</el-card>
</template>
<script>
import ProductInfoDetail from './ProductInfoDetail';
import ProductSaleDetail from './ProductSaleDetail';
import ProductAttrDetail from './ProductAttrDetail';
// import ProductRelationDetail from './ProductRelationDetail';
import {
createProduct,
getProduct,
updateProduct
} from '@/api/product';
const defaultProductParam = {
albumPics: '',
brandId: null,
brandName: '',
deleteStatus: 0,
description: '',
tags: '',
tagsArr: '',
detailDesc: '',
detailHtml: '',
detailMobileHtml: '',
detailTitle: '',
feightTemplateId: 0,
flashPromotionCount: 0,
flashPromotionId: 0,
flashPromotionPrice: 0,
flashPromotionSort: 0,
giftPoint: 0,
giftGrowth: 0,
keywords: '',
lowStock: 0,
name: '',
newStatus: 0,
note: '',
originalPrice: 0,
pic: '',
//{memberLevelId: 0,memberPrice: 0,memberLevelName: null}
memberPriceList: [],
//
productFullReductionList: [{
fullPrice: 0,
reducePrice: 0
}],
//
productLadderList: [{
count: 0,
discount: 0,
price: 0
}],
previewStatus: 0,
price: 0,
productAttributeCategoryId: null,
//{productAttributeId: 0, value: ''}
productAttributeValueList: [],
//sku{lowStock: 0, pic: '', price: 0, sale: 0, skuCode: '', sp1: '', sp2: '', sp3: '', stock: 0}
skuStockList: [],
//{subjectId: 0}
subjectProductRelationList: [],
//{prefrenceAreaId: 0}
prefrenceAreaProductRelationList: [],
productCategoryId: null,
productCategoryName: '',
areaId: null,
areaName: '',
productSn: '',
promotionEndTime: '',
promotionPerLimit: 0,
promotionPrice: 0,
promotionStartTime: '',
promotionType: 0,
storeClassId: null,
publishStatus: 0,
isFenxiao: 0,
isVip: 0,
recommandStatus: 0,
sale: 0,
serviceIds: '',
sort: 0,
stock: 0,
subTitle: '',
unit: '',
usePointLimit: 0,
verifyStatus: 0,
transfee: 0,
weight: 0
};
export default {
name: 'ProductDetail',
components: {
ProductInfoDetail,
ProductSaleDetail,
ProductAttrDetail
// , ProductRelationDetail
},
props: {
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
active: 0,
productParam: Object.assign({}, defaultProductParam),
showStatus: [true, false, false, false]
}
},
created() {
if (this.isEdit) {
getProduct(this.$route.query.id).then(response => {
this.productParam = response.data;
console.log('kkkkk', this.productParam)
});
}
},
methods: {
hideAll() {
for (let i = 0; i < this.showStatus.length; i++) {
this.showStatus[i] = false;
}
},
prevStep() {
if (this.active > 0 && this.active < this.showStatus.length) {
this.active--;
this.hideAll();
this.showStatus[this.active] = true;
}
},
nextStep() {
if (this.active < this.showStatus.length - 1) {
this.active++;
this.hideAll();
this.showStatus[this.active] = true;
}
},
finishCommit(isEdit) {
console.log(this.productParam)
if (this.productParam.tagList) {
this.productParam.tags = this.productParam.tagList.join(',');
this.productParam.tagList = null;
}
this.$confirm('是否要提交该产品', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (isEdit) {
updateProduct(this.$route.query.id, this.productParam).then(response => {
this.$message({
type: 'success',
message: '提交成功',
duration: 1000
});
this.$router.back();
});
} else {
createProduct(this.productParam).then(response => {
this.$message({
type: 'success',
message: '提交成功',
duration: 1000
});
location.reload();
});
}
})
}
}
}
</script>
<style>
.form-container {
width: 800px;
}
</style>

434
src/views/pms/product/components/ProductInfoDetail.vue

@ -0,0 +1,434 @@
<template>
<div style="margin-top: 50px">
<el-form :model="value" :rules="rules" ref="productInfoForm" label-width="120px" style="width: 600px" size="small">
<el-form-item label="商品分类:" prop="productCategoryId">
<el-cascader
change-on-select
v-model="selectProductCateValue"
:options="productCateOptions">
</el-cascader>
</el-form-item>
<el-form-item label="商品名称:" prop="name">
<el-input v-model="value.name"></el-input>
</el-form-item>
<el-form-item label="副标题:" prop="subTitle">
<el-input v-model="value.subTitle"></el-input>
</el-form-item>
<el-form-item label="商品品牌:" prop="brandId">
<el-select
v-model="value.brandId"
@change="handleBrandChange"
placeholder="请选择品牌">
<el-option
v-for="item in brandOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<!-- <el-form-item label="店内分类:" prop="storeClassId">
<el-select
v-model="value.storeClassId"
placeholder="请选择店内分类">
<el-option
v-for="item in storeClassOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="区域:" prop="areaId">
<el-cascader
change-on-select
v-model="selectAreaValue"
:options="areaOptions">
</el-cascader>
</el-form-item> -->
<el-form-item label="标签" prop="tags">
<el-select
v-model="value.tagList"
style="width: 437px"
multiple
placeholder="请选择"
@remove-tag="deleteTag"
@change="changeRole"
>
<el-option
v-for="item in TagList"
:key="item.name"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="商品介绍:">
<el-input
:autoSize="true"
v-model="value.description"
type="textarea"
placeholder="请输入内容"></el-input>
</el-form-item>
<el-form-item label="商品货号:">
<el-input v-model="value.productSn"></el-input>
</el-form-item>
<el-form-item label="商品售价:">
<el-input v-model="value.price"></el-input>
</el-form-item>
<el-form-item label="惠农价:">
<el-input v-model="value.originalPrice"></el-input>
</el-form-item>
<el-form-item label="商品库存:">
<el-input v-model="value.stock"></el-input>
</el-form-item>
<el-form-item label="计量单位:">
<el-select
v-model="value.unit"
placeholder="请选择计量单位">
<el-option
v-for="item in unitOptions"
:key="item.id"
:label="item.id"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="商品重量:">
<el-input v-model="value.weight" style="width: 300px"></el-input>
<span style="margin-left: 20px">千克</span>
</el-form-item>
<!-- <el-form-item label="固定运费:">
<el-input v-model="value.transfee" style="width: 300px"></el-input>
<span style="margin-left: 20px">优先于运费模版</span>
</el-form-item>
<el-form-item label="运费模版::">
<el-select
v-model="value.feightTemplateId"
placeholder="请选择运费模版">
<el-option
v-for="item in feightTemplateOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item> -->
<el-form-item label="排序">
<el-input v-model="value.sort"></el-input>
</el-form-item>
<el-form-item style="text-align: center">
<el-button type="primary" size="medium" @click="handleNext('productInfoForm')">下一步</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {fetchListWithChildren} from '@/api/productCate'
import {fetchAreaListWithChildren,getArea} from '@/api/area'
import {fetchList as fetchTagList} from '@/api/ums/umsMemberTag'
import {fetchList as fetchBrandList} from '@/api/brand'
import {fetchList as fetchStoreClassList} from '@/api/sys/sysStoreClass'
import {fetchList as fetchFeightTemplateList} from '@/api/pms/feightTemplate';
import {getProduct} from '@/api/product';
let userRoles = []
export default {
name: "ProductInfoDetail",
props: {
value: Object,
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
hasEditCreated:false,
//
selectProductCateValue: [],
productCateOptions: [],
//
selectAreaValue: [],
areaOptions: [],
brandOptions: [],
storeClassOptions:[],
area:null,
TagList:[],
areaList:[],
feightTemplateOptions:[],
unitOptions:[{
id: "个",
name: "个",
},{
id: "袋",
name: "袋",
},
{
id: "箱",
name: "箱",
},
{
id: "条",
name: "条",
},
{
id: "盒",
name: "盒",
},{
id: "包",
name: "包",
},{
id: "斤",
name: "斤",
},{
id: "两",
name: "两",
},{
id: "件",
name: "件",
},{
id: "瓶",
name: "瓶",
},{
id: "千克",
name: "千克",
}],
rules: {
name: [
{required: true, message: '请输入商品名称', trigger: 'blur'},
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
],
subTitle: [{required: true, message: '请输入商品副标题', trigger: 'blur'}],
productCategoryId: [{required: true, message: '请选择商品分类', trigger: 'blur'}],
brandId: [{required: true, message: '请选择商品品牌', trigger: 'blur'}],
description: [{required: true, message: '请输入商品介绍', trigger: 'blur'}],
requiredProp: [{required: true, message: '该项为必填项', trigger: 'blur'}]
}
};
},
created() {
this.getProductCateList();
this.getAreaList();
this.getBrandList();
this.getTagList();
this.getFeightTemplateList();
this.getStoreClassList();
},
computed:{
//
productId(){
return this.value.id;
}
},
watch: {
productId:function(newValue){
if(!this.isEdit)return;
if(this.hasEditCreated)return;
console.log(newValue)
if(newValue===undefined||newValue==null||newValue===0)return;
this.handleEditCreated();
},
selectProductCateValue: function (newValue) {
if (newValue != null) {
this.value.productCategoryId = newValue[newValue.length-1 >0?newValue.length-1:0];
this.value.productCategoryName= this.getCateNameById(this.value.productCategoryId);
} else {
this.value.productCategoryId = null;
this.value.productCategoryName=null;
}
},
selectAreaValue: function (newValue) {
if (newValue != null) {
console.log(newValue)
this.value.areaId = newValue[newValue.length-1 >0?newValue.length-1:0];
getArea(this.value.areaId).then(response => {
this.value.areaName = response.data.name;
});
} else {
this.value.areaId = null;
this.value.areaName=null;
}
}
},
methods: {
changeRole(value) {
userRoles = []
value.forEach(function(data, index) {
const role = { id: data }
userRoles.push(role)
})
},
deleteTag(value) {
userRoles.forEach(function(data, index) {
if (data.id === value) {
userRoles.splice(index, value)
}
})
},
afterErrorMethod(crud) {
// select
const initRoles = []
userRoles.forEach(function(role, index) {
initRoles.push(role.id)
})
this.value.tagList = initRoles
},
//
handleEditCreated(){
console.log(this.value)
if(this.value.productCategoryId!=null){
let seleval = []
seleval.push(this.value.cateParentId);
seleval.push(this.value.productCategoryId);
this.selectProductCateValue = seleval
// this.selectProductCateValue.push(this.value.cateParentId);
// this.selectProductCateValue.push(this.value.productCategoryId);
}
if(this.value.areaId!=null){
getArea(this.value.areaId).then(response => {
this.selectAreaValue.push(response.data.pid);
this.selectAreaValue.push(this.value.areaId);
});
}
console.log(this.selectAreaValue)
userRoles = []
const roles = []
this.value.tagList.forEach(function(role, index) {
roles.push(role.id)
//
const rol = { id: role.id }
userRoles.push(rol)
})
console.log(this.value.tagList)
this.value.tagList = roles
this.hasEditCreated=true;
},
getAreaList() {
fetchAreaListWithChildren().then(response => {
let list = response.data;
this.areaList=list;
this.areaOptions = [];
for (let i = 0; i < list.length; i++) {
let children = [];
if (list[i].children != null && list[i].children.length > 0) {
for (let j = 0; j < list[i].children.length; j++) {
children.push({label: list[i].children[j].name, value: list[i].children[j].id});
}
}
this.areaOptions.push({label: list[i].name, value: list[i].id, children: children});
}
});
},
getCateNameById(id){
let name=null;
for(let i=0;i<this.productCateOptions.length;i++){
for(let j=0;j<this.productCateOptions[i].children.length;j++){
if( this.productCateOptions[i].children[j].value && this.productCateOptions[i].children[j].value!=undefined && this.productCateOptions[i].children[j].value===id){
name=this.productCateOptions[i].children[j].label;
return name;
}
}
}
return name;
},
getProductCateList() {
fetchListWithChildren().then(response => {
let list = response.data;
this.productCateOptions = [];
for (let i = 0; i < list.length; i++) {
let children = [];
if (list[i].children != null && list[i].children.length > 0) {
for (let j = 0; j < list[i].children.length; j++) {
children.push({label: list[i].children[j].name, value: list[i].children[j].id});
}
}
this.productCateOptions.push({label: list[i].name, value: list[i].id, children: children});
}
});
},
getFeightTemplateList() {
fetchFeightTemplateList({pageNum: 1, pageSize: 100}).then(response => {
this.feightTemplateOptions = [];
let feightTemplateList = response.data.records;
for (let i = 0; i < feightTemplateList.length; i++) {
this.feightTemplateOptions.push({label: feightTemplateList[i].name, value: feightTemplateList[i].id});
}
});
},
getBrandList() {
fetchBrandList({pageNum: 1, pageSize: 100}).then(response => {
this.brandOptions = [];
let brandList = response.data.records;
for (let i = 0; i < brandList.length; i++) {
this.brandOptions.push({label: brandList[i].name, value: brandList[i].id});
}
});
},
getStoreClassList() {
fetchStoreClassList({pageNum: 1, pageSize: 100}).then(response => {
this.storeClassOptions = [];
let brandList = response.data.records;
for (let i = 0; i < brandList.length; i++) {
this.storeClassOptions.push({label: brandList[i].name, value: brandList[i].id});
}
});
},
getTagList() {
fetchTagList({pageNum: 1, pageSize: 100,type:2,status:1}).then(response => {
this.TagList = response.data.records;
});
},
handleNext(formName){
this.$refs[formName].validate((valid) => {
if (valid) {
this.$emit('nextStep');
} else {
this.$message({
message: '验证失败',
type: 'error',
duration:1000
});
return false;
}
});
},
handleBrandChange(val) {
let brandName = '';
for (let i = 0; i < this.brandOptions.length; i++) {
if (this.brandOptions[i].value === val) {
brandName = this.brandOptions[i].label;
break;
}
}
this.value.brandName = brandName;
}
}
}
</script>
<style scoped>
</style>

145
src/views/pms/product/components/ProductRelationDetail.vue

@ -0,0 +1,145 @@
<template>
<div style="margin-top: 50px">
<el-form :model="value"
ref="productRelationForm"
label-width="120px"
style="width: 680px"
size="small">
<el-form-item label="关联专题:">
<el-transfer
style="display: inline-block"
filterable
:filter-method="filterMethod"
filter-placeholder="请输入专题名称"
v-model="selectSubject"
:titles="subjectTitles"
:data="subjectList">
</el-transfer>
</el-form-item>
<el-form-item label="关联优选:">
<el-transfer
style="display: inline-block"
filterable
:filter-method="filterMethod"
filter-placeholder="请输入优选名称"
v-model="selectPrefrenceArea"
:titles="prefrenceAreaTitles"
:data="prefrenceAreaList">
</el-transfer>
</el-form-item>
<el-form-item style="text-align: center">
<el-button size="medium" @click="handlePrev">上一步填写商品属性</el-button>
<el-button type="primary" size="medium" @click="handleFinishCommit">完成提交商品</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {fetchList as fetchSubjectList} from '@/api/cms/subject'
import {fetchList as fetchPrefrenceAreaList} from '@/api/prefrenceArea'
export default {
name: "ProductRelationDetail",
props: {
value: Object,
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
//
subjectList: [],
//
subjectTitles: ['待选择', '已选择'],
//
prefrenceAreaList: [],
//
prefrenceAreaTitles: ['待选择', '已选择']
};
},
created() {
this.getSubjectList();
this.getPrefrenceAreaList();
},
computed:{
//
selectSubject:{
get:function () {
let subjects =[];
if(this.value.subjectProductRelationList==null||this.value.subjectProductRelationList.length<=0){
return subjects;
}
for(let i=0;i<this.value.subjectProductRelationList.length;i++){
subjects.push(this.value.subjectProductRelationList[i].subjectId);
}
return subjects;
},
set:function (newValue) {
this.value.subjectProductRelationList=[];
for(let i=0;i<newValue.length;i++){
this.value.subjectProductRelationList.push({subjectId:newValue[i]});
}
}
},
//
selectPrefrenceArea:{
get:function () {
let prefrenceAreas =[];
if(this.value.prefrenceAreaProductRelationList==null||this.value.prefrenceAreaProductRelationList.length<=0){
return prefrenceAreas;
}
for(let i=0;i<this.value.prefrenceAreaProductRelationList.length;i++){
prefrenceAreas.push(this.value.prefrenceAreaProductRelationList[i].prefrenceAreaId);
}
return prefrenceAreas;
},
set:function (newValue) {
this.value.prefrenceAreaProductRelationList=[];
for(let i=0;i<newValue.length;i++){
this.value.prefrenceAreaProductRelationList.push({prefrenceAreaId:newValue[i]});
}
}
}
},
methods: {
filterMethod(query, item) {
return item.label.indexOf(query) > -1;
},
getSubjectList() {
fetchSubjectList().then(response => {
let list = response.data.records;
for (let i = 0; i < list.length; i++) {
this.subjectList.push({
label: list[i].title,
key: list[i].id
});
}
});
},
getPrefrenceAreaList() {
fetchPrefrenceAreaList().then(response=>{
let list = response.data.records;
for (let i = 0; i < list.length; i++) {
this.prefrenceAreaList.push({
label: list[i].name,
key: list[i].id
});
}
});
},
handlePrev(){
this.$emit('prevStep')
},
handleFinishCommit(){
this.$emit('finishCommit',this.isEdit);
}
}
}
</script>
<style scoped>
</style>

322
src/views/pms/product/components/ProductSaleDetail.vue

@ -0,0 +1,322 @@
<template>
<div style="margin-top: 50px">
<el-form :model="value" ref="productSaleForm" label-width="120px" style="width: 600px" size="small">
<!-- <el-form-item label="赠送积分:">
<el-input v-model="value.giftPoint"></el-input>
</el-form-item>
<el-form-item label="赠送成长值:">
<el-input v-model="value.giftGrowth"></el-input>
</el-form-item>
<el-form-item label="积分购买限制:">
<el-input v-model="value.usePointLimit"></el-input>
</el-form-item>
<el-form-item label="预告商品:">
<el-switch
v-model="value.previewStatus"
:active-value="1"
:inactive-value="0">
</el-switch>
</el-form-item> -->
<el-form-item label="商品上架:">
<el-switch
v-model="value.publishStatus"
:active-value="1"
:inactive-value="0">
</el-switch>
</el-form-item>
<!-- <el-form-item label="分销商品:">
<el-switch
v-model="value.isFenxiao"
:active-value="1"
:inactive-value="0">
</el-switch>
</el-form-item>
<el-form-item label="会员商品:">
<el-switch
v-model="value.isVip"
:active-value="1"
:inactive-value="0">
</el-switch>
</el-form-item> -->
<el-form-item label="商品推荐:">
<span style="margin-right: 10px">新品</span>
<el-switch
v-model="value.newStatus"
:active-value="1"
:inactive-value="0">
</el-switch>
<span style="margin-left: 10px;margin-right: 10px">推荐</span>
<el-switch
v-model="value.recommandStatus"
:active-value="1"
:inactive-value="0">
</el-switch>
</el-form-item>
<el-form-item label="服务保证:">
<el-checkbox-group v-model="selectServiceList">
<el-checkbox :label="1">无忧退货</el-checkbox>
<el-checkbox :label="2">快速退款</el-checkbox>
<el-checkbox :label="3">正品保证</el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="详细页标题:">
<el-input v-model="value.detailTitle"></el-input>
</el-form-item>
<el-form-item label="详细页描述:">
<el-input v-model="value.detailDesc"></el-input>
</el-form-item>
<el-form-item label="商品关键字:">
<el-input v-model="value.keywords"></el-input>
</el-form-item>
<el-form-item label="商品备注:">
<el-input v-model="value.note" type="textarea" :autoSize="true"></el-input>
</el-form-item>
<!-- <el-form-item label="选择优惠方式:">
<el-radio-group v-model="value.promotionType" size="small">
<el-radio-button :label="0">无优惠</el-radio-button>
<el-radio-button :label="1">特惠促销</el-radio-button>
<el-radio-button :label="2">会员价格</el-radio-button>
<el-radio-button :label="3">阶梯价格</el-radio-button>
<el-radio-button :label="4">满减价格</el-radio-button>
</el-radio-group>
</el-form-item> -->
<el-form-item v-show="value.promotionType===1">
<div>
开始时间
<el-date-picker
v-model="value.promotionStartTime"
type="datetime"
:picker-options="pickerOptions1"
placeholder="选择开始时间">
</el-date-picker>
</div>
<div class="littleMargin">
结束时间
<el-date-picker
v-model="value.promotionEndTime"
type="datetime"
:picker-options="pickerOptions1"
placeholder="选择结束时间">
</el-date-picker>
</div>
<div class="littleMargin">
促销价格
<el-input style="width: 220px" v-model="value.promotionPrice" placeholder="输入促销价格"></el-input>
</div>
</el-form-item>
<el-form-item v-show="value.promotionType===2">
<div v-for="(item, index) in value.memberPriceList" :class="{littleMargin:index!==0}">
{{item.memberLevelName}}
<el-input v-model="item.memberPrice" style="width: 200px"></el-input>
</div>
</el-form-item>
<el-form-item v-show="value.promotionType===3">
<el-table :data="value.productLadderList"
style="width: 80%" border>
<el-table-column
label="数量"
align="center"
width="120">
<template slot-scope="scope">
<el-input v-model="scope.row.count"></el-input>
</template>
</el-table-column>
<el-table-column
label="折扣"
align="center"
width="120">
<template slot-scope="scope">
<el-input v-model="scope.row.discount"></el-input>
</template>
</el-table-column>
<el-table-column
align="center"
label="操作">
<template slot-scope="scope">
<el-button type="text" @click="handleRemoveProductLadder(scope.$index, scope.row)">删除</el-button>
<el-button type="text" @click="handleAddProductLadder(scope.$index, scope.row)">添加</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item v-show="value.promotionType===4">
<el-table :data="value.productFullReductionList"
style="width: 80%" border>
<el-table-column
label="满"
align="center"
width="120">
<template slot-scope="scope">
<el-input v-model="scope.row.fullPrice"></el-input>
</template>
</el-table-column>
<el-table-column
label="立减"
align="center"
width="120">
<template slot-scope="scope">
<el-input v-model="scope.row.reducePrice"></el-input>
</template>
</el-table-column>
<el-table-column
align="center"
label="操作">
<template slot-scope="scope">
<el-button type="text" @click="handleRemoveFullReduction(scope.$index, scope.row)">删除</el-button>
<el-button type="text" @click="handleAddFullReduction(scope.$index, scope.row)">添加</el-button>
</template>
</el-table-column>
</el-table>
</el-form-item>
<el-form-item style="text-align: center">
<el-button size="medium" @click="handlePrev">上一步</el-button>
<el-button type="primary" size="medium" @click="handleNext">下一步</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {fetchList as fetchMemberLevelList} from '@/api/memberLevel'
export default {
name: "ProductSaleDetail",
props: {
value: Object,
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
//
pickerOptions1: {
disabledDate(time) {
return time.getTime() < Date.now();
}
}
}
},
created() {
if (this.isEdit) {
// this.handleEditCreated();
} else {
fetchMemberLevelList({defaultStatus: 0}).then(response => {
let memberPriceList = [];
for (let i = 0; i < response.data.records.length; i++) {
let item = response.data.records[i];
memberPriceList.push({memberLevelId: item.id, memberLevelName: item.name})
}
this.value.memberPriceList = memberPriceList;
});
}
},
computed: {
//
selectServiceList: {
get() {
let list = [];
if (this.value.serviceIds === undefined || this.value.serviceIds == null || this.value.serviceIds === '') return list;
let ids = this.value.serviceIds.split(',');
for (let i = 0; i < ids.length; i++) {
list.push(Number(ids[i]));
}
return list;
},
set(newValue) {
let serviceIds = '';
if (newValue != null && newValue.length > 0) {
for (let i = 0; i < newValue.length; i++) {
serviceIds += newValue[i] + ',';
}
if (serviceIds.endsWith(',')) {
serviceIds = serviceIds.substr(0, serviceIds.length - 1)
}
this.value.serviceIds = serviceIds;
} else {
this.value.serviceIds = null;
}
}
}
},
methods: {
handleEditCreated() {
let ids = this.value.serviceIds.split(',');
console.log('handleEditCreated', ids);
for (let i = 0; i < ids.length; i++) {
this.selectServiceList.push(Number(ids[i]));
}
},
handleRemoveProductLadder(index, row) {
let productLadderList = this.value.productLadderList;
if (productLadderList.length === 1) {
productLadderList.pop();
productLadderList.push({
count: 0,
discount: 0,
price: 0
})
} else {
productLadderList.splice(index, 1);
}
},
handleAddProductLadder(index, row) {
let productLadderList = this.value.productLadderList;
if (productLadderList.length < 3) {
productLadderList.push({
count: 0,
discount: 0,
price: 0
})
} else {
this.$message({
message: '最多只能添加三条',
type: 'warning'
});
}
},
handleRemoveFullReduction(index, row) {
let fullReductionList = this.value.productFullReductionList;
if (fullReductionList.length === 1) {
fullReductionList.pop();
fullReductionList.push({
fullPrice: 0,
reducePrice: 0
});
} else {
fullReductionList.splice(index, 1);
}
},
handleAddFullReduction(index, row) {
let fullReductionList = this.value.productFullReductionList;
if (fullReductionList.length < 3) {
fullReductionList.push({
fullPrice: 0,
reducePrice: 0
});
} else {
this.$message({
message: '最多只能添加三条',
type: 'warning'
});
}
},
handlePrev() {
this.$emit('prevStep')
},
handleNext() {
this.$emit('nextStep')
}
}
}
</script>
<style scoped>
.littleMargin {
margin-top: 10px;
}
</style>

1017
src/views/pms/product/index.vue

File diff suppressed because it is too large

795
src/views/pms/product/productBySku.vue

@ -0,0 +1,795 @@
<template> 
<div class="app-container">
<el-card class="filter-container" shadow="never">
<div>
<i class="el-icon-search"></i>
<span>筛选搜索</span>
<el-button
style="float: right"
@click="handleSearchList()"
type="primary"
size="small">
查询结果
</el-button>
<el-button
style="float: right;margin-right: 15px"
@click="handleResetSearch()"
size="small">
重置
</el-button>
</div>
<div style="margin-top: 15px">
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<el-form-item label="输入搜索:">
<el-input style="width: 203px" v-model="listQuery.keyword" placeholder="商品名称"></el-input>
</el-form-item>
<el-form-item label="商品货号:">
<el-input style="width: 203px" v-model="listQuery.productSn" placeholder="商品货号"></el-input>
</el-form-item>
<el-form-item label="商品分类:">
<el-cascader
clearable
change-on-select
v-model="selectProductCateValue"
:options="productCateOptions">
</el-cascader>
</el-form-item>
<el-form-item label="商品品牌:">
<el-select v-model="listQuery.brandId" placeholder="请选择品牌" clearable>
<el-option
v-for="item in brandOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="上架状态:">
<el-select v-model="listQuery.publishStatus" placeholder="全部" clearable>
<el-option
v-for="item in publishStatusOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="审核状态:">
<el-select v-model="listQuery.verifyStatus" placeholder="全部" clearable>
<el-option
v-for="item in verifyStatusOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
</el-form>
</div>
</el-card>
<el-card class="operate-container" shadow="never">
<!--<i class="el-icon-tickets"></i>
<span>数据列表</span>-->
<el-button
class="btn-add"
@click="handleAddProduct()"
size="mini">
添加
</el-button>
</el-card>
<div class="table-container">
<el-table ref="productTable"
:data="list"
style="width: 100%"
@selection-change="handleSelectionChange"
v-loading="listLoading"
border>
<el-table-column type="selection" width="60" align="center"></el-table-column>
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<el-table-column label="商品图片" width="120" align="center">
<template slot-scope="scope"><img style="height: 80px" :src="scope.row.pic"></template>
</el-table-column>
<el-table-column label="商品名称" width="180" align="center">
<template slot-scope="scope">
<p>{{scope.row.name}}</p>
<p>品牌{{scope.row.brandName}}</p>
</template>
</el-table-column>
<el-table-column label="价格/货号" width="120" align="center">
<template slot-scope="scope">
<p>价格{{scope.row.price}}</p>
<p>货号{{scope.row.productSn}}</p>
<p>库存:{{scope.row.stock }}</p>
<p>销量:{{scope.row.sale }}</p>
</template>
</el-table-column>
<el-table-column label="规格" align="center">
<template slot-scope="scope" v-if='scope.row.skuStockList &&scope.row.skuStockList.length>0'>
<el-table ref="productTable"
:data="scope.row.skuStockList"
style="width: 100%"
border>
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<el-table-column label="商品图片" width="120" align="center">
<template slot-scope="scope"><img style="height: 80px" :src="scope.row.pic"></template>
</el-table-column>
<el-table-column label="库存" width="100" align="center">
<template slot-scope="scope">{{scope.row.stock}}</template>
</el-table-column>
<el-table-column label="价格/货号" width="120" align="center">
<template slot-scope="scope">
<p>规格1{{scope.row.sp1}}</p>
<p>规格2{{scope.row.sp2}}</p>
<p>规格3:{{scope.row.sp3 }}</p>
</template>
</el-table-column>
</el-table>
</template>
</el-table-column>
<el-table-column label="操作" width="160" align="center">
<template slot-scope="scope">
<p>
<el-button
size="mini"
@click="handleUpdateProduct(scope.$index, scope.row)">编辑
</el-button>
</p>
<p>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</p>
</template>
</el-table-column>
</el-table>
</div>
<div class="batch-operate-container">
<el-select
size="small"
v-model="operateType" placeholder="批量操作">
<el-option
v-for="item in operates"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button
style="margin-left: 20px"
class="search-button"
@click="handleBatchOperate()"
type="primary"
size="small">
确定
</el-button>
</div>
<div class="pagination-container">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes,prev, pager, next,jumper"
:page-size="listQuery.pageSize"
:page-sizes="[5,10,15]"
:current-page.sync="listQuery.pageNum"
:total="total">
</el-pagination>
</div>
<el-dialog
title="审核信息"
:visible.sync="vertyProduct.dialogVisible"
width="40%">
<el-form :model="vertyProduct" ref="brandFrom" label-width="150px">
<el-form-item label="审核状态:" prop="verifyStatus">
<el-switch v-model="vertyProduct.verifyStatus" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
<el-form-item label="审核备注:" prop="detail">
<el-input v-model="vertyProduct.detail"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="vertyProduct.dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleEditVConfirm"> </el-button>
</el-form-item>
</el-form>
<el-table style="width: 100%;margin-top: 20px"
:data="vertyProduct.list"
border>
<el-table-column label="审核状态" width="160" align="center">
<template slot-scope="scope">{{scope.row.status | verifyStatusFilter}}</template>
</el-table-column>
<el-table-column label="审核人" width="160" align="center">
<template slot-scope="scope">{{scope.row.vertifyMan}}</template>
</el-table-column>
<el-table-column label="审核信息" width="160" align="center">
<template slot-scope="scope">{{scope.row.detail}}</template>
</el-table-column>
<el-table-column label="审核时间" width="160" align="center">
<template slot-scope="scope">{{scope.row.createTime|formatTime}}</template>
</el-table-column>
</el-table>
</el-dialog>
<el-dialog
title="编辑货品信息"
:visible.sync="editSkuInfo.dialogVisible"
width="40%">
<span>商品货号</span>
<span>{{editSkuInfo.productSn}}</span>
<el-input placeholder="按sku编号搜索" v-model="editSkuInfo.keyword" size="small" style="width: 50%;margin-left: 20px">
<el-button slot="append" icon="el-icon-search" @click="handleSearchEditSku"></el-button>
</el-input>
<el-table style="width: 100%;margin-top: 20px"
:data="editSkuInfo.stockList"
border>
<el-table-column
label="SKU编号"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.skuCode"></el-input>
</template>
</el-table-column>
<el-table-column
v-for="(item,index) in editSkuInfo.productAttr"
:label="item.name"
:key="item.id"
align="center">
<template slot-scope="scope">
{{getProductSkuSp(scope.row,index)}}
</template>
</el-table-column>
<el-table-column
label="销售价格"
width="80"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.price"></el-input>
</template>
</el-table-column>
<el-table-column
label="商品库存"
width="80"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.stock"></el-input>
</template>
</el-table-column>
<el-table-column
label="库存预警值"
width="100"
align="center">
<template slot-scope="scope">
<el-input v-model="scope.row.lowStock"></el-input>
</template>
</el-table-column>
</el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="editSkuInfo.dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleEditSkuConfirm"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {formatDate} from '@/utils/date';
import {
listBySku,
fetchList,
updateDeleteStatus,
updateNewStatus,
updateRecommendStatus,
updatePaiMai,
updateFenxiao,
updateVip,
deleteProduct,
updatePublishStatus,
updateVerifyStatus,fetchVList
} from '@/api/product'
import {fetchList as fetchSkuStockList,update as updateSkuStockList} from '@/api/skuStock'
import {fetchList as fetchProductAttrList} from '@/api/productAttr'
import {fetchList as fetchBrandList} from '@/api/brand'
import {fetchListWithChildren} from '@/api/productCate'
const defaultListQuery = {
keyword: null,
pageNum: 1,
pageSize: 5,
status: 0,
publishStatus: null,
verifyStatus: null,
productSn: null,
productCategoryId: null,
brandId: null
};
export default {
name: "productList",
data() {
return {
dialogVVisible:false,
editSkuInfo:{
dialogVisible:false,
productId:null,
productSn:'',
productAttributeCategoryId:null,
stockList:[],
productAttr:[],
keyword:null
},
vertyProduct:{
dialogVisible:false,
productId:null,
detail:'',
verifyStatus:null,
list:null
},
operates: [
{
label: "商品上架",
value: "publishOn"
},
{
label: "商品下架",
value: "publishOff"
},
{
label: "设为推荐",
value: "recommendOn"
},
{
label: "取消推荐",
value: "recommendOff"
},
{
label: "设为新品",
value: "newOn"
},
{
label: "取消新品",
value: "newOff"
},
{
label: "转移到分类",
value: "transferCategory"
},
{
label: "移入回收站",
value: "recycle"
}
], tabsName: '1',
operateType: null,
listQuery: Object.assign({}, defaultListQuery),
list: null,
total: null,
listLoading: true,
selectProductCateValue: null,
multipleSelection: [],
productCateOptions: [],
brandOptions: [],
publishStatusOptions: [{
value: 1,
label: '上架'
}, {
value: 0,
label: '下架'
}],
verifyStatusOptions: [{
value: 1,
label: '审核通过'
}, {
value: 0,
label: '未审核'
}]
}
},
created() {
this.getList();
this.getBrandList();
this.getProductCateList();
},
watch: {
selectProductCateValue: function (newValue) {
console.log(newValue)
if (newValue != null) {
this.listQuery.productCategoryId = newValue[newValue.length-1 >0?newValue.length-1:0];
} else {
this.listQuery.productCategoryId = null;
}
}
},
filters: {
verifyStatusFilter(value) {
if (value === 1) {
return '审核通过';
} else {
return '未审核';
}
},
formatTime(time) {
if (time == null || time === '') {
return 'N/A';
}
let date = new Date(time);
return formatDate(date, 'yyyy-MM-dd hh:mm:ss')
},
},
methods: {
getProductSkuSp(row, index) {
if (index === 0) {
return row.sp1;
} else if (index === 1) {
return row.sp2;
} else {
return row.sp3;
}
},
getList() {
this.listLoading = true;
listBySku(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.records;
this.total = response.data.total;
});
},
getBrandList() {
fetchBrandList({pageNum: 1, pageSize: 100}).then(response => {
this.brandOptions = [];
let brandList = response.data.records;
for (let i = 0; i < brandList.length; i++) {
this.brandOptions.push({label: brandList[i].name, value: brandList[i].id});
}
});
},
getProductCateList() {
fetchListWithChildren().then(response => {
let list = response.data;
this.productCateOptions = [];
for (let i = 0; i < list.length; i++) {
let children = [];
if (list[i].children != null && list[i].children.length > 0) {
for (let j = 0; j < list[i].children.length; j++) {
children.push({label: list[i].children[j].name, value: list[i].children[j].id});
}
}
this.productCateOptions.push({label: list[i].name, value: list[i].id, children: children});
}
});
},
handleShowVeriyEditDialog(index,row){
this.vertyProduct.dialogVisible=true;
this.vertyProduct.productId=row.id;
this.vertyProduct.verifyStatus=row.verifyStatus;
fetchVList(row.id).then(response=>{
this.vertyProduct.list=response.data;
});
},
handleShowSkuEditDialog(index,row){
this.editSkuInfo.dialogVisible=true;
this.editSkuInfo.productId=row.id;
this.editSkuInfo.productSn=row.productSn;
this.editSkuInfo.productAttributeCategoryId = row.productAttributeCategoryId;
this.editSkuInfo.keyword=null;
fetchSkuStockList(row.id,{keyword:this.editSkuInfo.keyword}).then(response=>{
this.editSkuInfo.stockList=response.data;
});
if(row.productAttributeCategoryId && row.productAttributeCategoryId>0){
fetchProductAttrList(row.productAttributeCategoryId,{type:0}).then(response=>{
this.editSkuInfo.productAttr=response.data.records;
});
}
},
handleSearchEditSku(){
fetchSkuStockList(this.editSkuInfo.productId,{keyword:this.editSkuInfo.keyword}).then(response=>{
this.editSkuInfo.stockList=response.data;
});
},
handleEditSkuConfirm(){
if(this.editSkuInfo.stockList==null||this.editSkuInfo.stockList.length<=0){
this.$message({
message: '暂无sku信息',
type: 'warning',
duration: 1000
});
return
}
this.$confirm('是否要进行修改', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
updateSkuStockList(this.editSkuInfo.productId,this.editSkuInfo.stockList).then(response=>{
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
this.editSkuInfo.dialogVisible=false;
});
});
},
handleEditVConfirm(){
if(this.vertyProduct.detail==null){
this.$message({
message: '暂无审核信息',
type: 'warning',
duration: 1000
});
return
}
this.$confirm('是否要进行审核', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
let params = new URLSearchParams();
params.append('ids', this.vertyProduct.productId);
params.append('verifyStatus', this.vertyProduct.verifyStatus);
params.append('detail', this.vertyProduct.detail);
updateVerifyStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
this.getList();
});
this.vertyProduct.dialogVisible=false;
});
},
handleSearchList() {
this.listQuery.pageNum = 1;
this.getList();
},
handleAddProduct() {
this.$router.push({path:'/pms/addProduct'});
},
handleBatchOperate() {
if(this.operateType==null){
this.$message({
message: '请选择操作类型',
type: 'warning',
duration: 1000
});
return;
}
if(this.multipleSelection==null||this.multipleSelection.length<1){
this.$message({
message: '请选择要操作的商品',
type: 'warning',
duration: 1000
});
return;
}
this.$confirm('是否要进行该批量操作?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let ids=[];
for(let i=0;i<this.multipleSelection.length;i++){
ids.push(this.multipleSelection[i].id);
}
switch (this.operateType) {
case this.operates[0].value:
this.updatePublishStatus(1,ids);
break;
case this.operates[1].value:
this.updatePublishStatus(0,ids);
break;
case this.operates[2].value:
this.updateRecommendStatus(1,ids);
break;
case this.operates[3].value:
this.updateRecommendStatus(0,ids);
break;
case this.operates[4].value:
this.updateNewStatus(1,ids);
break;
case this.operates[5].value:
this.updateNewStatus(0,ids);
break;
case this.operates[6].value:
break;
case this.operates[7].value:
this.updateDeleteStatus(1,ids);
break;
default:
break;
}
this.getList();
});
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handlePublishStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updatePublishStatus(row.publishStatus, ids);
},
handleupdatePaiMaiChange(index, row) {
let ids = [];
ids.push(row.id);
this.updatePaiMai(row.publishStatus, ids);
},
handleVipStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updateVipStatus(row.isVip, ids);
},
handleFenxiaoStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updateFenxiaoStatus(row.isFenxiao, ids);
},
handleNewStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updateNewStatus(row.newStatus, ids);
},
handleVerifyStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updateVerifyStatus(row.verifyStatus, ids);
},
handleRecommendStatusChange(index, row) {
let ids = [];
ids.push(row.id);
this.updateRecommendStatus(row.recommandStatus, ids);
},
handleResetSearch() {
this.selectProductCateValue = [];
this.listQuery = Object.assign({}, defaultListQuery);
},
handleDelete(index, row){
this.$confirm('是否要进行删除操作?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let ids = [];
ids.push(row.id);
// this.updateDeleteStatus(1,ids);
deleteProduct(row.id).then(response => {
this.$message({
message: '删除成功',
type: 'success',
duration: 1000
});
this.getList();
});
});
},
handleUpdateProduct(index,row){
this.$router.push({path:'/pms/updateProduct',query:{id:row.id}});
},
handleShowProduct(index,row){
console.log("handleShowProduct",row);
},
handleShowVerifyDetail(index,row){
console.log("handleShowVerifyDetail",row);
},
handleShowLog(index,row){
console.log("handleShowLog",row);
},
updateVerifyStatus(publishStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('verifyStatus', verifyStatus);
updateVerifyStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updatePublishStatus(publishStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('publishStatus', publishStatus);
updatePublishStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateFenxiaoStatus(newStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('newStatus', newStatus);
updateFenxiao(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateVipStatus(newStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('newStatus', newStatus);
updateVip(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateNewStatus(newStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('newStatus', newStatus);
updateNewStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateRecommendStatus(recommendStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('recommendStatus', recommendStatus);
updateRecommendStatus(params).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
});
},
updateDeleteStatus(deleteStatus, ids) {
let params = new URLSearchParams();
params.append('ids', ids);
params.append('deleteStatus', deleteStatus);
updateDeleteStatus(params).then(response => {
this.$message({
message: '删除成功',
type: 'success',
duration: 1000
});
});
this.getList();
}
}
}
</script>
<style></style>

12
src/views/pms/product/update.vue

@ -0,0 +1,12 @@
<template> 
<product-detail :is-edit='true'></product-detail>
</template>
<script>
import ProductDetail from './components/ProductDetail'
export default {
name: 'updateProduct',
components: { ProductDetail }
}
</script>
<style>
</style>

15
src/views/pms/productAttr/addProductAttr.vue

@ -0,0 +1,15 @@
<template>
<product-attr-detail :is-edit='false'></product-attr-detail>
</template>
<script>
import ProductAttrDetail from './components/ProductAttrDetail'
export default {
name: 'addProductAttr',
components: { ProductAttrDetail }
}
</script>
<style scoped>
</style>

147
src/views/pms/productAttr/components/ProductAttrDetail.vue

@ -0,0 +1,147 @@
<template>
<el-card class="form-container" shadow="never">
<el-form :model="productAttr" :rules="rules" ref="productAttrFrom" label-width="150px">
<el-form-item label="属性名称:" prop="name">
<el-input v-model="productAttr.name"></el-input>
</el-form-item>
<el-form-item label="商品类型:">
<el-select v-model="productAttr.productAttributeCategoryId" placeholder="请选择">
<el-option
v-for="item in productAttrCateList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="类型:">
<el-radio-group v-model="productAttr.type">
<el-radio :label="1">属性</el-radio>
<el-radio :label="0">规格</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('productAttrFrom')">提交</el-button>
<el-button v-if="!isEdit" @click="resetForm('productAttrFrom')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</template>
<script>
import {fetchList} from '@/api/productAttrCate'
import {createProductAttr,getProductAttr,updateProductAttr} from '@/api/productAttr'
const defaultProductAttr = {
filterType: 0,
handAddStatus: 1,
inputList: '',
inputType: 0,
name: '',
productAttributeCategoryId: 0,
relatedStatus: 0,
searchType: 0,
selectType: 0,
sort: 0,
type: 0
};
export default {
name: "ProductAttrDetail",
props: {
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
productAttr: Object.assign({}, defaultProductAttr),
rules: {
name: [
{required: true, message: '请输入属性名称', trigger: 'blur'},
{min: 2, max: 140, message: '长度在 2 到 140 个字符', trigger: 'blur'}
]
},
productAttrCateList: null,
inputListFormat:null
}
},
created() {
if(this.isEdit){
getProductAttr(this.$route.query.id).then(response => {
this.productAttr = response.data;
this.inputListFormat = this.productAttr.inputList.replace(/,/g,'\n');
});
}else{
this.resetProductAttr();
}
this.getCateList();
},
watch:{
inputListFormat: function (newValue, oldValue) {
newValue = newValue.replace(/\n/g,',');
this.productAttr.inputList = newValue;
}
},
methods: {
getCateList() {
let listQuery = {pageNum: 1, pageSize: 100};
fetchList(listQuery).then(response => {
this.productAttrCateList = response.data.records;
});
},
resetProductAttr() {
this.productAttr = Object.assign({}, defaultProductAttr);
this.productAttr.productAttributeCategoryId = Number(this.$route.query.cid);
this.productAttr.type = Number(this.$route.query.type);
},
onSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$confirm('是否提交数据', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if(this.isEdit){
updateProductAttr(this.$route.query.id,this.productAttr).then(response=>{
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
});
this.$router.back();
});
}else{
createProductAttr(this.productAttr).then(response=>{
this.$message({
message: '提交成功',
type: 'success',
duration: 1000
});
this.resetForm('productAttrFrom');
});
}
});
} else {
this.$message({
message: '验证失败',
type: 'error',
duration: 1000
});
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
this.resetProductAttr();
}
},
}
</script>
<style scoped>
</style>

224
src/views/pms/productAttr/index.vue

@ -0,0 +1,224 @@
<template> 
<div class="app-container">
<el-card class="operate-container" shadow="never">
<i class="el-icon-tickets" style="margin-top: 5px"></i>
<span style="margin-top: 5px">数据列表</span>
<!-- <el-button
class="btn-add"
@click="addProductAttrCate()"
size="mini">
添加
</el-button> -->
</el-card>
<div class="table-container">
<el-table ref="productAttrCateTable"
style="width: 100%"
:data="list"
v-loading="listLoading"
border>
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<el-table-column label="类型名称" align="center">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<!-- <el-table-column label="属性数量" width="200" align="center">
<template slot-scope="scope">{{scope.row.attributeCount==null?0:scope.row.attributeCount}}</template>
</el-table-column>
<el-table-column label="参数数量" width="200" align="center">
<template slot-scope="scope">{{scope.row.paramCount==null?0:scope.row.paramCount}}</template>
</el-table-column>
<el-table-column label="设置" width="200" align="center">
<template slot-scope="scope">
<el-button
size="mini"
@click="getAttrList(scope.$index, scope.row)">规格列表
</el-button>
<el-button
size="mini"
@click="getParamList(scope.$index, scope.row)">参数列表
</el-button>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleUpdate(scope.$index, scope.row)">编辑
</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</template>
</el-table-column> -->
</el-table>
</div>
<div class="pagination-container">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes,prev, pager, next,jumper"
:page-size="listQuery.pageSize"
:page-sizes="[5,10,15]"
:current-page.sync="listQuery.pageNum"
:total="total">
</el-pagination>
</div>
<el-dialog
:title="dialogTitle"
:visible.sync="dialogVisible"
width="30%">
<el-form ref="productAttrCatForm":model="productAttrCate" :rules="rules" label-width="120px">
<el-form-item label="类型名称" prop="name">
<el-input v-model="productAttrCate.name" auto-complete="off"></el-input>
</el-form-item>
<el-form-item label="分类图标:">
<single-upload v-model="productAttrCate.pic"></single-upload>
</el-form-item>
<el-form-item label="列表样式:">
<el-radio-group v-model="productAttrCate.style">
<el-radio :label="1">一列一个</el-radio>
<el-radio :label="2">一列两个</el-radio>
<el-radio :label="3">一列3个</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否展示首页:">
<el-radio-group v-model="productAttrCate.showIndex">
<el-radio :label="1">展示</el-radio>
<el-radio :label="2">不展示</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="handleConfirm('productAttrCatForm')"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {fetchList,createProductAttrCate,deleteProductAttrCate,updateProductAttrCate} from '@/api/productAttrCate'
import SingleUpload from '@/components/Upload/singleUpload';
export default {
name: 'productAttrCateList',
components: {SingleUpload},
data() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
pageNum: 1,
pageSize: 5
},
dialogVisible: false,
dialogTitle:'',
productAttrCate:{
name:'',
id:null
},
rules: {
name: [
{ required: true, message: '请输入类型名称', trigger: 'blur' }
]
}
}
},
created() {
this.getList();
},
methods: {
getList() {
this.listLoading = true;
fetchList(this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.records;
this.total = response.data.total;
});
},
addProductAttrCate() {
this.dialogVisible = true;
this.dialogTitle = "添加类型";
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
handleDelete(index, row) {
this.$confirm('是否要删除该品牌', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteProductAttrCate(row.id).then(response=>{
this.$message({
message: '删除成功',
type: 'success',
duration:1000
});
this.getList();
});
});
},
handleUpdate(index, row) {
this.dialogVisible = true;
this.dialogTitle = "编辑类型";
this.productAttrCate.name = row.name;
this.productAttrCate.id = row.id;
},
getAttrList(index, row) {
this.$router.push({path: '/pms/productAttrList',query:{cid:row.id,cname:row.name,type:0}})
},
getParamList(index, row) {
this.$router.push({path: '/pms/productAttrList',query:{cid:row.id,cname:row.name,type:1}})
},
handleConfirm(formName){
this.$refs[formName].validate((valid) => {
if (valid) {
let data = new URLSearchParams();
data.append("name",this.productAttrCate.name);
data.append("style",this.productAttrCate.style);
data.append("showIndex",this.productAttrCate.showIndex);
data.append("pic",this.productAttrCate.pic);
if(this.dialogTitle==="添加类型"){
createProductAttrCate(data).then(response=>{
this.$message({
message: '添加成功',
type: 'success',
duration:1000
});
this.dialogVisible = false;
this.getList();
});
}else{
updateProductAttrCate(this.productAttrCate.id,data).then(response=>{
this.$message({
message: '修改成功',
type: 'success',
duration:1000
});
this.dialogVisible = false;
this.getList();
});
}
} else {
console.log('error submit!!');
return false;
}
});
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
</style>

255
src/views/pms/productAttr/productAttrList.vue

@ -0,0 +1,255 @@
<template> 
<div class="app-container">
<el-card class="filter-container" shadow="never">
<div>
<i class="el-icon-search"></i>
<span>筛选搜索</span>
<el-button
style="float: right"
@click="searchAdminDayStaticsList()"
type="primary"
size="small">
查询结果
</el-button>
</div>
<div style="margin-top: 15px">
<el-form :inline="true" :model="listQuery" size="small" label-width="140px">
<el-form-item label="输入搜索:">
<el-input style="width: 203px" v-model="listQuery.keyword" placeholder="类型名称/关键字"></el-input>
</el-form-item>
</el-form>
</div>
</el-card>
<el-card class="operate-container" shadow="never">
<i class="el-icon-tickets"></i>
<span>数据列表</span>
<el-button
class="btn-add"
@click="addProductAttr()"
size="mini">
添加
</el-button>
</el-card>
<div class="table-container">
<el-table ref="productAttrTable"
:data="list"
style="width: 100%"
@selection-change="handleSelectionChange"
v-loading="listLoading"
border>
<el-table-column type="selection" width="60" align="center"></el-table-column>
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{scope.row.id}}</template>
</el-table-column>
<el-table-column label="属性名称" width="140" align="center">
<template slot-scope="scope">{{scope.row.name}}</template>
</el-table-column>
<el-table-column label="所属类型" width="140" align="center">
<template slot-scope="scope">{{scope.row.productAttributeCategoryId}}</template>
</el-table-column>
<el-table-column label="类别" width="140" align="center">
<template slot-scope="scope">{{scope.row.type|typeFilter}}</template>
</el-table-column>
<el-table-column label="排序" width="100" align="center">
<template slot-scope="scope">{{scope.row.sort}}</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleUpdate(scope.$index, scope.row)">编辑
</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="batch-operate-container">
<el-select
size="small"
v-model="operateType" placeholder="批量操作">
<el-option
v-for="item in operates"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-button
style="margin-left: 20px"
class="search-button"
@click="handleBatchOperate()"
type="primary"
size="small">
确定
</el-button>
</div>
<div class="pagination-container">
<el-pagination
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes,prev, pager, next,jumper"
:page-size="listQuery.pageSize"
:page-sizes="[5,10,15]"
:current-page.sync="listQuery.pageNum"
:total="total">
</el-pagination>
</div>
</div>
</template>
<script>
import {fetchList, deleteProductAttr,fetchAllList} from '@/api/productAttr'
export default {
name: 'productAttrList',
data() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
pageNum: 1,
pageSize: 5,
type: this.$route.query.type
},
operateType: null,
multipleSelection: [],
operates: [
{
label: "删除",
value: "deleteProductAttr"
}
]
}
},
created() {
this.getList();
},
methods: {
getList() {
this.listLoading = true;
if (this.$route.query.cid){
fetchList(this.$route.query.cid, this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.records;
this.total = response.data.total;
});
} else {
fetchAllList( this.listQuery).then(response => {
this.listLoading = false;
this.list = response.data.records;
this.total = response.data.total;
});
}
},
searchAdminDayStaticsList() {
this.listQuery.pageNum = 1;
this.getList();
},
addProductAttr() {
this.$router.push({path:'/pms/addProductAttr',query:{cid:this.$route.query.cid,type:this.$route.query.type}});
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleBatchOperate() {
if (this.multipleSelection < 1) {
this.$message({
message: '请选择一条记录',
type: 'warning',
duration: 1000
});
return;
}
if (this.operateType !== 'deleteProductAttr') {
this.$message({
message: '请选择批量操作类型',
type: 'warning',
duration: 1000
});
return;
}
let ids = [];
for (let i = 0; i < this.multipleSelection.length; i++) {
ids.push(this.multipleSelection[i].id);
}
this.handleDeleteProductAttr(ids);
},
handleSizeChange(val) {
this.listQuery.pageNum = 1;
this.listQuery.pageSize = val;
this.getList();
},
handleCurrentChange(val) {
this.listQuery.pageNum = val;
this.getList();
},
handleUpdate(index, row) {
this.$router.push({path:'/pms/updateProductAttr',query:{id:row.id}});
},
handleDeleteProductAttr(ids) {
this.$confirm('是否要删除该属性', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let data = new URLSearchParams();
data.append("ids", ids);
deleteProductAttr(ids).then(response => {
this.$message({
message: '删除成功',
type: 'success',
duration: 1000
});
this.getList();
});
});
},
handleDelete(index, row) {
let ids = [];
ids.push(row.id);
this.handleDeleteProductAttr(ids);
},
},
filters: {
inputTypeFilter(value) {
if (value === 1) {
return '从列表中选取';
} else {
return '手工录入'
}
},
typeFilter(value) {
if (value === 1) {
return '属性';
} else {
return '规格'
}
},
selectTypeFilter(value) {
if (value === 1) {
return '单选';
} else if (value === 2) {
return '多选';
} else {
return '唯一'
}
},
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
</style>

15
src/views/pms/productAttr/updateProductAttr.vue

@ -0,0 +1,15 @@
<template>
<product-attr-detail :is-edit='true'></product-attr-detail>
</template>
<script>
import ProductAttrDetail from './components/ProductAttrDetail'
export default {
name: 'updateProductAttr',
components: { ProductAttrDetail }
}
</script>
<style scoped>
</style>

14
src/views/pms/productCate/add.vue

@ -0,0 +1,14 @@
<template> 
<product-cate-detail :is-edit='false'></product-cate-detail>
</template>
<script>
import ProductCateDetail from './components/ProductCateDetail'
export default {
name: 'addProductCate',
components: { ProductCateDetail }
}
</script>
<style>
</style>

291
src/views/pms/productCate/components/ProductCateDetail.vue

@ -0,0 +1,291 @@
<template>
<div class="main-content">
<el-card class="form-container" shadow="never">
<el-form ref="productCateFrom" :model="productCate" :rules="rules" label-width="150px">
<el-form-item label="分类名称:" prop="name">
<el-input v-model="productCate.name" />
</el-form-item>
<el-form-item label="上级分类:">
<el-select v-model="productCate.parentId" placeholder="请选择分类">
<el-option v-for="item in selectProductCateList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="数量单位:">
<el-input v-model="productCate.productUnit" />
</el-form-item>
<el-form-item label="排序:">
<el-input v-model="productCate.sort" />
</el-form-item>
<el-form-item label="是否显示:">
<el-radio-group v-model="productCate.showStatus">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item>
<!-- <el-form-item label="是否显示在导航栏:">
<el-radio-group v-model="productCate.navStatus">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item> -->
<!-- <el-form-item label="是否显示在首页:">
<el-radio-group v-model="productCate.indexStatus">
<el-radio :label="1"></el-radio>
<el-radio :label="0"></el-radio>
</el-radio-group>
</el-form-item> -->
<el-form-item label="分类图标:">
<single-upload v-model="productCate.icon" />
</el-form-item>
<el-form-item
v-for="(filterProductAttr, index) in filterProductAttrList"
:key="filterProductAttr.key"
:label="index | filterLabelFilter"
>
<el-cascader v-model="filterProductAttr.value" clearable :options="filterAttrs" />
<el-button style="margin-left: 20px" @click.prevent="removeFilterAttr(filterProductAttr)">删除</el-button>
</el-form-item>
<el-form-item>
<el-button size="small" type="primary" @click="handleAddFilterAttr()">新增</el-button>
</el-form-item>
<el-form-item label="关键词:">
<el-input v-model="productCate.keywords" />
</el-form-item>
<el-form-item label="分类描述:">
<el-input v-model="productCate.description" type="textarea" :autosize="true" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit('productCateFrom')">提交</el-button>
<el-button v-if="!isEdit" @click="resetForm('productCateFrom')">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import {
fetchList,
createProductCate,
updateProductCate,
getProductCate
} from '@/api/productCate'
import {
fetchListWithAttr
} from '@/api/productAttrCate'
import {
getProductAttrInfo
} from '@/api/productAttr'
import SingleUpload from '@/components/Upload/singleUpload'
const defaultProductCate = {
description: '',
icon: '',
keywords: '',
name: '',
navStatus: 1,
parentId: 0,
productUnit: '',
showStatus: 0,
indexStatus: 1,
sort: 0,
productAttributeIdList: []
}
export default {
name: 'ProductCateDetail',
components: {
SingleUpload
},
filters: {
filterLabelFilter(index) {
if (index === 0) {
return '筛选属性:'
} else {
return ''
}
}
},
props: {
isEdit: {
type: Boolean,
default: false
}
},
data() {
return {
productCate: Object.assign({}, defaultProductCate),
selectProductCateList: [],
rules: {
name: [{
required: true,
message: '请输入品牌名称',
trigger: 'blur'
},
{
min: 2,
max: 140,
message: '长度在 2 到 140 个字符',
trigger: 'blur'
}
]
},
filterAttrs: [],
filterProductAttrList: [{
value: []
}]
}
},
created() {
if (this.isEdit) {
getProductCate(this.$route.query.id).then(response => {
this.productCate = response.data
})
getProductAttrInfo(this.$route.query.id).then(response => {
if (response.data != null && response.data.length > 0) {
this.filterProductAttrList = []
for (let i = 0; i < response.data.length; i++) {
this.filterProductAttrList.push({
key: Date.now() + i,
value: [response.data[i].attributeCategoryId, response.data[i].attributeId]
})
}
}
})
} else {
this.productCate = Object.assign({}, defaultProductCate)
}
this.getSelectProductCateList()
this.getProductAttrCateList()
},
methods: {
getSelectProductCateList() {
fetchList(0, {
pageSize: 100,
pageNum: 1
}).then(response => {
this.selectProductCateList = response.data.records
this.selectProductCateList.unshift({
id: 0,
name: '无上级分类'
})
})
},
getProductAttrCateList() {
fetchListWithAttr().then(response => {
const list = response.data
for (let i = 0; i < list.length; i++) {
const productAttrCate = list[i]
const children = []
if (productAttrCate.productAttributeList != null && productAttrCate.productAttributeList
.length > 0) {
for (let j = 0; j < productAttrCate.productAttributeList.length; j++) {
children.push({
label: productAttrCate.productAttributeList[j].name,
value: productAttrCate.productAttributeList[j].id
})
}
}
this.filterAttrs.push({
label: productAttrCate.name,
value: productAttrCate.id,
children: children
})
}
})
},
getProductAttributeIdList() {
//
const productAttributeIdList = []
for (let i = 0; i < this.filterProductAttrList.length; i++) {
const item = this.filterProductAttrList[i]
if (item.value !== null && item.value.length === 2) {
productAttributeIdList.push(item.value[1])
}
}
return productAttributeIdList
},
onSubmit(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$confirm('是否提交数据', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.isEdit) {
this.productCate.productAttributeIdList = this.getProductAttributeIdList()
updateProductCate(this.$route.query.id, this.productCate).then(
response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
})
this.$router.back()
})
} else {
this.productCate.productAttributeIdList = this.getProductAttributeIdList()
createProductCate(this.productCate).then(response => {
this.$refs[formName].resetFields()
this.resetForm(formName)
this.$message({
message: '提交成功',
type: 'success',
duration: 1000
})
})
}
})
} else {
this.$message({
message: '验证失败',
type: 'error',
duration: 1000
})
return false
}
})
},
resetForm(formName) {
this.$refs[formName].resetFields()
this.productCate = Object.assign({}, defaultProductCate)
this.getSelectProductCateList()
this.filterProductAttrList = [{
value: []
}]
},
removeFilterAttr(productAttributeId) {
if (this.filterProductAttrList.length === 1) {
this.$message({
message: '至少要留一个',
type: 'warning',
duration: 1000
})
return
}
var index = this.filterProductAttrList.indexOf(productAttributeId)
if (index !== -1) {
this.filterProductAttrList.splice(index, 1)
}
},
handleAddFilterAttr() {
if (this.filterProductAttrList.length === 3) {
this.$message({
message: '最多添加三个',
type: 'warning',
duration: 1000
})
return
}
this.filterProductAttrList.push({
value: null,
key: Date.now()
})
}
}
}
</script>
<style scoped>
</style>

269
src/views/pms/productCate/index.vue

@ -0,0 +1,269 @@
<template>
<div class="app-container">
<div class="main-content">
<el-card class="operate-container" shadow="never">
<i class="el-icon-tickets" style="margin-top: 5px" />
<span style="margin-top: 5px">数据列表</span>
<el-button class="btn-add" size="mini" @click="handleAddProductCate()">
添加
</el-button>
</el-card>
<div class="table-container">
<el-table ref="productCateTable" v-loading="listLoading" style="width: 100%" :data="list" border>
<el-table-column label="编号" width="100" align="center">
<template slot-scope="scope">{{ scope.row.id }}</template>
</el-table-column>
<el-table-column label="分类名称" align="center">
<template slot-scope="scope">{{ scope.row.name }}</template>
</el-table-column>
<el-table-column label="级别" width="100" align="center">
<template slot-scope="scope">{{ scope.row.level | levelFilter }}</template>
</el-table-column>
<el-table-column label="商品数量" width="100" align="center">
<template slot-scope="scope">{{ scope.row.productCount }}</template>
</el-table-column>
<el-table-column label="数量单位" width="100" align="center">
<template slot-scope="scope">{{ scope.row.productUnit }}</template>
</el-table-column>
<!-- <el-table-column label="导航栏" width="100" align="center">
<template slot-scope="scope">
<el-switch
@change="handleNavStatusChange(scope.$index, scope.row)"
:active-value="1"
:inactive-value="0"
v-model="scope.row.navStatus">
</el-switch>
</template>
</el-table-column> -->
<el-table-column label="是否显示" width="100" align="center">
<template slot-scope="scope">
<el-switch
v-model="scope.row.showStatus"
:active-value="1"
:inactive-value="0"
@change="handleShowStatusChange(scope.$index, scope.row)"
/>
</template>
</el-table-column>
<!-- <el-table-column label="是否首页显示" width="100" align="center">
<template slot-scope="scope">
<el-switch
@change="handleIndexStatusChange(scope.$index, scope.row)"
:active-value="1"
:inactive-value="0"
v-model="scope.row.indexStatus">
</el-switch>
</template>
</el-table-column> -->
<el-table-column label="排序" width="100" align="center">
<template slot-scope="scope">{{ scope.row.sort }}</template>
</el-table-column>
<el-table-column label="设置" width="200" align="center">
<template slot-scope="scope">
<el-button
size="mini"
:disabled="scope.row.level | disableNextLevel"
@click="handleShowNextLevel(scope.$index, scope.row)"
>查看下级
</el-button>
<!-- <el-button
size="mini"
@click="handleTransferProduct(scope.$index, scope.row)">转移商品
</el-button> -->
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button size="mini" @click="handleUpdate(scope.$index, scope.row)">编辑
</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="pagination-container">
<el-pagination
background
layout="total, sizes,prev, pager, next,jumper"
:page-size="listQuery.pageSize"
:page-sizes="[5,10,15]"
:current-page.sync="listQuery.pageNum"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
</template>
<script>
import {
fetchList,
deleteProductCate,
updateShowStatus,
updateNavStatus,
updateIndexStatus
} from '@/api/productCate'
export default {
name: 'ProductCateList',
filters: {
levelFilter(value) {
if (value === 0) {
return '一级'
} else if (value === 1) {
return '二级'
}
},
disableNextLevel(value) {
if (value === 0) {
return false
} else {
return true
}
}
},
data() {
return {
list: null,
total: null,
listLoading: true,
listQuery: {
pageNum: 1,
pageSize: 5
},
parentId: 0
}
},
watch: {
$route(route) {
this.resetParentId()
this.getList()
}
},
created() {
this.resetParentId()
this.getList()
},
methods: {
resetParentId() {
console.log('parentId>>>', this.$route.query.parentId)
if (this.$route.query.parentId != null) {
this.parentId = this.$route.query.parentId
} else {
this.parentId = 0
}
},
handleAddProductCate() {
this.$router.push('/pms/addProductCate')
},
getList() {
this.listLoading = true
console.log('parentId>>>', this.parentId)
console.log('listQuery>>>', this.listQuery)
fetchList(this.parentId, this.listQuery).then(response => {
this.listLoading = false
console.log('list>>>', response.data.records)
this.list = response.data.records
this.total = response.data.total
})
},
handleSizeChange(val) {
this.listQuery.pageNum = 1
this.listQuery.pageSize = val
this.getList()
},
handleCurrentChange(val) {
this.listQuery.pageNum = val
this.getList()
},
handleNavStatusChange(index, row) {
const data = new URLSearchParams()
const ids = []
ids.push(row.id)
data.append('ids', ids)
data.append('navStatus', row.navStatus)
updateNavStatus(data).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
})
})
},
handleShowStatusChange(index, row) {
const data = new URLSearchParams()
const ids = []
ids.push(row.id)
data.append('ids', ids)
data.append('showStatus', row.showStatus)
updateShowStatus(data).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
})
})
},
handleIndexStatusChange(index, row) {
const data = new URLSearchParams()
const ids = []
ids.push(row.id)
data.append('ids', ids)
data.append('indexStatus', row.indexStatus)
updateIndexStatus(data).then(response => {
this.$message({
message: '修改成功',
type: 'success',
duration: 1000
})
})
},
handleShowNextLevel(index, row) {
this.listQuery = {
pageNum: 1,
pageSize: 5
}
this.$router.push({
path: '/pms/productCate',
query: {
parentId: row.id
}
})
},
handleTransferProduct(index, row) {
console.log('handleAddProductCate')
},
handleUpdate(index, row) {
this.$router.push({
path: '/pms/updateProductCate',
query: {
id: row.id
}
})
},
handleDelete(index, row) {
this.$confirm('是否要删除该分类', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
deleteProductCate(row.id).then(response => {
this.$message({
message: '删除成功',
type: 'success',
duration: 1000
})
this.getList()
})
})
}
}
}
</script>
<style scoped>
</style>

14
src/views/pms/productCate/update.vue

@ -0,0 +1,14 @@
<template> 
<product-cate-detail :is-edit='true'></product-cate-detail>
</template>
<script>
import ProductCateDetail from './components/ProductCateDetail'
export default {
name: 'updateProductCate',
components: { ProductCateDetail }
}
</script>
<style>
</style>
Loading…
Cancel
Save