['设置中心']

This commit is contained in:
2021-09-24 15:11:14 +08:00
parent 08c56ea921
commit 3dc185139c
172 changed files with 13194 additions and 433 deletions

627
pages/goods/add.vue Normal file
View File

@@ -0,0 +1,627 @@
<template>
<view class="content">
<!-- 商品图片 -->
<view class="form-block">
<view class="form-upd">
<view class="form-title">商品轮播图<text>首图封面图点击预览长按删除</text></view>
<view class="form-imgs">
<view
class="item"
v-for="(item, index) in pictures"
:key="index"
@click="openImg(index, 'pictures')"
@longpress="removeImg(index, 'pictures')"
>
<image class="item-cover" :src="item.showpath" mode="aspectFill"></image>
</view>
<view class="item item-add" @click="updCover('pictures')">
<image class="item-cover" src="@/static/icons/add-icon.png" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<!-- 商品基本信息 -->
<view class="form-block">
<view class="form-box inputs-flex">
<label class="form-label">商品标题</label>
<input type="text" v-model="name" placeholder="输入商品标题"/>
</view>
<view class="form-box inputs-flex">
<label class="form-label">商品描述</label>
<input type="text" v-model="description" placeholder="输入商品描述"/>
</view>
<view class="form-box inputs-flex">
<label class="form-label">规格单位</label>
<input type="text" v-model="skus_unit" placeholder="输入规格单位 如:件"/>
</view>
<view class="form-upd">
<view class="form-title">商品详情点击预览长按删除</view>
<view class="form-imgs">
<view
class="item"
v-for="(item, index) in content"
:key="index"
@click="openImg(index, 'content')"
@longpress="removeImg(index, 'content')"
>
<image class="item-cover" :src="item.showpath" mode="aspectFill"></image>
</view>
<view class="item item-add" @click="updCover('content')">
<image class="item-cover" src="@/static/icons/add-icon.png" mode="aspectFill"></image>
</view>
</view>
</view>
</view>
<!-- 商品价格 -->
<view class="form-block">
<view class="form-box inputs-flex input-unit">
<label class="form-label">市场价格</label>
<input type="digit" v-model="skus_cost" placeholder="0.00"/>
<text class="units">{{skus_unit != '' ? '/' + skus_unit : ''}}</text>
</view>
<view class="form-box inputs-flex input-unit">
<label class="form-label">销售价格</label>
<input type="digit" v-model="skus_price" placeholder="0.00"/>
<text class="units">{{skus_unit != '' ? '/' + skus_unit : ''}}</text>
</view>
<view class="form-box inputs-flex input-unit">
<label class="form-label">分销佣金</label>
<input type="digit" v-model="skus_charge" placeholder="0.00"/>
<text class="units">{{skus_unit != '' ? '/' + skus_unit : ''}}</text>
</view>
</view>
<!-- 商品详情介绍 -->
<view class="form-block">
<view class="form-box picker-flex">
<label class="form-label">支持易货</label>
<view class="picker-switch">
<switch :checked="isChange" color="#e93340" @change="pickerChange($event, 'isChange')"/>
</view>
</view>
<view class="form-box inputs-flex" v-if="isChange">
<label class="form-label">最低易货量</label>
<input type="number" v-model="skus_number" placeholder="输入最低易货量"/>
</view>
<view class="form-box inputs-flex">
<label class="form-label">发行权证数</label>
<input type="number" v-model="skus_stock" placeholder="输入商品发行权证数"/>
</view>
</view>
<!-- 售后服务 -->
<view class="form-block">
<view class="form-box picker-flex">
<label class="form-label">配送方式</label>
<picker :range="logisticArr" range-key="text" :value="logisticType" @change="pickerChange($event, 'logisticType')">
<view class="picker-text">
{{logisticArr[logisticType].text}}
<uni-icons class="picker-icon" type="arrowright" color="#999"></uni-icons>
</view>
</picker>
</view>
<view class="form-box picker-flex" v-if="logisticType === 1">
<label class="form-label">关联店铺</label>
<view class="picker-text" @click="opnePopup('storePopup')">
已关联{{stores.length}}家店铺<uni-icons class="picker-icon" type="arrowright" color="#999"></uni-icons>
</view>
</view>
<view class="form-box picker-flex">
<label class="form-label">允许售后</label>
<view class="picker-switch">
<switch :checked="isPostSale" color="#e93340" @change="pickerChange($event, 'isPostSale')"/>
</view>
</view>
<view class="form-box picker-flex">
<label class="form-label">可选服务</label>
<view class="picker-text" @click="opnePopup('categoryPopup')">
已选{{services.length}}项服务<uni-icons class="picker-icon" type="arrowright" color="#999"></uni-icons>
</view>
</view>
</view>
<!-- 售后服务 -->
<view class="form-block" v-if="type == 2">
<view class="form-box picker-flex">
<label class="form-label">到期时间</label>
<picker mode="date" :value="expiriedAt" @change="pickerChange($event, 'expiriedAt')">
<view class="picker-text">
{{expiriedAt || '选择服务到期时间'}}
<uni-icons class="picker-icon" type="arrowright" color="#999"></uni-icons>
</view>
</picker>
</view>
</view>
<!-- 可选服务 -->
<uni-popup ref="categoryPopup">
<view class="category-popup">
<view class="header">
<view class="title">选择商品服务</view>
</view>
<view class="category-flex">
<view class="category-flex-item" :class="{'show' : item.check}" v-for="(item, index) in servicesArr" :key="index" @click="item.check = !item.check">
<view class="category-name">{{item.name}}</view>
<view class="category-content">{{item.content}}</view>
</view>
</view>
<view class="btns">
<button type="default" size="default" @click="affirmCategory('services', 'categoryPopup')">确定</button>
</view>
</view>
</uni-popup>
<!-- 选择店铺 -->
<uni-popup ref="storePopup">
<view class="category-popup">
<view class="header">
<view class="title">选择店铺</view>
</view>
<view class="category-flex">
<view class="category-flex-item" :class="{'show' : item.check}" v-for="(item, index) in storesArr" :key="index" @click="item.check = !item.check">
<view class="category-name">{{item.name}}</view>
<view class="category-content">{{item.address}}</view>
</view>
</view>
<view class="btns">
<button type="default" size="default" @click="affirmCategory('stores', 'storePopup')">确定</button>
</view>
</view>
</uni-popup>
<!-- 安全区 -->
<view class="ios-bottom"></view>
<!-- footer -->
<view class="footer">
<button class="footer-btn" type="default" @click="submitAdd">{{type == 2 ? '发布': '发布并认证'}}</button>
<view class="ios-bottom"></view>
</view>
</view>
</template>
<script>
import { managesGoodsCreate, managesCreate, managesGoodsEdit, managesGoodsPut } from '@/apis/interfaces/goods'
import { uploads } from '@/apis/interfaces/uploading'
export default {
data() {
return {
categoryId : '', // 一级分类
categoryCid : '', // 二级分类
name : '', // 标题
pictures : [], // 轮播图
content : [], // 详情图
description : '', // 商品描述
isPostSale : false, // 是否允许售后
services : [], // 商品服务
skus_cost : '', // 市场价格
skus_price : '', // 销售价格
skus_number : 1, // 易货起购数量
skus_unit : '件', // 规格文字
skus_charge : '', // 分销佣金
skus_stock : '', // 库存
isChange : false, // 是否支持易货
stores : [], // 关联店铺
expiriedAt : '', // 活动到期时间
logisticType: 0, // 配送方式
logisticArr : [
{text: '快递', type: 1},
{text: '自提', type: 2}
],
// 配置信息
storesArr : [], // 可选店铺
tags : [], // 可选商品标签
tagsIndex : 0, // 选择标签的下标
servicesArr : [], // 可选服务
type : 1, // 1为商品2为服务
};
},
created() {
// 编辑状态信息
if(this.$Route.query.type && this.$Route.query.type === 'edit'){
managesGoodsEdit(this.$Route.query.id).then(res => {
let services = [], stores = []
let servicesArr = res.services.map(val => {
let check = (res.data.services.findIndex(obj => obj.service_id === val.service_id)) >= 0
if(check){
services.push(val.service_id)
}
return{
check,
...val
}
})
let storesArr = res.stores.map(val => {
let check = (res.data.stores.findIndex(obj => obj.store_id === val.store_id)) >= 0
if(check){
stores.push(val.store_id)
}
return {
check,
...val
}
})
this.categoryId = res.data.category.category_id
this.categoryCid = res.data.category_sub.category_id
this.name = res.data.name
this.content = res.data.content
this.description = res.data.description
this.pictures = res.data.pictures
this.skus_cost = res.data.skus[0].cost
this.skus_price = res.data.skus[0].price
this.skus_number = res.data.skus[0].number
this.skus_unit = res.data.skus[0].unit
this.skus_charge = res.data.skus[0].charge
this.skus_stock = res.data.skus[0].stock
this.isPostSale = res.data.is_post_sale == 0
this.isChange = res.data.is_change == 0
this.logisticType= this.logisticArr.findIndex(val => val.type === res.data.logistic_type)
this.servicesArr = servicesArr
this.storesArr = storesArr
this.services = services
this.stores = stores
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
return
}
// 添加配置信息
managesCreate({
category_cid: this.$Route.query.cid
}).then(res => {
res.services = res.services.map(val => {
return {
check: false,
...val
}
})
res.stores = res.stores.map(val => {
return {
check: false,
...val
}
})
this.storesArr = res.stores
this.tags = res.tags
this.servicesArr= res.services
this.type = res.type
this.categoryId = this.$Route.query.id
this.categoryCid= this.$Route.query.cid
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
methods: {
// 选择商品服务
opnePopup(key){
this.$refs[key].open('bottom')
},
// 确认选择商品服务
affirmCategory(key, popupKey){
let keyArr = key == 'services' ? 'servicesArr' : 'storesArr'
this[key] = []
for(let val of this[keyArr]){
if(val.check){
this[key].push(val.service_id || val.store_id)
}
}
this.$refs[popupKey].close()
},
// picker选择
pickerChange(e, key){
this[key] = e.detail.value
},
// 图片预览
openImg(index, key){
let paths = this[key].map(val => {
return val.showpath
})
uni.previewImage({
urls : paths,
current : index,
indicator: 'number'
})
},
// 删除图片
removeImg(index, key){
this[key].splice(index, 1)
},
// 上传图片
updCover(key){
uni.chooseImage({
success : res => {
let path = res.tempFiles.map((val, index) => {
return {
name: 'uploads' + index,
uri : val.path
}
})
uploads(path).then(updRes => {
for(let i in updRes.path){
this[key].push({
path : updRes.path[i],
showpath: updRes.url[i]
})
}
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
},
// 发布产品
submitAdd(){
let pictures = this.pictures.map(val => {return val.path}),
content = this.content.map(val => {return val.path})
let submitData = {
name : this.name,
cover : this.pictures[0].path,
category_id : this.categoryId,
category_cid : this.categoryCid,
pictures : pictures,
content : content,
description : this.description,
is_post_sale : this.isPostSale ? 0 : 1,
services : this.services,
skus_cost : this.skus_cost,
skus_price : this.skus_price,
skus_number : this.skus_number,
skus_unit : this.skus_unit,
skus_charge : this.skus_charge,
skus_stock : this.skus_stock,
is_change : this.isChange ? 0 : 1,
logistic_type: this.logisticArr[this.logisticType].type,
stores : this.stores,
expiried_at : this.expiriedAt
}
let submitFund = this.$Route.query.type === 'edit' ? managesGoodsPut(this.$Route.query.id, submitData) : managesGoodsCreate(submitData)
submitFund.then(res => {
if(this.type === 2){
uni.showModal({
title : '提示',
content : '商品权证已发布,请耐心等待平台审核',
showCancel : false,
success : res => {
if(res.confirm){
this.$Router.back(this.$Route.query.type === 'edit' ? 1 : 2)
}
}
})
return
}
uni.showModal({
title : '提示',
content : this.$Route.query.type === 'edit' ? '商品权证已更新,是否立即补充产品附加信息认证?' : '商品权证已发布,是否立即补充产品附加信息认证?',
cancelText : '稍后认证',
confirmText : '立即认证',
success : res => {
if(res.cancel){
this.$Router.back(this.$Route.query.type === 'edit' ? 1 : 2)
}
if(res.confirm){
let goodsId = this.$Route.query.type === 'edit' ? this.$Route.query.id : res
this.$Router.push({name: 'goodsAuth', params: { id: goodsId , type: 'goodsAdd', edit: this.$Route.query.type === 'edit'}})
}
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss" scoped>
.content{
padding-bottom: 150rpx;
}
// 表单
.form-block{
background: white;
margin-top: $margin - 10;
.form-box{
position: relative;
padding-left: 240rpx;
padding-right: $padding;
font-size: $title-size-lg;
min-height: 80rpx;
&::after{
position: absolute;
bottom: 0;
left: $margin;
right: 0;
height: 1rpx;
content: " ";
background: $border-color;
}
&:last-child::after{
display: none;
}
.form-label{
position: absolute;
left: $margin;
line-height: 80rpx;
top: 0;
width: calc(240rpx - #{$margin});
}
}
.inputs-flex{
input{
height: 80rpx;
line-height: 80rpx;
}
}
.input-unit{
padding-right: 200rpx;
.units{
position: absolute;
right: 0;
top: 0;
line-height: 80rpx;
height: 80rpx;
width: 200rpx;
padding-right: $padding;
text-align: right;
box-sizing: border-box;
}
}
.picker-flex{
.picker-text{
position: relative;
line-height: 80rpx;
min-height: 80rpx;
padding-right: 80rpx;
@extend .nowrap;
.picker-icon{
right: 0;
position: absolute;
}
}
.picker-switch{
line-height: 80rpx;
min-height: 80rpx;
text-align: right;
margin-right: -15rpx;
switch{
transform:scale(0.7)
}
}
}
.form-upd{
.form-title{
font-size: $title-size-lg;
line-height: 80rpx;
padding: 0 $padding;
text{
font-size: 80%;
color: $text-gray;
}
}
.form-imgs{
margin-top: -($margin/3);
padding: 0 20rpx 20rpx;
display: flex;
flex-wrap: wrap;
.item{
width: calc(20% - 14rpx);
padding-top: calc(20% - 14rpx);
margin: 7rpx;
position: relative;
.item-cover{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
.item-add{
border: dashed 2rpx $border-color;
box-sizing: border-box;
.item-cover{
top: calc(15% - 2rpx);
left: calc(15% - 2rpx);
width: 70%;
height: 70%;
}
}
}
}
}
// 发布
.footer{
background: white;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx $padding;
box-shadow: 0 0 4rpx 4rpx rgba($color: #000000, $alpha: .02);
z-index: 9;
.footer-btn{
border: none;
border-radius: 0;
background: $text-price;
height: 90rpx;
line-height: 90rpx;
font-weight: bold;
font-size: $title-size;
color: white;
&::after{
border: none;
}
}
}
// 可选服务
.category-popup{
background: #F5F5F5;
padding: 0 $padding * 2 $padding * 2 $padding * 2;
.header{
padding: $padding*2 0;
box-sizing: border-box;
@extend .vertical;
.title{
text-align: center;
font-size: $title-size + 14;
font-weight: bold;
line-height: 90rpx;
}
.subtitle{
font-size: $title-size-m;
color: $text-gray;
text-align: center;
}
}
.category-flex{
max-height: 50vh;
overflow-y: scroll;
.category-flex-item{
margin-bottom: $margin;
padding: $padding;
background: white;
border:solid 1rpx white;
box-sizing: border-box;
.category-name{
padding-bottom: $padding/2;
font-weight: bold;
font-size: $title-size-lg;
}
.category-content{
font-size: $title-size-sm;
color: $text-gray;
@extend .ellipsis;
}
&.show{
color: $text-price;
border:solid 1rpx $text-price;
}
&:last-child{
margin-bottom: 0;
}
}
}
.btns{
padding-top: $padding * 2;
button{
background: $text-price;
border-radius: 0;
height: 90rpx;
line-height: 90rpx;
font-size: $title-size;
color: white;
font-weight: bold;
&::after{
border: none;
}
}
}
}
</style>