|  | @@ -0,0 +1,257 @@
 | 
	
		
			
				|  |  | +<template>
 | 
	
		
			
				|  |  | +  <Dialog title="活动奖品配置" v-model="dialogVisible" style="width: 70%;">
 | 
	
		
			
				|  |  | +    <div class="text-right mb-20px">
 | 
	
		
			
				|  |  | +      <el-button type="primary" plain @click="handleAddPrize">
 | 
	
		
			
				|  |  | +        <Icon icon="ep:plus" class="mr-5px" /> 新增奖品
 | 
	
		
			
				|  |  | +      </el-button>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +    <div style="display: inline-block; width: 100%;">
 | 
	
		
			
				|  |  | +      <el-table v-loading="loading" :data="list" :stripe="true">
 | 
	
		
			
				|  |  | +      <el-table-column label="奖品名称" align="center" prop="name" />
 | 
	
		
			
				|  |  | +      <el-table-column label="奖品图片" align="center" min-width="80" prop="image">
 | 
	
		
			
				|  |  | +        <template #default="scope">
 | 
	
		
			
				|  |  | +          <img :src="scope.row.image" alt="" class="h-70px" />
 | 
	
		
			
				|  |  | +        </template>
 | 
	
		
			
				|  |  | +      </el-table-column>
 | 
	
		
			
				|  |  | +      <el-table-column label="奖品数量" align="center" prop="total" />
 | 
	
		
			
				|  |  | +      <el-table-column label="权重" align="center" prop="chance" />
 | 
	
		
			
				|  |  | +      <el-table-column label="类型" align="center" prop="type">
 | 
	
		
			
				|  |  | +        <template #default="scope">
 | 
	
		
			
				|  |  | +          <dict-tag :type="DICT_TYPE.PROMOTION_LUCK_PRIZE_TYPE" :value="scope.row.type" />
 | 
	
		
			
				|  |  | +        </template>
 | 
	
		
			
				|  |  | +      </el-table-column>
 | 
	
		
			
				|  |  | +      <el-table-column label="提示语" align="center" prop="prompt" />
 | 
	
		
			
				|  |  | +      <el-table-column label="排序" align="center" prop="sort" />
 | 
	
		
			
				|  |  | +      <el-table-column label="操作" align="center">
 | 
	
		
			
				|  |  | +        <template #default="scope">
 | 
	
		
			
				|  |  | +          <el-button link type="primary" @click="handleEdit(scope.row.id)">编辑</el-button>
 | 
	
		
			
				|  |  | +          <el-button link type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
 | 
	
		
			
				|  |  | +        </template>
 | 
	
		
			
				|  |  | +      </el-table-column>
 | 
	
		
			
				|  |  | +    </el-table>
 | 
	
		
			
				|  |  | +    <!-- 分页 -->
 | 
	
		
			
				|  |  | +    <Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +    <template #footer>
 | 
	
		
			
				|  |  | +      <el-button @click="dialogVisible = false">取 消</el-button>
 | 
	
		
			
				|  |  | +    </template>
 | 
	
		
			
				|  |  | +  </Dialog>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  <Dialog title="添加奖品" v-model="showAddPrize">
 | 
	
		
			
				|  |  | +    <el-form
 | 
	
		
			
				|  |  | +      ref="formRef"
 | 
	
		
			
				|  |  | +      :model="addPrizeData"
 | 
	
		
			
				|  |  | +      :rules="addPrizeFormRules"
 | 
	
		
			
				|  |  | +      label-width="80px"
 | 
	
		
			
				|  |  | +    >
 | 
	
		
			
				|  |  | +      <el-form-item label="奖品" prop="type">
 | 
	
		
			
				|  |  | +        <el-radio-group v-model="addPrizeData.type">
 | 
	
		
			
				|  |  | +          <el-radio v-for="dict in getIntDictOptions(DICT_TYPE.PROMOTION_LUCK_PRIZE_TYPE)" :key="dict.value" :value="dict.value.toString()" @change="handleChangeType">{{ dict.label }}</el-radio>
 | 
	
		
			
				|  |  | +        </el-radio-group>
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +      <el-form-item v-if="isShowSpu" label="商品" prop="productId">
 | 
	
		
			
				|  |  | +        <div style="width: 100%;">
 | 
	
		
			
				|  |  | +          <el-image v-if="Object.keys(spu).length && spu?.id" class="w-100px h-100px" :src="spu?.picUrl" />
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +        <el-button :icon="Plus" type="primary" @click.stop="spuQueryParams.pageNo = 1,showSpu = true">选择商品</el-button>
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +      <el-form-item label="奖品名称" prop="name">
 | 
	
		
			
				|  |  | +        <el-input v-model="addPrizeData.name" placeholder="请输入奖品名称" />
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +      <el-form-item label="奖品图片" prop="image">
 | 
	
		
			
				|  |  | +        <UploadImg v-model="addPrizeData.image" :validSpecifications="true" height="150px" width="150px" :fileSize="10" :maxWidth="150" :maxHeight="150" />
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +      <el-form-item label="排序" prop="sort">
 | 
	
		
			
				|  |  | +        <el-input-number v-model="addPrizeData.sort" :min="1" />
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +      <el-form-item label="奖品数量" prop="total">
 | 
	
		
			
				|  |  | +        <el-input-number v-model="addPrizeData.total" :min="1" />
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +      <el-form-item label="奖品权重" prop="chance">
 | 
	
		
			
				|  |  | +        <el-input-number v-model="addPrizeData.chance" :min="1" />
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +      <el-form-item label="提示语" prop="prompt">
 | 
	
		
			
				|  |  | +        <el-input v-model="addPrizeData.prompt" placeholder="请输入提示语" />
 | 
	
		
			
				|  |  | +      </el-form-item>
 | 
	
		
			
				|  |  | +    </el-form>
 | 
	
		
			
				|  |  | +    <template #footer>
 | 
	
		
			
				|  |  | +      <el-button @click="submitPrize" type="primary">确 定</el-button>
 | 
	
		
			
				|  |  | +      <el-button @click="showAddPrize = false, spu = {}">取 消</el-button>
 | 
	
		
			
				|  |  | +    </template>
 | 
	
		
			
				|  |  | +  </Dialog>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  <Dialog title="商品列表" v-model="showSpu" style="width: 70%;">
 | 
	
		
			
				|  |  | +    <div style="display: inline-block; width: 100%;">
 | 
	
		
			
				|  |  | +      <SpuList @select="handleSelectSpu" @refresh="getSpuList" />
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +    <template #footer>
 | 
	
		
			
				|  |  | +      <el-button @click="showSpu = false">取 消</el-button>
 | 
	
		
			
				|  |  | +    </template>
 | 
	
		
			
				|  |  | +  </Dialog>
 | 
	
		
			
				|  |  | +</template>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<script setup lang="ts">
 | 
	
		
			
				|  |  | +  import { Plus } from '@element-plus/icons-vue'
 | 
	
		
			
				|  |  | +  import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
 | 
	
		
			
				|  |  | +  import { LuckLotteryApi } from '@/api/mall/promotion/lottery/config'
 | 
	
		
			
				|  |  | +  import * as ProductSpuApi from '@/api/mall/product/spu'
 | 
	
		
			
				|  |  | +  import SpuList from './components/spuList.vue'
 | 
	
		
			
				|  |  | +              
 | 
	
		
			
				|  |  | +  /** 幸运抽奖-活动 表单 */
 | 
	
		
			
				|  |  | +  defineOptions({ name: 'LuckLotteryForm' })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const message = useMessage() // 消息弹窗
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const loading = ref(false)
 | 
	
		
			
				|  |  | +  const list = ref([])
 | 
	
		
			
				|  |  | +  const dialogVisible = ref(false) // 弹窗的是否展示
 | 
	
		
			
				|  |  | +  const total = ref(0)
 | 
	
		
			
				|  |  | +  const queryParams = reactive({
 | 
	
		
			
				|  |  | +    pageNo: 1,
 | 
	
		
			
				|  |  | +    pageSize: 10,
 | 
	
		
			
				|  |  | +    lotteryId: undefined as any
 | 
	
		
			
				|  |  | +  })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 获取奖品分页
 | 
	
		
			
				|  |  | +  const getList = async () => {
 | 
	
		
			
				|  |  | +    loading.value = true
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      const res = await LuckLotteryApi.getLuckLotteryPrizePage(queryParams)
 | 
	
		
			
				|  |  | +      list.value = res.list
 | 
	
		
			
				|  |  | +      total.value = res.total
 | 
	
		
			
				|  |  | +    } finally {
 | 
	
		
			
				|  |  | +      loading.value = false
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 商品列表
 | 
	
		
			
				|  |  | +  const showSpu = ref(false)
 | 
	
		
			
				|  |  | +  const spuLoading = ref(false)
 | 
	
		
			
				|  |  | +  const spuList = ref([])
 | 
	
		
			
				|  |  | +  const spuTotal = ref(0)
 | 
	
		
			
				|  |  | +  const spuQueryParams = reactive({
 | 
	
		
			
				|  |  | +    pageNo: 1,
 | 
	
		
			
				|  |  | +    pageSize: 10
 | 
	
		
			
				|  |  | +  })
 | 
	
		
			
				|  |  | +  const getSpuList = async () => {
 | 
	
		
			
				|  |  | +    spuLoading.value = true
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      const res = await ProductSpuApi.getSpuPage(spuQueryParams)
 | 
	
		
			
				|  |  | +      spuList.value = res.list
 | 
	
		
			
				|  |  | +      spuTotal.value = res.total
 | 
	
		
			
				|  |  | +    } finally {
 | 
	
		
			
				|  |  | +      spuLoading.value = false
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +              
 | 
	
		
			
				|  |  | +  /** 打开弹窗 */
 | 
	
		
			
				|  |  | +  const open = async (id: number) => {
 | 
	
		
			
				|  |  | +    queryParams.lotteryId = id
 | 
	
		
			
				|  |  | +    await getList()
 | 
	
		
			
				|  |  | +    dialogVisible.value = true
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  defineExpose({ open }) // 提供 open 方法,用于打开弹窗
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 删除奖品
 | 
	
		
			
				|  |  | +  const handleDelete = async (id: number) => {
 | 
	
		
			
				|  |  | +    await message.confirm('确定删除该奖品吗?')
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      await LuckLotteryApi.deleteLuckLotteryPrize(id)
 | 
	
		
			
				|  |  | +      message.success('删除成功')
 | 
	
		
			
				|  |  | +      await getList()
 | 
	
		
			
				|  |  | +    } catch {}
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 编辑奖品
 | 
	
		
			
				|  |  | +  const formType = ref('add')
 | 
	
		
			
				|  |  | +  const handleEdit = async (id: number) => {
 | 
	
		
			
				|  |  | +    resetForm()
 | 
	
		
			
				|  |  | +    formType.value = 'edit'
 | 
	
		
			
				|  |  | +    if (!id) return
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      const data = await LuckLotteryApi.getLuckLotteryPrize(id)
 | 
	
		
			
				|  |  | +      addPrizeData.value = data
 | 
	
		
			
				|  |  | +      spu.value = data.spu
 | 
	
		
			
				|  |  | +      isShowSpu.value = data.type === '6'
 | 
	
		
			
				|  |  | +      showAddPrize.value = true
 | 
	
		
			
				|  |  | +    } catch {}
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 添加奖品
 | 
	
		
			
				|  |  | +  const addPrizeData = ref({
 | 
	
		
			
				|  |  | +    type: '1',
 | 
	
		
			
				|  |  | +    productId: undefined,
 | 
	
		
			
				|  |  | +    name: undefined,
 | 
	
		
			
				|  |  | +    total: 10,
 | 
	
		
			
				|  |  | +    chance: 10,
 | 
	
		
			
				|  |  | +    prompt: undefined,
 | 
	
		
			
				|  |  | +    image: undefined,
 | 
	
		
			
				|  |  | +    status: 0,
 | 
	
		
			
				|  |  | +    sort: 0,
 | 
	
		
			
				|  |  | +    lotteryId: undefined as any
 | 
	
		
			
				|  |  | +  })
 | 
	
		
			
				|  |  | +  const showAddPrize = ref(false)
 | 
	
		
			
				|  |  | +  const formRef = ref()
 | 
	
		
			
				|  |  | +  const addPrizeFormRules = reactive({
 | 
	
		
			
				|  |  | +    type: [{ required: true, message: '奖品类型不能为空', trigger: 'change' }],
 | 
	
		
			
				|  |  | +    name: [{ required: true, message: '奖品名称不能为空', trigger: 'blur' }],
 | 
	
		
			
				|  |  | +    chance: [{ required: true, message: '奖品权重不能为空', trigger: 'blur' }],
 | 
	
		
			
				|  |  | +    image: [{ required: true, message: '奖品图片不能为空', trigger: 'blur' }],
 | 
	
		
			
				|  |  | +    total: [{ required: true, message: '商品数量不能为空', trigger: 'blur' }],
 | 
	
		
			
				|  |  | +    prompt: [{ required: true, message: '提示语不能为空', trigger: 'blur' }]
 | 
	
		
			
				|  |  | +  })
 | 
	
		
			
				|  |  | +  const handleAddPrize = async () => {
 | 
	
		
			
				|  |  | +    formType.value = 'add'
 | 
	
		
			
				|  |  | +    isShowSpu.value = false
 | 
	
		
			
				|  |  | +    resetForm()
 | 
	
		
			
				|  |  | +    showAddPrize.value = true
 | 
	
		
			
				|  |  | +    await getSpuList()
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 只有站内商品才展示商品信息
 | 
	
		
			
				|  |  | +  const isShowSpu = ref(false)
 | 
	
		
			
				|  |  | +  const handleChangeType = (val: string) => {
 | 
	
		
			
				|  |  | +    isShowSpu.value = val === '6'
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  const submitPrize = async () => {
 | 
	
		
			
				|  |  | +    // 校验表单
 | 
	
		
			
				|  |  | +    await formRef.value.validate()
 | 
	
		
			
				|  |  | +    if (isShowSpu.value && !Object.keys(spu.value).length && !spu.value?.id) return message.warning('请选择商品')
 | 
	
		
			
				|  |  | +    addPrizeData.value.lotteryId = queryParams.lotteryId
 | 
	
		
			
				|  |  | +    addPrizeData.value.productId = spu.value.id
 | 
	
		
			
				|  |  | +    addPrizeData.value.image = spu.value?.picUrl
 | 
	
		
			
				|  |  | +    delete addPrizeData.value.spu
 | 
	
		
			
				|  |  | +    try {
 | 
	
		
			
				|  |  | +      formType.value === 'add' ? await LuckLotteryApi.createLuckLotteryPrize(addPrizeData.value) : await LuckLotteryApi.updateLuckLotteryPrize(addPrizeData.value)
 | 
	
		
			
				|  |  | +      message.success(formType.value === 'add' ? '添加成功' : '修改成功')
 | 
	
		
			
				|  |  | +      showAddPrize.value = false
 | 
	
		
			
				|  |  | +      spu.value = {}
 | 
	
		
			
				|  |  | +      getList()
 | 
	
		
			
				|  |  | +    } catch {}
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  const resetForm = () => {
 | 
	
		
			
				|  |  | +    spu.value = {}
 | 
	
		
			
				|  |  | +    addPrizeData.value = {
 | 
	
		
			
				|  |  | +      type: '1',
 | 
	
		
			
				|  |  | +      productId: undefined,
 | 
	
		
			
				|  |  | +      name: undefined,
 | 
	
		
			
				|  |  | +      total: 10,
 | 
	
		
			
				|  |  | +      chance: 10,
 | 
	
		
			
				|  |  | +      prompt: undefined,
 | 
	
		
			
				|  |  | +      image: undefined,
 | 
	
		
			
				|  |  | +      status: 0,
 | 
	
		
			
				|  |  | +      sort: 0,
 | 
	
		
			
				|  |  | +      lotteryId: undefined as any
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 选中商品
 | 
	
		
			
				|  |  | +  const spu = ref({})
 | 
	
		
			
				|  |  | +  const handleSelectSpu = (row: any) =>{
 | 
	
		
			
				|  |  | +    spu.value = row
 | 
	
		
			
				|  |  | +    addPrizeData.value.name = row.name
 | 
	
		
			
				|  |  | +    addPrizeData.value.image = row.picUrl
 | 
	
		
			
				|  |  | +    showSpu.value = false
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +</script>
 |