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/promotion/discountActivity/DiscountActivityForm.vue | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 265 insertions(+), 0 deletions(-)
diff --git a/src/views/mall/promotion/discountActivity/DiscountActivityForm.vue b/src/views/mall/promotion/discountActivity/DiscountActivityForm.vue
new file mode 100644
index 0000000..6c2469f
--- /dev/null
+++ b/src/views/mall/promotion/discountActivity/DiscountActivityForm.vue
@@ -0,0 +1,265 @@
+<template>
+ <Dialog v-model="dialogVisible" :title="dialogTitle" width="65%">
+ <Form
+ ref="formRef"
+ v-loading="formLoading"
+ :isCol="true"
+ :rules="rules"
+ :schema="allSchemas.formSchema"
+ >
+ <!-- 鍏堥�夋嫨 -->
+ <template #spuId>
+ <el-button @click="spuSelectRef.open()">閫夋嫨鍟嗗搧</el-button>
+ <SpuAndSkuList
+ ref="spuAndSkuListRef"
+ :deletable="true"
+ :rule-config="ruleConfig"
+ :spu-list="spuList"
+ :spu-property-list-p="spuPropertyList"
+ @delete="deleteSpu"
+ >
+ <el-table-column align="center" label="浼樻儬閲戦" min-width="168">
+ <template #default="{ row }">
+ <el-input-number
+ v-model="row.productConfig.discountPrice"
+ :max="parseFloat(fenToYuan(row.price))"
+ :min="0"
+ :precision="2"
+ :step="0.1"
+ class="w-100%"
+ @change="handleSkuDiscountPriceChange(row)"
+ />
+ </template>
+ </el-table-column>
+ <el-table-column align="center" label="鎶樻墸鐧惧垎姣�(%)" min-width="168">
+ <template #default="{ row }">
+ <el-input-number
+ v-model="row.productConfig.discountPercent"
+ :max="100"
+ :min="0"
+ :precision="2"
+ :step="0.1"
+ class="w-100%"
+ @change="handleSkuDiscountPercentChange(row)"
+ />
+ </template>
+ </el-table-column>
+ </SpuAndSkuList>
+ </template>
+ </Form>
+ <template #footer>
+ <el-button :disabled="formLoading" type="primary" @click="submitForm">纭� 瀹�</el-button>
+ <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+ </template>
+ </Dialog>
+ <SpuSelect ref="spuSelectRef" :isSelectSku="true" @confirm="selectSpu" />
+</template>
+<script lang="ts" setup>
+import { SpuAndSkuList, SpuProperty, SpuSelect } from '../components'
+import { allSchemas, rules } from './discountActivity.data'
+import { cloneDeep, debounce } from 'lodash-es'
+import * as DiscountActivityApi from '@/api/mall/promotion/discount/discountActivity'
+import * as ProductSpuApi from '@/api/mall/product/spu'
+import { getPropertyList, RuleConfig } from '@/views/mall/product/spu/components'
+import { convertToInteger, erpCalculatePercentage, fenToYuan, yuanToFen } from '@/utils'
+import { PromotionDiscountTypeEnum } from '@/utils/constants'
+
+defineOptions({ name: 'PromotionDiscountActivityForm' })
+
+const { t } = useI18n() // 鍥介檯鍖�
+const message = useMessage() // 娑堟伅寮圭獥
+
+const dialogVisible = ref(false) // 寮圭獥鐨勬槸鍚﹀睍绀�
+const dialogTitle = ref('') // 寮圭獥鐨勬爣棰�
+const formLoading = ref(false) // 琛ㄥ崟鐨勫姞杞戒腑锛�1锛変慨鏀规椂鐨勬暟鎹姞杞斤紱2锛夋彁浜ょ殑鎸夐挳绂佺敤
+const formType = ref('') // 琛ㄥ崟鐨勭被鍨嬶細create - 鏂板锛泆pdate - 淇敼
+const formRef = ref() // 琛ㄥ崟 Ref
+// ================= 鍟嗗搧閫夋嫨鐩稿叧 =================
+
+const spuSelectRef = ref() // 鍟嗗搧鍜屽睘鎬ч�夋嫨 Ref
+const spuAndSkuListRef = ref() // sku 闄愭椂鎶樻墸 閰嶇疆缁勪欢Ref
+const ruleConfig: RuleConfig[] = [
+ {
+ name: 'productConfig.discountPrice',
+ rule: (arg) => arg > 0,
+ message: '鍟嗗搧浼樻儬閲戦涓嶈兘涓� 0 锛侊紒锛�'
+ }
+]
+const spuList = ref<DiscountActivityApi.SpuExtension[]>([]) // 閫夋嫨鐨� spu
+const spuPropertyList = ref<SpuProperty<DiscountActivityApi.SpuExtension>[]>([])
+const spuIds = ref<number[]>([])
+const selectSpu = (spuId: number, skuIds: number[]) => {
+ getSpuDetails(spuId, skuIds)
+}
+/**
+ * 鑾峰彇 SPU 璇︽儏
+ */
+const getSpuDetails = async (
+ spuId: number,
+ skuIds: number[] | undefined,
+ products?: DiscountActivityApi.DiscountProductVO[],
+ type?: string
+) => {
+ // 濡傛灉宸茬粡鍖呭惈 SPU 鍒欒烦杩�
+ if (spuIds.value.includes(spuId)) {
+ if (type !== 'load') {
+ message.error('鏁版嵁閲嶅閫夋嫨锛�')
+ }
+ return
+ }
+ spuIds.value.push(spuId)
+ const res = (await ProductSpuApi.getSpuDetailList([spuId])) as DiscountActivityApi.SpuExtension[]
+ if (res.length == 0) {
+ return
+ }
+ //spuList.value = []
+ // 鍥犱负鍙兘閫夋嫨涓�涓�
+ const spu = res[0]
+ const selectSkus =
+ typeof skuIds === 'undefined' ? spu?.skus : spu?.skus?.filter((sku) => skuIds.includes(sku.id!))
+ selectSkus?.forEach((sku) => {
+ let config: DiscountActivityApi.DiscountProductVO = {
+ skuId: sku.id!,
+ spuId: spu.id!,
+ discountType: 1,
+ discountPercent: 0,
+ discountPrice: 0
+ }
+ if (typeof products !== 'undefined') {
+ const product = products.find((item) => item.skuId === sku.id)
+ if (product) {
+ product.discountPercent = fenToYuan(product.discountPercent) as any
+ product.discountPrice = fenToYuan(product.discountPrice) as any
+ }
+ config = product || config
+ }
+ sku.productConfig = config
+ })
+ spu.skus = selectSkus as DiscountActivityApi.SkuExtension[]
+ spuPropertyList.value.push({
+ spuId: spu.id!,
+ spuDetail: spu,
+ propertyList: getPropertyList(spu)
+ })
+ spuList.value.push(spu)
+}
+
+// ================= end =================
+
+/** 鎵撳紑寮圭獥 */
+const open = async (type: string, id?: number) => {
+ dialogVisible.value = true
+ dialogTitle.value = t('action.' + type)
+ formType.value = type
+ await resetForm()
+ // 淇敼鏃讹紝璁剧疆鏁版嵁
+ if (id) {
+ formLoading.value = true
+ try {
+ const data = (await DiscountActivityApi.getDiscountActivity(
+ id
+ )) as DiscountActivityApi.DiscountActivityVO
+ for (let productsKey in data.products) {
+ const supId = data.products[productsKey].spuId
+ await getSpuDetails(
+ supId!,
+ data.products?.map((sku) => sku.skuId),
+ data.products,
+ 'load'
+ )
+ }
+ formRef.value.setValues(data)
+ } finally {
+ formLoading.value = false
+ }
+ }
+}
+defineExpose({ open }) // 鎻愪緵 open 鏂规硶锛岀敤浜庢墦寮�寮圭獥
+
+/** 鎻愪氦琛ㄥ崟 */
+const emit = defineEmits(['success']) // 瀹氫箟 success 浜嬩欢锛岀敤浜庢搷浣滄垚鍔熷悗鐨勫洖璋�
+const submitForm = async () => {
+ // 鏍¢獙琛ㄥ崟
+ if (!formRef) return
+ const valid = await formRef.value.getElFormRef().validate()
+ if (!valid) return
+ // 鎻愪氦璇锋眰
+ formLoading.value = true
+ try {
+ // 鑾峰彇鎶樻墸鍟嗗搧閰嶇疆
+ const products = cloneDeep(spuAndSkuListRef.value.getSkuConfigs('productConfig'))
+ products.forEach((item: DiscountActivityApi.DiscountProductVO) => {
+ item.discountPercent = convertToInteger(item.discountPercent)
+ item.discountPrice = convertToInteger(item.discountPrice)
+ })
+ const data = cloneDeep(formRef.value.formModel) as DiscountActivityApi.DiscountActivityVO
+ data.products = products
+ // 鐪熸鎻愪氦
+ if (formType.value === 'create') {
+ await DiscountActivityApi.createDiscountActivity(data)
+ message.success(t('common.createSuccess'))
+ } else {
+ await DiscountActivityApi.updateDiscountActivity(data)
+ message.success(t('common.updateSuccess'))
+ }
+ dialogVisible.value = false
+ // 鍙戦�佹搷浣滄垚鍔熺殑浜嬩欢
+ emit('success')
+ } finally {
+ formLoading.value = false
+ }
+}
+
+/** 澶勭悊 sku 浼樻儬閲戦鍙樺姩 */
+const handleSkuDiscountPriceChange = debounce((row: any) => {
+ // 鏍¢獙杈圭晫
+ if (row.productConfig.discountPrice <= 0) {
+ return
+ }
+
+ // 璁剧疆浼樻儬绫诲瀷锛氭弧鍑�
+ row.productConfig.discountType = PromotionDiscountTypeEnum.PRICE.type
+ // 璁剧疆鎶樻墸
+ row.productConfig.discountPercent = erpCalculatePercentage(
+ row.price - yuanToFen(row.productConfig.discountPrice),
+ row.price
+ )
+}, 200)
+/** 澶勭悊 sku 浼樻儬鎶樻墸鍙樺姩 */
+const handleSkuDiscountPercentChange = debounce((row: any) => {
+ // 鏍¢獙杈圭晫
+ if (row.productConfig.discountPercent <= 0 || row.productConfig.discountPercent >= 100) {
+ return
+ }
+
+ // 璁剧疆浼樻儬绫诲瀷锛氭姌鎵�
+ row.productConfig.discountType = PromotionDiscountTypeEnum.PERCENT.type
+ // 璁剧疆婊″噺閲戦
+ row.productConfig.discountPrice = fenToYuan(
+ row.price - row.price * (row.productConfig.discountPercent / 100.0 || 0)
+ )
+}, 200)
+
+/** 閲嶇疆琛ㄥ崟 */
+const resetForm = async () => {
+ spuList.value = []
+ spuPropertyList.value = []
+ spuIds.value = []
+ await nextTick()
+ formRef.value.getElFormRef().resetFields()
+}
+
+/**
+ * 鍒犻櫎 SPU
+ */
+const deleteSpu = (spuId: number) => {
+ spuIds.value.splice(
+ spuIds.value.findIndex((item) => item == spuId),
+ 1
+ )
+ spuPropertyList.value.splice(
+ spuPropertyList.value.findIndex((item) => item.spuId == spuId),
+ 1
+ )
+}
+</script>
--
Gitblit v1.8.0