cashier_app/pageProduct/add-Product/add-Product.vue

1591 lines
38 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="u-p-30 safe-page min-page">
<up-sticky v-if="option.type==='edit'" offset-top="20" zIndex="99">
<my-tabs :list="tabsList" v-model="tabsCurrent"></my-tabs>
</up-sticky>
<view class="box">
<template v-if="tabsCurrent===0">
<view class="basic">
<uni-forms :model="FormData" :rules="rules" :border="true" label-position="top"
err-show-type="toast" validateTrigger="submit" label-width="350" ref="Forms">
<view class="block">
<view class="border-top-0 typeEnum">
<uni-forms-item label="商品类型" required showRequired>
<up-radio-group v-model="FormData.type" @change="changeFormDatatype">
<view style="display: flex;flex-wrap: wrap;justify-content: flex-start;">
<view v-for="(item, index) in pageData.types" :key="index"
style="margin-right: 30rpx;">
<up-radio :label="item.name" :name="item.value"></up-radio>
</view>
</view>
</up-radio-group>
</uni-forms-item>
</view>
<view class="" v-if="FormData.type==='package'">
<uni-forms-item label="套餐商品">
<up-radio-group v-model="FormData.groupType" placement="row">
<up-radio :custom-style="{marginRight:'30px'}"
v-for="(item, index) in packageType.list" :key="index" :label="item.name"
:name="item.value">
</up-radio>
</up-radio-group>
</uni-forms-item>
</view>
<uni-forms-item required name="name" label="商品名称" showRequired>
<uni-easyinput :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
:inputBorder="inputBorder" v-model="FormData.name" placeholder="请输入商品名称" />
</uni-forms-item>
<uni-forms-item ref="fileItem" label="图片" required showRequired>
<my-upload-file ref="refFile" :images="FormData.images"
:imageStyles="imageStyles"></my-upload-file>
<view class="u-m-t-16 color-999 u-font-24">
注:第一张图为商品封面图图片尺寸为750x750
</view>
</uni-forms-item>
<view class="u-relative">
<uni-forms-item label="商品分类" required showRequired name="categoryId">
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}"
placeholder="请选择商品分类" popup-title="请选择商品分类" :localdata="pageData.category"
v-model="FormData.categoryId">
</uni-data-picker>
</uni-forms-item>
<view class="zhezhao u-absolute position-all" @click="canEditGoodsCategory(true)"
v-if="option.type=='edit'&&disabledChangeCategory">
</view>
</view>
<view class="">
<uni-forms-item label="单位" required showRequired name="units">
<uni-data-picker :clear-icon="false" @change="unitIdChange"
:map="{text:'name',value:'id'}" placeholder="请选择单位" popup-title="请选择单位"
:localdata="pageData.units" v-model="FormData.unitId">
</uni-data-picker>
</uni-forms-item>
</view>
<template v-if="FormData.type==='package'">
<view class="border-top" v-if="FormData.proGroupVo">
<view class=""
v-if=" (FormData.groupType==1&&FormData.proGroupVo.length)||(FormData.groupType==0&&FormData.proGroupVo.length&&FormData.proGroupVo[0].goods.length) ">
<view class="border-bottom u-p-b-32"
v-for="(item,index) in FormData.proGroupVo" :key="index">
<view class=" u-p-t-24" v-if="FormData.groupType==1">
<view class="u-flex u-row-between">
<view class="u-flex">
<text class="color-red">*</text>
<text class="font-bold">套餐名称</text>
</view>
<view class="u-flex color-999 " @tap="delproGroupVo(index)">
<uni-icons type="minus-filled" :size="16"
:color="color.ColorRed"></uni-icons>
<view class="u-m-l-10">删除套餐组</view>
</view>
</view>
<view class="u-flex u-m-t-16">
<up-input v-model="item.title" placeholder="请输入套餐名称"></up-input>
<view class="u-flex color-main u-font-24 u-m-l-24"
@click="proGroupVoAddGoods(index,item.goods)">
<up-icon name="plus" :size="12"
:color="color.ColorMain"></up-icon>
<view class="font-bold">添加商品</view>
</view>
</view>
</view>
<view class="u-m-t-24" v-if="item.goods.length>0">
<!-- <view class="font-bold">商品信息</view> -->
<view class=" u-font-24 table">
<view class="u-flex title">
<view class="u-flex-1 ">名称</view>
<view class="u-flex-1 u-text-center">规格</view>
<view class="u-flex-1 u-text-center">价格</view>
<view class=" u-flex-1 u-text-right">
<view class="u-p-r-40">数量</view>
</view>
</view>
<view class="u-flex row u-p-24 u-row-between"
v-for="(product,goodsIndex) in item.goods" :key="goodsIndex">
<view class=" u-flex u-flex-1">
<view class=" ">
{{product.name||product.proName}}
</view>
</view>
<view class=" u-flex u-row-center u-flex-1">
<view
@click="refChooseGuigeOpen(product.skuList,index,goodsIndex)"
class="">
<template
v-if="!product.skuName&&product.type=='sku'">
<up-button type="primary"
size="mini">设置规格</up-button>
</template>
<template v-else>
<text class="color-main">{{product.skuName}}</text>
</template>
</view>
</view>
<view class=" u-flex u-flex-1 u-row-center">
<view class=" u-text-center ">
{{product.lowPrice||product.price}}
</view>
</view>
<view class=" u-flex u-text-right u-flex-1 u-row-right">
<view class="u-flex u-p-r-30">
<up-number-box :button-size="14" integer
v-model="product.number">
<template #minus>
<view class="minus">
<up-icon name="minus" size="12"></up-icon>
</view>
</template>
<template #plus>
<view class="plus">
<up-icon name="plus" size="12"></up-icon>
</view>
</template>
</up-number-box>
</view>
<up-icon @click="proGroupVoGoodsDel(index,goodsIndex)"
size="14" name="trash"
:color="color.ColorMain"></up-icon>
</view>
</view>
</view>
</view>
<template v-if="FormData.groupType==1">
<view class="u-m-t-24">
<text class="color-red">*</text>
<text class="font-bold">几选几</text>
</view>
<view class="u-flex u-m-t-16">
<uni-number-box :min="1" :max="item.goods.length" :width="200"
v-model="item.number" placeholder="几选几"></uni-number-box>
</view>
</template>
</view>
</view>
<template v-if="FormData.groupType==1">
<view class="bg-fff u-flex u-p-t-24 u-p-b-24 border-r-12 "
@tap="proGroupVoPush">
<uni-icons type="plus-filled" :color="color.ColorMain"
:size="20"></uni-icons>
<view class="u-m-l-16">添加套餐组</view>
</view>
</template>
<template v-else>
<view class="bg-fff u-flex u-p-t-24 u-p-b-24 border-r-12 "
@tap="proGroupVoAddGoods()">
<uni-icons type="plus-filled" :color="color.ColorMain"
:size="20"></uni-icons>
<view class="u-m-l-16">添加商品</view>
</view>
</template>
</view>
</template>
<view class="">
<uni-forms-item label="商品描述">
<uni-easyinput :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
type="textarea" v-model="FormData.shortTitle" placeholder="请填写商品简述" />
</uni-forms-item>
</view>
</view>
<template v-if="FormData.type == 'sku'">
<view class="block border-top-0 u-p-t-32 u-p-b-32">
<view class="u-flex u-row-between ">
<view class="color-333 font-bold">
<text v-if="!skuList.list.length">选择规格</text>
<text v-else>编辑规格</text>
</view>
<view class="u-flex u-col-center" @tap="toGuige">
<view>
<text v-if="FormData.specName">{{FormData.specName}}</text>
<text class="color-999" v-else>请选择</text>
</view>
<view class="u-flex u-p-t-2">
<uni-icons type="right" :size="14" color="#999"></uni-icons>
</view>
</view>
</view>
</view>
</template>
<template v-if="FormData.type != 'sku'">
<view class="block u-p-t-32 u-p-b-32" v-for="(sku,index) in skuList.list" :key="index">
<view class=" font-bold u-m-b-32 u-text-center">规格属性</view>
<view class="u-flex w-full gap-26 u-row-between">
<view class="u-flex-1">
<view>
<text class="color-red">*</text>
<text>原价</text>
</view>
<view class="u-m-t-16">
<price-number-box placeholder="请输入原价"
v-model="sku.originPrice"></price-number-box>
</view>
</view>
<view class="u-flex-1">
<view>
<text class="color-red">*</text>
<text>售价</text>
</view>
<view class="u-m-t-16">
<price-number-box placeholder="请输入售价"
v-model="sku.salePrice"></price-number-box>
</view>
</view>
</view>
<view class="u-flex w-full gap-26 u-row-between u-m-t-24">
<view class="u-flex-1">
<view>
<text class="color-red">*</text>
<text>会员价</text>
</view>
<view class="u-m-t-16">
<price-number-box placeholder="请输入会员价(元)"
v-model="sku.memberPrice"></price-number-box>
</view>
</view>
<view class="u-flex-1">
<view>
<text class="color-red">*</text>
<text>成本价</text>
</view>
<view class="u-m-t-16">
<price-number-box placeholder="请输入成本价"
v-model="sku.costPrice"></price-number-box>
</view>
</view>
</view>
<view class="u-m-t-24">
<view>
<text class="color-red">*</text>
<text>起售数量</text>
</view>
<view class="u-m-t-16">
<price-number-box inputType="number" placeholder="请输入起售数量"
v-model="sku.suitNum"></price-number-box>
</view>
</view>
<view class="u-m-t-24">
<view class="">
商品条形码
</view>
<view class="u-m-t-16 barCode color-999">
{{sku.barCode}}
</view>
</view>
</view>
</template>
<template v-if="FormData.type == 'weight'">
<view class="block u-p-t-32 u-p-b-32">
<view class="font-bold">
<text class="color-red">*</text>
<text>单位</text>
</view>
<view class=" u-m-t-16">
<up-input v-model="FormData.weight">
<template #suffix>
<view class="bg-gray">{{activeinHouseList}}</view>
</template>
</up-input>
<view class="u-m-t-16 color-999 u-font-24">用于快递或配送运费计重</view>
</view>
</view>
</template>
<template v-if="FormData.type!='group'">
<view class="block ">
<view>
<uni-forms-item label="">
<view class="u-flex u-row-between" @tap="toTimerPage">
<view style="display: flex;">
<text class="color-red">*</text>
<view class="label-title">定时上下架</view>
</view>
<view class="u-flex u-font-24">
<view>
<view class="color-666">{{returnTimerDayText()}}</view>
<view class="color-666 u-m-t-4" v-if="FormData.days">
{{returnTimerTimeText()}}
</view>
</view>
<uni-icons type="right"></uni-icons>
</view>
</view>
</uni-forms-item>
</view>
<view class="">
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">上架</view>
<my-switch disabled :openDisabledClass="false" @click="isGroundingChange"
v-model="FormData.isSale"></my-switch>
</view>
</uni-forms-item>
</view>
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">库存开关</view>
<my-switch v-model="FormData.isStock"></my-switch>
</view>
<view class="color-999 u-m-t-16 u-font-24">注:关闭则不计算出入库数据</view>
</uni-forms-item>
<template v-if="FormData.isStock">
<view class="u-relative">
<uni-forms-item label="库存数量">
<uni-easyinput @blur="priceFormat(FormData,'stockNumber')"
:paddingNone="inputPaddingNone" :disabled="disabledStock"
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="FormData.stockNumber" type="digit" placeholder="请输入库存数量" />
</uni-forms-item>
<view class="u-absolute position-all" v-if="disabledStock"
@click="canEditGoodsStock(true)">
</view>
</view>
</template>
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">设为推荐</view>
<my-switch v-model="FormData.isHot"></my-switch>
</view>
</uni-forms-item>
<uni-forms-item label="打包费">
<uni-easyinput @blur="priceFormat(FormData,'packFee')"
:paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
:inputBorder="inputBorder" v-model="FormData.packFee" type="digit"
placeholder="请输入打包费" />
</uni-forms-item>
<template v-if="option.type==='edit'">
<uni-forms-item label="排序">
<uni-easyinput @blur="priceFormat(FormData,'sort')"
:paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
:inputBorder="inputBorder" v-model="FormData.sort" type="digit"
placeholder="请输入排序" />
</uni-forms-item>
</template>
</view>
</template>
</uni-forms>
<view style="height: 100rpx;"></view>
<view style="padding-left: 110rpx;padding-right: 110rpx;" class="u-m-t-20"
v-if="option.type==='edit'" @click="delModelShow">
<my-button bgColor="#F9F9F9" shape="circle" type="cancel">
<view class="color-red">删除该商品</view>
</my-button>
</view>
<view class="bootom">
<view class="save-btn-box">
<my-button fontWeight="700" shape="circle" @tap="save">保存</my-button>
</view>
</view>
</view>
</template>
<template v-if="tabsCurrent===1">
<edit-haocai @updateGoods="updateGoodsDetail" :goods="FormData"
@cancel="changeTabsCurrent(0)"></edit-haocai>
</template>
</view>
<!-- 删除弹窗 -->
<my-model @confirm="delmodelConfirm" ref="delModel" desc="确认删除">
</my-model>
<!-- 选择商品 -->
<choose-goods ref="refChooseGoods" @confirm="refChooseGoodsConfirm"
:category="pageData.category"></choose-goods>
<!-- 选择规格 -->
<choose-guige ref="refChooseGuige" @confirm="refChooseGuigeConfirm"></choose-guige>
</view>
</template>
<script setup>
import {
computed,
onBeforeUnmount,
reactive,
ref,
watch,
nextTick
} from 'vue';
import {
onLoad,
onShow,
onReady
} from '@dcloudio/uni-app';
import {
ColorMain
} from '@/commons/color.js'
import dayjs from "dayjs";
import {
formatPrice
} from "@/commons/utils/format.js";
import go from '@/commons/utils/go.js';
import color from '@/commons/color.js';
import chooseGoods from './components/choose-goods'
import chooseGuige from './components/choose-guige'
import editHaocai from './components/edit-haocai.vue'
import chooseGroupCategory from './components/choose-coupon-category'
import priceNumberBox from './components/price-number-box'
import infoBox from "@/commons/utils/infoBox.js"
import { hasPermission } from '@/commons/utils/hasPermission.js';
import { $types, $defaultSku } from '@/commons/goodsData.js'
import {
getCategoryList,
getProdUnitList,
getProductDetail,
addProduct,
updateProduct,
delProduct,
productBindCons
} from '@/api/product.js'
import {
uploadFile
} from '@/api/index.js'
const imageStyles = reactive({
width: 82,
height: 82,
border: {
radius: '4px'
}
})
let option = reactive({
type: 'add',
productId: ''
})
// 表单样式
//可以不使用ref但是小程序一堆wraning 改为了ref
const placeholderStyle = ref('font-size:28rpx;')
const inputPaddingNone = ref(true)
//表单边框
const inputBorder = ref(false)
const FormData = reactive({
id: "",
name: "", //商品名称
shortTitle: "", //商品介绍
unitId: "", //单位id
categoryId: "", //商品分类id
coverImg: "", //封面图url
images: [], //详情图urls
type: 'single', //商品类型single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券
specId: "", //规格ID
skuList: [], //规格数据
groupType: null, //套餐类型
proGroupVo: [], //套餐数据
weight: 0, //重量
isAllowTempModifyPrice: 1, //是否允许改价
days: "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday", //定时上下架周期
startTime: "00:00:00", //开始时间
endTime: "23:59:00", //结束时间
isSale: 1, //是否上架
isStock: 0, //是否开启库存
isHot: 0, //设为推荐
stockNumber: 0, //库存数量
packFee: 0, //打包费
sort: 1, //排序值
specName: '', //规格模版名称
unitName: "",
specificationsGroup: '',
})
//页面全部数据
const pageData = reactive({
// 商品类型
types: [{
name: '单规格商品',
value: 'single'
},
{
name: '多规格商品',
value: 'sku'
},
{
name: '套餐商品',
value: 'package'
},
{
name: '称重商品',
value: 'weight'
},
// {
// name: '团购券',
// value: 'coupon'
// },
],
// 单位
units: [],
// 分类
category: [],
//库存
skuList: []
})
const skuList = reactive({
list: [{
...$defaultSku,
barCode: `${uni.getStorageSync("shopId")}${dayjs().valueOf()}`
}]
})
let $goodsData = {}
// 商品图片组件
const refFile = ref(null)
/**
* 监听商品类型变化
*/
console.log(FormData)
watch(() => FormData.type, (newval) => {
if (option.type == 'edit') {
FormData.specId = newval != 'sku' ? '' : ($goodsData.specId || '')
console.log($goodsData)
if (newval == $goodsData.type) {
skuList.list = $goodsData.skuList
if ($goodsData.groupSnap) {
FormData.proGroupVo = $goodsData.groupSnap || []
} else {
initDefaultProGroupVo()
}
} else {
if (newval != 'sku') {
skuList.list = [{
...$defaultSku,
barCode: `${uni.getStorageSync("shopId")}${dayjs().valueOf()}`
}]
} else {
skuList.list = []
}
}
if (FormData.groupType == null) {
FormData.groupType = 0
}
} else {
FormData.specId = ''
if (newval != 'sku') {
skuList.list = [{
...$defaultSku,
barCode: `${uni.getStorageSync("shopId")}${dayjs().valueOf()}`
}]
} else {
skuList.list = []
}
if (newval == 'package') {
initDefaultProGroupVo()
}
}
})
/**
* 监听套餐类型变化
*/
watch(() => FormData.groupType, (newval) => {
if (newval == 0) {
return initDefaultProGroupVo()
}
if (option.type == 'edit') {
if (newval == $goodsData.groupType) {
FormData.proGroupVo = $goodsData.groupSnap
}
return
}
initDefaultProGroupVo()
})
watch(() => pageData.types, (newval) => {
Forms.value.setRules(rules)
})
watch(() => skuList.list, (newval) => {
console.log(newval);
})
onLoad((params) => {
if (params && JSON.stringify(params) !== '{}') {
option.type = params.type ? params.type : 'add'
option.productId = params.productId
}
canEditGoodsCategory()
uni.setNavigationBarTitle({
title: option.type === 'add' ? '添加商品' : '编辑商品'
})
if (option.type === 'edit') {
getGoodsDetail()
}
getCategory()
getTbShopUnit()
})
onReady(() => {
Forms.value && Forms.value.setRules(rules)
})
onShow(() => {
watchSpecificationsSave()
watchTimerSave()
})
function getGoodsDetail() {
getProductDetail(option.productId).then(res => {
res.images = res.images.map(v => {
return {
url: v
}
})
res.consList.map(v=>{
const item = res.skuList.find(v => v.productId == v.productId)
if (item) {
if (item.hasOwnProperty('haoCaiList')) {
item.haoCaiList.push(v)
} else {
item.haoCaiList = [v]
}
}
})
res.skuList = (res.skuList.length ? res.skuList : [])
$goodsData = res
skuList.list = res.skuList
Object.assign(FormData, res)
//多规格
if (res.type == 'sku') {
FormData.specificationsGroup = {
specId: res.specId,
selectSpecInfo: res.selectSpecInfo,
result: res.skuList.map(v => {
const names = v.specInfo.split(',').reduce((prve, cur) => {
let key;
for (var oe in res.selectSpecInfo) {
res.selectSpecInfo[oe].map(i=>{
if( i == cur ){
key = oe
}
})
}
prve[key] = cur
return prve
}, {})
return {
skus: {
...v
},
names,
specInfo: v.specInfo,
coverImg: v.coverImg
}
}),
}
} else {
// 单规格
}
})
}
/**
* 获取分类
*/
function getCategory() {
getCategoryList({
page: 1,
size: 200
}).then(res => {
pageData.category = res
})
}
/**
* 获取单位数据
*/
function getTbShopUnit() {
getProdUnitList().then(res => {
pageData.units = res
})
}
/**
* 耗材取消监听
* @param {Object} newval
*/
function changeTabsCurrent(newval) {
tabsCurrent.value = newval
}
/**
* 分类选择监听
*/
const changeFormDatatype = (e) => {
if(FormData.type == 'package'){
FormData.groupType = 0
}else{
FormData.groupType = null
}
console.log(FormData)
}
/**
* 选择单位监听
* @param {Object} e
*/
function unitIdChange(e) {
FormData.unitName = e.detail.value[0].text
}
async function isGroundingChange(e) {
// if (option.type == 'add') {
// FormData.isSale = FormData.isSale ? 0 : 1
// return
// }
// const res = await hasPermission('允许上下架商品')
// if (!res) {
// return
// }
FormData.isSale = FormData.isSale ? 0 : 1
}
/**
* 固定套餐设置规格
*/
const refChooseGuige = ref(null)
let proGroupVoGoodsIndex = undefined
/**
* 规格打开
* @param {Object} skuList
* @param {Object} groupIndex
* @param {Object} goodsIndex
*/
function refChooseGuigeOpen(skuList, groupIndex, goodsIndex) {
proGroupVoIndex = groupIndex
proGroupVoGoodsIndex = goodsIndex
console.log(skuList)
refChooseGuige.value.open(skuList)
}
/**
* 规格确认
* @param {Object} sku
*/
function refChooseGuigeConfirm(sku) {
FormData.proGroupVo[proGroupVoIndex].goods[proGroupVoGoodsIndex].skuName = sku.specInfo || sku.name
FormData.proGroupVo[proGroupVoIndex].goods[proGroupVoGoodsIndex].skuId = sku.id
proGroupVoIndex = undefined
proGroupVoGoodsIndex = undefined
}
/**
* 套餐商品选择
*/
const refChooseGoods = ref(null)
let proGroupVoIndex = undefined
/**
* 添加商品
* @param {Object} index
* @param {Object} arr
*/
function proGroupVoAddGoods(index, arr) {
proGroupVoIndex = index
if (!FormData.proGroupVo) {
initDefaultProGroupVo()
}
if (FormData.groupType == 0) {
const goods = FormData.proGroupVo[0].goods
refChooseGoods.value.open(goods)
} else {
refChooseGoods.value.open(arr)
}
}
/**
* 添加套餐组
*/
function proGroupVoPush() {
FormData.proGroupVo.push({
title: '',
count: 1,
goods: []
})
}
/**
* 删除套餐组
* @param {Object} index
*/
function delproGroupVo(index) {
FormData.proGroupVo.splice(index, 1)
}
/**
* 删除套餐商品
* @param {Object} index
* @param {Object} goodsIndex
*/
function proGroupVoGoodsDel(index, goodsIndex) {
FormData.proGroupVo[index].goods.splice(goodsIndex, 1)
}
function refChooseGoodsClose() {
refChooseGoods.value.close()
}
/**
* 套餐选择商品
* @param {Object} arr
*/
function refChooseGoodsConfirm(arr) {
refChooseGoodsClose()
arr = arr.map(v => {
const {
proId,
id,
name,
unitName,
lowPrice,
type,
skuList
} = v
if (proId) {
return v
}
return {
proId: id,
proName: name,
unitName,
price: lowPrice,
number: 1,
type,
skuList,
skuId: '',
skuName: ''
}
})
if (FormData.groupType == 0) {
return FormData.proGroupVo[0].goods = arr
}
if (FormData.groupType == 1 && proGroupVoIndex !== undefined) {
return FormData.proGroupVo[proGroupVoIndex].goods = arr
}
FormData.proGroupVo.push({
title: '',
count: 1,
goods: arr
})
}
/**
* number类型数据限制
* @param {Object} item
* @param {Object} key
*/
function priceFormat(item, key) {
nextTick(() => {
const min = 0;
const max = 100000000;
if (item[key] === '') {
return
}
const newval = formatPrice(item[key], min, max, true)
if (typeof newval !== 'number') {
item[key] = newval.value
uni.showToast({
title: `请输入${min}${max}范围内的数字`,
icon: 'none'
})
} else {
item[key] = newval
}
})
}
/**
* 套餐商品类型
*/
const packageType = reactive({
list: [{
name: '固定套餐',
value: 0
}, {
name: '可选套餐',
value: 1
}],
sel: 0
})
const tabsList = ['基础设置', '耗材绑定']
let tabsCurrent = ref(0)
const Forms = ref(null)
const delModel = ref(null)
const rules = {
images: {
rules: [{
validateFunction: function(rule, value, data, callback) {
console.log(value);
if (value.length < 1) {
callback('请上传商品图片')
}
return true
}
}]
},
name: {
rules: [{
required: true,
errorMessage: '请输入商品名称',
},
{
minLength: 1,
maxLength: 40,
errorMessage: '商品名称长度在 {minLength} 到 {maxLength} 个字符',
}
]
},
categoryId: {
rules: [{
required: true,
errorMessage: '请选择商品分类',
}]
},
floorPrice: {
rules: [{
required: true,
errorMessage: '请填写商品底价',
}]
}
}
/**
* 删除提示打开
*/
function delModelShow() {
delModel.value.open()
}
/**
* 删除商品
*/
function delmodelConfirm() {
delProduct(option.productId).then(res => {
uni.showToast({
icon: 'none',
title: '删除成功'
})
setTimeout(() => {
uni.$emit('del:productIndex', option.productId)
go.back()
}, 500)
})
}
function updateGoodsDetail() {
getGoodsDetail()
}
let timer = null
function settimeoutBack(time) {
clearTimeout(timer)
timer = setTimeout(() => {
uni.$emit('update:productIndex')
uni.navigateBack()
}, time)
}
//保存
async function save() {
const bol = await hasPermission('允许修改商品')
if (!bol) {
return
}
Forms.value.validate().then(res => {
const {
groupType,
type
} = FormData
const images = refFile.value.getFileList()
if (images.length <= 0) {
return infoBox.showToast('请上传商品图片')
}
let selectSpecInfo = $goodsData.selectSpecInfo
if (FormData.specificationsGroup.specAllList) {
selectSpecInfo = {}
for (let i of FormData.specificationsGroup.selectSpecInfo) {
if (i.selectSpecResult.length) {
selectSpecInfo[i.name] = i.selectSpecResult
}
}
}
if (type != 'sku') {
let lowPrice = skuList.list[0] ? skuList.list[0].salePrice : FormData.salePrice
let suitNum = skuList.list[0] ? skuList.list[0].suitNum : 0
if (lowPrice === '') {
return infoBox.showToast('请输入售价')
}
if (suitNum <= 0) {
return infoBox.showToast('起售数量不能小于0')
}
if (FormData.stockNumber === '') {
return infoBox.showToast('请输入库存数量!')
}
}
if (type == 'sku') {
if ( selectSpecInfo.length ==0 || JSON.stringify(selectSpecInfo) == '{}') {
return infoBox.showToast('请选择规格!')
}
}
if (type == 'package') {
if (groupType == 0 && FormData.proGroupVo[0].goods.length <= 0) {
// 固定套餐
return infoBox.showToast('套餐组合至少需要包含一种商品,请添加商品')
}
if (groupType == 1) {
let ispase = FormData.proGroupVo.length > 0 ? true : false
let tips = ispase ? '' : '请添加至少一种套餐'
for (let i in FormData.proGroupVo) {
FormData.proGroupVo[i].count = FormData.proGroupVo[i].goods.length
const item = FormData.proGroupVo[i]
if (item.goods.length <= 0) {
ispase = false
tips = '套餐组合至少需要包含一种商品,请添加商品'
break
}
if (!item.title) {
ispase = false
tips = '请输入套餐名称'
break
}
}
if (!ispase) {
return infoBox.showToast(tips)
}
// 可选套餐
} else {
FormData.proGroupVo[0].count = FormData.proGroupVo[0].goods.length
FormData.proGroupVo[0].number = null
}
}
if (type == 'weight') {
if (!FormData.weight) {
return infoBox.showToast('请输入重量')
}
}
const submitData = {
...FormData,
proGroupVo: type != 'package' ? '' : FormData.proGroupVo,
images: images,
coverImg: images[0] || '',
skuList: skuList.list,
selectSpecInfo: selectSpecInfo
}
//编辑
if (option.type === 'edit') {
return updateProduct(submitData).then(res => {
infoBox.showSuccessToast('更新成功')
settimeoutBack(1500)
})
}
// 如果套餐没选择规格,默认选中第一条
if (submitData.proGroupVo) {
submitData.proGroupVo.forEach((res, index) => {
submitData.proGroupVo[index].goods.forEach(ele => {
if (!ele.skuId) {
ele.skuId = ele.skuList[0].id
ele.skuName = ele.skuList[0].specInfo || ele.skuList[0].name
}
})
})
}
addProduct(submitData).then(res => {
infoBox.showSuccessToast('添加成功')
settimeoutBack(1500)
})
}).catch(err => {
console.log(err);
})
}
/**
* 监听规格保存,拿到数据
*/
function watchSpecificationsSave() {
uni.$off('emitspecificationsSave')
uni.$on('emitspecificationsSave', function(data) {
console.log(data)
FormData.specificationsGroup = data
FormData.specId = data.specId
FormData.specName = data.specName
skuList.list = data.result.map(v => {
return {
...v.skus,
...v.names,
specInfo: v.specInfo,
coverImg: v.coverImg || ''
}
})
console.log(skuList.list);
})
}
/**
* 编辑规格
*/
function toGuige() {
console.log(FormData.specificationsGroup)
uni.setStorageSync('guige', FormData.specificationsGroup)
go.to('PAGES_PRODUCT_GUIGE_CHOOSE', {
emitName: 'emitspecificationsSave',
type: option.type,
})
}
/**
* 监听定时器保存,拿到数据
* @param {Boolean} open //控制开启或关闭监听
*/
function watchTimerSave(open = true) {
uni.$off('timerSave')
uni.$on('timerSave', function(timer) {
Object.assign(FormData, timer)
})
}
/**
* 设置定时上下级
*/
function toTimerPage() {
go.to('PAGES_PRODUCT_TIMER', {
days: FormData.days,
startTime: FormData.startTime,
endTime: FormData.endTime
})
}
const $week = {
Monday: '周一',
Tuesday: '周二',
Wednesday: '周三',
Thursday: '周四',
Friday: '周无',
Saturday: '周六',
Sunday: '周日',
}
/**
* 定时数据显示处理
*/
function returnTimerDayText() {
if (!FormData.days) {
return ''
}
return FormData.days.split(',').filter(v => v).map(v => $week[v]).join(',')
// return FormData.timer.length ? `当前有${FormData.timer.length}个定时器` : '没有定时器'
}
/**
* 定时数据显示处理
*/
function returnTimerTimeText() {
if (!FormData.startTime || !FormData.endTime) {
return ''
}
return FormData.startTime + '-' + FormData.endTime
}
function initDefaultProGroupVo() {
FormData.proGroupVo = [{
title: '',
count: 1,
number: 1,
goods: []
}]
console.log(FormData.proGroupVo);
}
/**
* 权限start
*/
// 允许修改商品库存
let disabledStock = ref(false)
async function canEditGoodsStock(tips = false) {
console.log(tips);
if (option.type === 'edit') {
const res = await hasPermission({
text: '允许修改商品库存',
tips: tips
})
disabledStock.value = !res
}
}
watch(() => FormData.isStock, (newval) => {
if (newval) {
canEditGoodsStock()
}
})
// 允许修改商品分类
let disabledChangeCategory = ref(false)
async function canEditGoodsCategory(tips = false) {
if (option.type === 'edit') {
const res = await hasPermission({
text: '允许修改分类',
tips
})
disabledChangeCategory.value = !res
}
}
const activeinHouseList = computed(() => {
try {
return pageData.units.filter((item) => {
if (item.id == FormData.unitId) {
return item.name
}
})[0].name
} catch (error) {
//TODO handle the exception
}
});
/**
* 销毁
*/
onBeforeUnmount(() => {
clearTimeout(timer)
})
</script>
<style scoped>
page {
background: #F9F9F9;
}
</style>
<style lang="scss" scoped>
.barCode {
border: 1px solid #E5E5E5;
border-radius: 8rpx 8rpx 8rpx 8rpx;
padding: 22rpx 24rpx;
background: #FCFCFC;
}
.top {
position: fixed;
// left: 28rpx;
// right: 28rpx;
// /* #ifdef H5 */
// top: calc(44px + 24rpx);
// /* #endif */
// /* #ifndef H5 */
// top: calc(var(--status-bar-height) + 24rpx);
// /* #endif */
// z-index: 999;
}
::v-deep .uni-forms-item--border {
padding-top: 12px;
padding-bottom: 12px;
}
.stick-bottom {
top: 0;
z-index: 10;
}
::v-deep .stock .uni-data-checklist .checklist-group .checklist-box {
margin-right: 30rpx;
}
.stock .btns {
position: fixed;
bottom: 100rpx;
left: 110rpx;
right: 110rpx;
display: flex;
flex-direction: column;
gap: 20rpx;
}
.u-p-l-100 {
padding-left: 100rpx;
}
.bg-gray {
background: #F9F9F9;
padding: 0 20rpx;
}
.safe-page {
background: #F9F9F9;
}
.my-switch {
transform: scale(0.7);
}
.label-title {
font-size: 28rpx;
font-weight: bold;
font-family: Source Han Sans CN, Source Han Sans CN;
}
.lh40 {
line-height: 40rpx;
}
.bootom {
position: fixed;
left: 110rpx;
right: 110rpx;
bottom: 60px;
z-index: 9;
}
.minus {}
.plus {}
.box {
margin-top: 32rpx;
font-size: 28rpx;
.block {
background: #FFFFFF;
border-radius: 8rpx 18rpx 8rpx 18rpx;
padding: 12rpx 24rpx;
margin-bottom: 32rpx;
}
}
::v-deep.uni-forms-item {
align-items: inherit;
}
::v-deep .typeEnum .u-radio-group--row {
flex-wrap: nowrap;
justify-content: space-between;
}
::v-deep .typeEnum .u-checkbox-group--row {
flex-wrap: nowrap;
justify-content: space-between;
}
::v-deep .uni-forms-item .uni-forms-item__label {
text-indent: 0;
font-size: 28rpx !important;
font-weight: bold;
color: #333;
}
::v-deep .stock .uni-forms-item {
min-height: initial !important;
}
.gap-26 {
gap: 26rpx;
}
::v-deep .bg-gray .uni-forms-item {
background-color: transparent !important;
}
::v-deep .border-top-0 .uni-forms-item.is-direction-top {
border-color: transparent !important;
}
::v-deep .uni-data-checklist .checklist-group .checklist-box .checklist-content .checklist-text {
font-size: 28rpx;
color: #333;
}
::v-deep .none-label .uni-forms-item.is-direction-top {
padding: 0 !important;
min-height: initial !important;
}
::v-deep .uni-easyinput__content-input {
height: inherit;
}
::v-deep .none-label .uni-forms-item .uni-forms-item__label {
padding: 0 !important;
}
.save-btn {
background-color: $my-main-color;
color: #fff;
border-radius: 100rpx;
font-size: 28rpx;
}
.btn-hover-class {
opacity: .6;
}
.zuofa {
padding: 28rpx 0;
background: #F9F9F9;
padding-left: 42rpx;
border-radius: 14rpx 14rpx 14rpx 14rpx;
}
::v-deep .uni-input-placeholder {
font-size: 28rpx;
}
.table {
background: #F9F9F9;
border-radius: 8rpx;
overflow: hidden;
.title {
padding: 12rpx 24rpx 12rpx 24rpx;
background: #AEBAD2;
border-radius: 8rpx 8rpx 0rpx 0rpx;
color: #fff;
}
.row:nth-of-type(2n+1) {
background: #F0F0F0;
}
}
.types {
.item {
padding: 6rpx 20rpx;
border: 1px solid #bbb;
border-radius: 8rpx;
margin-right: 30rpx;
margin-bottom: 20rpx;
text-align: center;
position: relative;
.gou {
display: none;
position: absolute;
right: 0;
top: 0;
background-color: $my-main-color;
width: 32rpx;
height: 32rpx;
clip-path: polygon(100% 0, 0 0, 100% 100%);
}
}
.active {
border-color: $my-main-color;
.gou {
display: flex;
}
.title {
color: $my-main-color;
}
}
&.disabled {
position: relative;
&::after {
position: absolute;
content: '';
display: block;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.item {
background-color: #f9f9f9;
border-color: #eee;
&.active {
border-color: rgba(49, 138, 254, .3);
}
.gou {
opacity: .5;
}
.title {
color: #999;
}
}
}
}
</style>