You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

830 lines
21 KiB

<template>
<view class="index-box">
<view class="add-goodsimg-box">
<view class="img-box acea-row">
<view class="upload-box" @click="uploadImgs">
<image src="../../../static/images/upload.png"></image>
</view>
<view class="upload-box" @click="uploadImg(0)">
<image src="../../../static/images/addimg.png" v-if="!slider_image[0] || slider_image[0] == ''"></image>
<image :src="slider_image[0]" mode="aspectFill" v-else></image>
</view>
<view class="upload-box" @click="uploadImg(1)">
<image src="../../../static/images/addimg.png" v-if="!slider_image[1] || slider_image[1] == ''"></image>
<image :src="slider_image[1]" mode="aspectFill" v-else></image>
</view>
<view class="upload-box" @click="uploadImg(2)">
<image src="../../../static/images/addimg.png" v-if="!slider_image[2] || slider_image[2] == ''"></image>
<image :src="slider_image[2]" mode="aspectFill" v-else></image>
</view>
</view>
<view class="tips acea-row row-middle">
<image src="../../../static/images/tips-icon.png"></image>
<text>最少上传一张,最多只能上传三张图片哦!</text>
</view>
</view>
<view class="goodsInfo-box">
<view class="goodsInfo-item">
<text>商品名称<text class="colR">*</text></text>
<input type="text" v-model="store_name" placeholder="输入商品名称" />
</view>
<view class="goodsInfo-item">
<text>商品单位<text class="colR">*</text></text>
<input type="text" v-model="unit_name" placeholder="输入商品单位" />
</view>
<view class="goodsInfo-item">
<text>商品详情<text class="colR">*</text></text>
<view class="toEdit acea-row row-middle" @click="toGoodsDetails">
<text>{{description == '' ? '去编辑' : '已编辑'}}</text>
<image src="../../../static/images/arror-r-s.png"></image>
</view>
</view>
</view>
<!-- <view class="title2" @click="addSku">添加规格</view> -->
<!-- <view class="add-sku-box">
<view class="sku-item" v-for="(item,index) in attrs" :key="index">
<view class="close-btn" @click="delSku(index)">×</view>
<view class="sku img-sku acea-row row-middle row-between">
<text>图片</text>
<image src="../../../static/images/upload.png" v-if="item.pic == ''" @tap="uploadSkuImg(index)"></image>
<image :src="item.pic" v-else @tap="uploadSkuImg(index)" mode="aspectFill"></image>
</view>
<view class="sku img-sku acea-row row-middle row-between">
<text>价格<text class="colR">*</text></text>
<input type="number" v-model="item.price" placeholder="请输入售价(元)" />
</view>
<view class="sku img-sku acea-row row-middle row-between">
<text>市场价格</text>
<input type="number" v-model="item.ot_orice" placeholder="请输入市场价格(元)" />
</view>
<view class="sku img-sku acea-row row-middle row-between">
<text>库存<text class="colR">*</text></text>
<input type="number" v-model="item.stock" placeholder="请输入库存" />
</view>
<view class="sku img-sku acea-row row-middle row-between">
<text>重量</text>
<input type="number" v-model="item.weight" placeholder="请输入重量kg" />
</view>
<view class="sku img-sku acea-row row-middle row-between">
<text>体积</text>
<input type="number" v-model="item.volume" placeholder="请输入体积m³" />
</view>
</view>
</view> -->
<!-- //规格属性 -->
<view class="set-title">规格设置</view>
<view class="setattr-box">
<view class="attr-item colB" @click="addAttr">添加属性</view>
<view class="attr-item acea-row row-between row-middle"
v-for="(item,index) in attrArr"
:key="index"
@click="editAttr(index)"
>
<view class="attr-item-l">{{item.value}}({{item.detail.length}})</view>
<image src="../../../static/images/arror-r-s.png"></image>
<view class="del-attr" @tap.stop="delAttr(index)">×</view>
</view>
</view>
<!-- 规格设置 -->
<view class="add-sku-box">
<view class="sku-item">
<view class="sku img-sku acea-row row-middle row-between">
<text>价格<text class="colR">*</text></text>
<input type="number" v-model="attrs[0].price" @input="changePrice" placeholder="请输入售价(元)" />
</view>
<view class="sku img-sku acea-row row-middle row-between">
<text>库存<text class="colR">*</text></text>
<input type="number" v-model="attrs[0].stock" @input="changeStock" placeholder="请输入库存" />
<!-- <view class="acea-row row-middle">
<switch :checked="!infinite" @change="stockChange" style="transform: scale(0.8);" />
<view>{{infinite ? '不限' : '有限'}}</view>
</view>
<view class="colB">批量设置</view> -->
</view>
</view>
</view>
<!-- 批量操作 -->
<view class="batch-set-box" v-if="batchData.titleStr">
<view class="box-top acea-row row-between-wrapper">
<view class="name">{{batchData.titleStr}}</view>
<view class="attr-name w15">库存</view>
<view class="attr-name w15">价格</view>
</view>
<block v-for="(i,idx) in batchData.priceArr" :key="idx">
<view class="box-b acea-row row-between-wrapper">
<!-- <view class="name line1">{{i.sku.replace(/,/, '/')}}</view> -->
<view class="name line1">{{i.sku.split(',').reverse().join('/')}}</view>
<view class="inp-box w15"><input type="number" placeholder="0" v-model="i.stock"></view>
<view class="inp-box w15"><input type="number" placeholder="0" v-model="i.price"></view>
</view>
</block>
</view>
<view class="temp-box acea-row row-between-wrapper" @click="toTempList">
<text>运费模板</text>
<view class="acea-row row-middle">
<text>{{temp}}</text>
<image src="../../../static/images/arror-r-s.png"></image>
</view>
</view>
<view class="temp-box goods-state acea-row row-between-wrapper">
<text>商品状态</text>
<view class="acea-row row-middle">
<radio-group @change="radioChange">
<label>
<radio :value="0" :checked="state == 0" /><text>上架</text>
</label>
<label>
<radio :value="1" :checked="state == 1" /><text>下架</text>
</label>
</radio-group>
</view>
</view>
<view class="btn-box">
<view class="btn" @tap="submit">提交</view>
</view>
<!-- //添加规格弹框 -->
<view class="mask-box" v-if="maskShow == true">
<view class="addattr-dialog" v-if="addOptionsDialog == true">
<view class="dialog-top acea-row row-between row-middle">
<text>规格属性</text>
<view class="close" @click="maskShow = false; addOptionsDialog = false">×</view>
</view>
<view>
<view class="a-name"><input type="text" v-model="attr.value" placeholder="输入属性名称,如:颜色"></view>
<view class="o-name-box">
<block v-for="(o,i) in attr.detail" :key="i">
<view class="o-item-box acea-row row-between row-middle">
<input type="text" v-model="attr.detail[i]" placeholder="输入选项,如:红色">
<text class="close" @click="delOption(i)">×</text>
</view>
</block>
<view class="add-option-btn" @click="addOption">+选项</view>
</view>
</view>
<view class="s-btn" @click="submitAddAttr">确定</view>
</view>
</view>
</view>
</template>
<script>
import { chooseImage, chooseImages } from "@/utils"
import { addProduct, getProductInfo, editProduct, getFormatAttr } from '@/api/store'
export default{
data(){
return {
id: '',
store_name: '',
unit_name: '',
image:'', //主图
slider_image: [] ,// 轮播图
description: '', //商品详情富文本
tempId: 1, //运费方案
temp: '默认免邮',
attrs: [ // 单规格一个,多规格多个
{
pic: '', //"规格图片 --可选",
price: '', //"价格 元",
ot_orice: '', //"市场价格 --可选",
stock: '', //"库存",
weight: '', //"重量 --可选",
volume: '', //"体积 --可选"
}
],
items: [],
attrArr:[],
attr:{},
state: 0,
maskShow: false,
addOptionsDialog: false,
infinite: false,
batchData: {},
editattr: false,
priceArr: [],
}
},
onLoad() {
this.id = this.$yroute.query.id || ''
if(this.id){
uni.setNavigationBarTitle({
 title:'修改商品'
})
getProductInfo({id: this.id}).then((res)=>{
var info = res.data
this.slider_image = info.slider_image
this.image = info.slider_image[0]
this.unit_name = info.unit_name
this.description = info.description
this.store_name = info.store_name
this.items = info.items
if(info.attrs){
this.$set(this.batchData,'priceArr',info.attrs)
this.attrArr = info.items
let strArr = info.items.map(item=>{
return item.value
})
console.log(strArr)
this.$set(this.batchData,'titleStr',strArr.join('/'))
} else{
this.attrs[0].price = info.price
this.attrs[0].stock = info.stock
}
})
} else{
console.log('新增')
}
},
methods:{
uploadImgs(){
var imgurls = []
chooseImages((imgs)=>{
imgurls.push(imgs)
})
this.slider_image = imgurls
},
uploadImg(idx){
chooseImage((img)=>{
if(this.slider_image[idx]){
this.$set(this.slider_image,idx,img)
} else{
this.slider_image.push(img)
}
})
},
uploadSkuImg(idx){
chooseImage((img)=>{
this.$set(this.attrs,idx,{pic: img})
})
},
toGoodsDetails(){
uni.navigateTo({
url: '/pages/life/goodsDetails/index?desc='+encodeURIComponent(this.description)
});
},
toTempList(){
uni.navigateTo({
url: '/pages/life/tempList/index'
})
},
//添加属性按钮
addAttr(){
let j = {
value: '',
detail:['']
}
this.attr = j
this.editattr = false; //添加新属性时是否编辑attr切换成FALSE
this.maskShow = true;
this.addOptionsDialog = true
},
//修改属性
editAttr(i){
this.attr = this.attrArr[i]
this.editattr = true; //修改属性时是否编辑attr切换成true
this.maskShow = true;
this.addOptionsDialog = true
},
delAttr(i){
this.attrArr.splice(i,1)
this.getFormatAttr()
},
addOption(){
this.attr.detail.push('')
},
delOption(i){
this.attr.detail.splice(i,1)
},
///添加属性提交
submitAddAttr(){
if(this.attr.value == ''){
return uni.showToast({
title: '请填写属性名称!',
icon: 'none'
})
}
try{
var o = this.attr.detail;
o.forEach(function(item,index) {
if(item == ""){
throw "属性规格不能为空!";
}
});
}catch(e){
uni.showToast({
title: e,
icon: 'none'
})
return false
}
if(!this.editattr){
this.attrArr.push(this.attr)
}
this.items = this.attrArr
this.getFormatAttr()
this.addOptionsDialog = false
this.maskShow = false
},
//属性数据接口
getFormatAttr(){
let data = { attrs: this.items, productId: this.id || 0 }
getFormatAttr(data).then((res)=>{
if(res.success){
this.$set(this.batchData,'priceArr',res.data.value)
let strArr = res.data.attr.map(item=>{
return item.value
})
this.$set(this.batchData,'titleStr',strArr.join('/'))
} else{
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
},
//属性设置数据
setBatchData(arr){
var titleArr = []
for (var i in arr) {
titleArr.push(arr[i].value)
}
var titleStr = titleArr.join('/')
var attrArr = this.setData(arr)
var branchList = []
var hash = {}
attrArr.forEach((item,idx)=>{
branchList.push({
sku: item.join('/'),
pic: '', //"规格图片 --可选",
price: '', //"价格 元",
ot_orice: '', //"市场价格 --可选",
stock: '', //"库存",
weight: '', //"重量 --可选",
volume: '', //"体积 --可选"
})
})
console.log(attrArr,'attrArr')
this.priceArr = branchList
this.batchData.attrArr = attrArr
console.log(this.batchData)
},
//数组整合
setData(attrArr){
var tmp = []
for (var i in attrArr) {
tmp.push(attrArr[i].detail)
}
function cartesianProductOf() {
return Array.prototype.reduce.call(arguments, function (a, b) {
var ret = [];
a.forEach(function (a) {
b.forEach(function (b) {
ret.push(a.concat([b]));
});
});
return ret;
}, [[]]);
}
let allArr = cartesianProductOf(...tmp)
return allArr
},
// 批量设置价格库存
changePrice(e){
const price = e.detail.value
this.batchData.priceArr.forEach((item,i)=>{
item.price = price
})
this.attrs[0].price = price
// console.log(this.batchData.priceArr,'this.batchData.priceArr')
},
changeStock(e){
const stock = e.detail.value
this.batchData.priceArr.forEach((item,i)=>{
item.stock = stock
})
this.attrs[0].stock = stock
},
//单规格
addSku(){
let item = {
pic: '', //"规格图片 --可选",
price: '', //"价格 元",
ot_orice: '', //"市场价格 --可选",
stock: '', //"库存",
weight: '', //"重量 --可选",
volume: '', //"体积 --可选"
}
this.attrs.push(item)
uni.pageScrollTo({
scrollTop: 999999
})
},
delSku(idx){
this.attrs.splice(idx,1)
},
//库存有限无限切换
stockChange(e){
// console.log(e)
this.infinite = !e.detail.value
},
radioChange(e){
this.state = e.detail.value
},
submit(){
// console.log(this.batchData)
var arrtsArr = []
if(this.batchData.priceArr && this.batchData.priceArr[0].price != ''){
arrtsArr = this.batchData.priceArr
} else{
arrtsArr = this.attrs
}
let form = {
store_name: this.store_name,
unit_name: this.unit_name,
image: this.slider_image[0], //主图
slider_image: this.slider_image , // 轮播图
description: this.description, //商品详情富文本
tempId: 1, //运费方案
attrs: arrtsArr,
state: this.state,
items: this.items,
spec_type: arrtsArr.length > 1 ? 1 : 0 //单规格,多规格
}
console.log(form)
if(form.store_name == ''){
this.alertMessage('请填写商品名称')
return
} else if(form.slider_image[0] == ''){
this.alertMessage('请至少上传一张商品图片')
return
} else if(form.description == ''){
this.alertMessage('请填写商品详情')
return
} else if(form.description == ''){
this.alertMessage('请填写商品详情')
return
}
form.attrs.forEach((item,index)=>{
if(item.price == ''){
this.alertMessage('请商品规格价格')
return
} else if(item.stock == ''){
this.alertMessage('请商品规格库存')
return
}
})
if(this.id != ''){
form.id = this.id
editProduct(form).then((res)=>{
if(res.success){
uni.showToast({
title: res.msg,
duration: 1500
})
setTimeout((res)=>{
uni.navigateTo({
url: '/pages/user/goodsManage/index'
})
},1500)
} else{
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
} else{
addProduct(form).then((res)=>{
if(res.success){
uni.showToast({
title: res.msg,
duration: 1500
})
setTimeout((res)=>{
uni.navigateTo({
url: '/pages/user/goodsManage/index'
})
},1500)
} else{
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
}
console.log(form,'form')
},
alertMessage(msg){
uni.showToast({
title: msg,
icon: 'none'
})
}
}
}
</script>
<style lang="less">
.index-box{
width: 100%;
min-height: 100vh;
background: #F5F6F7;
padding: 20rpx 40rpx 110rpx;
position: relative;
.add-goodsimg-box{
width: 100%;
padding: 24rpx;
background: #fff;
border-radius: 8rpx;
.upload-box{
width: 140rpx;
height: 140rpx;
margin-right: 20rpx;
&:nth-last-child(1){
margin-right: 0;
}
image{
width: 100%;
height: 100%;
border-radius: 8rpx;
}
}
.tips{
color: #FF0707;
font-size: 20rpx;
margin-top: 16rpx;
image{
width: 18rpx;
height: 18rpx;
margin-right: 8rpx;
}
}
}
.goodsInfo-box{
width: 100%;
background: #fff;
border-radius: 8rpx;
font-size: 28rpx;
font-weight: 500;
margin-top: 40rpx;
.goodsInfo-item{
width: 100%;
height: 82rpx;
padding: 0 32rpx;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 2rpx solid #EEEEEE;
&:nth-last-child(1){
border: none;
}
input{
text-align: right;
}
.toEdit{
image{
width: 24rpx;
height: 24rpx;
margin-left: 6rpx;
}
}
}
}
.title2{
width: 100%;
height: 76rpx;
line-height: 76rpx;
border: 2rpx solid #B8B8B8;
background: #fff;
border-radius: 8rpx;
font-size: 28rpx;
text-align: center;
margin: 24rpx auto;
}
.add-sku-box{
width: 100%;
border-radius: 8rpx;
font-size: 28rpx;
font-weight: 500;
margin-top: 24rpx;
image{
width: 110rpx;
height: 110rpx;
}
.sku-item{
padding: 32rpx 0;
background: #fff;
margin-bottom: 12rpx;
position: relative;
.close-btn{
color: #fff;
font-size: 38rpx;
position: absolute;
right: -16rpx;
top: -22rpx;
border-radius: 50%;
line-height: 40rpx;
width: 46rpx;
height: 46rpx;
text-align: center;
background: #FF5E16;
border-radius: 50%;
}
.sku{
padding: 0 32rpx;
width: 100%;
min-height: 86rpx;
border-bottom: 2rpx solid #EEEEEE;
}
input{
text-align: right;
}
}
}
.temp-box{
width: 100%;
background: #fff;
border-radius: 8rpx;
padding: 32rpx;
font-size: 28rpx;
font-weight: 500;
image{
width: 24rpx;
height: 24rpx;
margin-left: 6rpx;
}
}
label{
margin-left: 16rpx;
}
.btn-box{
.btn{
width: 230rpx;
height: 80rpx;
background: linear-gradient(134deg, #FFA782 0%, #FF6D31 100%);
text-align: center;
line-height: 80rpx;
font-size: 38rpx;
font-weight: 500;
border-radius: 40rpx;
color: #fff;
margin: 32rpx auto;
}
}
.colR{
color: #FF0000;
}
.set-title{
font-size: 32rpx;
color: #343434;
margin: 34rpx 0 24rpx;
}
.setattr-box{
width: 100%;
background: #fff;
.attr-item{
width: 100%;
padding: 20rpx 50rpx 20rpx 32rpx;
border-bottom: 2rpx solid #eee;
font-size: 28rpx;
position: relative;
.del-attr{
font-size: 40rpx;
position: absolute;
right: 10rpx;
top: 20rpx;
width: 36rpx;
height: 36rpx;
// background: #FFA079;
line-height: 32rpx;
text-align: center;
border-radius: 50%;
color: #FFA079;
}
image{
width: 24rpx;
height: 24rpx;
}
}
}
// 批量设置库存
.batch-set-box{
width: 100%;
background: #fff;
padding: 24rpx;
color: #343434;
font-size: 28rpx;
margin: 12rpx 0;
.box-top{
padding: 0 0 12rpx;
border-bottom: 2rpx solid #EEEEEE;
color: #ABABAB;
.name{
width: 60%;
}
.w15{
width: 19%;
text-align: center;
}
}
.box-b{
margin-top: 6rpx;
.name{
width: 60%;
}
.w15{
width: 19%;
}
.inp-box{
text-align: center;
height: 44rpx;
border-radius: 12rpx;
background: #DCDCDC;
input{
width: 100%;
height: 100%;
}
}
}
}
//弹出层
.mask-box{
width: 100%;
height: 100%;
background: rgba(0,0,0,.7);
position: fixed;
top: 0;
left: 0;
z-index: 99;
.addattr-dialog{
width: 680rpx;
min-height: 590rpx;
background: #FFFFFF;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
border-radius: 40rpx;
padding: 80rpx 64rpx;
.dialog-top{
margin-bottom: 26rpx;
}
.close{
font-size: 46rpx;
}
.a-name{
width: 560rpx;
height: 104rpx;
background: #F7F7F7;
border-radius: 12rpx;
padding: 30rpx;
}
.o-name-box{
background: #f7f7f7;
padding: 36rpx 42rpx 0;
margin: 28rpx 0 0;
border-radius: 12rpx;
font-size: 26rpx;
input{
width: 80%;
}
.o-item-box{
height: 56rpx;
padding-bottom: 10rpx;
margin-bottom: 10rpx;
border-bottom: 2rpx solid #ececec;
}
}
.add-option-btn{
width: 100%;
padding: 20rpx 0;
text-align: center;
color: #BFBFBF;
background: #f7f7f7;
// border-top: 2rpx solid #ececec;
font-size: 26rpx;
}
.s-btn{
width: 230rpx;
height: 80rpx;
background: linear-gradient(134deg, #FFA782 0%, #FF6D31 100%);
border-radius: 40rpx;
text-align: center;
line-height: 80rpx;
color: #fff;
font-size: 26rpx;
margin: 70rpx auto 0;
}
}
}
.colB{
color: #0932FF;
}
}
</style>