提交 e1798446 authored 作者: 王鹏飞's avatar 王鹏飞

update

上级 1eb24e70
......@@ -24,6 +24,12 @@ export function updateGoods(data) {
export function deleteGoods(data) {
return httpRequest.post('/api/shop/commodity/spu/delete', data)
}
/**
* 更新商品状态
*/
export function updateGoodsStatus(data) {
return httpRequest.post('/api/shop/commodity/spu/status/modify', data)
}
/**
* 获取商品分组
......
......@@ -208,4 +208,7 @@ export default {
padding: 10px 0;
text-align: right;
}
.el-table-column--selection .cell {
padding: 0 14px !important;
}
</style>
......@@ -45,7 +45,7 @@ export default {
return
}
let fileList = []
if (Array.isArray(value)) {
if (this.isMultiple) {
fileList = value.map(item => {
return { name: item.name || item, url: item.url || item }
})
......@@ -56,6 +56,11 @@ export default {
}
}
},
computed: {
isMultiple() {
return Array.isArray(this.value)
}
},
methods: {
beforeUpload(file) {
const fileName = file.name
......@@ -75,7 +80,7 @@ export default {
})
},
handleSuccess(response, file) {
if (Array.isArray(this.value)) {
if (this.isMultiple) {
this.fileList.push({ name: file.name, url: file.raw.url })
this.$emit('input', this.fileList)
} else {
......@@ -86,7 +91,7 @@ export default {
// 删除
handleRemove(index) {
this.fileList.splice(index, 1)
this.$emit('input', Array.isArray(this.value) ? this.fileList : '')
this.$emit('input', this.isMultiple ? this.fileList : '')
},
// 预览
handlePreview(file) {
......@@ -96,26 +101,11 @@ export default {
}
}
</script>
<style>
<style lang="scss">
.el-upload-list--picture-card .el-upload-list__item-thumbnail {
object-fit: cover;
}
.el-upload-list__item {
transition: none !important;
}
/* .el-upload--text {
background-color: #fbfdff;
border: 1px dashed #c0ccda;
border-radius: 6px;
box-sizing: border-box;
width: 148px;
height: 148px;
cursor: pointer;
line-height: 146px;
vertical-align: top;
}
.el-upload--text i {
font-size: 28px;
color: #8c939d;
} */
</style>
<template>
<app-upload class="avatar-uploader" accept="image/*" :show-file-list="false" v-bind="$attrs" v-on="$listeners">
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</app-upload>
</template>
<script>
import AppUpload from './upload'
export default {
name: 'AppUploadImage',
components: { AppUpload },
data() {
return {}
},
computed: {
imageUrl() {
return this.$attrs.value
}
}
}
</script>
<style lang="scss">
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 148px;
height: 148px;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
line-height: 148px;
text-align: center;
}
.avatar {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
</style>
<template>
<app-upload class="video-uploader" accept="video/*" :show-file-list="false" v-bind="$attrs" v-on="$listeners">
<img v-if="videoUrl" :src="`${videoUrl}?x-oss-process=video/snapshot,t_1,f_jpg,w_0,h_0,m_fast`" class="avatar" />
<i v-else class="el-icon-plus video-uploader-icon"></i>
</app-upload>
</template>
<script>
import AppUpload from './upload'
export default {
name: 'AppUploadImage',
components: { AppUpload },
data() {
return {}
},
computed: {
videoUrl() {
return this.$attrs.value
}
}
}
</script>
<style lang="scss">
.video-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 148px;
height: 148px;
}
.video-uploader .el-upload:hover {
border-color: #409eff;
}
.video-uploader-icon {
font-size: 28px;
color: #8c939d;
line-height: 148px;
text-align: center;
}
.avatar {
width: 100%;
height: 100%;
display: block;
object-fit: cover;
}
</style>
......@@ -10,11 +10,14 @@
<script>
import MessageItem from './messageItem'
export default {
props: { data: { type: Array, default: () => [] } },
props: { value: { type: Array, default: () => [] } },
components: { MessageItem },
data() {
return {
list: [{ filed: '手机号', type: 'text', required: true }]
return {}
},
computed: {
list() {
return this.value
}
},
methods: {
......
......@@ -73,9 +73,9 @@ export default {
data() {
return {
header: [
{ formType: 'input', key: 'price', value: '价格(元)' },
{ formType: 'input', key: 'price', value: '*价格(元)' },
{ formType: 'input', key: 'mark_price', value: '划线价(元)' },
{ formType: 'input', key: 'stock', value: '库存' },
{ formType: 'input', key: 'stock', value: '*库存' },
{ formType: 'input', key: 'prime_price', value: '成本价' }
],
showBatchInput: false,
......@@ -108,9 +108,9 @@ export default {
// 设置默认数据
const defaultStock = Object.assign(
{
spec_id: valueIdsText,
spec_id: values.ids.join(','),
spec_name: values.names.join(','),
spec_value_id: values.valueIds.join(','),
spec_value_id: valueIdsText,
spec_value: values.valueNames.join(',')
},
this.defaultStockParams
......@@ -156,7 +156,6 @@ export default {
return Object.assign({ rowspan: trLength / rowspanDivide }, item, value)
})
})
console.log(list)
// 笛卡尔积
return list.length ? this.cartesianProduct(list) : list
},
......
......@@ -30,9 +30,7 @@
<p class="form-tips">建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张</p>
</el-form-item>
<el-form-item label="主图视频" prop="main_chart_oss">
<app-upload v-model="ruleForm.main_chart_oss" accept="video/*">
<el-button size="small" type="primary">点击上传</el-button>
</app-upload>
<app-upload-video v-model="ruleForm.main_chart_oss"></app-upload-video>
<p class="form-tips">
添加主图视频可提升成交转化,有利于获取更多新流量;建议视频突出商品核心卖点,时长 9-30 秒,宽高比 16:9
</p>
......@@ -57,8 +55,8 @@
</el-form-item>
</app-card>
<app-card title="其他信息">
<el-form-item label="留言" prop="sales_type">
<message></message>
<el-form-item label="留言" prop="messageList">
<message v-model="ruleForm.messageList"></message>
</el-form-item>
<el-form-item label="开售方式" prop="sales_type">
<el-radio-group v-model="ruleForm.sales_type">
......@@ -108,6 +106,7 @@
// 组件
import AppCard from '@/components/base/card'
import AppUpload from '@/components/base/upload'
import AppUploadVideo from '@/components/base/uploadVideo'
import Sku from '@/components/goods/sku'
import SkuView from '@/components/goods/skuView'
import Message from '@/components/goods/message'
......@@ -115,7 +114,7 @@ import Message from '@/components/goods/message'
// 接口
import { addGoods, updateGoods, getGoodsList } from '@/api/goods'
export default {
components: { AppCard, AppUpload, Sku, SkuView, Message },
components: { AppCard, AppUpload, AppUploadVideo, Sku, SkuView, Message },
props: { isEdit: { type: Boolean, default: false } },
data() {
return {
......@@ -138,7 +137,8 @@ export default {
sales_time: '', // 开售时间
buy_limit: '', // 限购
goodStockList: [], // 规格明细
skuKeyValueList: []
skuKeyValueList: [],
messageList: [] // 留言
},
buyButtonTextRadio: '1',
rules: {
......@@ -176,8 +176,43 @@ export default {
Object.assign(this.ruleForm, data)
// 图片
try {
this.ruleForm.chart_oss = JSON.parse(data.chart_oss)
} catch (error) {}
this.ruleForm.chart_oss = data.chart_oss ? JSON.parse(data.chart_oss) : []
} catch (error) {
console.log('商品图片解析失败', error)
}
// 规格明细
try {
const goodStockList = data.spec ? JSON.parse(data.spec) : []
this.ruleForm.goodStockList = goodStockList
// 根据规格明细生成商品规格数据
this.ruleForm.skuKeyValueList = goodStockList.reduce((result, item, index) => {
const ids = item.spec_id.split(',')
const names = item.spec_name.split(',')
const valueIds = item.spec_value_id.split(',')
const valueNames = item.spec_value.split(',')
if (index === 0) {
result = ids.map((id, index) => {
return { spec_id: id, spec_name: names[index], spec_values: [] }
})
}
valueIds.map((valueId, index) => {
const skuValues = result[index].spec_values
const found = skuValues.find(item => item.spec_value_id === valueId)
if (!found) {
skuValues.push({ spec_value_id: valueId, spec_value: valueNames[index] })
}
})
return result
}, [])
} catch (error) {
console.log('商品规格解析失败', error)
}
// 留言
try {
this.ruleForm.messageList = data.app_button_text ? JSON.parse(data.app_button_text) : []
} catch (error) {
console.log('留言解析失败', error)
}
// 购买按钮
this.buyButtonTextRadio = data.buy_button_text === '立即购买' ? '1' : '2'
this.loading = false
......@@ -186,21 +221,31 @@ export default {
// 确定
onSubmit() {
// 基本信息表单校验
this.$refs.ruleForm.validate().then(valid => {
// 规格明细校验
// if (this.ruleForm.goodStockList && this.ruleForm.goodStockList.length) {
// this.$lodash.forEach(this.ruleForm.goodStockList, item => {
// if (isNaN(parseFloat(item.sellPrice)) || isNaN(parseFloat(item.balanceCount))) {
// this.$message({ message: '请完善规格明细表单', type: 'error' })
// return false
// }
// })
// }
const params = Object.assign({ shop_id: this.shopId }, this.ruleForm)
params.chart_oss = JSON.stringify(params.chart_oss)
params.spec = JSON.stringify(params.goodStockList)
this.isEdit ? this.onEdit(params) : this.onAdd(params)
})
this.$refs.ruleForm
.validate()
.then(valid => {
// 规格明细校验
const goodStockList = this.ruleForm.goodStockList
if (goodStockList && goodStockList.length) {
for (const item of goodStockList) {
if (isNaN(parseFloat(item.price)) || isNaN(parseFloat(item.stock))) {
this.$message({ message: '请完善规格明细表单', type: 'error' })
return false
}
}
} else {
this.$message({ message: '请创建商品规格', type: 'error' })
return false
}
const params = Object.assign({ shop_id: this.shopId }, this.ruleForm)
params.chart_oss = JSON.stringify(params.chart_oss)
params.spec = JSON.stringify(params.goodStockList)
params.app_button_text = JSON.stringify(params.messageList)
this.isEdit ? this.onEdit(params) : this.onAdd(params)
})
.catch(() => {
this.$message({ message: '请完善表单信息', type: 'error' })
})
},
// 取消
onCancel() {
......
<template>
<app-card>
<table-list v-bind="tableOptions" ref="list">
<table-list v-bind="tableOptions" ref="list" @selection-change="handleSelectionChange">
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
<el-tab-pane :label="item.label" :name="item.name" v-for="item in tabList" :key="item.name"></el-tab-pane>
</el-tabs>
......@@ -11,13 +11,14 @@
</template>
<template v-slot:table-x="{ row }">
<el-button type="text" @click="handleUpdate(row)">编辑</el-button>
<!-- <el-popconfirm confirm-button-text="确认" title="确定要删除该商品吗?" @confirm="handleRemove(row)">
<el-button type="text" slot="reference">删除</el-button>
</el-popconfirm> -->
<el-button type="text" @click="handlePromote(row)">推广</el-button>
<el-button type="text" @click="handleCopy(row)">复制</el-button>
</template>
</table-list>
<div class="footer">
<el-button size="medium" :disabled="!multipleSelection.length" @click="handleUpdateStatus">上架</el-button>
<el-button size="medium" :disabled="!multipleSelection.length" @click="onRemove">删除</el-button>
</div>
</app-card>
</template>
......@@ -26,7 +27,7 @@
import TableList from '@/components/base/tableList'
import AppCard from '@/components/base/card'
// 接口
import { getGoodsList, deleteGoods } from '@/api/goods'
import { getGoodsList, deleteGoods, updateGoodsStatus } from '@/api/goods'
export default {
components: { AppCard, TableList },
......@@ -38,7 +39,8 @@ export default {
{ label: '销售中', name: '2' },
{ label: '已售罄', name: '3' },
{ label: '仓库中', name: '1' }
]
],
multipleSelection: []
}
},
computed: {
......@@ -60,17 +62,19 @@ export default {
{
type: 'input',
prop: 'spu_name',
placeholder: '请输入商品名称'
placeholder: '商品名称'
},
{
type: 'select',
prop: 'group_id',
options: this.groupList,
labelKey: 'group_name',
valueKey: 'group_id'
valueKey: 'group_id',
placeholder: '商品分组'
}
],
columns: [
{ type: 'selection', align: 'left' },
{ label: '商品名', prop: 'spu_name' },
{ label: '价格(元)', prop: 'price_zone' },
{ label: '访问量', prop: 'page_view' },
......@@ -103,8 +107,17 @@ export default {
this.$router.push({ name: 'goodsEdit', params: { id: data.spu_id } })
},
// 删除
handleRemove(row) {
deleteGoods({ shop_id: this.shopId, spu_id: row.spu_id }).then(res => {
onRemove() {
this.$confirm('商品删除请谨慎操作,确定删除?', '删除商品', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(this.handleRemove)
},
// 删除
handleRemove() {
const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id }))
deleteGoods({ shop_id: this.shopId, data }).then(res => {
this.$refs.list.refetch()
})
},
......@@ -113,6 +126,17 @@ export default {
// 复制
handleCopy(data) {
this.$router.push({ name: 'goodsAdd', query: { id: data.spu_id } })
},
// 选择
handleSelectionChange(value) {
this.multipleSelection = value
},
// 上架
handleUpdateStatus() {
const data = this.multipleSelection.map(item => ({ spu_id: item.spu_id, status: '2' }))
updateGoodsStatus({ shop_id: this.shopId, data }).then(res => {
this.$refs.list.refetch()
})
}
},
beforeMount() {
......
......@@ -58,7 +58,8 @@ export default {
},
// 确定修改商品
onEdit() {
updateGroup(this.ruleForm).then(this.handleSuccess)
const { shop_id: shopId, group_id: groupId, group_name: groupName } = this.ruleForm
updateGroup({ shop_id: shopId, group_id: groupId, group_name: groupName }).then(this.handleSuccess)
},
// 成功
handleSuccess(response) {
......
......@@ -6,7 +6,7 @@
</template>
<template v-slot:table-x="{ row }">
<el-button type="text" @click="handleUpdate(row)">编辑</el-button>
<el-popconfirm confirm-button-text="确认" title="确定要删除该分组吗?" @confirm="handleRemove(row)">
<el-popconfirm title="确定要删除该分组吗?" @confirm="handleRemove(row)" style="margin: 0 10px">
<el-button type="text" slot="reference">删除</el-button>
</el-popconfirm>
<el-button type="text" @click="handlePromote(row)">推广</el-button>
......
......@@ -23,7 +23,7 @@
<el-input v-model="ruleForm.shop_name" placeholder="请输入店铺、品牌、机构的全称"></el-input>
</el-form-item>
<el-form-item label="店铺头像" prop="shop_logo">
<app-upload v-model="ruleForm.shop_logo" accept="image/*" :show-file-list="false"></app-upload>
<app-upload-image v-model="ruleForm.shop_logo" accept="image/*" :show-file-list="false"></app-upload-image>
</el-form-item>
<el-form-item label="店铺有效期" prop="end_time">
<el-date-picker
......@@ -51,16 +51,17 @@
<script>
import AppCard from '@/components/base/card'
import AppUpload from '@/components/base/upload'
import AppUploadImage from '@/components/base/uploadImage'
import { updateShop } from '@/api/shop'
export default {
components: { AppCard, AppUpload },
components: { AppCard, AppUploadImage },
data() {
return {
ruleForm: { shop_name: '', shop_logo: '', shop_desc: '', shop_tel: '', shop_type: '1' },
rules: {
shop_name: [{ required: true, message: '必填', trigger: 'blur' }],
shop_logo: [{ required: true, message: '请上传', trigger: 'change' }],
end_time: [{ required: true, message: '请选择', trigger: 'change' }],
shop_desc: [{ required: true, message: '必填', trigger: 'blur' }],
shop_tel: [{ required: true, message: '必填', trigger: 'blur' }]
},
......
......@@ -7,7 +7,7 @@
<el-input v-model="ruleForm.shop_name" placeholder="请输入店铺、品牌、机构的全称"></el-input>
</el-form-item>
<el-form-item label="店铺头像" prop="shop_logo">
<app-upload v-model="ruleForm.shop_logo"></app-upload>
<app-upload-image v-model="ruleForm.shop_logo"></app-upload-image>
</el-form-item>
<el-form-item label="店铺有效期" prop="end_time">
<el-date-picker
......@@ -36,18 +36,19 @@
<script>
// 组件
import PageMain from '@/components/common/pageMain'
import AppUpload from '@/components/base/upload'
import AppUploadImage from '@/components/base/uploadImage'
// 接口
import { addShop } from '@/api/shop'
export default {
components: { PageMain, AppUpload },
components: { PageMain, AppUploadImage },
data() {
return {
ruleForm: { shop_name: '', shop_logo: '', shop_desc: '', shop_tel: '', shop_type: '1' },
rules: {
shop_name: [{ required: true, message: '必填', trigger: 'blur' }],
shop_logo: [{ required: true, message: '请上传', trigger: 'change' }],
end_time: [{ required: true, message: '请选择', trigger: 'change' }],
shop_desc: [{ required: true, message: '必填', trigger: 'blur' }],
shop_tel: [{ required: true, message: '必填', trigger: 'blur' }]
}
......
......@@ -45,7 +45,6 @@ const store = new Vuex.Store({
// 获取商品分组列表
getGroups({ commit, state }) {
getGroupList({ shop_id: state.shopId }).then(response => {
console.log(response)
const { data = [] } = response
commit('setGroups', data)
})
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论