|
|
|
@ -1,429 +1,550 @@
|
|
|
|
<template>
|
|
|
|
<template>
|
|
|
|
<view v-if="load" class="content p-2 bg-gray-100">
|
|
|
|
<view v-if="load" class="content p-2 bg-gray-100">
|
|
|
|
<wd-toast />
|
|
|
|
<wd-toast />
|
|
|
|
<wd-form ref="form" :model="model">
|
|
|
|
<wd-form ref="form" :model="model">
|
|
|
|
<wd-cell-group border>
|
|
|
|
<wd-cell-group border>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="rounded-md overflow-hidden">
|
|
|
|
<div class="rounded-md overflow-hidden">
|
|
|
|
<div class="bg-gray-100 ">
|
|
|
|
<div class="bg-gray-100 ">
|
|
|
|
<div class="bg-gray-100 rounded mb-2">
|
|
|
|
<div class="bg-gray-100 rounded mb-2">
|
|
|
|
<div class="bg-white flex flex-col pt-3 pl-3">
|
|
|
|
<div class="bg-white flex flex-col pt-3 pl-3">
|
|
|
|
<div class="name mb-2 text-xs">缩略图</div>
|
|
|
|
<div class="name mb-2 text-xs">缩略图</div>
|
|
|
|
<yUpload v-model="model.pic_url"></yUpload>
|
|
|
|
<yUpload v-model="model.pic_url"></yUpload>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="bg-gray-100">
|
|
|
|
<div class="bg-gray-100">
|
|
|
|
<div class="bg-gray-100 rounded mb-2">
|
|
|
|
<div class="bg-gray-100 rounded mb-2">
|
|
|
|
<div class="bg-white flex flex-col pt-3 pl-3">
|
|
|
|
<div class="bg-white flex flex-col pt-3 pl-3">
|
|
|
|
<div class="name mb-2 text-xs">商品主图</div>
|
|
|
|
<div class="name mb-2 text-xs">商品主图</div>
|
|
|
|
<yUpload v-model="model.pic_list" :size="4"></yUpload>
|
|
|
|
<yUpload v-model="model.pic_list" :size="4"></yUpload>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class=" p-3 rounded mb-2">
|
|
|
|
<view class=" p-3 rounded mb-2">
|
|
|
|
<div class="name mb-2 text-xs">商品名称</div>
|
|
|
|
<div class="name mb-2 text-xs">商品名称</div>
|
|
|
|
<view class="bg-white px-3 py-1 rounded">
|
|
|
|
<view class="bg-white px-3 py-1 rounded">
|
|
|
|
<wd-textarea v-model="model.name" auto-height />
|
|
|
|
<wd-textarea v-model="model.name" auto-height />
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class=" p-3 rounded mb-2">
|
|
|
|
<view class=" p-3 rounded mb-2">
|
|
|
|
<div class="name mb-2 text-xs">商品分类</div>
|
|
|
|
<div class="name mb-2 text-xs">商品分类</div>
|
|
|
|
<view class="bg-white px-3 py-1 rounded">
|
|
|
|
<view class="bg-white px-3 py-1 rounded">
|
|
|
|
<wd-checkbox-group v-model="model.classify_list">
|
|
|
|
<wd-checkbox-group v-model="model.classify_list">
|
|
|
|
|
|
|
|
|
|
|
|
<view class="flex overflow-auto flex-wrap">
|
|
|
|
<view class="flex overflow-auto flex-wrap">
|
|
|
|
<div class="grid grid-cols-3">
|
|
|
|
<div class="grid grid-cols-3">
|
|
|
|
<wd-checkbox style="width: 100%;" shape="button" v-for="cat of classifyList"
|
|
|
|
<wd-checkbox style="width: 100%;" shape="button" v-for="cat of classifyList"
|
|
|
|
:modelValue="JSON.stringify(cat.parentIds)">
|
|
|
|
:modelValue="JSON.stringify(cat.parentIds)">
|
|
|
|
{{ cat.name }}
|
|
|
|
{{ cat.name }}
|
|
|
|
</wd-checkbox>
|
|
|
|
</wd-checkbox>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
</wd-checkbox-group>
|
|
|
|
</wd-checkbox-group>
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="bg-gray-100 rounded mb-2">
|
|
|
|
<view class="bg-gray-100 rounded mb-2">
|
|
|
|
<div class="p-2 bg-white">
|
|
|
|
<div class="p-2 bg-white">
|
|
|
|
<div class="name mb-2 text-xs">服务内容</div>
|
|
|
|
<div class="name mb-2 text-xs">服务内容</div>
|
|
|
|
<view class="bg-white px-3 py-1 rounded">
|
|
|
|
<view class="bg-white px-3 py-1 rounded">
|
|
|
|
<wd-input type="text" v-model="model.server_project" placeholder="例子: 正品保障,极速发货,7天退换货。多个请使用英文逗号“,”分隔" />
|
|
|
|
<wd-input type="text" v-model="model.server_project"
|
|
|
|
</view>
|
|
|
|
placeholder="例子: 正品保障,极速发货,7天退换货。多个请使用英文逗号“,”分隔" />
|
|
|
|
</div>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<view class=" p-3 rounded mb-2">
|
|
|
|
|
|
|
|
<div class="name mb-2 text-xs">商品重量</div>
|
|
|
|
<view class=" p-3 rounded mb-2">
|
|
|
|
<view class="bg-white px-3 py-2 rounded flex items-center mb-4">
|
|
|
|
<div class="name mb-2 text-xs">商品重量</div>
|
|
|
|
<wd-input-number v-model="model.weight" />
|
|
|
|
<view class="bg-white px-3 py-2 rounded flex items-center mb-4">
|
|
|
|
<view class="text-xs from-neutral-300 ml-4">千克</view>
|
|
|
|
<wd-input-number v-model="model.weight" />
|
|
|
|
</view>
|
|
|
|
<view class="text-xs from-neutral-300 ml-4">千克</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
<wd-picker v-if="freightRules.length" class="w-full" :columns="freightRules" label="运费模板"
|
|
|
|
|
|
|
|
v-model="model.freight_id" />
|
|
|
|
<wd-picker v-if="freightRules.length" class="w-full" :columns="freightRules" label="运费模板"
|
|
|
|
|
|
|
|
v-model="model.freight_id" />
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<view class="p-3 rounded mb-2">
|
|
|
|
|
|
|
|
<div class="name mb-2 text-xs">商品状态</div>
|
|
|
|
<view class="p-3 rounded mb-2">
|
|
|
|
<view class="bg-white px-3 py-2 rounded flex items-center">
|
|
|
|
<div class="name mb-2 text-xs">商品状态</div>
|
|
|
|
<wd-switch v-model="model.status" :active-value="1" :inactive-value="0" />
|
|
|
|
<view class="bg-white px-3 py-2 rounded flex items-center">
|
|
|
|
</view>
|
|
|
|
<wd-switch v-model="model.status" :active-value="1" :inactive-value="0" />
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<view class="p-3 rounded mb-2">
|
|
|
|
|
|
|
|
<div class="name mb-2 text-xs">规格</div>
|
|
|
|
<view class="p-3 rounded mb-2">
|
|
|
|
<view class="bg-white px-3 py-2 rounded flex items-center">
|
|
|
|
<div class="name mb-2 text-xs">规格</div>
|
|
|
|
<wd-radio-group shape="button" v-model="model.use_sku">
|
|
|
|
<view class="bg-white px-3 py-2 rounded flex items-center">
|
|
|
|
<wd-radio :value="0">单规格</wd-radio>
|
|
|
|
<wd-radio-group shape="button" v-model="model.use_sku">
|
|
|
|
<wd-radio :value="1">多规格</wd-radio>
|
|
|
|
<wd-radio :value="0">单规格</wd-radio>
|
|
|
|
</wd-radio-group>
|
|
|
|
<wd-radio :value="1">多规格</wd-radio>
|
|
|
|
</view>
|
|
|
|
</wd-radio-group>
|
|
|
|
</view>
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
|
|
|
|
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<skuEdit ref="skuEditRef" :skuGroup="skuGroup"
|
|
|
|
|
|
|
|
:Pdata="{ skuDefault, skuLibrary, skuGroup, use_sku: model.use_sku }">
|
|
|
|
<skuEdit ref="skuEditRef" :skuGroup="skuGroup"
|
|
|
|
</skuEdit>
|
|
|
|
:Pdata="{ skuDefault, skuLibrary, skuGroup, use_sku: model.use_sku }">
|
|
|
|
|
|
|
|
</skuEdit>
|
|
|
|
</wd-cell-group>
|
|
|
|
|
|
|
|
<view class="footer mt-4">
|
|
|
|
<view class="h-2 bg-gray-100"></view>
|
|
|
|
<wd-button @click="saveGoods" type="primary" size="large" block>保存</wd-button>
|
|
|
|
<view>
|
|
|
|
</view>
|
|
|
|
<view style="font-size: 36rpx;border-bottom: 1rpx solid #F0F0F0;display: flex;flex-wrap: wrap;align-items: center;">
|
|
|
|
</wd-form>
|
|
|
|
<view
|
|
|
|
</view>
|
|
|
|
:style="{
|
|
|
|
|
|
|
|
margin: '20rpx',
|
|
|
|
|
|
|
|
fontWeight: formats.bold ? '800' : '400'
|
|
|
|
|
|
|
|
}"
|
|
|
|
|
|
|
|
@click="format('bold', (formats.bold ? false : true))">加粗</view>
|
|
|
|
|
|
|
|
<view
|
|
|
|
|
|
|
|
:style="{
|
|
|
|
|
|
|
|
margin: '20rpx',
|
|
|
|
|
|
|
|
fontWeight: formats.italic ? '800' : '400'
|
|
|
|
|
|
|
|
}"
|
|
|
|
|
|
|
|
@click="format('italic', (formats.italic ? false : true))">斜体</view>
|
|
|
|
|
|
|
|
<view
|
|
|
|
|
|
|
|
:style="{
|
|
|
|
|
|
|
|
margin: '20rpx',
|
|
|
|
|
|
|
|
fontWeight: formats.underline ? '800' : '400'
|
|
|
|
|
|
|
|
}"
|
|
|
|
|
|
|
|
@click="format('underline', (formats.underline ? false : true))">下划线</view>
|
|
|
|
|
|
|
|
<view
|
|
|
|
|
|
|
|
:style="{
|
|
|
|
|
|
|
|
margin: '20rpx',
|
|
|
|
|
|
|
|
fontWeight: formats.align == 'center' ? '800' : '400'
|
|
|
|
|
|
|
|
}"
|
|
|
|
|
|
|
|
@click="format('align', (formats.align == 'center' ? 'left' : 'center'))">居中</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<view style="margin: 20rpx;" >
|
|
|
|
|
|
|
|
<yUpload :width="40" :height="40" v-model="editor_upload" :size="4"></yUpload>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
<view style="padding: 10px;">
|
|
|
|
|
|
|
|
<editor style="min-height: 70vh;" id="editor" class="ql-container"
|
|
|
|
|
|
|
|
placeholder="开始输入..." show-img-size show-img-toolbar
|
|
|
|
|
|
|
|
@statuschange="onStatusChange"
|
|
|
|
|
|
|
|
show-img-resize :read-only="false" @ready="onEditorReady">
|
|
|
|
|
|
|
|
</editor>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</wd-cell-group>
|
|
|
|
|
|
|
|
<view class="footer mt-4">
|
|
|
|
|
|
|
|
<wd-button @click="saveGoods" type="primary" size="large" block>保存</wd-button>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
|
|
|
|
</wd-form>
|
|
|
|
|
|
|
|
</view>
|
|
|
|
</template>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
<script setup>
|
|
|
|
import { ref } from 'vue';
|
|
|
|
import {
|
|
|
|
import { useToast, useMessage } from '@/uni_modules/wot-design-uni';
|
|
|
|
ref,
|
|
|
|
import goods from '@/api/store/goods.js';
|
|
|
|
watch
|
|
|
|
import system from '@/api/modules/system.js';
|
|
|
|
} from 'vue';
|
|
|
|
import skuEdit from "./components/skuEdit.vue";
|
|
|
|
import {
|
|
|
|
import yUpload from "@/components/yUpload/index.vue";
|
|
|
|
useToast,
|
|
|
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
|
|
|
useMessage
|
|
|
|
|
|
|
|
} from '@/uni_modules/wot-design-uni';
|
|
|
|
/**
|
|
|
|
import goods from '@/api/store/goods.js';
|
|
|
|
* @typedef {import('@/api/store/goods').GoodsItem} GoodsItem
|
|
|
|
import system from '@/api/modules/system.js';
|
|
|
|
*/
|
|
|
|
import skuEdit from "./components/skuEdit.vue";
|
|
|
|
|
|
|
|
import yUpload from "@/components/yUpload/index.vue";
|
|
|
|
/**
|
|
|
|
import {
|
|
|
|
* @typedef {import('@/api/store/goods').FreightRule} FreightRule
|
|
|
|
onLoad,
|
|
|
|
*/
|
|
|
|
onShow
|
|
|
|
|
|
|
|
} from "@dcloudio/uni-app";
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @typedef {Object} Sku
|
|
|
|
/**
|
|
|
|
* @property {string} price - 商品价格
|
|
|
|
* @typedef {import('@/api/store/goods').GoodsItem} GoodsItem
|
|
|
|
* @property {string} stock - 商品库存
|
|
|
|
*/
|
|
|
|
* @property {string} original_price - 商品原价
|
|
|
|
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @typedef {import('@/api/store/goods').FreightRule} FreightRule
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
* @typedef {Object} Model
|
|
|
|
|
|
|
|
* @property {number} id - 商品ID
|
|
|
|
/**
|
|
|
|
* @property {Array<string>} classify_list - 商品分类组
|
|
|
|
* @typedef {Object} Sku
|
|
|
|
* @property {string} name - 商品名称
|
|
|
|
* @property {string} price - 商品价格
|
|
|
|
* @property {string} keywords - 商品关键词
|
|
|
|
* @property {string} stock - 商品库存
|
|
|
|
* @property {number} sort - 商品排序
|
|
|
|
* @property {string} original_price - 商品原价
|
|
|
|
* @property {number} status - 商品状态
|
|
|
|
*/
|
|
|
|
* @property {number} freight_id - 运费规则ID
|
|
|
|
|
|
|
|
* @property {number} weight - 商品重量
|
|
|
|
/**
|
|
|
|
* @property {string} pic_url - 商品缩略图
|
|
|
|
* @typedef {Object} Model
|
|
|
|
* @property {Array<string>} pic_list - 商品图组
|
|
|
|
* @property {number} id - 商品ID
|
|
|
|
* @property {string} video - 商品视频
|
|
|
|
* @property {Array<string>} classify_list - 商品分类组
|
|
|
|
* @property {string} detail - 图文详情
|
|
|
|
* @property {string} name - 商品名称
|
|
|
|
* @property {number} use_sku - 是否使用规格
|
|
|
|
* @property {string} keywords - 商品关键词
|
|
|
|
* @property {Array<Sku>} sku_list - 规格信息
|
|
|
|
* @property {number} sort - 商品排序
|
|
|
|
* @property {number} is_discount - 是否有折扣
|
|
|
|
* @property {number} status - 商品状态
|
|
|
|
* @property {number} discount - 折扣比例(小数)
|
|
|
|
* @property {number} freight_id - 运费规则ID
|
|
|
|
* @property {number} dist_price - 分销价格
|
|
|
|
* @property {number} weight - 商品重量
|
|
|
|
* @property {number} limit - 限购
|
|
|
|
* @property {string} pic_url - 商品缩略图
|
|
|
|
* @property {number} is_check - 自定义核销佣金
|
|
|
|
* @property {Array<string>} pic_list - 商品图组
|
|
|
|
* @property {number} check_type - 佣金类型
|
|
|
|
* @property {string} video - 商品视频
|
|
|
|
* @property {number} check_price - 佣金
|
|
|
|
* @property {string} detail - 图文详情
|
|
|
|
*/
|
|
|
|
* @property {number} use_sku - 是否使用规格
|
|
|
|
|
|
|
|
* @property {Array<Sku>} sku_list - 规格信息
|
|
|
|
/**
|
|
|
|
* @property {number} is_discount - 是否有折扣
|
|
|
|
* @typedef {Object} FileItem
|
|
|
|
* @property {number} discount - 折扣比例(小数)
|
|
|
|
* @property {string} pic_url - 图片URL
|
|
|
|
* @property {number} dist_price - 分销价格
|
|
|
|
*/
|
|
|
|
* @property {number} limit - 限购
|
|
|
|
|
|
|
|
* @property {number} is_check - 自定义核销佣金
|
|
|
|
/**
|
|
|
|
* @property {number} check_type - 佣金类型
|
|
|
|
* @typedef {Object} SkuGroup
|
|
|
|
* @property {number} check_price - 佣金
|
|
|
|
* @property {Array<Sku>} skuDefault - 默认规格
|
|
|
|
*/
|
|
|
|
* @property {Array<Sku>} skuLibrary - 规格库
|
|
|
|
|
|
|
|
* @property {Array<Sku>} skuGroup - 规格组
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
* @typedef {Object} FileItem
|
|
|
|
|
|
|
|
* @property {string} pic_url - 图片URL
|
|
|
|
/**
|
|
|
|
*/
|
|
|
|
* @typedef {Object} SkuEditRef
|
|
|
|
|
|
|
|
* @property {SkuGroup} skuGroup - 规格组
|
|
|
|
/**
|
|
|
|
* @property {number} skuDefault - 默认规格
|
|
|
|
* @typedef {Object} SkuGroup
|
|
|
|
* @property {number} skuLibrary - 规格库
|
|
|
|
* @property {Array<Sku>} skuDefault - 默认规格
|
|
|
|
*/
|
|
|
|
* @property {Array<Sku>} skuLibrary - 规格库
|
|
|
|
|
|
|
|
* @property {Array<Sku>} skuGroup - 规格组
|
|
|
|
/** @type {Ref<Array<FileItem>>} */
|
|
|
|
*/
|
|
|
|
const fileList = ref([]);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @typedef {Object} SkuEditRef
|
|
|
|
* @param {Object} param0
|
|
|
|
* @property {SkuGroup} skuGroup - 规格组
|
|
|
|
* @param {FileItem} param0.file - 要删除的文件
|
|
|
|
* @property {number} skuDefault - 默认规格
|
|
|
|
* @param {Function} param0.resolve - 删除文件的回调函数
|
|
|
|
* @property {number} skuLibrary - 规格库
|
|
|
|
* @param {number} param0.index - 文件索引
|
|
|
|
*/
|
|
|
|
* @returns {void}
|
|
|
|
|
|
|
|
*/
|
|
|
|
/** @type {Ref<Array<FileItem>>} */
|
|
|
|
const beforeRemove = ({ file, resolve, index }) => {
|
|
|
|
const fileList = ref([]);
|
|
|
|
fileList.value.splice(index, 1);
|
|
|
|
|
|
|
|
resolve(true);
|
|
|
|
/**
|
|
|
|
};
|
|
|
|
* @param {Object} param0
|
|
|
|
|
|
|
|
* @param {FileItem} param0.file - 要删除的文件
|
|
|
|
/** @type {Ref<Model>} */
|
|
|
|
* @param {Function} param0.resolve - 删除文件的回调函数
|
|
|
|
const model = ref({
|
|
|
|
* @param {number} param0.index - 文件索引
|
|
|
|
classify_list: [], // 商品分类组
|
|
|
|
* @returns {void}
|
|
|
|
name: "", // 商品名称
|
|
|
|
*/
|
|
|
|
keywords: "", // 商品关键词
|
|
|
|
const beforeRemove = ({
|
|
|
|
sort: 1000,
|
|
|
|
file,
|
|
|
|
status: 0, // 商品状态
|
|
|
|
resolve,
|
|
|
|
freight_id: 99999999, //运费规则
|
|
|
|
index
|
|
|
|
weight: 0, // 商品重量
|
|
|
|
}) => {
|
|
|
|
pic_url: "", // 商品缩略图
|
|
|
|
fileList.value.splice(index, 1);
|
|
|
|
pic_list: [], // 商品图组
|
|
|
|
resolve(true);
|
|
|
|
video: "", // 商品视频
|
|
|
|
};
|
|
|
|
detail: "默认", // 图文详情
|
|
|
|
|
|
|
|
use_sku: 0, // 是否使用规格
|
|
|
|
|
|
|
|
sku_list: [], // 规格信息
|
|
|
|
const editorCtx = ref(null);
|
|
|
|
is_discount: 0, // 是否有折扣
|
|
|
|
const onEditorReady = () => {
|
|
|
|
discount: 50, // 折扣比例(小数)
|
|
|
|
// #ifdef MP-BAIDU
|
|
|
|
dist_price: 0, // 分销价格
|
|
|
|
editorCtx.value = requireDynamicLib('editorLib').createEditorContext('editor');
|
|
|
|
limit: 0, // 限购
|
|
|
|
// #endif
|
|
|
|
is_check: 0, // 自定义核销佣金
|
|
|
|
|
|
|
|
check_type: 0, // 佣金类型
|
|
|
|
// #ifdef APP-PLUS || MP-WEIXIN || H5
|
|
|
|
check_price: 0, // 佣金
|
|
|
|
uni.createSelectorQuery().select('#editor').context((res) => {
|
|
|
|
});
|
|
|
|
editorCtx.value = res.context
|
|
|
|
|
|
|
|
}).exec()
|
|
|
|
/** @type {Ref<boolean>} */
|
|
|
|
// #endif
|
|
|
|
const load = ref(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
const formats = ref({});
|
|
|
|
/** @type {Ref<SkuGroup>} */
|
|
|
|
const onStatusChange = (e) => {
|
|
|
|
const skuGroup = ref([]);
|
|
|
|
formats.value = e.detail
|
|
|
|
/** @type {Ref<Array<GoodsItem>>} */
|
|
|
|
}
|
|
|
|
const skuDefault = ref([]);
|
|
|
|
|
|
|
|
/** @type {Ref<Array<GoodsItem>>} */
|
|
|
|
const format = (name, value) => {
|
|
|
|
const skuLibrary = ref([]);
|
|
|
|
editorCtx.value.format(name, value)
|
|
|
|
|
|
|
|
}
|
|
|
|
/** @type {Ref<SkuEditRef>} */
|
|
|
|
|
|
|
|
const skuEditRef = ref(null);
|
|
|
|
const editor_upload = ref([]);
|
|
|
|
|
|
|
|
watch(editor_upload, (newX) => {
|
|
|
|
/** @type {Ref<Array<FreightRule>>} */
|
|
|
|
if (newX && newX.length > 0) {
|
|
|
|
const freightRules = ref([{
|
|
|
|
newX.forEach(item => {
|
|
|
|
label: "默认",
|
|
|
|
editorCtx.value.insertImage({
|
|
|
|
value: "99999999"
|
|
|
|
src: item,
|
|
|
|
}]);
|
|
|
|
alt: '图像',
|
|
|
|
|
|
|
|
success: function() {
|
|
|
|
onLoad(async (e) => {
|
|
|
|
console.log('insert image success')
|
|
|
|
model.value.id = e.id;
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
/**
|
|
|
|
})
|
|
|
|
* 获取运费规则
|
|
|
|
|
|
|
|
* @returns {void}
|
|
|
|
editor_upload.value = []
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
const GetfreightRules = () => {
|
|
|
|
// console.log(newX, `newX is`)
|
|
|
|
goods.freightRules().then(res => {
|
|
|
|
})
|
|
|
|
freightRules.value = [
|
|
|
|
|
|
|
|
...freightRules.value,
|
|
|
|
|
|
|
|
...res.data.rows.map(item => {
|
|
|
|
/** @type {Ref<Model>} */
|
|
|
|
return {
|
|
|
|
const model = ref({
|
|
|
|
label: item.name,
|
|
|
|
classify_list: [], // 商品分类组
|
|
|
|
value: item.id
|
|
|
|
name: "", // 商品名称
|
|
|
|
};
|
|
|
|
keywords: "", // 商品关键词
|
|
|
|
})
|
|
|
|
sort: 1000,
|
|
|
|
];
|
|
|
|
status: 0, // 商品状态
|
|
|
|
});
|
|
|
|
freight_id: 99999999, //运费规则
|
|
|
|
};
|
|
|
|
weight: 0, // 商品重量
|
|
|
|
|
|
|
|
pic_url: "", // 商品缩略图
|
|
|
|
GetfreightRules();
|
|
|
|
pic_list: [], // 商品图组
|
|
|
|
|
|
|
|
video: "", // 商品视频
|
|
|
|
if (e.id > 0) {
|
|
|
|
detail: "默认", // 图文详情
|
|
|
|
const res = await goods.goodsItem({
|
|
|
|
use_sku: 0, // 是否使用规格
|
|
|
|
id: e.id
|
|
|
|
sku_list: [], // 规格信息
|
|
|
|
});
|
|
|
|
is_discount: 0, // 是否有折扣
|
|
|
|
|
|
|
|
discount: 50, // 折扣比例(小数)
|
|
|
|
model.value = res.data;
|
|
|
|
dist_price: 0, // 分销价格
|
|
|
|
model.value.pic_list = res.data.pic_list.map(({ pic_url }) => pic_url);
|
|
|
|
limit: 0, // 限购
|
|
|
|
|
|
|
|
is_check: 0, // 自定义核销佣金
|
|
|
|
if (!model.value.freight_id) {
|
|
|
|
check_type: 0, // 佣金类型
|
|
|
|
model.value.freight_id = 99999999;
|
|
|
|
check_price: 0, // 佣金
|
|
|
|
}
|
|
|
|
});
|
|
|
|
model.value.classify_list = model.value.classify_list.map(item => JSON.stringify(item));
|
|
|
|
|
|
|
|
|
|
|
|
/** @type {Ref<boolean>} */
|
|
|
|
if (res.data.use_sku == 0) {
|
|
|
|
const load = ref(false);
|
|
|
|
skuDefault.value = res.data.goods_sku;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
/** @type {Ref<SkuGroup>} */
|
|
|
|
skuLibrary.value = res.data.goods_sku;
|
|
|
|
const skuGroup = ref([]);
|
|
|
|
}
|
|
|
|
/** @type {Ref<Array<GoodsItem>>} */
|
|
|
|
skuGroup.value = res.data.sku_group ? res.data.sku_group : [];
|
|
|
|
const skuDefault = ref([]);
|
|
|
|
load.value = true;
|
|
|
|
/** @type {Ref<Array<GoodsItem>>} */
|
|
|
|
} else {
|
|
|
|
const skuLibrary = ref([]);
|
|
|
|
load.value = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
/** @type {Ref<SkuEditRef>} */
|
|
|
|
});
|
|
|
|
const skuEditRef = ref(null);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/** @type {Ref<Array<FreightRule>>} */
|
|
|
|
* 保存商品信息
|
|
|
|
const freightRules = ref([{
|
|
|
|
* @returns {Promise<void>}
|
|
|
|
label: "默认",
|
|
|
|
*/
|
|
|
|
value: "99999999"
|
|
|
|
const saveGoods = async () => {
|
|
|
|
}]);
|
|
|
|
// 判断商品分类是否为空
|
|
|
|
|
|
|
|
if (model.value.classify_list.length === 0) {
|
|
|
|
onLoad(async (e) => {
|
|
|
|
return uni.showToast({
|
|
|
|
model.value.id = e.id;
|
|
|
|
title: '请选择商品分类!',
|
|
|
|
|
|
|
|
icon: 'none'
|
|
|
|
/**
|
|
|
|
});
|
|
|
|
* 获取运费规则
|
|
|
|
}
|
|
|
|
* @returns {void}
|
|
|
|
|
|
|
|
*/
|
|
|
|
// 判断商品名称是否为空
|
|
|
|
const GetfreightRules = () => {
|
|
|
|
if (model.value.name.trim() === "") {
|
|
|
|
goods.freightRules().then(res => {
|
|
|
|
return uni.showToast({
|
|
|
|
freightRules.value = [
|
|
|
|
title: '请输入商品名称!',
|
|
|
|
...freightRules.value,
|
|
|
|
icon: 'none'
|
|
|
|
...res.data.rows.map(item => {
|
|
|
|
});
|
|
|
|
return {
|
|
|
|
}
|
|
|
|
label: item.name,
|
|
|
|
|
|
|
|
value: item.id
|
|
|
|
// 判断商品重量是否为非负数
|
|
|
|
};
|
|
|
|
if (model.value.weight < 0) {
|
|
|
|
})
|
|
|
|
return uni.showToast({
|
|
|
|
];
|
|
|
|
title: '请输入合法的商品重量!',
|
|
|
|
});
|
|
|
|
icon: 'none'
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
GetfreightRules();
|
|
|
|
|
|
|
|
|
|
|
|
// 判断商品缩略图是否为空
|
|
|
|
if (e.id > 0) {
|
|
|
|
if (String(model.value.pic_url).trim() === "") {
|
|
|
|
const res = await goods.goodsItem({
|
|
|
|
return uni.showToast({
|
|
|
|
id: e.id
|
|
|
|
title: '请上传商品缩略图!',
|
|
|
|
});
|
|
|
|
icon: 'none'
|
|
|
|
|
|
|
|
});
|
|
|
|
model.value = res.data;
|
|
|
|
}
|
|
|
|
model.value.pic_list = res.data.pic_list.map(({
|
|
|
|
|
|
|
|
pic_url
|
|
|
|
// 判断商品图组是否为空
|
|
|
|
}) => pic_url);
|
|
|
|
if (model.value.pic_list.length === 0) {
|
|
|
|
|
|
|
|
return uni.showToast({
|
|
|
|
if (!model.value.freight_id) {
|
|
|
|
title: '请上传商品图片组!',
|
|
|
|
model.value.freight_id = 99999999;
|
|
|
|
icon: 'none'
|
|
|
|
}
|
|
|
|
});
|
|
|
|
model.value.classify_list = model.value.classify_list.map(item => JSON.stringify(item));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (res.data.use_sku == 0) {
|
|
|
|
model.value.sku_group = [];
|
|
|
|
skuDefault.value = res.data.goods_sku;
|
|
|
|
model.value.sku_list = [];
|
|
|
|
} else {
|
|
|
|
model.value.dist_price = Number.parseInt(model.value.dist_price);
|
|
|
|
skuLibrary.value = res.data.goods_sku;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (model.value.use_sku == 1) {
|
|
|
|
skuGroup.value = res.data.sku_group ? res.data.sku_group : [];
|
|
|
|
model.value.sku_group = skuEditRef.value.skuGroup;
|
|
|
|
|
|
|
|
model.value.sku_list = skuEditRef.value.skuLibrary;
|
|
|
|
setTimeout(() => {
|
|
|
|
} else {
|
|
|
|
editorCtx.value.setContents({
|
|
|
|
model.value.sku_list = skuEditRef.value.skuDefault;
|
|
|
|
html: res.data.detail
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
}, 1000)
|
|
|
|
if (!model.value.sku_list.length) {
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
load.value = true;
|
|
|
|
title: '规格不完整,请调整!',
|
|
|
|
} else {
|
|
|
|
icon: 'none'
|
|
|
|
load.value = true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (!model.value.sku_list.every(item => Boolean(item.price !== "" && item.stock !== "" && item.original_price !== ""))) {
|
|
|
|
/**
|
|
|
|
uni.showToast({
|
|
|
|
* 保存商品信息
|
|
|
|
title: '规格不完整,请调整!',
|
|
|
|
* @returns {Promise<void>}
|
|
|
|
icon: 'none'
|
|
|
|
*/
|
|
|
|
});
|
|
|
|
const saveGoods = async () => {
|
|
|
|
|
|
|
|
// 判断商品分类是否为空
|
|
|
|
return;
|
|
|
|
if (model.value.classify_list.length === 0) {
|
|
|
|
}
|
|
|
|
return uni.showToast({
|
|
|
|
|
|
|
|
title: '请选择商品分类!',
|
|
|
|
let freight_id = model.value.freight_id;
|
|
|
|
icon: 'none'
|
|
|
|
if (freight_id = 99999999) {
|
|
|
|
});
|
|
|
|
freight_id = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 判断商品名称是否为空
|
|
|
|
const pic_list = model.value.pic_list.map(item => ({
|
|
|
|
if (model.value.name.trim() === "") {
|
|
|
|
pic_url: item
|
|
|
|
return uni.showToast({
|
|
|
|
}));
|
|
|
|
title: '请输入商品名称!',
|
|
|
|
|
|
|
|
icon: 'none'
|
|
|
|
const classify_list = model.value.classify_list.map(item => JSON.parse(item));
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
const res = await goods.goodsEdit({ ...model.value, pic_list, freight_id, classify_list });
|
|
|
|
|
|
|
|
|
|
|
|
// 判断商品重量是否为非负数
|
|
|
|
if (res.code == 0) {
|
|
|
|
if (model.value.weight < 0) {
|
|
|
|
uni.showToast({
|
|
|
|
return uni.showToast({
|
|
|
|
title: '商品信息保存成功!',
|
|
|
|
title: '请输入合法的商品重量!',
|
|
|
|
icon: 'success'
|
|
|
|
icon: 'none'
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
uni.navigateBack();
|
|
|
|
|
|
|
|
}
|
|
|
|
// 判断商品缩略图是否为空
|
|
|
|
};
|
|
|
|
if (String(model.value.pic_url).trim() === "") {
|
|
|
|
|
|
|
|
return uni.showToast({
|
|
|
|
/** @type {Ref<Array<Object>>} */
|
|
|
|
title: '请上传商品缩略图!',
|
|
|
|
const classifyList = ref([]);
|
|
|
|
icon: 'none'
|
|
|
|
|
|
|
|
});
|
|
|
|
/**
|
|
|
|
}
|
|
|
|
* 获取商品分类
|
|
|
|
|
|
|
|
* @returns {void}
|
|
|
|
// 判断商品图组是否为空
|
|
|
|
*/
|
|
|
|
if (model.value.pic_list.length === 0) {
|
|
|
|
const getClassify = () => {
|
|
|
|
return uni.showToast({
|
|
|
|
/**
|
|
|
|
title: '请上传商品图片组!',
|
|
|
|
* 递归展平商品分类
|
|
|
|
icon: 'none'
|
|
|
|
* @param {Array<GoodsItem>} categories - 商品分类数组
|
|
|
|
});
|
|
|
|
* @param {Array<number>} [parentIds=[]] - 父级分类ID数组
|
|
|
|
}
|
|
|
|
* @returns {Array<Object>} - 展平后的商品分类数组
|
|
|
|
|
|
|
|
*/
|
|
|
|
model.value.sku_group = [];
|
|
|
|
function flattenCategories(categories, parentIds = []) {
|
|
|
|
model.value.sku_list = [];
|
|
|
|
let flatCategories = [];
|
|
|
|
model.value.dist_price = Number.parseInt(model.value.dist_price);
|
|
|
|
|
|
|
|
|
|
|
|
for (const category of categories) {
|
|
|
|
if (model.value.use_sku == 1) {
|
|
|
|
const categoryWithParents = {
|
|
|
|
model.value.sku_group = skuEditRef.value.skuGroup;
|
|
|
|
...category,
|
|
|
|
model.value.sku_list = skuEditRef.value.skuLibrary;
|
|
|
|
parentIds: [...parentIds, category.id],
|
|
|
|
} else {
|
|
|
|
};
|
|
|
|
model.value.sku_list = skuEditRef.value.skuDefault;
|
|
|
|
|
|
|
|
}
|
|
|
|
flatCategories.push(categoryWithParents);
|
|
|
|
|
|
|
|
|
|
|
|
if (!model.value.sku_list.length) {
|
|
|
|
if (category.children && category.children.length > 0) {
|
|
|
|
uni.showToast({
|
|
|
|
flatCategories = flatCategories.concat(flattenCategories(category.children, [...parentIds, category.id]));
|
|
|
|
title: '规格不完整,请调整!',
|
|
|
|
}
|
|
|
|
icon: 'none'
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
return flatCategories;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (!model.value.sku_list.every(item => Boolean(item.price !== "" && item.stock !== "" && item
|
|
|
|
|
|
|
|
.original_price !== ""))) {
|
|
|
|
goods.classify.list().then(res => {
|
|
|
|
uni.showToast({
|
|
|
|
classifyList.value = flattenCategories(res.data);
|
|
|
|
title: '规格不完整,请调整!',
|
|
|
|
});
|
|
|
|
icon: 'none'
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
getClassify();
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let freight_id = model.value.freight_id;
|
|
|
|
|
|
|
|
if (freight_id = 99999999) {
|
|
|
|
|
|
|
|
freight_id = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const pic_list = model.value.pic_list.map(item => ({
|
|
|
|
|
|
|
|
pic_url: item
|
|
|
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const classify_list = model.value.classify_list.map(item => JSON.parse(item));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let detail = ''
|
|
|
|
|
|
|
|
await editorCtx.value.getContents({
|
|
|
|
|
|
|
|
success(res) {
|
|
|
|
|
|
|
|
detail = res.html
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const res = await goods.goodsEdit({
|
|
|
|
|
|
|
|
...model.value,
|
|
|
|
|
|
|
|
pic_list,
|
|
|
|
|
|
|
|
freight_id,
|
|
|
|
|
|
|
|
classify_list,
|
|
|
|
|
|
|
|
detail
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (res.code == 0) {
|
|
|
|
|
|
|
|
uni.showToast({
|
|
|
|
|
|
|
|
title: '商品信息保存成功!',
|
|
|
|
|
|
|
|
icon: 'success'
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uni.navigateBack();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** @type {Ref<Array<Object>>} */
|
|
|
|
|
|
|
|
const classifyList = ref([]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 获取商品分类
|
|
|
|
|
|
|
|
* @returns {void}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
const getClassify = () => {
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 递归展平商品分类
|
|
|
|
|
|
|
|
* @param {Array<GoodsItem>} categories - 商品分类数组
|
|
|
|
|
|
|
|
* @param {Array<number>} [parentIds=[]] - 父级分类ID数组
|
|
|
|
|
|
|
|
* @returns {Array<Object>} - 展平后的商品分类数组
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function flattenCategories(categories, parentIds = []) {
|
|
|
|
|
|
|
|
let flatCategories = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const category of categories) {
|
|
|
|
|
|
|
|
const categoryWithParents = {
|
|
|
|
|
|
|
|
...category,
|
|
|
|
|
|
|
|
parentIds: [...parentIds, category.id],
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
flatCategories.push(categoryWithParents);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (category.children && category.children.length > 0) {
|
|
|
|
|
|
|
|
flatCategories = flatCategories.concat(flattenCategories(category.children, [...parentIds, category
|
|
|
|
|
|
|
|
.id
|
|
|
|
|
|
|
|
]));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return flatCategories;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goods.classify.list().then(res => {
|
|
|
|
|
|
|
|
classifyList.value = flattenCategories(res.data);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
getClassify();
|
|
|
|
</script>
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss"></style>
|
|
|
|
<style lang="scss"></style>
|