|
@@ -0,0 +1,589 @@
|
|
|
+import {type GoodsDTO, SkuEditItem} from "@/types/goods";
|
|
|
+import {reactive, Ref, ref, watch, watchEffect} from "vue";
|
|
|
+import {type Category} from "@nutui/icons-vue-taro";
|
|
|
+import {type ProductGroup, Specification} from "@/types";
|
|
|
+import Taro, {useLoad} from "@tarojs/taro";
|
|
|
+import {getCategoryList} from "@/api/category";
|
|
|
+import {getShopCatList} from "@/api/shopcat";
|
|
|
+import {getSpecificationList} from "@/api/specification";
|
|
|
+import {addGoods, getGoodsDetail, getGoodsSku, updateGoods} from "@/api/goods";
|
|
|
+import {findPath, redirectTo} from "@/utils/commonJs";
|
|
|
+import { FileItem } from "@nutui/nutui-taro/dist/types/__VUE/uploader/type";
|
|
|
+import { baseBaseUrl } from "@/http/baseUrl";
|
|
|
+import { useShopCategoryStoreHook } from "@/store/shopCategoryStore";
|
|
|
+import { useShopStoreHook } from "@/store/shopStore";
|
|
|
+import { useCategoryStoreHook } from "@/store/categoryStore";
|
|
|
+import { uploadFile } from "@/api/file";
|
|
|
+
|
|
|
+
|
|
|
+export function useProductPublishHook() {
|
|
|
+
|
|
|
+ // 商品表单数据主体
|
|
|
+ const formData = reactive<GoodsDTO>({
|
|
|
+ category_id: 0,
|
|
|
+ category_name: '',
|
|
|
+ shop_cat_id: 0,
|
|
|
+ shop_cat_name: '',
|
|
|
+ brand_id: undefined,
|
|
|
+ goods_name: '',
|
|
|
+ sn: '',
|
|
|
+ price: 0,
|
|
|
+ cost: 0,
|
|
|
+ mktprice: 0,
|
|
|
+ weight: 0,
|
|
|
+ exchange: undefined,
|
|
|
+ goods_gallery_list: undefined,
|
|
|
+ goods_id: undefined,
|
|
|
+ goods_params_list: undefined,
|
|
|
+ goods_transfee_charge: 1,
|
|
|
+ has_changed: 0,
|
|
|
+ intro: undefined,
|
|
|
+ market_enable: 1,
|
|
|
+ meta_description: undefined,
|
|
|
+ meta_keywords: undefined,
|
|
|
+ page_title: undefined,
|
|
|
+ quantity: undefined,
|
|
|
+ sku_list: [],
|
|
|
+ template_id: 0
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ // 分类选择相关状态
|
|
|
+ const visible = ref(false);
|
|
|
+ const categoryValue = ref<number[]>([]);
|
|
|
+ const options = ref<Category[]>([])
|
|
|
+
|
|
|
+ // 商品分组选择相关状态
|
|
|
+ const shopCatShow = ref(false)
|
|
|
+ const shopCatOption = ref<ProductGroup[]>([])
|
|
|
+ const shopCatValue = ref<number[]>([])
|
|
|
+
|
|
|
+ // 规格选择相关状态
|
|
|
+ const specChooseVisible = ref(false)
|
|
|
+ const specList = ref<Specification[]>([])
|
|
|
+ const specSelectValue = ref<string[]>([])
|
|
|
+ const goodsSkus: Ref<SkuEditItem[]> = ref([])
|
|
|
+
|
|
|
+ // 表单校验引用
|
|
|
+ const formRef = ref()
|
|
|
+ const formRefSku = ref()
|
|
|
+
|
|
|
+ // 图片上传相关状态
|
|
|
+ const goodsImages = ref<any[]>([])
|
|
|
+
|
|
|
+ // 分类选择器改变事件
|
|
|
+ const change = (val, pathNodes) => {
|
|
|
+ console.log('val', val)
|
|
|
+ formData.category_id = val[val.length - 1]
|
|
|
+ formData.category_name = pathNodes.map(item => item.text).join('/')
|
|
|
+ customBlurValidate('category_name')
|
|
|
+ }
|
|
|
+
|
|
|
+ // 商品分组选择器确认
|
|
|
+ const shopCatConfirm = ({selectedOptions}) => {
|
|
|
+ formData.shop_cat_id = selectedOptions[0].shop_cat_id
|
|
|
+ formData.shop_cat_name = selectedOptions[0].shop_cat_name
|
|
|
+ shopCatShow.value = false
|
|
|
+ customBlurValidate('shop_cat_name')
|
|
|
+ }
|
|
|
+
|
|
|
+ // 页面显示生命周期
|
|
|
+ useLoad(async (option) => {
|
|
|
+ if (option) {
|
|
|
+ console.log(option)
|
|
|
+ }
|
|
|
+ // //加载分类
|
|
|
+ // const {data: categorys} = await getCategoryList(-1)
|
|
|
+ // options.value = categorys
|
|
|
+ // //加载商品分组
|
|
|
+ // const {data: groups} = await getShopCatList()
|
|
|
+ // shopCatOption.value = groups
|
|
|
+
|
|
|
+
|
|
|
+ if (option?.goods_id) {
|
|
|
+ Taro.setNavigationBarTitle({
|
|
|
+ title: '编辑商品'
|
|
|
+ })
|
|
|
+ loadGoodsDetail(option?.goods_id)
|
|
|
+ loadGoodsSku(option?.goods_id)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ })
|
|
|
+
|
|
|
+ // 保存商品
|
|
|
+ const publishGood = async () => {
|
|
|
+ formData.goods_gallery_list = goodsImages.value.map((item, index) => {
|
|
|
+ return {
|
|
|
+ original: item.url,
|
|
|
+ img_id: (typeof item.uid === 'string') ? -1 : item.uid,
|
|
|
+ sort: index
|
|
|
+ }
|
|
|
+ })
|
|
|
+ formData.has_changed = 1
|
|
|
+ const {valid:val1, errors} = await formRef.value?.validate()
|
|
|
+ const {valid:val2, errors:errors2} = await formRefSku.value?.validate()
|
|
|
+ //详情图片,转成html
|
|
|
+ if(introImages.value.length>0){
|
|
|
+ formData.intro = `<p style="font-size:0;line-height:0;">${introImages.value.map(item => `<img src="${item}" mode="widthFix" alt="" />`).join('')}</p>`
|
|
|
+ console.log('formData.intro',formData.intro)
|
|
|
+ }else{
|
|
|
+ formData.intro = ""
|
|
|
+ }
|
|
|
+ console.log('validate',val1,val2,errors,errors2)
|
|
|
+ if(val1&&val2){
|
|
|
+ if (formData.goods_id) {
|
|
|
+ //编辑商品
|
|
|
+ updateGoods(formData).then(() => {
|
|
|
+ Taro.showToast({
|
|
|
+ title: '更新成功',
|
|
|
+ icon: 'success',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ }).catch(error => {
|
|
|
+ Taro.showToast({
|
|
|
+ title: error.msg,//'编辑失败',
|
|
|
+ icon: 'none',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }else{//添加商品
|
|
|
+ addGoods(formData).then((res)=>{
|
|
|
+ Object.assign(formData, res.data)
|
|
|
+ const categoryPath = findPath(options.value, res.data.category_id)
|
|
|
+ categoryValue.value = [...categoryPath.map(item => item.category_id)]
|
|
|
+ console.log('categoryPath',categoryValue)
|
|
|
+ formData.category_name = categoryPath.map(item => item.name).join('/')
|
|
|
+ shopCatValue.value = [res.data.shop_cat_id as number]
|
|
|
+ formData.shop_cat_name = shopCatOption.value.find(item => item.shop_cat_id === res.data.shop_cat_id)?.shop_cat_name
|
|
|
+ Taro.showToast({
|
|
|
+ title: '添加成功',
|
|
|
+ icon: 'success',
|
|
|
+ duration: 2000
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ //加载规格
|
|
|
+ const loadSpecifications = (data) => {
|
|
|
+ getSpecificationList(data).then(res => {
|
|
|
+ specList.value = [...res.data]
|
|
|
+ // console.log('specs',specs.value)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ //确定选择规格
|
|
|
+ const onOkspecChoose = () => {
|
|
|
+ console.log('specSelect', specSelectValue.value)
|
|
|
+ const specValues = specList.value.flatMap(item => item.value_list).filter(p => {
|
|
|
+ return specSelectValue.value.includes(`${p?.spec_id}_${p?.spec_value_id}`)
|
|
|
+ })
|
|
|
+ const groupSpecValue = groupBy(specValues, 'spec_id')
|
|
|
+ console.log('specValues', groupSpecValue)
|
|
|
+
|
|
|
+ console.log('cartesianProduct', cartesianProduct(groupSpecValue))
|
|
|
+ const specCombine = cartesianProduct(groupSpecValue);
|
|
|
+ specCombine.forEach(item => {
|
|
|
+ if(!formData.sku_list?.some(p=>p.key===item.map(p=>p.spec_value_id).sort().join('_'))){
|
|
|
+ if(goodsSkus.value.some(p=>p.key===item.map(p=>p.spec_value_id).sort().join('_'))){
|
|
|
+ const oldSku = goodsSkus.value.find(p=>p.key===item.map(p=>p.spec_value_id).sort().join('_'))||null
|
|
|
+ console.log('oldSku',oldSku)
|
|
|
+ if(oldSku) {
|
|
|
+ formData.sku_list?.push(oldSku)
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ formData.sku_list?.push({
|
|
|
+ cost: 0,
|
|
|
+ price: 0,
|
|
|
+ quantity: 0,
|
|
|
+ sn: '',
|
|
|
+ weight: 0,
|
|
|
+ spec_list: [...item],
|
|
|
+ sku_id: undefined,
|
|
|
+ key: item.map(p => p.spec_value_id).sort().join('_')
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ formData.sku_list = formData.sku_list?.filter(item => specCombine.some(p => p.map(p => p.spec_value_id).sort().join('_') === item.key))
|
|
|
+
|
|
|
+ // formData.sku_list = cartesianProduct(groupSpecValue)
|
|
|
+ specChooseVisible.value = false
|
|
|
+ }
|
|
|
+ //加载商品详情
|
|
|
+ const loadGoodsDetail = (id: number) => {
|
|
|
+ getGoodsDetail(id).then(res => {
|
|
|
+ Object.assign(formData, res.data)
|
|
|
+ console.log('options',options.value)
|
|
|
+ const categoryPath = findPath(options.value, res.data.category_id)
|
|
|
+ categoryValue.value = [...categoryPath.map(item => item.category_id)]
|
|
|
+ console.log('categoryValue',categoryValue)
|
|
|
+ formData.category_name = categoryPath.map(item => item.name).join('/')
|
|
|
+ shopCatValue.value = [res.data.shop_cat_id as number]
|
|
|
+ formData.shop_cat_name = shopCatOption.value.find(item => item.shop_cat_id === res.data.shop_cat_id)?.shop_cat_name
|
|
|
+ //详情图片,提取图片地址
|
|
|
+ if(res.data.intro){
|
|
|
+ const matches = res.data.intro.match(/<img[^>]*src="([^"]*)"[^>]*>/g)
|
|
|
+ introImages.value = matches ? matches.map(item => {
|
|
|
+ const match = item.match(/src="([^"]*)"/);
|
|
|
+ return match ? match[1] : null;
|
|
|
+ }).filter(Boolean) as string[] : [];
|
|
|
+ console.log('introImages', introImages.value)
|
|
|
+ }
|
|
|
+
|
|
|
+ }).catch(() => {
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ //查询商品SKU
|
|
|
+ const loadGoodsSku = (goodsId: number) => {
|
|
|
+ getGoodsSku(goodsId).then(res => {
|
|
|
+ goodsSkus.value = res.data.map(item => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ key: item.spec_list.map(p => p.spec_value_id).sort().join('_')
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ if(formData.sku_list){
|
|
|
+ Object.assign(formData.sku_list, [...goodsSkus.value])
|
|
|
+ }
|
|
|
+ console.log('sku', goodsSkus.value)
|
|
|
+ }).catch(() => {
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+ const goodsImagesUploader = ref()
|
|
|
+ const fileChange=async ({fileList,event})=>{
|
|
|
+ // console.log('fileChange',fileList,event)
|
|
|
+ // console.log('上传前',goodsImages.value)
|
|
|
+ // const file:FileItem = fileList[fileList.length-1];
|
|
|
+ // Taro.cropImage({
|
|
|
+ // src: fileList[fileList.length-1].url,
|
|
|
+ // cropScale: '1:1', // 裁剪比例
|
|
|
+ // success: (res) => {
|
|
|
+ // file.url = res.tempFilePath
|
|
|
+ // file.name = res.tempFilePath
|
|
|
+ // file.path = res.tempFilePath
|
|
|
+ // file.status="ready"
|
|
|
+ // goodsImages.value[fileList.length-1]=file
|
|
|
+ // // console.log(res.tempFilePath)
|
|
|
+ // // goodsImages.value[fileList.length-1].url = res.tempFilePath
|
|
|
+ // // goodsImages.value[fileList.length-1].name = res.tempFilePath
|
|
|
+ // // goodsImages.value[fileList.length-1].path = 'ready'
|
|
|
+ // goodsImagesUploader.value.submit()
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ const file: FileItem = fileList[fileList.length - 1]
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 从商品图片列表中移除当前文件
|
|
|
+ goodsImages.value = goodsImages.value.filter(item => item.uid !== file.uid)
|
|
|
+
|
|
|
+ // 添加一个带上传状态的临时文件
|
|
|
+ const tempFile = {
|
|
|
+ ...file,
|
|
|
+ status: 'uploading',
|
|
|
+ message: '处理中',
|
|
|
+ percentage: 0
|
|
|
+ }
|
|
|
+ goodsImages.value.push(tempFile)
|
|
|
+
|
|
|
+ // 裁剪图片
|
|
|
+ const cropResult = await new Promise((resolve, reject) => {
|
|
|
+ Taro.cropImage({
|
|
|
+ src: file.url ?? '',
|
|
|
+ cropScale: '1:1',
|
|
|
+ success: resolve,
|
|
|
+ fail: reject
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ // 更新临时文件状态
|
|
|
+ tempFile.percentage = 50
|
|
|
+ tempFile.message = '上传中'
|
|
|
+
|
|
|
+ // 上传裁剪后的图片
|
|
|
+ const uploadTask = Taro.uploadFile({
|
|
|
+ url: `${baseBaseUrl}/uploaders?scene=shop`,
|
|
|
+ filePath: (cropResult as any).tempFilePath,
|
|
|
+ name: 'file',
|
|
|
+ success: (res) => {
|
|
|
+ const uploadResult = JSON.parse(res.data)
|
|
|
+ // 移除临时文件
|
|
|
+ goodsImages.value = goodsImages.value.filter(item => item.uid !== tempFile.uid)
|
|
|
+ // 添加上传成功的文件
|
|
|
+ goodsImages.value.push({
|
|
|
+ url: uploadResult.url,
|
|
|
+ uid: file.uid,
|
|
|
+ status: 'success',
|
|
|
+ message: '上传成功',
|
|
|
+ percentage: 100,
|
|
|
+ type: 'image'
|
|
|
+ })
|
|
|
+ },
|
|
|
+ fail: (error) => {
|
|
|
+ console.error('上传失败:', error)
|
|
|
+ tempFile.status = 'error'
|
|
|
+ tempFile.message = '上传失败'
|
|
|
+ tempFile.percentage = 0
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 监听上传进度
|
|
|
+ uploadTask.progress((res) => {
|
|
|
+ tempFile.percentage = 50 + (res.progress / 2) // 50-100%的进度
|
|
|
+ })
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error('处理失败:', error)
|
|
|
+ goodsImages.value = goodsImages.value.filter(item => item.uid !== file.uid)
|
|
|
+ goodsImages.value.push({
|
|
|
+ ...file,
|
|
|
+ status: 'error',
|
|
|
+ message: '处理失败',
|
|
|
+ percentage: 0
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 图片上传成功回调
|
|
|
+ const uploadSucces=({data,option,fileItem})=>{
|
|
|
+ const uploadResult = JSON.parse(data.data)
|
|
|
+ console.log('uploadSucces',uploadResult,option,fileItem)
|
|
|
+ goodsImages.value=goodsImages.value.filter(item=>item.uid!==fileItem.uid)
|
|
|
+ goodsImages.value.push({
|
|
|
+ url: uploadResult.url,
|
|
|
+ uid: fileItem.uid,
|
|
|
+ status: 'success',
|
|
|
+ message: '上传成功',
|
|
|
+ percentage: "100",
|
|
|
+ type: 'image'
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 删除SKU
|
|
|
+ const removeSku=(key)=>{
|
|
|
+ if(formData.sku_list){
|
|
|
+ formData.sku_list= formData.sku_list.filter(item=>item.key!==key)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 失去焦点校验
|
|
|
+ const customBlurValidate = (prop) => {
|
|
|
+ console.log('prop',formRef.value)
|
|
|
+ formRef.value?.validate(prop)
|
|
|
+ formRefSku.value?.validate(prop)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 监听器:处理响应式更新
|
|
|
+ watch(() => formData.category_id, (val) => {
|
|
|
+ // 当分类改变时,加载对应的规格列表
|
|
|
+ loadSpecifications({category_id: val})
|
|
|
+ })
|
|
|
+
|
|
|
+ watch(() => formData.goods_gallery_list, (val) => {
|
|
|
+ // 监听并更新商品图片列表
|
|
|
+ if(val&&val.length>0){
|
|
|
+ goodsImages.value= val?.map(item => {
|
|
|
+ return {
|
|
|
+ url: item.original,
|
|
|
+ uid: item.img_id,
|
|
|
+ status: 'success',
|
|
|
+ message: '上传成功',
|
|
|
+ percentage: "100",
|
|
|
+ type: 'image'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ watch(() => formData.sku_list, (val) => {
|
|
|
+ // 当SKU列表变化时,更新商品总库存
|
|
|
+ if(val&&val.length>0){
|
|
|
+ console.log(val.reduce((prev,cur)=>Number(prev)+Number(cur.quantity??0),0))
|
|
|
+ formData.quantity= val.reduce((prev,cur)=>Number(prev)+Number(cur.quantity??0),0)
|
|
|
+ }
|
|
|
+ }, {deep: true})
|
|
|
+
|
|
|
+ watchEffect(() => {
|
|
|
+ // 反向赋值已选中规格
|
|
|
+ if(formData.sku_list){
|
|
|
+ specSelectValue.value = formData.sku_list.flatMap(item => item.spec_list).map(p => `${p.spec_id}_${p.spec_value_id}`)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 生成规格的笛卡尔积组合
|
|
|
+ function cartesianProduct(obj) {
|
|
|
+ const keys = Object.keys(obj);
|
|
|
+ const result: any = [];
|
|
|
+ // 递归生成笛卡尔积
|
|
|
+ function helper(tempArray, index) {
|
|
|
+ if (index === keys.length) {
|
|
|
+ if(tempArray.length>0){
|
|
|
+ result.push(tempArray);
|
|
|
+ }
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const key = keys[index];
|
|
|
+ const values = obj[key];
|
|
|
+
|
|
|
+ values.forEach(item => {
|
|
|
+ helper([...tempArray, item], index + 1);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ helper([], 0);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 数组分组方法
|
|
|
+ const groupBy = (array, key) => {
|
|
|
+ return array.reduce((result, currentValue) => {
|
|
|
+ // 根据指定键获取值
|
|
|
+ const groupKey = currentValue[key];
|
|
|
+
|
|
|
+ // 如果 result 中还没有这个键,创建一个空数组
|
|
|
+ if (!result[groupKey]) {
|
|
|
+ result[groupKey] = [];
|
|
|
+ }
|
|
|
+ // 将当前元素添加到对应的组中
|
|
|
+ result[groupKey].push(currentValue);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }, {});
|
|
|
+ };
|
|
|
+
|
|
|
+ // 初始化加载分类数据
|
|
|
+ const loadCategories = async () => {
|
|
|
+ const categoryList = useCategoryStoreHook().categoryList
|
|
|
+ if(categoryList.length>0){
|
|
|
+ options.value = categoryList
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const catRootId= useShopStoreHook().currentShop?.shop_type==='2'?0:-1;
|
|
|
+ const {data:categorys} = await getCategoryList(catRootId)
|
|
|
+ options.value=categorys
|
|
|
+ }
|
|
|
+
|
|
|
+ // 初始化加载商品分组数据,如果本地有数据则直接使用本地数据
|
|
|
+ const shopCategoryList = useShopCategoryStoreHook().shopCategoryList
|
|
|
+ if(shopCategoryList.length===0){
|
|
|
+ getShopCatList().then(res=>{
|
|
|
+ shopCatOption.value = res.data
|
|
|
+ useShopCategoryStoreHook().setShopCategoryList(res.data)
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ shopCatOption.value = shopCategoryList
|
|
|
+ }
|
|
|
+
|
|
|
+ // 暂存商品信息,添加规格
|
|
|
+ const goSetSpec=(category_id:number)=>{
|
|
|
+ redirectTo('/subPackageA/pages/product-spec-add/index',{category_id})
|
|
|
+ }
|
|
|
+
|
|
|
+ // 商品详情图片
|
|
|
+ const introImages=ref<string[]>([])
|
|
|
+ // 选择图片
|
|
|
+ const chooseMedia=()=>{
|
|
|
+ Taro.chooseMedia({
|
|
|
+ count: 1,
|
|
|
+ mediaType: ['image'],
|
|
|
+ sourceType: ['album', 'camera'],
|
|
|
+ success: (res) => {
|
|
|
+ Taro.cropImage({ //裁剪图片
|
|
|
+ src: res.tempFiles[0].tempFilePath,
|
|
|
+ cropScale: '9:16', // 裁剪比例
|
|
|
+ success: (rs) => {
|
|
|
+ uploadFile({filePath: rs.tempFilePath, scene: 'shop_logo'}) //上传图片
|
|
|
+ .then(rsd => {
|
|
|
+ console.log(rsd)
|
|
|
+ const data = JSON.parse(rsd.data)
|
|
|
+ introImages.value.push(data.url)
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 图片排序
|
|
|
+ const overlayIndex = ref<number | null>(null);
|
|
|
+ // 显示图片排序
|
|
|
+ const showOverlay = (index: number) => {
|
|
|
+ console.log(index)
|
|
|
+ overlayIndex.value = index;
|
|
|
+ };
|
|
|
+ // 隐藏图片排序
|
|
|
+ const hideOverlay = () => {
|
|
|
+ overlayIndex.value = null;
|
|
|
+ };
|
|
|
+ // 删除图片
|
|
|
+ const deleteImage = (index: number) => {
|
|
|
+ introImages.value.splice(index, 1);
|
|
|
+ }
|
|
|
+ // 上移图片
|
|
|
+ const moveImageUp = (index: number) => {
|
|
|
+ if (index > 0) {
|
|
|
+ const temp = introImages.value[index];
|
|
|
+ introImages.value[index] = introImages.value[index - 1];
|
|
|
+ introImages.value[index - 1] = temp;
|
|
|
+ overlayIndex.value = index - 1;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ // 下移图片
|
|
|
+ const moveImageDown = (index: number) => {
|
|
|
+ if (index < introImages.value.length - 1) {
|
|
|
+ const temp = introImages.value[index];
|
|
|
+ introImages.value[index] = introImages.value[index + 1];
|
|
|
+ introImages.value[index + 1] = temp;
|
|
|
+ overlayIndex.value = index + 1;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ loadCategories();
|
|
|
+
|
|
|
+ return {
|
|
|
+ formData,
|
|
|
+ formRef,
|
|
|
+ formRefSku,
|
|
|
+ customBlurValidate,
|
|
|
+ visible,
|
|
|
+ categoryValue,
|
|
|
+ options,
|
|
|
+ change,
|
|
|
+ shopCatShow,
|
|
|
+ shopCatOption,
|
|
|
+ shopCatValue,
|
|
|
+ fileChange,
|
|
|
+ uploadSucces,
|
|
|
+ shopCatConfirm,
|
|
|
+ publishGood,
|
|
|
+ goodsImages,
|
|
|
+ specChooseVisible,
|
|
|
+ specList,
|
|
|
+ specSelectValue,
|
|
|
+ onOkspecChoose,
|
|
|
+ removeSku,
|
|
|
+ goSetSpec,
|
|
|
+ goodsImagesUploader,
|
|
|
+ chooseMedia,
|
|
|
+ introImages,
|
|
|
+ overlayIndex,
|
|
|
+ showOverlay,
|
|
|
+ hideOverlay,
|
|
|
+ deleteImage,
|
|
|
+ moveImageUp,
|
|
|
+ moveImageDown
|
|
|
+ }
|
|
|
+}
|