From a1d7e81859f554f3a53680cc35f0f49bf1f77098 Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期四, 14 五月 2026 14:37:02 +0800
Subject: [PATCH] 导入项目

---
 src/views/mall/product/spu/form/index.vue |  204 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 204 insertions(+), 0 deletions(-)

diff --git a/src/views/mall/product/spu/form/index.vue b/src/views/mall/product/spu/form/index.vue
new file mode 100644
index 0000000..c4e4b7b
--- /dev/null
+++ b/src/views/mall/product/spu/form/index.vue
@@ -0,0 +1,204 @@
+<template>
+  <ContentWrap v-loading="formLoading">
+    <el-tabs v-model="activeName">
+      <el-tab-pane label="鍩虹璁剧疆" name="info">
+        <InfoForm
+          ref="infoRef"
+          v-model:activeName="activeName"
+          :is-detail="isDetail"
+          :propFormData="formData"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="浠锋牸搴撳瓨" name="sku">
+        <SkuForm
+          ref="skuRef"
+          v-model:activeName="activeName"
+          :is-detail="isDetail"
+          :propFormData="formData"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="鐗╂祦璁剧疆" name="delivery">
+        <DeliveryForm
+          ref="deliveryRef"
+          v-model:activeName="activeName"
+          :is-detail="isDetail"
+          :propFormData="formData"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="鍟嗗搧璇︽儏" name="description">
+        <DescriptionForm
+          ref="descriptionRef"
+          v-model:activeName="activeName"
+          :is-detail="isDetail"
+          :propFormData="formData"
+        />
+      </el-tab-pane>
+      <el-tab-pane label="鍏跺畠璁剧疆" name="other">
+        <OtherForm
+          ref="otherRef"
+          v-model:activeName="activeName"
+          :is-detail="isDetail"
+          :propFormData="formData"
+        />
+      </el-tab-pane>
+    </el-tabs>
+    <el-form>
+      <el-form-item style="float: right">
+        <el-button v-if="!isDetail" :loading="formLoading" type="primary" @click="submitForm">
+          淇濆瓨
+        </el-button>
+        <el-button @click="close">杩斿洖</el-button>
+      </el-form-item>
+    </el-form>
+  </ContentWrap>
+</template>
+<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'
+
+defineOptions({ name: 'ProductSpuAdd' })
+
+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 getDetail = async () => {
+  if ('ProductSpuDetail' === name) {
+    isDetail.value = true
+  }
+  const id = params.id as unknown 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
+    }
+  }
+}
+
+/** 鎻愪氦鎸夐挳 */
+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) => {
+      // 缁檚ku 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 = params.id as unknown as number
+    if (!id) {
+      await ProductSpuApi.createSpu(data)
+      message.success(t('common.createSuccess'))
+    } else {
+      await ProductSpuApi.updateSpu(data)
+      message.success(t('common.updateSuccess'))
+    }
+    close()
+  } finally {
+    formLoading.value = false
+  }
+}
+
+/** 鍏抽棴鎸夐挳 */
+const close = () => {
+  delView(unref(currentRoute))
+  push({ name: 'ProductSpu' })
+}
+
+/** 鍒濆鍖� */
+onMounted(async () => {
+  await getDetail()
+})
+</script>

--
Gitblit v1.8.0