|
|
@@ -0,0 +1,392 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container">
|
|
|
+ <el-card shadow="never" class="mb-4">
|
|
|
+ <template #header>
|
|
|
+ <div class="flex justify-between items-center">
|
|
|
+ <span class="text-lg font-bold">基础信息</span>
|
|
|
+ <el-button type="warning" @click="handleBack">返回</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <el-form :model="form" label-width="140px" class="detail-form">
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="商品编号" required>
|
|
|
+ <el-input v-model="form.productNo" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="商品名称" required>
|
|
|
+ <el-input v-model="form.itemName" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="我方平台分类" required>
|
|
|
+ <el-input v-model="form.categoryName" disabled placeholder="请选择" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="商品品牌" required>
|
|
|
+ <el-input v-model="form.brandName" disabled placeholder="请力" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="单位" required>
|
|
|
+ <el-input v-model="form.unitName" disabled placeholder="包" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="可售状态" required>
|
|
|
+ <el-switch
|
|
|
+ v-model="form.canSale"
|
|
|
+ active-text="是"
|
|
|
+ inactive-text="否"
|
|
|
+ disabled
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="起订量" required>
|
|
|
+ <el-input-number v-model="form.minOrderQuantity" :min="1" disabled style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="市场价" required>
|
|
|
+ <el-input-number v-model="form.marketPrice" :precision="2" :min="0" disabled style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="平台价格" required>
|
|
|
+ <el-input-number v-model="form.memberPrice" :precision="2" :min="0" disabled style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="最低单价">
|
|
|
+ <el-input-number v-model="form.minSellingPrice" :precision="2" :min="0" disabled style="width: 100%" />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="副标题">
|
|
|
+ <el-input v-model="form.subtitle" placeholder="请输入副标题" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="UPC条码(69码)">
|
|
|
+ <el-input v-model="form.upcBarcode" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row :gutter="20">
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="规格/型号">
|
|
|
+ <el-input v-model="form.specification" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="16">
|
|
|
+ <el-form-item label="第三方电商链接">
|
|
|
+ <el-input v-model="form.referenceLink" placeholder="请输入第三方电商链接" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="商品卖点">
|
|
|
+ <el-input
|
|
|
+ v-model="form.mainLibraryIntro"
|
|
|
+ type="textarea"
|
|
|
+ :rows="3"
|
|
|
+ disabled
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 图片管理 -->
|
|
|
+ <el-card shadow="never" class="mb-4">
|
|
|
+ <template #header>
|
|
|
+ <span class="text-lg font-bold">图片管理</span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <div class="image-gallery">
|
|
|
+ <div class="image-item main-image">
|
|
|
+ <el-image
|
|
|
+ :src="form.productImage"
|
|
|
+ fit="cover"
|
|
|
+ :preview-src-list="[form.productImage]"
|
|
|
+ >
|
|
|
+ <template #error>
|
|
|
+ <div class="image-slot">
|
|
|
+ <el-icon><Picture /></el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-image>
|
|
|
+ <div class="image-label">+ 主图</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div
|
|
|
+ v-for="(image, index) in additionalImages"
|
|
|
+ :key="index"
|
|
|
+ class="image-item"
|
|
|
+ >
|
|
|
+ <el-image
|
|
|
+ :src="image"
|
|
|
+ fit="cover"
|
|
|
+ :preview-src-list="allImages"
|
|
|
+ :initial-index="index + 1"
|
|
|
+ >
|
|
|
+ <template #error>
|
|
|
+ <div class="image-slot">
|
|
|
+ <el-icon><Picture /></el-icon>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-image>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="image-item add-image">
|
|
|
+ <div class="image-placeholder">
|
|
|
+ <el-icon><Plus /></el-icon>
|
|
|
+ <span>+ 附图</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+
|
|
|
+ <!-- 产品详情 -->
|
|
|
+ <el-card shadow="never">
|
|
|
+ <template #header>
|
|
|
+ <span class="text-lg font-bold">产品详情</span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <div class="editor-container">
|
|
|
+ <Editor v-model="form.pcDetail" :read-only="true" />
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts" name="ProductBaseDetail">
|
|
|
+import { getBase } from '@/api/product/base';
|
|
|
+import { BaseVO, BaseForm } from '@/api/product/base/types';
|
|
|
+import { useRoute, useRouter } from 'vue-router';
|
|
|
+import Editor from '@/components/Editor/index.vue';
|
|
|
+import { Picture, Plus } from '@element-plus/icons-vue';
|
|
|
+
|
|
|
+const route = useRoute();
|
|
|
+const router = useRouter();
|
|
|
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
+
|
|
|
+const loading = ref(false);
|
|
|
+const form = ref<any>({
|
|
|
+ id: undefined,
|
|
|
+ productNo: '',
|
|
|
+ itemName: '',
|
|
|
+ brandId: undefined,
|
|
|
+ topCategoryId: undefined,
|
|
|
+ mediumCategoryId: undefined,
|
|
|
+ bottomCategoryId: undefined,
|
|
|
+ unitId: undefined,
|
|
|
+ productImage: '',
|
|
|
+ productImageUrl: '',
|
|
|
+ isSelf: '',
|
|
|
+ productReviewStatus: '',
|
|
|
+ homeRecommended: '',
|
|
|
+ categoryRecommendation: '',
|
|
|
+ cartRecommendation: '',
|
|
|
+ recommendedProductOrder: 0,
|
|
|
+ isPopular: '',
|
|
|
+ isNew: '',
|
|
|
+ productStatus: '',
|
|
|
+ dataSource: '',
|
|
|
+ marketPrice: 0,
|
|
|
+ memberPrice: 0,
|
|
|
+ minSellingPrice: 0,
|
|
|
+ purchasingPrice: 0,
|
|
|
+ tempGrossMargin: 0,
|
|
|
+ remark: '',
|
|
|
+ mainLibraryIntro: '',
|
|
|
+ upcBarcode: '',
|
|
|
+ specification: '',
|
|
|
+ referenceLink: '',
|
|
|
+ minOrderQuantity: 1,
|
|
|
+ brandName: '',
|
|
|
+ categoryName: '',
|
|
|
+ unitName: '',
|
|
|
+ pcDetail: '',
|
|
|
+ subtitle: '',
|
|
|
+ canSale: true
|
|
|
+});
|
|
|
+
|
|
|
+// 可售状态
|
|
|
+const canSale = computed({
|
|
|
+ get: () => form.value.productStatus === '1',
|
|
|
+ set: (val: boolean) => {
|
|
|
+ form.value.productStatus = val ? '1' : '0';
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+// 附加图片列表
|
|
|
+const additionalImages = ref<string[]>([]);
|
|
|
+
|
|
|
+// 所有图片列表(用于预览)
|
|
|
+const allImages = computed(() => {
|
|
|
+ return [form.value.productImage, ...additionalImages.value].filter(img => img);
|
|
|
+});
|
|
|
+
|
|
|
+/** 获取产品详情 */
|
|
|
+const getDetail = async () => {
|
|
|
+ loading.value = true;
|
|
|
+ try {
|
|
|
+ const id = route.params.id as string;
|
|
|
+ const res = await getBase(id);
|
|
|
+ form.value = res.data;
|
|
|
+
|
|
|
+ // 解析附加图片(如果有的话,根据实际数据结构调整)
|
|
|
+ if (form.value.mainImage) {
|
|
|
+ const images = form.value.mainImage.split(',');
|
|
|
+ additionalImages.value = images.slice(1); // 第一张是主图,其余是附图
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取详情失败:', error);
|
|
|
+ proxy?.$modal.msgError('获取详情失败');
|
|
|
+ } finally {
|
|
|
+ loading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/** 返回 */
|
|
|
+const handleBack = () => {
|
|
|
+ router.back();
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getDetail();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.app-container {
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.detail-form {
|
|
|
+ :deep(.el-form-item__label) {
|
|
|
+ color: #606266;
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+
|
|
|
+ :deep(.el-input.is-disabled .el-input__inner),
|
|
|
+ :deep(.el-textarea.is-disabled .el-textarea__inner),
|
|
|
+ :deep(.el-input-number.is-disabled .el-input__inner) {
|
|
|
+ color: #606266;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.image-gallery {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
|
|
+ gap: 16px;
|
|
|
+ padding: 10px 0;
|
|
|
+
|
|
|
+ .image-item {
|
|
|
+ position: relative;
|
|
|
+ width: 150px;
|
|
|
+ height: 150px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ border-color: #409eff;
|
|
|
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
|
+ }
|
|
|
+
|
|
|
+ &.main-image {
|
|
|
+ border-color: #67c23a;
|
|
|
+ border-width: 2px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-image {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-label {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ background: rgba(0, 0, 0, 0.6);
|
|
|
+ color: #fff;
|
|
|
+ text-align: center;
|
|
|
+ padding: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-slot {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: #f5f7fa;
|
|
|
+ color: #909399;
|
|
|
+
|
|
|
+ .el-icon {
|
|
|
+ font-size: 30px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .add-image {
|
|
|
+ border-style: dashed;
|
|
|
+ background: #fafafa;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #f5f7fa;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image-placeholder {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ color: #909399;
|
|
|
+
|
|
|
+ .el-icon {
|
|
|
+ font-size: 30px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ }
|
|
|
+
|
|
|
+ span {
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.editor-container {
|
|
|
+ min-height: 400px;
|
|
|
+
|
|
|
+ :deep(.w-e-text-container) {
|
|
|
+ background-color: #f5f7fa !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|