|  | @@ -4,7 +4,7 @@
 | 
											
												
													
														|  |  		draggable class="dialog">
 |  |  		draggable class="dialog">
 | 
											
												
													
														|  |  		<template #header="{ close }">
 |  |  		<template #header="{ close }">
 | 
											
												
													
														|  |  			<div class="my-header">
 |  |  			<div class="my-header">
 | 
											
												
													
														|  | -				<div class="my-header-left">{{dialogTitle}}</div>
 |  | 
 | 
											
												
													
														|  | 
 |  | +				<div class="my-header-left">{{ dialogTitle }}</div>
 | 
											
												
													
														|  |  				<div class="my-header-right">
 |  |  				<div class="my-header-right">
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  					<span @click="fullScreen">
 |  |  					<span @click="fullScreen">
 | 
											
										
											
												
													
														|  | @@ -18,7 +18,7 @@
 | 
											
												
													
														|  |  				</div>
 |  |  				</div>
 | 
											
												
													
														|  |  			</div>
 |  |  			</div>
 | 
											
												
													
														|  |  		</template>
 |  |  		</template>
 | 
											
												
													
														|  | -		<ContentWrap v-loading="formLoading">
 |  | 
 | 
											
												
													
														|  | 
 |  | +		<ContentWrap v-loading="formLoading" style="max-height:560px;min-height:560px;overflow-y: auto;">
 | 
											
												
													
														|  |  			<div class="left">
 |  |  			<div class="left">
 | 
											
												
													
														|  |  				<SPuUploadImg v-model="formData.picUrl" :disabled="isDetail" />
 |  |  				<SPuUploadImg v-model="formData.picUrl" :disabled="isDetail" />
 | 
											
												
													
														|  |  				<el-tabs v-model="activeName" tab-position="left" class="child-tabs">
 |  |  				<el-tabs v-model="activeName" tab-position="left" class="child-tabs">
 | 
											
										
											
												
													
														|  | @@ -50,411 +50,411 @@
 | 
											
												
													
														|  |  				</div>
 |  |  				</div>
 | 
											
												
													
														|  |  			</div>
 |  |  			</div>
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -			<el-form style="clear: both;">
 |  | 
 | 
											
												
													
														|  | -				<el-form-item style="float: right">
 |  | 
 | 
											
												
													
														|  | 
 |  | +			<div style="clear: both;"></div>
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -					<!-- 不在回收站的才可以停用 -->
 |  | 
 | 
											
												
													
														|  | -					<el-button v-if="!isDetail && parentTabType!=4 && openType != 'create'" :loading="formLoading"
 |  | 
 | 
											
												
													
														|  | -						type="danger" plain @click="handleStatus02Change(ProductSpuStatusEnum.RECYCLE.status)">
 |  | 
 | 
											
												
													
														|  | 
 |  | +		</ContentWrap>
 | 
											
												
													
														|  | 
 |  | +		<template #footer v-if="!isDetail">
 | 
											
												
													
														|  | 
 |  | +      <div class="dialog-footer">
 | 
											
												
													
														|  | 
 |  | +        <el-button v-if="!isDetail && parentTabType != 4 && openType != 'create'" :loading="formLoading" type="danger"
 | 
											
												
													
														|  | 
 |  | +						plain @click="handleStatus02Change(ProductSpuStatusEnum.RECYCLE.status)">
 | 
											
												
													
														|  |  						停用
 |  |  						停用
 | 
											
												
													
														|  |  					</el-button>
 |  |  					</el-button>
 | 
											
												
													
														|  |  					<!-- 在回收站的可以选择恢复或者删除 -->
 |  |  					<!-- 在回收站的可以选择恢复或者删除 -->
 | 
											
												
													
														|  | -					<el-button v-if="!isDetail && parentTabType==4" :loading="formLoading"
 |  | 
 | 
											
												
													
														|  | -						v-hasPermi="['product:spu:delete']" type="danger" plain @click="handleDelete(productId)">
 |  | 
 | 
											
												
													
														|  | 
 |  | +					<el-button v-if="!isDetail && parentTabType == 4" :loading="formLoading" v-hasPermi="['product:spu:delete']"
 | 
											
												
													
														|  | 
 |  | +						type="danger" plain @click="handleDelete(productId)">
 | 
											
												
													
														|  |  						删除
 |  |  						删除
 | 
											
												
													
														|  |  					</el-button>
 |  |  					</el-button>
 | 
											
												
													
														|  | -					<el-button v-if="!isDetail && parentTabType==4" :loading="formLoading"
 |  | 
 | 
											
												
													
														|  | -						v-hasPermi="['product:spu:update']" type="primary"
 |  | 
 | 
											
												
													
														|  | -						@click="handleStatus02Change(ProductSpuStatusEnum.DISABLE.status)">
 |  | 
 | 
											
												
													
														|  | 
 |  | +					<el-button v-if="!isDetail && parentTabType == 4" :loading="formLoading" v-hasPermi="['product:spu:update']"
 | 
											
												
													
														|  | 
 |  | +						type="primary" @click="handleStatus02Change(ProductSpuStatusEnum.DISABLE.status)">
 | 
											
												
													
														|  |  						恢复
 |  |  						恢复
 | 
											
												
													
														|  |  					</el-button>
 |  |  					</el-button>
 | 
											
												
													
														|  |  					<el-button v-if="!isDetail && openType != 'create'" :loading="formLoading" type="primary"
 |  |  					<el-button v-if="!isDetail && openType != 'create'" :loading="formLoading" type="primary"
 | 
											
												
													
														|  |  						@click="handleStatusChange">
 |  |  						@click="handleStatusChange">
 | 
											
												
													
														|  | -						{{parentRow.status == 0 ?"上架":"下架"}}
 |  | 
 | 
											
												
													
														|  | 
 |  | +						{{ parentRow.status == 0 ? "上架" : "下架" }}
 | 
											
												
													
														|  |  					</el-button>
 |  |  					</el-button>
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  |  					<el-button v-if="!isDetail" :loading="formLoading" type="primary" @click="submitForm">
 |  |  					<el-button v-if="!isDetail" :loading="formLoading" type="primary" @click="submitForm">
 | 
											
												
													
														|  |  						保存
 |  |  						保存
 | 
											
												
													
														|  |  					</el-button>
 |  |  					</el-button>
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -				</el-form-item>
 |  | 
 | 
											
												
													
														|  | -			</el-form>
 |  | 
 | 
											
												
													
														|  | -		</ContentWrap>
 |  | 
 | 
											
												
													
														|  | 
 |  | +      </div>
 | 
											
												
													
														|  | 
 |  | +    </template>
 | 
											
												
													
														|  |  	</el-dialog>
 |  |  	</el-dialog>
 | 
											
												
													
														|  |  	<!-- </div> -->
 |  |  	<!-- </div> -->
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  </template>
 |  |  </template>
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  |  <script lang="ts" setup>
 |  |  <script lang="ts" setup>
 | 
											
												
													
														|  | -	import { cloneDeep } from 'lodash-es'
 |  | 
 | 
											
												
													
														|  | -	import { useTagsViewStore } from '@/store/modules/tagsView'
 |  | 
 | 
											
												
													
														|  | -	import * as ProductSpuApi from '@/api/mall/product/spu'
 |  | 
 | 
											
												
													
														|  | -	import InfoForm from './InfoForm.vue'
 |  | 
 | 
											
												
													
														|  | -	import DescriptionForm from './DescriptionForm.vue'
 |  | 
 | 
											
												
													
														|  | -	import OtherForm from './OtherForm.vue'
 |  | 
 | 
											
												
													
														|  | -	import SkuForm from './SkuForm.vue'
 |  | 
 | 
											
												
													
														|  | -	import DeliveryForm from './DeliveryForm.vue'
 |  | 
 | 
											
												
													
														|  | -	import { convertToInteger, floatToFixed2, formatToFraction } from '@/utils'
 |  | 
 | 
											
												
													
														|  | -	import {
 |  | 
 | 
											
												
													
														|  | -		Close,
 |  | 
 | 
											
												
													
														|  | -		FullScreen
 |  | 
 | 
											
												
													
														|  | -	} from '@element-plus/icons-vue'
 |  | 
 | 
											
												
													
														|  | -	import { Icon } from '@/components/Icon'
 |  | 
 | 
											
												
													
														|  | -	import { ProductSpuStatusEnum } from '@/utils/constants'
 |  | 
 | 
											
												
													
														|  | -	defineOptions({ name: 'ProductSpuForm' })
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -	const { t } = useI18n() // 国际化
 |  | 
 | 
											
												
													
														|  | -	const message = useMessage() // 消息弹窗
 |  | 
 | 
											
												
													
														|  | -	const { push, currentRoute } = useRouter() // 路由
 |  | 
 | 
											
												
													
														|  | -	const { params, name } = useRoute() // 查询参数
 |  | 
 | 
											
												
													
														|  | -	const { delView } = useTagsViewStore() // 视图操作
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -	const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 |  | 
 | 
											
												
													
														|  | -	const activeName = ref('info') // Tag 激活的窗口
 |  | 
 | 
											
												
													
														|  | -	const isDetail = ref(false) // 是否查看详情
 |  | 
 | 
											
												
													
														|  | -	const infoRef = ref() // 商品信息 Ref
 |  | 
 | 
											
												
													
														|  | -	const skuRef = ref() // 商品规格 Ref
 |  | 
 | 
											
												
													
														|  | -	const deliveryRef = ref() // 物流设置 Ref
 |  | 
 | 
											
												
													
														|  | -	const descriptionRef = ref() // 商品详情 Ref
 |  | 
 | 
											
												
													
														|  | -	const otherRef = ref() // 其他设置 Ref
 |  | 
 | 
											
												
													
														|  | -	// SPU 表单数据
 |  | 
 | 
											
												
													
														|  | -	const formData = ref<ProductSpuApi.Spu>({
 |  | 
 | 
											
												
													
														|  | -		name: '', // 商品名称
 |  | 
 | 
											
												
													
														|  | -		categoryId: undefined, // 商品分类
 |  | 
 | 
											
												
													
														|  | -		keyword: '', // 关键字
 |  | 
 | 
											
												
													
														|  | -		picUrl: '', // 商品封面图
 |  | 
 | 
											
												
													
														|  | -		sliderPicUrls: [], // 商品轮播图
 |  | 
 | 
											
												
													
														|  | -		introduction: '', // 商品简介
 |  | 
 | 
											
												
													
														|  | -		deliveryTypes: [], // 配送方式数组
 |  | 
 | 
											
												
													
														|  | -		deliveryTemplateId: undefined, // 运费模版
 |  | 
 | 
											
												
													
														|  | -		brandId: undefined, // 商品品牌
 |  | 
 | 
											
												
													
														|  | -		specType: false, // 商品规格
 |  | 
 | 
											
												
													
														|  | -		subCommissionType: false, // 分销类型
 |  | 
 | 
											
												
													
														|  | -		skus: [
 |  | 
 | 
											
												
													
														|  | -			{
 |  | 
 | 
											
												
													
														|  | -				price: 0, // 商品价格
 |  | 
 | 
											
												
													
														|  | -				marketPrice: 0, // 市场价
 |  | 
 | 
											
												
													
														|  | -				costPrice: 0, // 成本价
 |  | 
 | 
											
												
													
														|  | -				barCode: '', // 商品条码
 |  | 
 | 
											
												
													
														|  | -				picUrl: '', // 图片地址
 |  | 
 | 
											
												
													
														|  | -				stock: 0, // 库存
 |  | 
 | 
											
												
													
														|  | -				weight: 0, // 商品重量
 |  | 
 | 
											
												
													
														|  | -				volume: 0, // 商品体积
 |  | 
 | 
											
												
													
														|  | -				firstBrokeragePrice: 0, // 一级分销的佣金
 |  | 
 | 
											
												
													
														|  | -				secondBrokeragePrice: 0 // 二级分销的佣金
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | -		],
 |  | 
 | 
											
												
													
														|  | -		description: '', // 商品详情
 |  | 
 | 
											
												
													
														|  | -		sort: 0, // 商品排序
 |  | 
 | 
											
												
													
														|  | -		giveIntegral: 0, // 赠送积分
 |  | 
 | 
											
												
													
														|  | -		virtualSalesCount: 0 // 虚拟销量
 |  | 
 | 
											
												
													
														|  | -	})
 |  | 
 | 
											
												
													
														|  | -	const addFormData = ref<ProductSpuApi.Spu>({
 |  | 
 | 
											
												
													
														|  | -		name: '', // 商品名称
 |  | 
 | 
											
												
													
														|  | -		categoryId: undefined, // 商品分类
 |  | 
 | 
											
												
													
														|  | -		keyword: '', // 关键字
 |  | 
 | 
											
												
													
														|  | -		picUrl: '', // 商品封面图
 |  | 
 | 
											
												
													
														|  | -		sliderPicUrls: [], // 商品轮播图
 |  | 
 | 
											
												
													
														|  | -		introduction: '', // 商品简介
 |  | 
 | 
											
												
													
														|  | -		deliveryTypes: [], // 配送方式数组
 |  | 
 | 
											
												
													
														|  | -		deliveryTemplateId: undefined, // 运费模版
 |  | 
 | 
											
												
													
														|  | -		brandId: undefined, // 商品品牌
 |  | 
 | 
											
												
													
														|  | -		specType: false, // 商品规格
 |  | 
 | 
											
												
													
														|  | -		subCommissionType: false, // 分销类型
 |  | 
 | 
											
												
													
														|  | -		skus: [
 |  | 
 | 
											
												
													
														|  | -			{
 |  | 
 | 
											
												
													
														|  | -				price: 0, // 商品价格
 |  | 
 | 
											
												
													
														|  | -				marketPrice: 0, // 市场价
 |  | 
 | 
											
												
													
														|  | -				costPrice: 0, // 成本价
 |  | 
 | 
											
												
													
														|  | -				barCode: '', // 商品条码
 |  | 
 | 
											
												
													
														|  | -				picUrl: '', // 图片地址
 |  | 
 | 
											
												
													
														|  | -				stock: 0, // 库存
 |  | 
 | 
											
												
													
														|  | -				weight: 0, // 商品重量
 |  | 
 | 
											
												
													
														|  | -				volume: 0, // 商品体积
 |  | 
 | 
											
												
													
														|  | -				firstBrokeragePrice: 0, // 一级分销的佣金
 |  | 
 | 
											
												
													
														|  | -				secondBrokeragePrice: 0 // 二级分销的佣金
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | -		],
 |  | 
 | 
											
												
													
														|  | -		description: '', // 商品详情
 |  | 
 | 
											
												
													
														|  | -		sort: 0, // 商品排序
 |  | 
 | 
											
												
													
														|  | -		giveIntegral: 0, // 赠送积分
 |  | 
 | 
											
												
													
														|  | -		virtualSalesCount: 0 // 虚拟销量
 |  | 
 | 
											
												
													
														|  | -	})
 |  | 
 | 
											
												
													
														|  | -	const dialogVisible = ref(false) // 弹窗的是否展示
 |  | 
 | 
											
												
													
														|  | -	const dialogTitle = ref('') // 弹窗的标题
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -	const parentTabType = ref(0)
 |  | 
 | 
											
												
													
														|  | -	const productId = ref()
 |  | 
 | 
											
												
													
														|  | -	const picUrl = ref("")
 |  | 
 | 
											
												
													
														|  | -	const parentRow = ref()
 |  | 
 | 
											
												
													
														|  | -	const openType = ref("")
 |  | 
 | 
											
												
													
														|  | -	const parentNewStatus = ref(0)
 |  | 
 | 
											
												
													
														|  | -	const isFullScreen = ref(false)
 |  | 
 | 
											
												
													
														|  | -	// const handleError = (e) => {
 |  | 
 | 
											
												
													
														|  | -	// 	e.target.src = "https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"
 |  | 
 | 
											
												
													
														|  | -	// }
 |  | 
 | 
											
												
													
														|  | -	/** 打开弹窗 */
 |  | 
 | 
											
												
													
														|  | -	const open = async (type : string, row : any, newStatus : number, tabType : number) => {
 |  | 
 | 
											
												
													
														|  | -		parentTabType.value = tabType
 |  | 
 | 
											
												
													
														|  | -		parentRow.value = row
 |  | 
 | 
											
												
													
														|  | -		parentNewStatus.value = newStatus
 |  | 
 | 
											
												
													
														|  | -		dialogVisible.value = true
 |  | 
 | 
											
												
													
														|  | -		productId.value = row.id
 |  | 
 | 
											
												
													
														|  | -		picUrl.value = row.picUrl
 |  | 
 | 
											
												
													
														|  | -		isFullScreen.value = false
 |  | 
 | 
											
												
													
														|  | -		await getDetail()
 |  | 
 | 
											
												
													
														|  | -		activeName.value = 'info'
 |  | 
 | 
											
												
													
														|  | -		openType.value = type
 |  | 
 | 
											
												
													
														|  | -		dialogTitle.value = t('action.' + type)
 |  | 
 | 
											
												
													
														|  | -		if (type == "view") {
 |  | 
 | 
											
												
													
														|  | -			dialogTitle.value = "查看"
 |  | 
 | 
											
												
													
														|  | -		} else if (type == "create") {
 |  | 
 | 
											
												
													
														|  | -			formData.value = cloneDeep(addFormData.value)
 |  | 
 | 
											
												
													
														|  | -			// console.log(formData.value)
 |  | 
 | 
											
												
													
														|  | -			// console.log(addFormData.value)
 |  | 
 | 
											
												
													
														|  | 
 |  | +import { cloneDeep } from 'lodash-es'
 | 
											
												
													
														|  | 
 |  | +import { useTagsViewStore } from '@/store/modules/tagsView'
 | 
											
												
													
														|  | 
 |  | +import * as ProductSpuApi from '@/api/mall/product/spu'
 | 
											
												
													
														|  | 
 |  | +import InfoForm from './InfoForm.vue'
 | 
											
												
													
														|  | 
 |  | +import DescriptionForm from './DescriptionForm.vue'
 | 
											
												
													
														|  | 
 |  | +import OtherForm from './OtherForm.vue'
 | 
											
												
													
														|  | 
 |  | +import SkuForm from './SkuForm.vue'
 | 
											
												
													
														|  | 
 |  | +import DeliveryForm from './DeliveryForm.vue'
 | 
											
												
													
														|  | 
 |  | +import { convertToInteger, floatToFixed2, formatToFraction } from '@/utils'
 | 
											
												
													
														|  | 
 |  | +import {
 | 
											
												
													
														|  | 
 |  | +	Close,
 | 
											
												
													
														|  | 
 |  | +	FullScreen
 | 
											
												
													
														|  | 
 |  | +} from '@element-plus/icons-vue'
 | 
											
												
													
														|  | 
 |  | +import { Icon } from '@/components/Icon'
 | 
											
												
													
														|  | 
 |  | +import { ProductSpuStatusEnum } from '@/utils/constants'
 | 
											
												
													
														|  | 
 |  | +defineOptions({ name: 'ProductSpuForm' })
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const { t } = useI18n() // 国际化
 | 
											
												
													
														|  | 
 |  | +const message = useMessage() // 消息弹窗
 | 
											
												
													
														|  | 
 |  | +const { push, currentRoute } = useRouter() // 路由
 | 
											
												
													
														|  | 
 |  | +const { params, name } = useRoute() // 查询参数
 | 
											
												
													
														|  | 
 |  | +const { delView } = useTagsViewStore() // 视图操作
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
 | 
											
												
													
														|  | 
 |  | +const activeName = ref('info') // Tag 激活的窗口
 | 
											
												
													
														|  | 
 |  | +const isDetail = ref(false) // 是否查看详情
 | 
											
												
													
														|  | 
 |  | +const infoRef = ref() // 商品信息 Ref
 | 
											
												
													
														|  | 
 |  | +const skuRef = ref() // 商品规格 Ref
 | 
											
												
													
														|  | 
 |  | +const deliveryRef = ref() // 物流设置 Ref
 | 
											
												
													
														|  | 
 |  | +const descriptionRef = ref() // 商品详情 Ref
 | 
											
												
													
														|  | 
 |  | +const otherRef = ref() // 其他设置 Ref
 | 
											
												
													
														|  | 
 |  | +// SPU 表单数据
 | 
											
												
													
														|  | 
 |  | +const formData = ref<ProductSpuApi.Spu>({
 | 
											
												
													
														|  | 
 |  | +	name: '', // 商品名称
 | 
											
												
													
														|  | 
 |  | +	categoryId: undefined, // 商品分类
 | 
											
												
													
														|  | 
 |  | +	keyword: '', // 关键字
 | 
											
												
													
														|  | 
 |  | +	picUrl: '', // 商品封面图
 | 
											
												
													
														|  | 
 |  | +	sliderPicUrls: [], // 商品轮播图
 | 
											
												
													
														|  | 
 |  | +	introduction: '', // 商品简介
 | 
											
												
													
														|  | 
 |  | +	deliveryTypes: [], // 配送方式数组
 | 
											
												
													
														|  | 
 |  | +	deliveryTemplateId: undefined, // 运费模版
 | 
											
												
													
														|  | 
 |  | +	brandId: undefined, // 商品品牌
 | 
											
												
													
														|  | 
 |  | +	specType: false, // 商品规格
 | 
											
												
													
														|  | 
 |  | +	subCommissionType: false, // 分销类型
 | 
											
												
													
														|  | 
 |  | +	skus: [
 | 
											
												
													
														|  | 
 |  | +		{
 | 
											
												
													
														|  | 
 |  | +			price: 0, // 商品价格
 | 
											
												
													
														|  | 
 |  | +			marketPrice: 0, // 市场价
 | 
											
												
													
														|  | 
 |  | +			costPrice: 0, // 成本价
 | 
											
												
													
														|  | 
 |  | +			barCode: '', // 商品条码
 | 
											
												
													
														|  | 
 |  | +			picUrl: '', // 图片地址
 | 
											
												
													
														|  | 
 |  | +			stock: 0, // 库存
 | 
											
												
													
														|  | 
 |  | +			weight: 0, // 商品重量
 | 
											
												
													
														|  | 
 |  | +			volume: 0, // 商品体积
 | 
											
												
													
														|  | 
 |  | +			firstBrokeragePrice: 0, // 一级分销的佣金
 | 
											
												
													
														|  | 
 |  | +			secondBrokeragePrice: 0 // 二级分销的佣金
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -		// 判断打开状态,如果是view那就只能查看 否则可以编辑
 |  | 
 | 
											
												
													
														|  | -		if ('view' == openType.value) {
 |  | 
 | 
											
												
													
														|  | -			isDetail.value = true
 |  | 
 | 
											
												
													
														|  | -		} else {
 |  | 
 | 
											
												
													
														|  | -			isDetail.value = false
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -	//全屏/取消全屏弹窗
 |  | 
 | 
											
												
													
														|  | -	const fullScreen = () => {
 |  | 
 | 
											
												
													
														|  | -		isFullScreen.value = !isFullScreen.value
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	/** 获得详情 */
 |  | 
 | 
											
												
													
														|  | -	const getDetail = async () => {
 |  | 
 | 
											
												
													
														|  | -		console.log(productId.value)
 |  | 
 | 
											
												
													
														|  | -		const id = productId.value as any as number
 |  | 
 | 
											
												
													
														|  | -		if (id) {
 |  | 
 | 
											
												
													
														|  | -			formLoading.value = true
 |  | 
 | 
											
												
													
														|  | -			try {
 |  | 
 | 
											
												
													
														|  | -				const res = (await ProductSpuApi.getSpu(id)) as ProductSpuApi.Spu
 |  | 
 | 
											
												
													
														|  | -				res.skus?.forEach((item) => {
 |  | 
 | 
											
												
													
														|  | -					if (isDetail.value) {
 |  | 
 | 
											
												
													
														|  | -						item.price = floatToFixed2(item.price)
 |  | 
 | 
											
												
													
														|  | -						item.marketPrice = floatToFixed2(item.marketPrice)
 |  | 
 | 
											
												
													
														|  | -						item.costPrice = floatToFixed2(item.costPrice)
 |  | 
 | 
											
												
													
														|  | -						item.firstBrokeragePrice = floatToFixed2(item.firstBrokeragePrice)
 |  | 
 | 
											
												
													
														|  | -						item.secondBrokeragePrice = floatToFixed2(item.secondBrokeragePrice)
 |  | 
 | 
											
												
													
														|  | -					} else {
 |  | 
 | 
											
												
													
														|  | -						// 回显价格分转元
 |  | 
 | 
											
												
													
														|  | -						item.price = formatToFraction(item.price)
 |  | 
 | 
											
												
													
														|  | -						item.marketPrice = formatToFraction(item.marketPrice)
 |  | 
 | 
											
												
													
														|  | -						item.costPrice = formatToFraction(item.costPrice)
 |  | 
 | 
											
												
													
														|  | -						item.firstBrokeragePrice = formatToFraction(item.firstBrokeragePrice)
 |  | 
 | 
											
												
													
														|  | -						item.secondBrokeragePrice = formatToFraction(item.secondBrokeragePrice)
 |  | 
 | 
											
												
													
														|  | -					}
 |  | 
 | 
											
												
													
														|  | -				})
 |  | 
 | 
											
												
													
														|  | -				formData.value = res
 |  | 
 | 
											
												
													
														|  | -			} finally {
 |  | 
 | 
											
												
													
														|  | -				formLoading.value = false
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | 
 |  | +	],
 | 
											
												
													
														|  | 
 |  | +	description: '', // 商品详情
 | 
											
												
													
														|  | 
 |  | +	sort: 0, // 商品排序
 | 
											
												
													
														|  | 
 |  | +	giveIntegral: 0, // 赠送积分
 | 
											
												
													
														|  | 
 |  | +	virtualSalesCount: 0 // 虚拟销量
 | 
											
												
													
														|  | 
 |  | +})
 | 
											
												
													
														|  | 
 |  | +const addFormData = ref<ProductSpuApi.Spu>({
 | 
											
												
													
														|  | 
 |  | +	name: '', // 商品名称
 | 
											
												
													
														|  | 
 |  | +	categoryId: undefined, // 商品分类
 | 
											
												
													
														|  | 
 |  | +	keyword: '', // 关键字
 | 
											
												
													
														|  | 
 |  | +	picUrl: '', // 商品封面图
 | 
											
												
													
														|  | 
 |  | +	sliderPicUrls: [], // 商品轮播图
 | 
											
												
													
														|  | 
 |  | +	introduction: '', // 商品简介
 | 
											
												
													
														|  | 
 |  | +	deliveryTypes: [], // 配送方式数组
 | 
											
												
													
														|  | 
 |  | +	deliveryTemplateId: undefined, // 运费模版
 | 
											
												
													
														|  | 
 |  | +	brandId: undefined, // 商品品牌
 | 
											
												
													
														|  | 
 |  | +	specType: false, // 商品规格
 | 
											
												
													
														|  | 
 |  | +	subCommissionType: false, // 分销类型
 | 
											
												
													
														|  | 
 |  | +	skus: [
 | 
											
												
													
														|  | 
 |  | +		{
 | 
											
												
													
														|  | 
 |  | +			price: 0, // 商品价格
 | 
											
												
													
														|  | 
 |  | +			marketPrice: 0, // 市场价
 | 
											
												
													
														|  | 
 |  | +			costPrice: 0, // 成本价
 | 
											
												
													
														|  | 
 |  | +			barCode: '', // 商品条码
 | 
											
												
													
														|  | 
 |  | +			picUrl: '', // 图片地址
 | 
											
												
													
														|  | 
 |  | +			stock: 0, // 库存
 | 
											
												
													
														|  | 
 |  | +			weight: 0, // 商品重量
 | 
											
												
													
														|  | 
 |  | +			volume: 0, // 商品体积
 | 
											
												
													
														|  | 
 |  | +			firstBrokeragePrice: 0, // 一级分销的佣金
 | 
											
												
													
														|  | 
 |  | +			secondBrokeragePrice: 0 // 二级分销的佣金
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | 
 |  | +	],
 | 
											
												
													
														|  | 
 |  | +	description: '', // 商品详情
 | 
											
												
													
														|  | 
 |  | +	sort: 0, // 商品排序
 | 
											
												
													
														|  | 
 |  | +	giveIntegral: 0, // 赠送积分
 | 
											
												
													
														|  | 
 |  | +	virtualSalesCount: 0 // 虚拟销量
 | 
											
												
													
														|  | 
 |  | +})
 | 
											
												
													
														|  | 
 |  | +const dialogVisible = ref(false) // 弹窗的是否展示
 | 
											
												
													
														|  | 
 |  | +const dialogTitle = ref('') // 弹窗的标题
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +const parentTabType = ref(0)
 | 
											
												
													
														|  | 
 |  | +const productId = ref()
 | 
											
												
													
														|  | 
 |  | +const picUrl = ref("")
 | 
											
												
													
														|  | 
 |  | +const parentRow = ref()
 | 
											
												
													
														|  | 
 |  | +const openType = ref("")
 | 
											
												
													
														|  | 
 |  | +const parentNewStatus = ref(0)
 | 
											
												
													
														|  | 
 |  | +const isFullScreen = ref(false)
 | 
											
												
													
														|  | 
 |  | +// const handleError = (e) => {
 | 
											
												
													
														|  | 
 |  | +// 	e.target.src = "https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"
 | 
											
												
													
														|  | 
 |  | +// }
 | 
											
												
													
														|  | 
 |  | +/** 打开弹窗 */
 | 
											
												
													
														|  | 
 |  | +const open = async (type: string, row: any, newStatus: number, tabType: number) => {
 | 
											
												
													
														|  | 
 |  | +	parentTabType.value = tabType
 | 
											
												
													
														|  | 
 |  | +	parentRow.value = row
 | 
											
												
													
														|  | 
 |  | +	parentNewStatus.value = newStatus
 | 
											
												
													
														|  | 
 |  | +	dialogVisible.value = true
 | 
											
												
													
														|  | 
 |  | +	productId.value = row.id
 | 
											
												
													
														|  | 
 |  | +	picUrl.value = row.picUrl
 | 
											
												
													
														|  | 
 |  | +	isFullScreen.value = false
 | 
											
												
													
														|  | 
 |  | +	await getDetail()
 | 
											
												
													
														|  | 
 |  | +	activeName.value = 'info'
 | 
											
												
													
														|  | 
 |  | +	openType.value = type
 | 
											
												
													
														|  | 
 |  | +	dialogTitle.value = t('action.' + type)
 | 
											
												
													
														|  | 
 |  | +	if (type == "view") {
 | 
											
												
													
														|  | 
 |  | +		dialogTitle.value = "查看"
 | 
											
												
													
														|  | 
 |  | +	} else if (type == "create") {
 | 
											
												
													
														|  | 
 |  | +		formData.value = cloneDeep(addFormData.value)
 | 
											
												
													
														|  | 
 |  | +		// console.log(formData.value)
 | 
											
												
													
														|  | 
 |  | +		// console.log(addFormData.value)
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | -	const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 |  | 
 | 
											
												
													
														|  | -	/** 添加到仓库 / 回收站的状态 */
 |  | 
 | 
											
												
													
														|  | -	const handleStatus02Change = async (newStatus : number) => {
 |  | 
 | 
											
												
													
														|  | -		try {
 |  | 
 | 
											
												
													
														|  | -			// 二次确认
 |  | 
 | 
											
												
													
														|  | -			const text = newStatus === ProductSpuStatusEnum.RECYCLE.status ? '加入到回收站' : '恢复到仓库'
 |  | 
 | 
											
												
													
														|  | -			await message.confirm(`确认要"${parentRow.value.name}"${text}吗?`)
 |  | 
 | 
											
												
													
														|  | -			// 发起修改
 |  | 
 | 
											
												
													
														|  | -			await ProductSpuApi.updateStatus({ id: parentRow.value.id, status: newStatus })
 |  | 
 | 
											
												
													
														|  | -			message.success(text + '成功')
 |  | 
 | 
											
												
													
														|  | -			// 刷新 tabs 数据
 |  | 
 | 
											
												
													
														|  | -			// await getTabsCount()
 |  | 
 | 
											
												
													
														|  | -			// 刷新列表
 |  | 
 | 
											
												
													
														|  | -			close()
 |  | 
 | 
											
												
													
														|  | -			emit('success')
 |  | 
 | 
											
												
													
														|  | -		} catch { }
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	/** 删除按钮操作 */
 |  | 
 | 
											
												
													
														|  | -	const handleDelete = async (id : number) => {
 |  | 
 | 
											
												
													
														|  | -		try {
 |  | 
 | 
											
												
													
														|  | -			// 删除的二次确认
 |  | 
 | 
											
												
													
														|  | -			await message.delConfirm()
 |  | 
 | 
											
												
													
														|  | -			// 发起删除
 |  | 
 | 
											
												
													
														|  | -			await ProductSpuApi.deleteSpu(id)
 |  | 
 | 
											
												
													
														|  | -			message.success(t('common.delSuccess'))
 |  | 
 | 
											
												
													
														|  | -			close()
 |  | 
 | 
											
												
													
														|  | -			emit('success')
 |  | 
 | 
											
												
													
														|  | -		} catch { }
 |  | 
 | 
											
												
													
														|  | 
 |  | +	// 判断打开状态,如果是view那就只能查看 否则可以编辑
 | 
											
												
													
														|  | 
 |  | +	if ('view' == openType.value) {
 | 
											
												
													
														|  | 
 |  | +		isDetail.value = true
 | 
											
												
													
														|  | 
 |  | +	} else {
 | 
											
												
													
														|  | 
 |  | +		isDetail.value = false
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | -	/** 更新上架/下架状态 */
 |  | 
 | 
											
												
													
														|  | -	const handleStatusChange = async () => {
 |  | 
 | 
											
												
													
														|  | -		console.log(parentRow.value.status)
 |  | 
 | 
											
												
													
														|  | -		try {
 |  | 
 | 
											
												
													
														|  | -			// 二次确认
 |  | 
 | 
											
												
													
														|  | -			const text = !parentRow.value.status ? '上架' : '下架'
 |  | 
 | 
											
												
													
														|  | -			const updateStatus = !parentRow.value.status ? 1 : 0
 |  | 
 | 
											
												
													
														|  | -			await message.confirm(`确认要${text}"${parentRow.value.name}"吗?`)
 |  | 
 | 
											
												
													
														|  | -			// 发起修改
 |  | 
 | 
											
												
													
														|  | -			await ProductSpuApi.updateStatus({ id: parentRow.value.id, status: updateStatus })
 |  | 
 | 
											
												
													
														|  | -			message.success(text + '成功')
 |  | 
 | 
											
												
													
														|  | -			close()
 |  | 
 | 
											
												
													
														|  | -			emit('success')
 |  | 
 | 
											
												
													
														|  | -		} catch {
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -	/** 提交按钮 */
 |  | 
 | 
											
												
													
														|  | -	const submitForm = async () => {
 |  | 
 | 
											
												
													
														|  | -		// 提交请求
 |  | 
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +//全屏/取消全屏弹窗
 | 
											
												
													
														|  | 
 |  | +const fullScreen = () => {
 | 
											
												
													
														|  | 
 |  | +	isFullScreen.value = !isFullScreen.value
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +/** 获得详情 */
 | 
											
												
													
														|  | 
 |  | +const getDetail = async () => {
 | 
											
												
													
														|  | 
 |  | +	console.log(productId.value)
 | 
											
												
													
														|  | 
 |  | +	const id = productId.value as any as number
 | 
											
												
													
														|  | 
 |  | +	if (id) {
 | 
											
												
													
														|  |  		formLoading.value = true
 |  |  		formLoading.value = true
 | 
											
												
													
														|  |  		try {
 |  |  		try {
 | 
											
												
													
														|  | -			// 校验各表单
 |  | 
 | 
											
												
													
														|  | -			await unref(infoRef)?.validate()
 |  | 
 | 
											
												
													
														|  | -			await unref(skuRef)?.validate()
 |  | 
 | 
											
												
													
														|  | -			await unref(deliveryRef)?.validate()
 |  | 
 | 
											
												
													
														|  | -			await unref(descriptionRef)?.validate()
 |  | 
 | 
											
												
													
														|  | -			await unref(otherRef)?.validate()
 |  | 
 | 
											
												
													
														|  | -			// 深拷贝一份, 这样最终 server 端不满足,不需要影响原始数据
 |  | 
 | 
											
												
													
														|  | -			const deepCopyFormData = cloneDeep(unref(formData.value)) as ProductSpuApi.Spu
 |  | 
 | 
											
												
													
														|  | -			deepCopyFormData.skus!.forEach((item) => {
 |  | 
 | 
											
												
													
														|  | -				// 给sku name赋值
 |  | 
 | 
											
												
													
														|  | -				item.name = deepCopyFormData.name
 |  | 
 | 
											
												
													
														|  | -				// sku相关价格元转分
 |  | 
 | 
											
												
													
														|  | -				item.price = convertToInteger(item.price)
 |  | 
 | 
											
												
													
														|  | -				item.marketPrice = convertToInteger(item.marketPrice)
 |  | 
 | 
											
												
													
														|  | -				item.costPrice = convertToInteger(item.costPrice)
 |  | 
 | 
											
												
													
														|  | -				item.firstBrokeragePrice = convertToInteger(item.firstBrokeragePrice)
 |  | 
 | 
											
												
													
														|  | -				item.secondBrokeragePrice = convertToInteger(item.secondBrokeragePrice)
 |  | 
 | 
											
												
													
														|  | -			})
 |  | 
 | 
											
												
													
														|  | -			// 处理轮播图列表
 |  | 
 | 
											
												
													
														|  | -			const newSliderPicUrls : any[] = []
 |  | 
 | 
											
												
													
														|  | -			deepCopyFormData.sliderPicUrls!.forEach((item : any) => {
 |  | 
 | 
											
												
													
														|  | -				// 如果是前端选的图
 |  | 
 | 
											
												
													
														|  | -				typeof item === 'object' ? newSliderPicUrls.push(item.url) : newSliderPicUrls.push(item)
 |  | 
 | 
											
												
													
														|  | 
 |  | +			const res = (await ProductSpuApi.getSpu(id)) as ProductSpuApi.Spu
 | 
											
												
													
														|  | 
 |  | +			res.skus?.forEach((item) => {
 | 
											
												
													
														|  | 
 |  | +				if (isDetail.value) {
 | 
											
												
													
														|  | 
 |  | +					item.price = floatToFixed2(item.price)
 | 
											
												
													
														|  | 
 |  | +					item.marketPrice = floatToFixed2(item.marketPrice)
 | 
											
												
													
														|  | 
 |  | +					item.costPrice = floatToFixed2(item.costPrice)
 | 
											
												
													
														|  | 
 |  | +					item.firstBrokeragePrice = floatToFixed2(item.firstBrokeragePrice)
 | 
											
												
													
														|  | 
 |  | +					item.secondBrokeragePrice = floatToFixed2(item.secondBrokeragePrice)
 | 
											
												
													
														|  | 
 |  | +				} else {
 | 
											
												
													
														|  | 
 |  | +					// 回显价格分转元
 | 
											
												
													
														|  | 
 |  | +					item.price = formatToFraction(item.price)
 | 
											
												
													
														|  | 
 |  | +					item.marketPrice = formatToFraction(item.marketPrice)
 | 
											
												
													
														|  | 
 |  | +					item.costPrice = formatToFraction(item.costPrice)
 | 
											
												
													
														|  | 
 |  | +					item.firstBrokeragePrice = formatToFraction(item.firstBrokeragePrice)
 | 
											
												
													
														|  | 
 |  | +					item.secondBrokeragePrice = formatToFraction(item.secondBrokeragePrice)
 | 
											
												
													
														|  | 
 |  | +				}
 | 
											
												
													
														|  |  			})
 |  |  			})
 | 
											
												
													
														|  | -			deepCopyFormData.sliderPicUrls = newSliderPicUrls
 |  | 
 | 
											
												
													
														|  | -			// 校验都通过后提交表单
 |  | 
 | 
											
												
													
														|  | -			const data = deepCopyFormData as ProductSpuApi.Spu
 |  | 
 | 
											
												
													
														|  | -			const id = productId.value as any as number
 |  | 
 | 
											
												
													
														|  | -			if (!id) {
 |  | 
 | 
											
												
													
														|  | -				await ProductSpuApi.createSpu(data)
 |  | 
 | 
											
												
													
														|  | -				message.success(t('common.createSuccess'))
 |  | 
 | 
											
												
													
														|  | -			} else {
 |  | 
 | 
											
												
													
														|  | -				await ProductSpuApi.updateSpu(data)
 |  | 
 | 
											
												
													
														|  | -				message.success(t('common.updateSuccess'))
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | -			close()
 |  | 
 | 
											
												
													
														|  | -			emit('success')
 |  | 
 | 
											
												
													
														|  | 
 |  | +			formData.value = res
 | 
											
												
													
														|  |  		} finally {
 |  |  		} finally {
 | 
											
												
													
														|  |  			formLoading.value = false
 |  |  			formLoading.value = false
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 | 
											
												
													
														|  | 
 |  | +/** 添加到仓库 / 回收站的状态 */
 | 
											
												
													
														|  | 
 |  | +const handleStatus02Change = async (newStatus: number) => {
 | 
											
												
													
														|  | 
 |  | +	try {
 | 
											
												
													
														|  | 
 |  | +		// 二次确认
 | 
											
												
													
														|  | 
 |  | +		const text = newStatus === ProductSpuStatusEnum.RECYCLE.status ? '加入到回收站' : '恢复到仓库'
 | 
											
												
													
														|  | 
 |  | +		await message.confirm(`确认要"${parentRow.value.name}"${text}吗?`)
 | 
											
												
													
														|  | 
 |  | +		// 发起修改
 | 
											
												
													
														|  | 
 |  | +		await ProductSpuApi.updateStatus({ id: parentRow.value.id, status: newStatus })
 | 
											
												
													
														|  | 
 |  | +		message.success(text + '成功')
 | 
											
												
													
														|  | 
 |  | +		// 刷新 tabs 数据
 | 
											
												
													
														|  | 
 |  | +		// await getTabsCount()
 | 
											
												
													
														|  | 
 |  | +		// 刷新列表
 | 
											
												
													
														|  | 
 |  | +		close()
 | 
											
												
													
														|  | 
 |  | +		emit('success')
 | 
											
												
													
														|  | 
 |  | +	} catch { }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +/** 删除按钮操作 */
 | 
											
												
													
														|  | 
 |  | +const handleDelete = async (id: number) => {
 | 
											
												
													
														|  | 
 |  | +	try {
 | 
											
												
													
														|  | 
 |  | +		// 删除的二次确认
 | 
											
												
													
														|  | 
 |  | +		await message.delConfirm()
 | 
											
												
													
														|  | 
 |  | +		// 发起删除
 | 
											
												
													
														|  | 
 |  | +		await ProductSpuApi.deleteSpu(id)
 | 
											
												
													
														|  | 
 |  | +		message.success(t('common.delSuccess'))
 | 
											
												
													
														|  | 
 |  | +		close()
 | 
											
												
													
														|  | 
 |  | +		emit('success')
 | 
											
												
													
														|  | 
 |  | +	} catch { }
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +/** 更新上架/下架状态 */
 | 
											
												
													
														|  | 
 |  | +const handleStatusChange = async () => {
 | 
											
												
													
														|  | 
 |  | +	console.log(parentRow.value.status)
 | 
											
												
													
														|  | 
 |  | +	try {
 | 
											
												
													
														|  | 
 |  | +		// 二次确认
 | 
											
												
													
														|  | 
 |  | +		const text = !parentRow.value.status ? '上架' : '下架'
 | 
											
												
													
														|  | 
 |  | +		const updateStatus = !parentRow.value.status ? 1 : 0
 | 
											
												
													
														|  | 
 |  | +		await message.confirm(`确认要${text}"${parentRow.value.name}"吗?`)
 | 
											
												
													
														|  | 
 |  | +		// 发起修改
 | 
											
												
													
														|  | 
 |  | +		await ProductSpuApi.updateStatus({ id: parentRow.value.id, status: updateStatus })
 | 
											
												
													
														|  | 
 |  | +		message.success(text + '成功')
 | 
											
												
													
														|  | 
 |  | +		close()
 | 
											
												
													
														|  | 
 |  | +		emit('success')
 | 
											
												
													
														|  | 
 |  | +	} catch {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	/** 关闭按钮 */
 |  | 
 | 
											
												
													
														|  | -	const close = () => {
 |  | 
 | 
											
												
													
														|  | -		dialogVisible.value = false
 |  | 
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | -</script>
 |  | 
 | 
											
												
													
														|  | -<style type="text/css">
 |  | 
 | 
											
												
													
														|  | -	.el-dialog__body {
 |  | 
 | 
											
												
													
														|  | -		padding: unset;
 |  | 
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +/** 提交按钮 */
 | 
											
												
													
														|  | 
 |  | +const submitForm = async () => {
 | 
											
												
													
														|  | 
 |  | +	// 提交请求
 | 
											
												
													
														|  | 
 |  | +	formLoading.value = true
 | 
											
												
													
														|  | 
 |  | +	try {
 | 
											
												
													
														|  | 
 |  | +		// 校验各表单
 | 
											
												
													
														|  | 
 |  | +		await unref(infoRef)?.validate()
 | 
											
												
													
														|  | 
 |  | +		await unref(skuRef)?.validate()
 | 
											
												
													
														|  | 
 |  | +		await unref(deliveryRef)?.validate()
 | 
											
												
													
														|  | 
 |  | +		await unref(descriptionRef)?.validate()
 | 
											
												
													
														|  | 
 |  | +		await unref(otherRef)?.validate()
 | 
											
												
													
														|  | 
 |  | +		// 深拷贝一份, 这样最终 server 端不满足,不需要影响原始数据
 | 
											
												
													
														|  | 
 |  | +		const deepCopyFormData = cloneDeep(unref(formData.value)) as ProductSpuApi.Spu
 | 
											
												
													
														|  | 
 |  | +		deepCopyFormData.skus!.forEach((item) => {
 | 
											
												
													
														|  | 
 |  | +			// 给sku name赋值
 | 
											
												
													
														|  | 
 |  | +			item.name = deepCopyFormData.name
 | 
											
												
													
														|  | 
 |  | +			// sku相关价格元转分
 | 
											
												
													
														|  | 
 |  | +			item.price = convertToInteger(item.price)
 | 
											
												
													
														|  | 
 |  | +			item.marketPrice = convertToInteger(item.marketPrice)
 | 
											
												
													
														|  | 
 |  | +			item.costPrice = convertToInteger(item.costPrice)
 | 
											
												
													
														|  | 
 |  | +			item.firstBrokeragePrice = convertToInteger(item.firstBrokeragePrice)
 | 
											
												
													
														|  | 
 |  | +			item.secondBrokeragePrice = convertToInteger(item.secondBrokeragePrice)
 | 
											
												
													
														|  | 
 |  | +		})
 | 
											
												
													
														|  | 
 |  | +		// 处理轮播图列表
 | 
											
												
													
														|  | 
 |  | +		const newSliderPicUrls: any[] = []
 | 
											
												
													
														|  | 
 |  | +		deepCopyFormData.sliderPicUrls!.forEach((item: any) => {
 | 
											
												
													
														|  | 
 |  | +			// 如果是前端选的图
 | 
											
												
													
														|  | 
 |  | +			typeof item === 'object' ? newSliderPicUrls.push(item.url) : newSliderPicUrls.push(item)
 | 
											
												
													
														|  | 
 |  | +		})
 | 
											
												
													
														|  | 
 |  | +		deepCopyFormData.sliderPicUrls = newSliderPicUrls
 | 
											
												
													
														|  | 
 |  | +		// 校验都通过后提交表单
 | 
											
												
													
														|  | 
 |  | +		const data = deepCopyFormData as ProductSpuApi.Spu
 | 
											
												
													
														|  | 
 |  | +		const id = productId.value as any as number
 | 
											
												
													
														|  | 
 |  | +		if (!id) {
 | 
											
												
													
														|  | 
 |  | +			await ProductSpuApi.createSpu(data)
 | 
											
												
													
														|  | 
 |  | +			message.success(t('common.createSuccess'))
 | 
											
												
													
														|  | 
 |  | +		} else {
 | 
											
												
													
														|  | 
 |  | +			await ProductSpuApi.updateSpu(data)
 | 
											
												
													
														|  | 
 |  | +			message.success(t('common.updateSuccess'))
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  | 
 |  | +		close()
 | 
											
												
													
														|  | 
 |  | +		emit('success')
 | 
											
												
													
														|  | 
 |  | +	} finally {
 | 
											
												
													
														|  | 
 |  | +		formLoading.value = false
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.dialog .el-card__body {
 |  | 
 | 
											
												
													
														|  | -		padding: 0 20px 20px 0;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +/** 关闭按钮 */
 | 
											
												
													
														|  | 
 |  | +const close = () => {
 | 
											
												
													
														|  | 
 |  | +	dialogVisible.value = false
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +</script>
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.dialog .el-dialog__headerbtn {
 |  | 
 | 
											
												
													
														|  | -		top: 0px;
 |  | 
 | 
											
												
													
														|  | -		line-height: 60px;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +<style type="text/css">
 | 
											
												
													
														|  | 
 |  | +.el-dialog__body {
 | 
											
												
													
														|  | 
 |  | +	padding: unset;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +.dialog .el-card__body {
 | 
											
												
													
														|  | 
 |  | +	padding: 0 20px 20px 0;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +.dialog .el-dialog__headerbtn {
 | 
											
												
													
														|  | 
 |  | +	top: 0px;
 | 
											
												
													
														|  | 
 |  | +	line-height: 60px;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +.dialog .el-dialog__headerbtn:hover {
 | 
											
												
													
														|  | 
 |  | +	background-color: #ef6b6b;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +.dialog .el-dialog__headerbtn:hover .el-dialog__close {
 | 
											
												
													
														|  | 
 |  | +	color: #fff;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +.dialog .el-dialog__header {
 | 
											
												
													
														|  | 
 |  | +	padding: 0;
 | 
											
												
													
														|  | 
 |  | +	margin: 0
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +</style>
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.dialog .el-dialog__headerbtn:hover {
 |  | 
 | 
											
												
													
														|  | -		background-color: #ef6b6b;
 |  | 
 | 
											
												
													
														|  | 
 |  | +<style lang="scss" scoped>
 | 
											
												
													
														|  | 
 |  | +::v-deep .left {
 | 
											
												
													
														|  | 
 |  | +	width: 106px;
 | 
											
												
													
														|  | 
 |  | +	float: left;
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +	img {
 | 
											
												
													
														|  | 
 |  | +		// width: 98%;
 | 
											
												
													
														|  | 
 |  | +		// border-bottom: 2px solid #e4e7ee;
 | 
											
												
													
														|  | 
 |  | +		// border-right: 2px solid #e4e7ee;
 | 
											
												
													
														|  | 
 |  | +		// margin-bottom: -5px;
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.dialog .el-dialog__headerbtn:hover .el-dialog__close {
 |  | 
 | 
											
												
													
														|  | -		color: #fff;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +.child-tabs {
 | 
											
												
													
														|  | 
 |  | +	border-top: 2px solid #e4e7ef;
 | 
											
												
													
														|  | 
 |  | +	margin-top: -7px;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.dialog .el-dialog__header {
 |  | 
 | 
											
												
													
														|  | -		padding: 0;
 |  | 
 | 
											
												
													
														|  | -		margin: 0
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | -</style>
 |  | 
 | 
											
												
													
														|  | -<style lang="scss" scoped>
 |  | 
 | 
											
												
													
														|  | -	::v-deep .left {
 |  | 
 | 
											
												
													
														|  | -		width: 106px;
 |  | 
 | 
											
												
													
														|  | -		float: left;
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -		img {
 |  | 
 | 
											
												
													
														|  | -			// width: 98%;
 |  | 
 | 
											
												
													
														|  | -			// border-bottom: 2px solid #e4e7ee;
 |  | 
 | 
											
												
													
														|  | -			// border-right: 2px solid #e4e7ee;
 |  | 
 | 
											
												
													
														|  | -			// margin-bottom: -5px;
 |  | 
 | 
											
												
													
														|  | -		}
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +::v-deep .child-tabs .is-active {
 | 
											
												
													
														|  | 
 |  | +	// border-left: 2px solid;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.child-tabs {
 |  | 
 | 
											
												
													
														|  | -		border-top: 2px solid #e4e7ef;
 |  | 
 | 
											
												
													
														|  | -		margin-top: -7px;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +::v-deep .child-tabs .el-tabs__active-bar {
 | 
											
												
													
														|  | 
 |  | +	// background-color: #30fdff;
 | 
											
												
													
														|  | 
 |  | +	// background-color: unset;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	::v-deep .child-tabs .is-active {
 |  | 
 | 
											
												
													
														|  | -		// border-left: 2px solid;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +::v-deep .child-tabs .el-tabs__item {
 | 
											
												
													
														|  | 
 |  | +	width: 106px;
 | 
											
												
													
														|  | 
 |  | +	justify-content: center;
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	::v-deep .child-tabs .el-tabs__active-bar {
 |  | 
 | 
											
												
													
														|  | -		// background-color: #30fdff;
 |  | 
 | 
											
												
													
														|  | -		// background-color: unset;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +::v-deep .child-tabs .el-tabs__item {}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	::v-deep .child-tabs .el-tabs__item {
 |  | 
 | 
											
												
													
														|  | -		width: 106px;
 |  | 
 | 
											
												
													
														|  | -		justify-content: center;
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +.right {
 | 
											
												
													
														|  | 
 |  | +	padding: 10px 0 60px;
 | 
											
												
													
														|  | 
 |  | +	border-left: 2px solid #e4e7ee;
 | 
											
												
													
														|  | 
 |  | +	margin-left: -2px;
 | 
											
												
													
														|  | 
 |  | +	float: left;
 | 
											
												
													
														|  | 
 |  | +	width: calc(100% - 120px);
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	::v-deep .child-tabs .el-tabs__item {}
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.right {
 |  | 
 | 
											
												
													
														|  | -		padding: 10px 0 60px;
 |  | 
 | 
											
												
													
														|  | -		border-left: 2px solid #e4e7ee;
 |  | 
 | 
											
												
													
														|  | -		margin-left: -2px;
 |  | 
 | 
											
												
													
														|  | -		float: left;
 |  | 
 | 
											
												
													
														|  | -		width: calc(100% - 120px);
 |  | 
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +.my-header {
 | 
											
												
													
														|  | 
 |  | +	display: flex;
 | 
											
												
													
														|  | 
 |  | +	justify-content: space-between;
 | 
											
												
													
														|  | 
 |  | +	align-items: center;
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | 
 |  | +	&-left {
 | 
											
												
													
														|  | 
 |  | +		font-weight: bold;
 | 
											
												
													
														|  | 
 |  | +		font-size: 18px;
 | 
											
												
													
														|  | 
 |  | +		padding: 20px;
 | 
											
												
													
														|  | 
 |  | +		padding-bottom: 10px
 | 
											
												
													
														|  | 
 |  | +	}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	.my-header {
 |  | 
 | 
											
												
													
														|  | -		display: flex;
 |  | 
 | 
											
												
													
														|  | -		justify-content: space-between;
 |  | 
 | 
											
												
													
														|  | -		align-items: center;
 |  | 
 | 
											
												
													
														|  | 
 |  | +	&-right {
 | 
											
												
													
														|  | 
 |  | +		span {
 | 
											
												
													
														|  | 
 |  | +			width: 55px;
 | 
											
												
													
														|  | 
 |  | +			height: 55px;
 | 
											
												
													
														|  | 
 |  | +			display: inline-block;
 | 
											
												
													
														|  | 
 |  | +			line-height: 55px;
 | 
											
												
													
														|  | 
 |  | +			text-align: center;
 | 
											
												
													
														|  | 
 |  | +			cursor: pointer;
 | 
											
												
													
														|  | 
 |  | +		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		&-left {
 |  | 
 | 
											
												
													
														|  | -			font-weight: bold;
 |  | 
 | 
											
												
													
														|  | -			font-size: 18px;
 |  | 
 | 
											
												
													
														|  | -			padding: 20px;
 |  | 
 | 
											
												
													
														|  | -			padding-bottom: 10px
 |  | 
 | 
											
												
													
														|  | 
 |  | +		span:first-child:hover {
 | 
											
												
													
														|  | 
 |  | +			background-color: #f6f6f6;
 | 
											
												
													
														|  | 
 |  | +			// color: white
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -		&-right {
 |  | 
 | 
											
												
													
														|  | -			span {
 |  | 
 | 
											
												
													
														|  | -				width: 55px;
 |  | 
 | 
											
												
													
														|  | -				height: 55px;
 |  | 
 | 
											
												
													
														|  | -				display: inline-block;
 |  | 
 | 
											
												
													
														|  | -				line-height: 55px;
 |  | 
 | 
											
												
													
														|  | -				text-align: center;
 |  | 
 | 
											
												
													
														|  | -				cursor: pointer;
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -			span:first-child:hover {
 |  | 
 | 
											
												
													
														|  | -				background-color: #f6f6f6;
 |  | 
 | 
											
												
													
														|  | -				// color: white
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -			span:last-child:hover {
 |  | 
 | 
											
												
													
														|  | -				background-color: #ef6b6b;
 |  | 
 | 
											
												
													
														|  | -				color: white
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | 
 |  | +		span:last-child:hover {
 | 
											
												
													
														|  | 
 |  | +			background-color: #ef6b6b;
 | 
											
												
													
														|  | 
 |  | +			color: white
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  |  </style>
 |  |  </style>
 |