parent
							
								
									e7e0c7a6b7
								
							
						
					
					
						commit
						84d538ad69
					
				| 
						 | 
				
			
			@ -4,7 +4,7 @@ import { Sku, Spu } from '@/api/mall/product/spu'
 | 
			
		|||
export interface CombinationActivityVO {
 | 
			
		||||
  id?: number
 | 
			
		||||
  name?: string
 | 
			
		||||
  spuIds?: number[]
 | 
			
		||||
  spuId?: number
 | 
			
		||||
  totalLimitCount?: number
 | 
			
		||||
  singleLimitCount?: number
 | 
			
		||||
  startTime?: Date
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ export interface CombinationProductVO {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
// 扩展 Sku 配置
 | 
			
		||||
type SkuExtension = Sku & {
 | 
			
		||||
export type SkuExtension = Sku & {
 | 
			
		||||
  productConfig: CombinationProductVO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -59,8 +59,3 @@ export const updateCombinationActivity = async (data: CombinationActivityVO) =>
 | 
			
		|||
export const deleteCombinationActivity = async (id: number) => {
 | 
			
		||||
  return await request.delete({ url: '/promotion/combination-activity/delete?id=' + id })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 导出拼团活动 Excel
 | 
			
		||||
export const exportCombinationActivity = async (params) => {
 | 
			
		||||
  return await request.download({ url: '/promotion/combination-activity/export-excel', params })
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@
 | 
			
		|||
      :rules="rules"
 | 
			
		||||
      :schema="allSchemas.formSchema"
 | 
			
		||||
    >
 | 
			
		||||
      <template #spuIds>
 | 
			
		||||
      <template #spuId>
 | 
			
		||||
        <el-button @click="spuSelectRef.open()">选择商品</el-button>
 | 
			
		||||
        <SpuAndSkuList
 | 
			
		||||
          ref="spuAndSkuListRef"
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +34,7 @@
 | 
			
		|||
      <el-button @click="dialogVisible = false">取 消</el-button>
 | 
			
		||||
    </template>
 | 
			
		||||
  </Dialog>
 | 
			
		||||
  <SpuSelect ref="spuSelectRef" @confirm="selectSpu" />
 | 
			
		||||
  <SpuSelect ref="spuSelectRef" :isSelectSku="true" @confirm="selectSpu" />
 | 
			
		||||
</template>
 | 
			
		||||
<script lang="ts" setup>
 | 
			
		||||
import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationactivity'
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ import { allSchemas, rules } from './combinationActivity.data'
 | 
			
		|||
import { SpuAndSkuList, SpuProperty, SpuSelect } from '@/views/mall/promotion/components'
 | 
			
		||||
import { getPropertyList, RuleConfig } from '@/views/mall/product/spu/components'
 | 
			
		||||
import * as ProductSpuApi from '@/api/mall/product/spu'
 | 
			
		||||
import { convertToInteger } from '@/utils'
 | 
			
		||||
import { convertToInteger, formatToFraction } from '@/utils'
 | 
			
		||||
 | 
			
		||||
defineOptions({ name: 'PromotionCombinationActivityForm' })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -71,32 +71,51 @@ const ruleConfig: RuleConfig[] = [
 | 
			
		|||
]
 | 
			
		||||
const selectSpu = (spuId: number, skuIds: number[]) => {
 | 
			
		||||
  formRef.value.setValues({ spuId })
 | 
			
		||||
  getSpuDetails([spuId])
 | 
			
		||||
  console.log(skuIds)
 | 
			
		||||
  getSpuDetails(spuId, skuIds)
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * 获取 SPU 详情
 | 
			
		||||
 * @param spuIds
 | 
			
		||||
 */
 | 
			
		||||
const getSpuDetails = async (spuIds: number[]) => {
 | 
			
		||||
const getSpuDetails = async (
 | 
			
		||||
  spuId: number,
 | 
			
		||||
  skuIds: number[] | undefined,
 | 
			
		||||
  products?: CombinationProductVO[]
 | 
			
		||||
) => {
 | 
			
		||||
  const spuProperties: SpuProperty<CombinationActivityApi.SpuExtension>[] = []
 | 
			
		||||
  const res = (await ProductSpuApi.getSpuDetailList(
 | 
			
		||||
    spuIds
 | 
			
		||||
  )) as CombinationActivityApi.SpuExtension[]
 | 
			
		||||
  const res = (await ProductSpuApi.getSpuDetailList([
 | 
			
		||||
    spuId
 | 
			
		||||
  ])) as CombinationActivityApi.SpuExtension[]
 | 
			
		||||
  if (res.length == 0) {
 | 
			
		||||
    return
 | 
			
		||||
  }
 | 
			
		||||
  spuList.value = []
 | 
			
		||||
  res?.forEach((spu) => {
 | 
			
		||||
    // 初始化每个 sku 秒杀配置
 | 
			
		||||
    spu.skus?.forEach((sku) => {
 | 
			
		||||
      const config: CombinationActivityApi.CombinationProductVO = {
 | 
			
		||||
        spuId: spu.id!,
 | 
			
		||||
        skuId: sku.id!,
 | 
			
		||||
        activePrice: 0
 | 
			
		||||
  // 因为只能选择一个
 | 
			
		||||
  const spu = res[0]
 | 
			
		||||
  const selectSkus =
 | 
			
		||||
    typeof skuIds === 'undefined' ? spu?.skus : spu?.skus?.filter((sku) => skuIds.includes(sku.id!))
 | 
			
		||||
  selectSkus?.forEach((sku) => {
 | 
			
		||||
    let config: CombinationProductVO = {
 | 
			
		||||
      spuId: spu.id!,
 | 
			
		||||
      skuId: sku.id!,
 | 
			
		||||
      activePrice: 0
 | 
			
		||||
    }
 | 
			
		||||
    if (typeof products !== 'undefined') {
 | 
			
		||||
      const product = products.find((item) => item.skuId === sku.id)
 | 
			
		||||
      if (product) {
 | 
			
		||||
        // 分转元
 | 
			
		||||
        product.activePrice = formatToFraction(product.activePrice)
 | 
			
		||||
      }
 | 
			
		||||
      sku.productConfig = config
 | 
			
		||||
    })
 | 
			
		||||
    spuProperties.push({ spuId: spu.id!, spuDetail: spu, propertyList: getPropertyList(spu) })
 | 
			
		||||
      config = product || config
 | 
			
		||||
    }
 | 
			
		||||
    sku.productConfig = config
 | 
			
		||||
  })
 | 
			
		||||
  spuList.value.push(...res)
 | 
			
		||||
  spu.skus = selectSkus as CombinationActivityApi.SkuExtension[]
 | 
			
		||||
  spuProperties.push({
 | 
			
		||||
    spuId: spu.id!,
 | 
			
		||||
    spuDetail: spu,
 | 
			
		||||
    propertyList: getPropertyList(spu)
 | 
			
		||||
  })
 | 
			
		||||
  spuList.value.push(spu)
 | 
			
		||||
  spuPropertyList.value = spuProperties
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,11 +126,19 @@ 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 CombinationActivityApi.getCombinationActivity(id)
 | 
			
		||||
      const data = (await CombinationActivityApi.getCombinationActivity(
 | 
			
		||||
        id
 | 
			
		||||
      )) as CombinationActivityApi.CombinationActivityVO
 | 
			
		||||
      await getSpuDetails(
 | 
			
		||||
        data.spuId!,
 | 
			
		||||
        data.products?.map((sku) => sku.skuId),
 | 
			
		||||
        data.products
 | 
			
		||||
      )
 | 
			
		||||
      formRef.value.setValues(data)
 | 
			
		||||
    } finally {
 | 
			
		||||
      formLoading.value = false
 | 
			
		||||
| 
						 | 
				
			
			@ -120,6 +147,14 @@ const open = async (type: string, id?: number) => {
 | 
			
		|||
}
 | 
			
		||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 | 
			
		||||
 | 
			
		||||
/** 重置表单 */
 | 
			
		||||
const resetForm = async () => {
 | 
			
		||||
  spuList.value = []
 | 
			
		||||
  spuPropertyList.value = []
 | 
			
		||||
  await nextTick()
 | 
			
		||||
  formRef.value.getElFormRef().resetFields()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 提交表单 */
 | 
			
		||||
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
 | 
			
		||||
const submitForm = async () => {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,7 +134,7 @@ const crudSchemas = reactive<CrudSchema[]>([
 | 
			
		|||
  },
 | 
			
		||||
  {
 | 
			
		||||
    label: '拼团商品',
 | 
			
		||||
    field: 'spuIds',
 | 
			
		||||
    field: 'spuId',
 | 
			
		||||
    isSearch: false,
 | 
			
		||||
    form: {
 | 
			
		||||
      colProps: {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,14 @@
 | 
			
		|||
        total: tableObject.total
 | 
			
		||||
      }"
 | 
			
		||||
    >
 | 
			
		||||
      <template #spuId="{ row }">
 | 
			
		||||
        <el-image
 | 
			
		||||
          :src="row.picUrl"
 | 
			
		||||
          class="w-30px h-30px align-middle mr-5px"
 | 
			
		||||
          @click="imagePreview(row.picUrl)"
 | 
			
		||||
        />
 | 
			
		||||
        <span class="align-middle">{{ row.spuName }}</span>
 | 
			
		||||
      </template>
 | 
			
		||||
      <template #action="{ row }">
 | 
			
		||||
        <el-button
 | 
			
		||||
          v-hasPermi="['promotion:combination-activity:update']"
 | 
			
		||||
| 
						 | 
				
			
			@ -57,6 +65,8 @@
 | 
			
		|||
import { allSchemas } from './combinationActivity.data'
 | 
			
		||||
import * as CombinationActivityApi from '@/api/mall/promotion/combination/combinationactivity'
 | 
			
		||||
import CombinationActivityForm from './CombinationActivityForm.vue'
 | 
			
		||||
import { cloneDeep } from 'lodash-es'
 | 
			
		||||
import { createImageViewer } from '@/components/ImageViewer'
 | 
			
		||||
 | 
			
		||||
defineOptions({ name: 'PromotionCombinationActivity' })
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -70,6 +80,13 @@ const { tableObject, tableMethods } = useTable({
 | 
			
		|||
// 获得表格的各种操作
 | 
			
		||||
const { getList, setSearchParams } = tableMethods
 | 
			
		||||
 | 
			
		||||
/** 商品图预览 */
 | 
			
		||||
const imagePreview = (imgUrl: string) => {
 | 
			
		||||
  createImageViewer({
 | 
			
		||||
    urlList: [imgUrl]
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** 添加/修改操作 */
 | 
			
		||||
const formRef = ref()
 | 
			
		||||
const openForm = (type: string, id?: number) => {
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +100,17 @@ const handleDelete = (id: number) => {
 | 
			
		|||
 | 
			
		||||
/** 初始化 **/
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
  /*
 | 
			
		||||
 TODO
 | 
			
		||||
 后面准备封装成一个函数来操作 tableColumns 重新排列:比如说需求是表单上商品选择是在后面的而列表展示的时候需要调到位置。
 | 
			
		||||
 封装效果支持批量操作,给出 field 和需要插入的位置,例:[{field:'spuId',index: 1}] 效果为把 field 为 spuId 的 column 移动到第一个位置
 | 
			
		||||
 */
 | 
			
		||||
  // 处理一下表格列让商品往前
 | 
			
		||||
  const index = allSchemas.tableColumns.findIndex((item) => item.field === 'spuId')
 | 
			
		||||
  const column = cloneDeep(allSchemas.tableColumns[index])
 | 
			
		||||
  allSchemas.tableColumns.splice(index, 1)
 | 
			
		||||
  // 添加到开头
 | 
			
		||||
  allSchemas.tableColumns.unshift(column)
 | 
			
		||||
  getList()
 | 
			
		||||
})
 | 
			
		||||
</script>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,7 +87,6 @@ const selectSpu = (spuId: number, skuIds: number[]) => {
 | 
			
		|||
}
 | 
			
		||||
/**
 | 
			
		||||
 * 获取 SPU 详情
 | 
			
		||||
 * @param spuIds
 | 
			
		||||
 */
 | 
			
		||||
const getSpuDetails = async (
 | 
			
		||||
  spuId: number,
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +112,7 @@ const getSpuDetails = async (
 | 
			
		|||
    if (typeof products !== 'undefined') {
 | 
			
		||||
      const product = products.find((item) => item.skuId === sku.id)
 | 
			
		||||
      if (product) {
 | 
			
		||||
        // 元转分
 | 
			
		||||
        // 分转元
 | 
			
		||||
        product.seckillPrice = formatToFraction(product.seckillPrice)
 | 
			
		||||
      }
 | 
			
		||||
      config = product || config
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue