shop-applet/pages/product/addGoodDetail/addGoodDetail.vue

892 lines
25 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class='content'>
<u--form :model="formData" :rules="rules" ref="formData" :labelStyle="{fontSize:'32rpx',color:'#444444'}"
labelWidth='auto'>
<view class="good-baseInfo card">
<u-form-item label="商品标题" prop="store_name" ref="item1" required>
<text slot='right' style="font-size:28rpx ; color:#989898 ;">{{value1.length}}/{{maxLength}}</text>
</u-form-item>
<u-form-item label="" prop="userInfo.name" ref="item1">
<u--textarea v-model="formData.store_name" placeholder="建议描述产品品牌、名称、规格、口味"
style="background-color: #F9F9F9;height: 166rpx;" :maxlength='maxLength'></u--textarea>
<!-- <u--textarea v-model="formData.store_name" placeholder="请输入内容"></u--textarea> -->
</u-form-item>
<u-form-item label="商品主图" prop="formData.imageList" ref="item1" required>
<text style="color: #E18C34;font-size: 24rpx">上传时应注重真实性、清晰度</text>
<!-- {{formData.imageList}}
{{formData.content.image}} -->
</u-form-item>
<view class="card" style="min-height: 150rpx;margin-bottom: 0;padding: 0;">
<view class="" style="display: flex;flex-wrap: wrap;">
<view v-for="(item,index) in formData.imageList"
style="margin-right: 20rpx;margin-bottom: 20rpx;">
<view class="video_list" v-if='vidioTypeList.includes(getSuffix(item))'>
<view class="video_list_item photo" style="position: relative;">
<view class="jiao" @click="formData.imageList.splice(index,1)">
<!-- video标签在app端层级过高 -->
<!--#ifndef APP-PLUS-->
<video :src="item"></video>
<!--#endif-->
<!--#ifdef APP-PLUS-->
<img src="https://lihai001.oss-cn-chengdu.aliyuncs.com/public/kk/luzhou/static4/3/video_bg.png"
style=" width:150rpx"></img>
<!--#endif-->
<image src="@/static/images/gban.png" mode="widthFix"></image>
</view>
<view style="position: absolute;top: 20rpx;z-index: 99;width: 140rpx;height: 100%;"
@click="videoshow(index)">
<view class="videoHover">
</view>
</view>
</view>
</view>
<view class="" style="position: relative;" v-else>
<view class="jiao" @click="formData.imageList.splice(index,1)">
<image src="@/static/images/gban.png" mode="widthFix"></image>
</view>
<u--image @click="preViewImg(item)" :src="item" :fade="true" duration="450"
width='140rpx' height='140rpx'></u--image>
</view>
</view>
<view class='uploadimg' @click="show=true,isDetail=false">
<u-icon name="plus" color="#777777"></u-icon>
<view class="" style="color: #777777;font-size: 20rpx;">
上传图片/视频
</view>
</view>
</view>
</view>
<u-form-item label="商品详情" prop="formData.content.image" required>
<text style="color: #E18C34;font-size: 24rpx">上传时应注重真实性、清晰度</text>
</u-form-item>
<view class="card" style="min-height: 150rpx;margin-bottom: 0;padding: 0;">
<view class="" style="display: flex;flex-wrap: wrap;">
<view v-for="(item,index) in formData.content.image"
style="margin-right: 20rpx;margin-bottom: 20rpx;">
<view class="video_list" v-if='vidioTypeList.includes(getSuffix(item))'>
<view class="video_list_item photo" style="position: relative;">
<view class="jiao" @click="formData.content.image.splice(index,1)">
<!-- video标签在app端层级过高 -->
<!--#ifndef APP-PLUS-->
<video :src="item"></video>
<!--#endif-->
<!--#ifdef APP-PLUS-->
<img src="https://lihai001.oss-cn-chengdu.aliyuncs.com/public/kk/luzhou/static4/3/video_bg.png"
style=" width:150rpx"></img>
<!--#endif-->
<image src="@/static/images/gban.png" mode="widthFix"></image>
</view>
<view style="position: absolute;top: 20rpx;z-index: 99;width: 140rpx;height: 100%;"
@click="videoshow(index)">
<view class="videoHover">
</view>
</view>
</view>
</view>
<view class="" style="position: relative;" v-else>
<view class="jiao" @click="formData.content.image.splice(index,1)">
<image src="@/static/images/gban.png" mode="widthFix"></image>
</view>
<u--image @click="preViewImg(item)" :src="item" :fade="true" duration="450"
width='140rpx' height='140rpx'></u--image>
</view>
</view>
<view class='uploadimg' @click="show=true,isDetail=true">
<u-icon name="plus" color="#777777"></u-icon>
<view class="" style="color: #777777;font-size: 20rpx;">
上传图片/视频
</view>
</view>
</view>
</view>
</view>
<view class='tips'>
商品类目属性
</view>
<view class="card" style="padding: 14rpx 30rpx;">
<u-form-item label="商品分类" prop="cate_name" ref="item1" labelPosition="left" required>
<view style="display: flex;align-items: center;font-size: 28rpx;color:#777777 ;" slot="right"
@click="navgo(`/pages/product/addGoodDetail/goodsType?mer_id=${mer_id}&&formData=${JSON.stringify(formData)}`)">
<view style="margin-right: 10rpx;line-height: 25rpx;">{{ formData.cate_name|| '请选择'}}</view>
<u-icon name="arrow-right"></u-icon>
</view>
</u-form-item>
<u-form-item label="商品属性" prop="userInfo.name" ref="item1" labelPosition="left">
<view style="display: flex;align-items: center;font-size: 28rpx;color:#777777 ;" slot="right"
@click="navgo(`/pages/product/addGoodDetail/goodsAttr?mer_id=${mer_id}&&formData=${JSON.stringify(formData)}`)">
<view style="margin-right: 10rpx;line-height: 25rpx;">
{{isSet(formData.product_attribute)?'已设置':'未设置' }}
</view>
<u-icon name="arrow-right"></u-icon>
</view>
</u-form-item>
</view>
<view class='tips'>
规格与价格
</view>
<view class="card" style="min-height: 100rpx;padding: 14rpx 30rpx;">
<u-form-item label="规格与价格" prop="formData.attrValue" ref="item1" labelPosition="left" required>
<view style="display: flex;align-items: center;font-size: 28rpx;color:#777777 ;" slot="right"
@click="navgo(`/pages/product/addGoodDetail/goodsPrice?formData=${JSON.stringify(formData)}&&mer_id=${mer_id}`)">
<view style="margin-right: 10rpx;line-height: 25rpx;">{{sets?"已设置":""}}
</view>
<u-icon name="arrow-right"></u-icon>
</view>
</u-form-item>
<view class="" v-if="showSet">
<view class="" v-for="(item,index) in formData.attrValue.filter(item=> item.is_use==0)">
<view class="" v-if='formData.attrValue.filter(item=> item.is_use==0).length==1'>
<u-line color="#CECECE" style="margin: 30rpx 0;"></u-line>
<view class="" style="display: flex;justify-content: space-around;">
<view class=""
style="display: flex;justify-content: space-around;flex: 1;border-right: 1px solid #CECECE;">
<text>零售价格</text>
<text>{{item.price}}元/{{item.unit_name}}</text>
</view>
<view class="" style="display: flex;justify-content: space-around;flex: 1;">
<text>商品库存</text>
<text>{{item.stock}}</text>
</view>
</view>
<u-line color="#CECECE" style="margin: 30rpx 0;" v-if='isWholeSale'></u-line>
<view class="" style="display: flex;justify-content: space-around;" v-if='isWholeSale'>
<view class=""
style="display: flex;justify-content: space-around;flex: 1;border-right: 1px solid #CECECE;">
<text>批发价格</text>
<text>{{item.wholesale_price}}元/{{item.wholesale_unit_name}}</text>
</view>
<view class="" style="display: flex;justify-content: space-around;flex: 1;">
<text>批发单位</text>
<text>{{item.stock}}</text>
</view>
</view>
</view>
<view class="" v-else>
<u-form-item :label="formData.attr[index].value" label-width="350rpx" prop="userInfo.name"
ref="item1" labelPosition="left" border-bottom>
<view class="" style="display: flex;justify-content: space-between;width: 100%">
<view style="width: 250rpx;" v-if='!formData.attr[index].value'>
</view>
<view style="font-size: 28rpx;color:#777777 ;">
零售价
</view>
<view style="font-size: 28rpx;color:#777777 ;">
{{item.price}}元/{{item.unit_name}}
</view>
</view>
</u-form-item>
<u-form-item label=" " label-width="350rpx" prop="userInfo.name" ref="item1"
labelPosition="left" border-bottom v-if='isWholeSale'>
<view class="" style="display: flex;justify-content: space-between;width: 100%">
<view style="font-size: 28rpx;color:#777777 ;">
批发价
</view>
<view style="font-size: 28rpx;color:#777777 ;">
{{item.wholesale_price}}元/{{item.wholesale_unit_name}}
</view>
</view>
</u-form-item>
</view>
</view>
</view>
</view>
<view class='tips'>
服务与承诺
</view>
<view class="card" style="padding: 14rpx 30rpx;">
<u-form-item label="商品详细描述" prop="userInfo.name" ref="item1" labelPosition="left">
<text slot='right' style="font-size:28rpx ; color:#989898 ;">{{value1.length}}/{{300}}</text>
</u-form-item>
<u--textarea v-model="formData.store_info" placeholder="货品描述请严格遵循《广告法》规定,避免出现虚假宣传和误导消费者的词语"
style="background-color: #F9F9F9;height: 166rpx;" :maxlength='300'></u--textarea>
<u-line color="#F3F3F3" style="margin: 30rpx 0;"></u-line>
<u-form-item label="送货方式" labelPosition="left" prop='delivery_way' required>
<u-checkbox-group v-model="formData.delivery_way" placement="row" slot="right">
<u-checkbox shape="circle" v-for="(item, index) in checkboxList1" :key="index"
:label="item.name" :name="item.value" activeColor="#20B128"
:customStyle="{marginRight: '8px'}"
:labelColor="checkboxValue1.includes(item.name)?'#20B128':'#777777'">
</u-checkbox>
</u-checkbox-group>
</u-form-item>
</view>
</u--form>
<view class="submit-btn">
<u-button text="确认发布" @click="submit" color="#33BB3C" class="custom-style"></u-button>
</view>
<view class="overlay">
<u-overlay :show="showlay">
<view class="overlay-content">
<view class="">
温馨提示
</view>
<view class="" style="font-family: PingFangFamily;font-size: 36rpx;">
发布中断可能导致商机流失
</view>
<view class="" style="font-size: 26rpx;color: #777777;">
<view class="">
您的商品信息已经填写了大半
</view>
<view class="">
只差最后几步就能上架销售了
</view>
</view>
<view class=""
style="font-size: 28rpx;color: #444444;background-color: #EDF8ED;padding: 20rpx 44rpx;border-radius: 12rpx;">
<view class="">
越早发布产品<text style='color: #21B129;'>曝光量越高</text>
</view>
<view class="">
越早发布产品可提前 <text style='color: #21B129;'>抢占商机</text>
</view>
</view>
<view style="display: flex;">
<view style="width: 236rpx;height: 84rpx;margin-right: 30rpx;">
<u-button text="确定返回" @click='back'></u-button>
</view>
<view style="width: 236rpx;height: 84rpx;">
<u-button type='primary' text="继续编辑" @click='showlay=false'></u-button>
</view>
</view>
</view>
</u-overlay>
</view>
<u-picker :show="show" :columns="columns" confirmColor='#33BB3C' @close='show=false' @confirm='choseMedia'
@cancel='show=false'></u-picker>
<view v-if="showVideo" class="video-count">
<video id="myVideo" class="videoLink" autoplay loop muted
:src=" isDetail?formData.content.image[videoIndex]: formData.imageList[videoIndex]"></video>
</view>
<view class='mask' catchtouchmove="true" :hidden='showVideo==false' @tap="showVideo=false"></view>
</view>
</template>
<script>
import {
Toast,
Modal
} from "@/libs/uniApi.js";
import {
HTTP_REQUEST_URL,
TOKENNAME
} from '@/config/app.js';
import store from 'store';
import {
productCreate,
productUpdate,
productDetail
} from '@/api/product.js';
import uploadImgVideo from "../addGood/components/uploadImgVideo.vue"
import form from "../../../uni_modules/uview-ui/libs/config/props/form";
export default {
components: {
uploadImgVideo,
},
data() {
return {
mode: 'add',
isDetail: false,
columns: [
['图片', '视频', ]
],
sets: false,
showVideo: false,
vidioTypeList: ['mp4', 'avi', 'mov', 'wmv', 'mkv', 'flv', 'mpeg', '3gp', 'webm'],
videoIndex: 0,
upload_max: 100,
uploadUrl: `${HTTP_REQUEST_URL}/api/upload/video`,
show: false, //选择图片还是视屏
showSet: false,
vidioTypeList: ['mp4', 'avi', 'mov', 'wmv', 'mkv', 'flv', 'mpeg', '3gp', 'webm'],
delivery_way: [],
isWholeSale: false,
formData: {
product_id: "",
"store_name": "",
"imageList": [
],
attr: [{
detail: [],
value: ""
}, ],
"attrValue": [{
detail: {
规格名: 'attr[index]value',
},
"price": "",
"unit_name": "",
"wholesale_unit_name": "",
"wholesale_price": '',
"cost": "",
"stock": "",
sku: 'attr[index]value',
"ot_price": "",
"procure_price": "",
"bar_code": "",
"weight": "",
"extension_one": "",
"extension_two": "",
uuid: "",
volume: "",
"is_use": 0,
}],
"cate_name": "",
"unit_name": "",
"cate_id": '',
"mer_cate_id": [
],
"mer_cate_name": "",
"spec_type": "",
"specifica": "",
"delivery_way": [
],
"delivery_free": "1",
"temp_id": "",
"tempName": "",
"once_min_count": "",
"image": "",
"slider_image": [
""
],
"is_good": 0,
"is_gift_bag": 0,
"sort": "",
"once_count": "",
"video_link": "",
"content": {
"title": "",
"image": []
},
"stock": "",
product_attribute: {
address: "",
leval: "",
pack: "",
attr: [{
label: "",
value: ''
}]
}
},
mer_id: "",
maxLength: 30,
fileList6: [],
showSex: false,
showlay: false,
go: true,
model1: {
userInfo: {
name: '',
sex: '',
},
},
range: [{
value: 0,
text: "篮球"
},
{
value: 1,
text: "足球"
},
{
value: 2,
text: "游泳"
},
],
text: "",
text1: "",
value1: "",
checkboxValue1: [],
checkboxList1: [{
name: '到店核销',
value: '1',
},
{
name: '快递配送',
value: '2',
},
],
attrRules: {
price: '单价不能为空',
unit_name: '计量单位不能为空',
wholesale_price: '批发价格不能为空',
wholesale_unit_name: '批发单位不能为空',
stock: '库存不能为空'
},
rules: {
"formData.imageList": [{
validator: (rule, value, callback) => {
return this.formData.imageList.length >= 2
},
message: '请至少上传2张图片',
trigger: ['change', 'blur'],
}],
"formData.attrValue": [{
validator: (rule, value, callback) => {
if (!this.isWholeSale) {
delete this.attrRules.wholesale_unit_name
delete this.attrRules.wholesale_price
}
let errList = []
this.formData.attrValue.forEach(item => {
for (let key in this.attrRules) {
if (!item[key]) {
errList.push(this.rules[key])
}
}
})
console.log(errList, 'err')
return errList.length == 0
},
message: '请填写完整商品规格',
trigger: ['change', 'blur'],
}],
'store_name': {
type: 'string',
required: true,
message: '请填写商品标题',
trigger: ['blur', 'change']
},
'cate_name': {
type: 'string',
required: true,
message: '请填写商品分类',
trigger: ['blur', 'change']
},
'delivery_way': {
validator: (rule, value, callback) => {
return this.formData.delivery_way.length > 0
},
required: true,
message: '请选择送货方式',
trigger: ['blur', 'change']
},
'formData.content.image': {
validator: (rule, value, callback) => {
return this.formData.content.image.length > 0
},
required: true,
message: '请上传商品详情图',
trigger: ['blur', 'change']
},
},
radio: '',
switchVal: false
};
},
methods: {
preViewImg(url) {
let that = this
uni.previewImage({
urls: [url],
});
},
deleteImage(index) {
// this.addGoodsSecoundData.video_link = '';
},
videoshow(index) {
this.videoIndex = index
this.showVideo = true
this.videoContext = uni.createVideoContext('myVideo', this);
this.$nextTick(() => {
this.videoContext.play();
})
},
getSuffix(url) {
const str = url;
const lastIndex = str.lastIndexOf(".");
if (lastIndex !== -1) {
const extension = str.substring(lastIndex + 1);
return extension
} else {
console.log("字符串中没有找到点号。");
}
},
choseMedia(e) {
console.log(e.value)
this.show = false
if (e.value[0] == '图片') {
this.handleChooseImage()
} else {
this.uploadVideo()
}
},
// 选择图片
handleChooseImage() {
let that = this;
that.$util.uploadImages({
count: 6,
url: 'upload/image'
}, function(res) {
if (that.isDetail) {
that.formData.content.image.push(res.data.path.replace(
/\\/g, ""));
} else {
that.$set(that.formData.imageList, that.formData.imageList.length, res.data.path.replace(
/\\/g,
""));
}
// that.formData.imageList.push(res.data.path);
});
},
// 上传视频
uploadVideo() {
let that = this
uni.chooseVideo({
sourceType: ['camera', 'album'],
success: res => {
uni.showLoading({
title: '正在上传中。。。'
});
if (Math.ceil(res.size / 1024) < this.upload_max * 1024) {
uni.uploadFile({
url: this.uploadUrl, //仅为示例,非真实的接口地址
filePath: res.tempFilePath,
name: 'file',
header: {
// #ifdef MP
'Content-Type': 'multipart/form-data',
// #endif
[TOKENNAME]: 'Bearer ' + store.state.app.token
},
success: uploadFileRes => {
uni.hideLoading();
let data = JSON.parse(uploadFileRes.data);
if (that.isDetail) {
that.formData.content.image.push(data.data.src.replace(
/\\/g, ""));
} else {
that.formData.imageList.push(data.data.src.replace(/\\/g,
""))
}
},
complete: a => {
// console.log(a);
}
});
} else {
uni.showModal({
title: '提示',
content: `视频超出限制${this.upload_max}MB,已过滤`
});
}
},
fail: err => {
console.log(err)
}
});
},
isSet(obj) {
for (let key in obj) {
if (typeof obj[key] == 'object') this.isSet(obj[key])
else {
if (Boolean(obj[key])) return 'true12';
}
}
},
isSet2(obj) {
let lists = ['unit_name', 'price', 'wholesale_price', 'stock']
lists.forEach(item => {
if (Boolean(this.formData.attrValue[0][item])) {
this.sets = true
}
})
},
sexSelect(e) {
this.model1.userInfo.sex = e.name
this.$refs.uForm.validateField('userInfo.sex')
},
navgo(url) {
uni.navigateTo({
url
})
},
back() {
// console.log('show')
this.go = false
uni.navigateBack()
},
showlayFn() {
uni.navigateBack()
},
// submit() {
// console.log(this.formData)
// },
getAttr(object) {
this.formData.product_attribute = object
},
getAttrValue(object) {
this.formData.attrValue = object
},
async handAdd() {
let that = this
let data = uni.$u.deepClone(this.formData)
data.image = data.imageList[0]
data.slider_image = data.imageList.splice(0, 1)
data.store_name = data.cate_name
that.formData.product_id ?
productUpdate(that.mer_id, that.formData.product_id, data)
.then(res => {
Modal('提交成功', '点击确定,前往商品列表页面').then(() => {
if (this.import == 1) {
uni.$emit('importAttrValueOK', this.setFormData.import_id);
uni.navigateBack();
} else uni.redirectTo({
url: `/pages/product/goodsOnSale/index?mer_id=${that.mer_id}&type=6`
})
}).catch(() => {
uni.navigateBack()
})
})
.catch(rej => {
// Toast(rej);
}) :
productCreate(that.mer_id, data)
.then(res => {
Modal('提交成功', '点击确定,前往商品列表页面').then(() => {
if (this.import == 1) {
uni.$emit('importAttrValueOK', this.setFormData.import_id);
uni.redirectTo({
url: `/pages/product/list/index?mer_id=${this.mer_id}&type=6`
})
} else uni.redirectTo({
url: `/pages/product/list/index?mer_id=${this.mer_id}&type=6`
})
}).catch(() => {
uni.navigateBack()
})
})
.catch(rej => {
// Toast(rej);
})
},
submit() {
this.$refs.formData.validate().then(res => {
this.handAdd()
}).catch(errors => {
uni.$u.toast(errors[0].message)
})
},
initFormData(option) {
this.isWholeSale = this.$store.state.app.userInfo?.mer_info?.wholesale == 2;
this.mer_id = option.mer_id
if (option.formData) {
this.formData = JSON.parse(option.formData)
}
}
},
onLoad(option) {
this.initFormData(option)
this.showSet = option.showSet ? JSON.parse(option.showSet) : this.showSet
let that = this
this.isSet2()
that.formData.delivery_way = that.$store.state.app.userInfo?.mer_info.delivery_way.split(',')
if (option.product_id) {
that.formData.product_id = option.product_id
this.mode = 'edit'
this.showSet = true
productDetail(option.mer_id, option.product_id).then(res => {
this.formData = res.data
//该死的后端,格式不按添加的格式来
this.formData.product_attribute = JSON.parse(this.formData.product_attribute)
this.formData.cate_name = this.formData.storeCategory.cate_name
this.formData.cate_id = this.formData.storeCategory.store_category_id
this.formData.imageList = this.formData.image_list
if (!that.formData.imageList) that.formData.imageList = []
})
}
},
onBackPress: function(e) {
this.showlay = true
return this.go;
}
};
</script>
<style lang='scss'>
.content {
width: 100vw;
min-height: 100vh;
background-color: #F1F1F1;
box-sizing: border-box;
padding-bottom: 280rpx;
font-family: PingFangRegular;
padding: 20rpx 20rpx 200rpx 20rpx;
.card {
background-color: white;
padding: 28rpx 30rpx;
border-radius: 12rpx;
margin-bottom: 30rpx;
}
.uploadimg {
width: 140rpx;
height: 140rpx;
border-radius: 16rpx;
border: 2rpx solid #F1F1F1;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
box-sizing: border-box;
padding: 20rpx 0;
/* margin-left: 20rpx; */
overflow: hidden;
}
.tips {
color: #777777;
font-size: 28rpx;
margin: 30rpx 0;
}
.submit-btn {
position: fixed;
bottom: 50rpx;
left: 50%;
transform: translate(-50%, 0);
width: 670rpx;
border-radius: 40rpx;
overflow: hidden;
}
}
.overlay-content {
width: 570rpx;
height: 640rpx;
box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 16rpx;
background-image: url('/static/images/addGodd/addGoodBg.png');
background-size: 100% 100%;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
padding: 70rpx 0 40rpx 0;
}
.jiao {
image {
position: absolute;
top: -14rpx;
right: -14rpx;
width: 50rpx;
height: 50rpx;
border-radius: 50%;
padding: 8rpx;
z-index: 2;
}
video {
width: 140rpx;
height: 140rpx;
}
}
.preview_video {
position: absolute;
background-color: red;
}
.content_list_video {
min-height: 154rpx;
padding: 23rpx 10rpx;
display: flex;
justify-content: space-between;
.content_list_video_title {
/* padding-top: 10rpx; */
}
}
.video-count {
position: fixed;
width: 600rpx;
height: 500rpx;
top: 50%;
left: 50%;
margin-left: -300rpx;
margin-top: -250rpx;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
.videoLink {
width: 600rpx;
height: 500rpx;
}
}
.video-text {
color: red;
font-size: 24rpx;
text-align: center;
/* position: absolute; */
}
</style>