jiuyiUniapp/jiuyi2/pages/release/commodity.vue

426 lines
9.7 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.

<script setup>
// 发布商品
import {
ref,
reactive,
getCurrentInstance,
nextTick
} from 'vue'
//
import {
onLoad
} from '@dcloudio/uni-app'
// api
import api from '@/api/index.js'
// 工具库
import util from '@/common/js/util.js'
// 编辑器
import editorArea from '@/components/public/editor/editor'
const {
proxy
} = getCurrentInstance()
// 表单
const form = reactive({
id: '',
categoryId: '',
sliderImage: [],
specs: [],
infoRichText: '',
})
// 分类
const category = reactive([])
// 分类下标
const categoryIndex = ref('')
onLoad((option) => {
if (option.id) {
form.id = option.id
Promise.all([getProDetail(), getCategory()]).then(rs => {
const detail = rs[0]
const cate = rs[1]
// 商品图片
form.sliderImage = detail.sliderImage.split(',')
// 下标
categoryIndex.value = cate.findIndex(item => item.id === detail.categoryId)
// 商品id
form.id = detail.id
// 商品规格
form.categoryId = detail.categoryId
// 商品价格
form.price = detail.price
// 商品名称
form.name = detail.name
// 商品成本价
form.cost = detail.cost
// 商品佣金
form.commission = detail.commission
// 商品详情
if (detail.infoRichText) {
form.infoRichText = decodeURIComponent(escape(atob(detail.infoRichText)))
console.log('form.infoRichText', form.infoRichText)
// 富文本编辑器初始化
proxy.$refs.editorAreaRef.init(form.infoRichText)
}
// 规格
form.specs = detail.specs.map(item => {
return {
image: item.image,
sku: item.sku,
stock: item.stock,
}
})
})
} else {
// 添加商品规格
handlePushSpec()
// 获取商品分类
getCategory()
}
})
// 获取商品详情
function getProDetail() {
return new Promise((resolve, reject) => {
api.shop.productDetail({
query: {
productionId: form.id
},
}).then(rs => {
if (rs.code === 200) {
resolve(rs.data)
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
})
}
// 获取商品分类
function getCategory() {
return new Promise((resolve, reject) => {
api.shop.getCategory({
query: {
categoryCode: '0'
},
}).then(rs => {
if (rs.code === 200) {
category.push(...rs.data)
resolve(category)
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
})
}
// 添加商品规格
function handlePushSpec() {
form.specs.push({
// 图片
image: '',
// 名称
sku: '',
// 库存
stock: '',
})
}
// 上传规格图片
function uploadSpecImage(item) {
util.upload_image({
type: 1,
success: rs => {
item.image = rs.value
}
})
}
/**
* 删除规格
* @param {Object} index 下标
*/
function handleRemoveSpec(index) {
form.specs.splice(index, 1)
}
// 上传轮播图
function uploadImage() {
util.upload_image({
type: 1,
success: rs => {
form.sliderImage.push(rs.value)
}
})
}
/**
* 移除图片
* @param {Object} index
*/
function removeImage(index) {
util.alert({
content: '确认删除图片?',
}).then(rs => {
if (!rs.confirm) return
form.sliderImage.splice(index, 1)
})
}
/**
* 选择分类
* @param {Object} ev
*/
function handleCate(ev) {
let index = ev.detail.value
if (index === categoryIndex.value) return
categoryIndex.value = index
form.categoryId = category[categoryIndex.value].id
}
// 发布商品
function handleSubmit() {
const data = {
...form
}
console.log('data', data)
if (!data.sliderImage[0]) {
util.alert('商品图片不能为空')
return
}
if (!data.categoryId) {
util.alert('商品类目不能为空')
return
}
if (!data.specs[0]) {
util.alert('商品规格不能为空')
return
}
if (!data.price) {
util.alert('商品价格不能为空')
return
}
if (!data.cost) {
util.alert('商品成本价不能为空')
return
}
// 查找规格是否有空值
for (let i = 0; i < data.specs.length; i++) {
let item = data.specs[i]
if (!item.image) {
util.alert('规格图片不能为空')
return
}
if (!item.sku) {
util.alert('规格名称不能为空')
return
}
if (!item.stock) {
util.alert('规格库存不能为空')
return
}
}
// 轮播图
data.sliderImage = data.sliderImage.join(',')
// 商品详情
if (data.infoRichText) data.infoRichText = btoa(unescape(encodeURIComponent(data.infoRichText)))
//
api.shop.saveProduct({
data,
}).then(rs => {
if (rs.code == 200) {
util.alert({
content: '商品发布成功,请等待后台审核',
showCancel: false,
}).then(() => {
uni.$emit('updateUserProduct')
uni.navigateBack()
})
return
}
util.alert({
content: rs.msg,
showCancel: false,
})
})
}
</script>
<template>
<view class="app">
<view class="container">
<view class="main area">
<view class="title mtb20">商品图片</view>
<view class="imgList mt20">
<view class="imgs" v-for="(item,index) in form.sliderImage">
<image class="wh120 br10" :src="item" mode="aspectFill" />
<view class="close" @click="removeImage(index)">
<uni-icons type="clear" color="#f00" size="40rpx" />
</view>
</view>
<view class="imgs" @click="uploadImage">
<image class="wh120" src="/static/shop-upload-image.png" mode="aspectFit" />
</view>
</view>
</view>
<view class="main area">
<view class="line">
<view class="title mtb20">商品标题</view>
<textarea v-model="form.name" class="textarea mtb20" placeholder="最多输入60字符30个汉字" />
</view>
<view class="line ptb20">
<picker :range="category" range-key="name" :value="categoryIndex" @change="handleCate">
<view class="rows">
<view class="title w150">类目</view>
<view class="col f1">
<text v-if="category[categoryIndex]">{{category[categoryIndex].name}}</text>
<text v-else class="placeholderStyle">点击选择</text>
</view>
<uni-icons type="right" />
</view>
</picker>
</view>
</view>
<view class="main area" v-for="(item,index) in form.specs" :key="index">
<view class="line rows">
<view class="name mtb30 f32">规格{{index + 1}}</view>
<view class="" @click="handleRemoveSpec(index)">
<uni-icons type="trash" size="40rpx" color="#aaa" />
</view>
</view>
<view class="line rows ptb20">
<view class="title w150">名称</view>
<view class="col f1">
<input type="text" v-model="item.sku" placeholder="输入规格" placeholder-class="placeholderStyle" />
</view>
</view>
<view class="line rows ptb20">
<view class="title w150">图片</view>
<view class="imgList mt20 f1">
<view class="imgs" v-if="item.image" @click="uploadSpecImage(item)">
<image class="wh120 br20" :src="item.image" mode="aspectFill" />
</view>
<view class="imgs" v-else @click="uploadSpecImage(item)">
<image class="wh120" src="/static/shop-upload-image.png" mode="aspectFit" />
</view>
</view>
</view>
<view class="line rows ptb20">
<view class="title w150">库存</view>
<view class="col f1">
<input type="text" v-model="item.stock" placeholder="输入库存"
placeholder-class="placeholderStyle" />
</view>
</view>
</view>
<view class="main fmid mtb20 mlr20 ptb20 c666 f34 br20 bfff" @click="handlePushSpec">
<uni-icons type="plus" size="40rpx" />
<view class="ml10">添加规格</view>
</view>
<view class="main area">
<view class="line rows ptb20">
<view class="title w150">商品价格</view>
<view class="col f1">
<input type="text" v-model="form.price" placeholder="输入价格"
placeholder-class="placeholderStyle" />
</view>
</view>
<view class="line rows ptb20">
<view class="title w150">商品成本价</view>
<view class="col f1">
<input type="text" v-model="form.cost" placeholder="输入价格"
placeholder-class="placeholderStyle" />
</view>
</view>
<view class="line rows ptb20">
<view class="title w150">出让佣金</view>
<view class="col f1">
<input type="text" v-model="form.commission" placeholder="输入价格"
placeholder-class="placeholderStyle" />
</view>
</view>
</view>
<view class="main area" v-if="0">
<view class="line rows ptb20">
<view class="title w150">代金券</view>
<view class="col f1">
<text class="placeholderStyle">点击选择</text>
</view>
</view>
</view>
<view class="main area" v-if="0">
<view class="title rows mtb20">
<image src="/static/commodity-release-video.png" mode="aspectFit" class="wh45" />
<view class="f1 ml20">添加链接到视频</view>
</view>
<view class="rows mtb20">
<view class="mr10 f28">再第几秒展示</view>
<input type="text" placeholder="输入秒数" placeholder-class="placeholderStyle" />
</view>
</view>
<view class="main area editor">
<editorArea ref="editorAreaRef" v-model="form.infoRichText" />
</view>
</view>
<view class="fill" style="height: 210rpx;"></view>
<view class="footer plr30 bfff shadow">
<view class="btn lg primary" @click="handleSubmit">立即上架</view>
</view>
</view>
</template>
<style lang="scss">
//
.container {
color: #333;
// 内容
.area {
overflow: hidden;
margin: 20rpx;
padding: 0 30rpx;
background-color: #fff;
border-radius: 20rpx;
}
.line+.line {
border-top: 2rpx solid #eee;
}
// 标题
.title {
font-size: 28rpx;
}
//
.textarea {
width: 100%;
height: 200rpx;
}
}
</style>