zjk
2026-04-27 fa50087e894462f4092b620ee1744e19c010f722
feat(活动管理): 优化活动策略和用户群配置界面样式

- 新增删除图标用于策略和用户群删除操作
- 重构策略配置卡片布局,优化视觉层次和间距
- 调整用户群配置界面,支持删除指定用户群
- 统一表单字段标签样式和按钮边框风格
- 优化数据表格空状态显示和分页逻辑
1个文件已添加
1个文件已修改
486 ■■■■■ 已修改文件
src/assets/pricingManagement/delete.svg 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/userContent/active/activityManagement/add.vue 485 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/pricingManagement/delete.svg
New file
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" fill="none" version="1.1" width="16" height="16" viewBox="0 0 16 16"><rect x="0" y="0" width="16" height="16" rx="0" fill="#171F26" fill-opacity="0.6000000238418579" style="opacity:0;"/><g><path d="M5,2.5C5,1.94771522,5.4477153000000005,1.5,6,1.5L10,1.5C10.5522842,1.5,11,1.9477151,11,2.5L11,3.5L14.5,3.5L14.5,4.5L13,4.5L13,13.5C13,14.052285,12.552284,14.5,12,14.5L4,14.5C3.447715,14.5,3,14.052284,3,13.5L3,4.5L1.5,4.5L1.5,3.5L5,3.5L5,2.5ZM6,3.5L10,3.5L10,2.5L6,2.5L6,3.5ZM4,4.5L4,13.5L12,13.5L12,4.5L4,4.5ZM6,11.5L6,6.5L7,6.5L7,11.5L6,11.5ZM9,11.5L9,6.5L10,6.5L10,11.5L9,11.5Z" fill-rule="evenodd" fill="#171F26" fill-opacity="0.6000000238418579"/></g></svg>
src/views/userContent/active/activityManagement/add.vue
@@ -33,6 +33,7 @@
import { addCouponActivity, fetchCouponActivityDetail, fetchCouponDetail } from '@/service/api/coupon'
import { fetchWhitelistDetail } from '@/service/api/whitelist'
import { customUploadRequest } from '@/utils/upload'
import deleteIcon from '@/assets/pricingManagement/delete.svg'
const route = useRoute()
const router = useRouter()
@@ -51,6 +52,7 @@
const currentSelectGroupIndex = ref(-1)
const showUserTypeHelpModal = ref(false)
const strategyList = ref<StrategyItem[]>([createStrategy()])
function handleOpenCouponModal(strategyIndex: number, type: 'normal' | 'afterUse') {
  currentSelectStrategyIndex.value = strategyIndex
@@ -81,13 +83,13 @@
  showUserModal.value = true
}
type UserListItem = {
interface UserListItem {
  id: number | string
  account: string
  remark: string
}
type UserGroupItem = {
interface UserGroupItem {
  actitcityId: number | null
  actitcityStrategeId: number | null
  id: number | null
@@ -115,18 +117,7 @@
// 用户群相关
const userGroupList = ref<UserGroupItem[]>([
  {
    ...createUserGroup(5),
    userList: [
      { id: 1, account: '15708179461', remark: '媒体' },
      { id: 2, account: '15708179461', remark: '-' },
      { id: 3, account: '15708179461', remark: '媒体' },
      { id: 4, account: '15708179461', remark: '-' },
      { id: 5, account: '15708179461', remark: '-' },
    ],
    pagination: { page: 1, pageSize: 10, total: 1000 },
  },
  createUserGroup(2),
  createUserGroup(1),
])
function handleSaveUsers(rows: any[]) {
@@ -141,26 +132,26 @@
  message.success(`成功导入了 ${newUsers.length} 名用户`)
}
const activeTab = ref(2)
const activeTab = ref(4)
const isEditMode = computed(() => route.query.mode === 'edit' && !!route.query.id)
type UsagePeriodItem = {
interface UsagePeriodItem {
  startTime: string | null
  endTime: string | null
}
type DistributionRulesAfterUse = {
interface DistributionRulesAfterUse {
  ruleType: 1 | 2
  couponList: any[]
}
type StrategyItem = {
interface StrategyItem {
  actitcityId: number | null
  id: number | null
  name: string
  distributionRules: 1 | 2 | 3
  distributionRulesAfterUse: DistributionRulesAfterUse
  effectRule: '领取后生效' | '领取后指定日期生效'
  effectRule: 1 | 2
  effectDate: number | null
  distributionsTotal: number | null
  effectiveDays: number | null
@@ -183,7 +174,7 @@
      ruleType: 1,
      couponList: [],
    },
    effectRule: '领取后生效',
    effectRule: 1,
    effectDate: null,
    distributionsTotal: null,
    effectiveDays: null,
@@ -196,8 +187,6 @@
    couponList: [],
  }
}
const strategyList = ref<StrategyItem[]>([createStrategy()])
const strategyGroupOptions = computed(() => {
  return strategyList.value.map((strategy, index) => ({
@@ -378,7 +367,7 @@
type NotifyTimingValue = 1 | 2 | 4
type NotifyFormModel = {
interface NotifyFormModel {
  activityId: number | null
  id: number | null
  noticeType: NotifyTimingValue[]
@@ -739,39 +728,39 @@
  const strategySource = toArray(detail.strategy)
  strategyList.value = strategySource.length
    ? strategySource.map((item: any) => ({
      actitcityId: item.actitcityId ?? currentActivityId.value,
      id: item.id ?? null,
      name: item.name || '',
      distributionRules: Number(item.distributionRules) as 1 | 2 | 3 || 1,
      distributionRulesAfterUse: parseDistributionRulesAfterUse(item.distributionRulesAfterUse),
      effectRule: '领取后生效',
      effectDate: null,
      distributionsTotal: item.distributionsTotal ?? null,
      effectiveDays: item.effectiveDays ?? null,
      effectiveRules: Number(item.effectiveRules) as 1 | 2 | 3 || 1,
      endTime: item.endTime ? new Date(item.endTime).getTime() : null,
      limitNumber: item.limitNumber ?? 1,
      stackedUsage: Number(item.stackedUsage) as 0 | 1 || 0,
      startUsing: Number(item.startUsing) as 0 | 1 || 0,
      usagePeriod: parseUsagePeriod(item.usagePeriod),
      couponList: toArray(item.couponIds).map((id: number | string) => ({
        id,
        couponName: `优惠券${id}`,
      })),
    }))
        actitcityId: item.actitcityId ?? currentActivityId.value,
        id: item.id ?? null,
        name: item.name || '',
        distributionRules: Number(item.distributionRules) as 1 | 2 | 3 || 1,
        distributionRulesAfterUse: parseDistributionRulesAfterUse(item.distributionRulesAfterUse),
        effectRule: item.effectRule || 1,
        effectDate: null,
        distributionsTotal: item.distributionsTotal ?? null,
        effectiveDays: item.effectiveDays ?? null,
        effectiveRules: Number(item.effectiveRules) as 1 | 2 | 3 || 1,
        endTime: item.endTime ? new Date(item.endTime).getTime() : null,
        limitNumber: item.limitNumber ?? 1,
        stackedUsage: Number(item.stackedUsage) as 0 | 1 || 0,
        startUsing: Number(item.startUsing) as 0 | 1 || 0,
        usagePeriod: parseUsagePeriod(item.usagePeriod),
        couponList: toArray(item.couponIds).map((id: number | string) => ({
          id,
          couponName: `优惠券${id}`,
        })),
      }))
    : [createStrategy()]
  const userSource = toArray(detail.activityUser)
  userGroupList.value = userSource.length
    ? userSource.map((item: any) => ({
      actitcityId: item.actitcityId ?? currentActivityId.value,
      actitcityStrategeId: item.actitcityStrategeId ?? null,
      id: item.id ?? null,
      strategyName: item.strategyName || '',
      userList: parseUserList(item.userList),
      userType: Number(item.userType) as 1 | 2 | 3 | 4 | 5 || 1,
      pagination: { page: 1, pageSize: 10, total: toArray(item.userList).length },
    }))
        actitcityId: item.actitcityId ?? currentActivityId.value,
        actitcityStrategeId: item.actitcityStrategeId ?? null,
        id: item.id ?? null,
        strategyName: item.strategyName || '',
        userList: parseUserList(item.userList),
        userType: Number(item.userType) as 1 | 2 | 3 | 4 | 5 || 1,
        pagination: { page: 1, pageSize: 10, total: toArray(item.userList).length },
      }))
    : [createUserGroup()]
  const notice = detail.notice || {}
@@ -1002,6 +991,10 @@
  activeTab.value++
}
function handleRemoveUserGroup(index: number) {
  userGroupList.value.splice(index, 1)
}
onMounted(() => {
  getDetail()
})
@@ -1010,7 +1003,7 @@
<template>
  <div class=" w-full h-full relative content flex flex-col">
    <div class="p-12px main flex flex-col flex-1 overflow-hidden">
      <NTabs v-model:value="activeTab" type="line" class="mb-8px custom-tabs" animated>
      <NTabs v-model:value="activeTab" type="line" class="custom-tabs" animated>
        <NTabPane :name="1" tab="活动介绍内容" />
        <NTabPane :name="2" tab="活动策略配置" />
        <NTabPane :name="3" tab="发放用户" />
@@ -1086,53 +1079,54 @@
        </NForm>
        <!-- 活动策略配置 -->
        <div v-show="activeTab === 2">
        <div v-show="activeTab === 2" class="flex flex-col">
          <div
            v-for="(strategy, strategyIndex) in strategyList" :key="strategyIndex"
            class="mb-24px pb-24px border-b border-[#EBEEF5] last:border-b-0 last:pb-0 last:mb-0"
            class="mb-12px p-24px pb-12px border border-[#EEE9E9] last:mb-0 rounded-6px"
          >
            <div
              v-if="strategyList.length > 1"
              class="flex justify-between items-center mb-16px bg-[#f5f7fa] p-12px rounded-4px"
            >
              <span class="text-14px font-bold text-[#171f26]">策略 {{ strategyIndex + 1 }}</span>
              <NButton text type="error" @click="handleRemoveStrategy(strategyIndex)">
                删除策略
              </NButton>
            </div>
            <NForm :model="strategy" :rules="strategyRules" label-placement="left" require-mark-placement="left">
              <!-- 策略名称 -->
              <NFormItem label="策略名称:" path="name">
                <NInput
                  v-model:value="strategy.name" placeholder="请输入" maxlength="20" clearable
                  style="width: 400px"
                />
              </NFormItem>
              <div class="flex items-center justify-between mb-16px">
                <!-- 策略名称 -->
                <NFormItem label="策略名称" path="name">
                  <NInput
                    v-model:value="strategy.name" placeholder="请输入" maxlength="20" clearable
                    style="width: 300px"
                  />
                </NFormItem>
                <img v-if="strategyList.length > 1" :src="deleteIcon" alt="删除" style="width: 16px;height: 16px;cursor: pointer;" @click="handleRemoveStrategy(strategyIndex)">
              </div>
              <!-- 优惠券 -->
              <NFormItem label="优惠券:">
                <div class="w-full flex flex-col gap-12px">
                  <NButton type="primary" class="w-120px" @click="handleOpenCouponModal(strategyIndex, 'normal')">
                    选择任意券
              <NFormItem label="优惠券">
                <div class="w-full flex justify-end">
                  <NButton type="primary" style="border: 1px solid #7ABDFF;" secondary class="w-97px" @click="handleOpenCouponModal(strategyIndex, 'normal')">
                    选择优惠券
                  </NButton>
                  <div class="border border-[#EBEEF5] rounded-4px overflow-hidden">
                    <NDataTable
                      :columns="createCouponColumns(strategyIndex, 'normal')"
                      :data="strategy.couponList"
                      :bordered="false"
                      size="small"
                    />
                  </div>
                </div>
              </NFormItem>
              <div class="mt-4px min-h-[262px]">
                <NDataTable
                  :columns="createCouponColumns(strategyIndex, 'normal')"
                  :data="strategy.couponList"
                  :bordered="false"
                  style="min-height: 263px"
                  flex-height
                  :pagination="false"
                >
                  <template #empty>
                    <div class="flex-center">
                      <img src="/src/assets/element-img/no-data.png" style="width:123px;height:125px" @error="(e: any) => { e.target.src = 'https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/9bed493b-a6aa-4ef6-ac10-7f67f5c6adc5.png' }">
                    </div>
                  </template>
                </NDataTable>
              </div>
              <!-- 发放规则 -->
              <NFormItem label="发放规则:">
                <div class="flex flex-col gap-16px w-full">
                  <NRadioGroup v-model:value="strategy.distributionRules">
              <NFormItem label="发放规则" class="mt-24px">
                <div class="w-full pl-8px">
                  <NRadioGroup v-model:value="strategy.distributionRules" class="h-32px flex items-center">
                    <NSpace>
                      <NRadio :value="1" label="每日0点循环发放" />
                      <NRadio :value="1" label="每日循环发放" />
                      <NRadio :value="2" label="仅发放一次" />
                      <NRadio :value="3" label="使用后发放" />
                    </NSpace>
@@ -1140,10 +1134,10 @@
                  <div
                    v-if="strategy.distributionRules === 3"
                    class="bg-[#FAFAFA] p-16px rounded-4px border border-[#EBEEF5] flex flex-col gap-16px w-full"
                    class="flex flex-col gap-16px w-full mt-8px"
                  >
                    <div class="flex items-center gap-16px">
                      <span class="text-[#606266]">使用后发放规则:</span>
                      <span>使用后发放规则</span>
                      <NRadioGroup v-model:value="strategy.distributionRulesAfterUse.ruleType">
                        <NSpace>
                          <NRadio :value="1" label="本券使用后循环发放" />
@@ -1152,22 +1146,30 @@
                      </NRadioGroup>
                    </div>
                    <div v-if="strategy.distributionRulesAfterUse.ruleType === 2" class="flex flex-col gap-12px w-full">
                      <div class="flex items-center gap-16px">
                        <span class="text-[#606266]">优惠券:</span>
                      <div class="flex items-center justify-between gap-16px">
                        <span>优惠券</span>
                        <NButton
                          type="primary" class="w-120px"
                          type="primary" secondary style="border: 1px solid #7ABDFF;" class="w-97px"
                          @click="handleOpenCouponModal(strategyIndex, 'afterUse')"
                        >
                          选择优惠券
                        </NButton>
                      </div>
                      <div class="border border-[#EBEEF5] rounded-4px overflow-hidden w-full">
                      <div class="overflow-hidden w-full">
                        <NDataTable
                          :columns="createCouponColumns(strategyIndex, 'afterUse')"
                          :data="strategy.distributionRulesAfterUse.couponList"
                          :bordered="false"
                          size="small"
                        />
                          style="min-height: 263px"
                          flex-height
                          :pagination="false"
                        >
                          <template #empty>
                            <div class="flex-center">
                              <img src="/src/assets/element-img/no-data.png" style="width:123px;height:125px" @error="(e: any) => { e.target.src = 'https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/9bed493b-a6aa-4ef6-ac10-7f67f5c6adc5.png' }">
                            </div>
                          </template>
                        </NDataTable>
                      </div>
                    </div>
                  </div>
@@ -1175,29 +1177,29 @@
              </NFormItem>
              <!-- 生效规则 -->
              <NFormItem label="生效规则:">
                <div class="flex flex-col gap-16px w-full">
                  <NRadioGroup v-model:value="strategy.effectRule">
              <NFormItem label="生效规则" class="mt-12px">
                <div class="flex flex-col pl-8px gap-8px w-full">
                  <NRadioGroup v-model:value="strategy.effectRule" class="h-32px flex items-center">
                    <NSpace>
                      <NRadio value="领取后生效" label="领取后生效" />
                      <NRadio value="领取后指定日期生效" label="领取后指定日期生效" />
                      <NRadio :value="1" label="领取后生效" />
                      <NRadio :value="2" label="领取后指定日期生效" />
                    </NSpace>
                  </NRadioGroup>
                  <div v-if="strategy.effectRule === '领取后指定日期生效'" class="flex items-center gap-16px">
                    <span class="text-[#606266]">生效日期</span>
                  <div v-if="strategy.effectRule === 2" class="flex items-center gap-16px">
                    <span>生效日期</span>
                    <NDatePicker
                      v-model:value="strategy.effectDate" type="date" format="yyyy/MM/dd" clearable
                      :actions="null" close-on-select placeholder="请选择日期" style="width: 200px;"
                      :actions="null" close-on-select placeholder="请选择日期" style="width: 240px;"
                    />
                  </div>
                </div>
              </NFormItem>
              <!-- 失效规则 -->
              <NFormItem label="失效规则:">
                <div class="flex flex-col gap-16px w-full">
                  <NRadioGroup v-model:value="strategy.effectiveRules">
              <NFormItem label="失效规则" class="mt-12px">
                <div class="flex flex-col gap-8px w-full pl-8px">
                  <NRadioGroup v-model:value="strategy.effectiveRules" class="h-32px flex items-center">
                    <NSpace>
                      <NRadio :value="1" label="次日0点失效" />
                      <NRadio :value="2" label="指定有效天数" />
@@ -1206,25 +1208,25 @@
                  </NRadioGroup>
                  <div v-if="strategy.effectiveRules === 2" class="flex items-center gap-16px">
                    <span class="text-[#606266]">有效天数</span>
                    <span>有效天数</span>
                    <NInputNumber
                      v-model:value="strategy.effectiveDays" placeholder="请输入天数" :min="1" :show-button="false"
                      style="width: 200px;"
                      style="width: 240px;"
                    />
                  </div>
                  <div v-if="strategy.effectiveRules === 3" class="flex items-center gap-16px">
                    <span class="text-[#606266]">有效期至</span>
                    <span>有效期至</span>
                    <NDatePicker
                      v-model:value="strategy.endTime" type="date" format="yyyy/MM/dd" clearable
                      :actions="null" close-on-select placeholder="请选择日期" style="width: 200px;"
                      :actions="null" close-on-select placeholder="请选择日期" style="width: 240px;"
                    />
                  </div>
                </div>
              </NFormItem>
              <!-- 是否可叠加使用 -->
              <NFormItem label="是否可叠加使用:">
                <NRadioGroup v-model:value="strategy.stackedUsage">
              <NFormItem label="是否可叠加使用" class="mt-8px">
                <NRadioGroup v-model:value="strategy.stackedUsage" class="h-32px flex items-center">
                  <NSpace>
                    <NRadio :value="0" label="不可叠加" />
                    <NRadio :value="1" label="可叠加" />
@@ -1233,60 +1235,54 @@
              </NFormItem>
              <!-- 使用限时 -->
              <NFormItem label="使用限时:">
                <div class="flex flex-col gap-12px w-full">
                  <span class="text-[#606266] text-14px">仅可在每天的以下时间段使用</span>
              <NFormItem label="使用限时">
                <div class="flex flex-col w-full">
                  <span class="text-[#171f26cc] text-13px h-32px line-height-32px">仅可在每天的以下时间段使用</span>
                  <div
                    v-for="(timeLimit, index) in strategy.usagePeriod" :key="index"
                    class="flex items-center gap-12px"
                    class="flex items-center gap-8px mt-8px"
                  >
                    <NTimePicker
                      v-model:formatted-value="timeLimit.startTime" format="HH:mm" value-format="HH:mm"
                      placeholder="请选择开始时间" style="width: 200px"
                      placeholder="请选择开始时间" style="width: 240px"
                    />
                    <span class="text-[#909399]">至</span>
                    <span class="text-[#171f26cc]">至</span>
                    <NTimePicker
                      v-model:formatted-value="timeLimit.endTime" format="HH:mm" value-format="HH:mm"
                      placeholder="请选择结束时间" style="width: 200px"
                      placeholder="请选择结束时间" style="width: 240px"
                    />
                    <div class="flex gap-8px ml-8px">
                      <div
                        v-if="index === strategy.usagePeriod.length - 1 && strategy.usagePeriod.length < 10"
                        class="w-24px h-24px rounded-full border border-[#0068FF] text-[#0068FF] flex items-center justify-center cursor-pointer"
                        @click="handleAddTimeLimit(strategyIndex)"
                      >
                        <span class="text-16px leading-none">+</span>
                      </div>
                      <div
                        v-if="strategy.usagePeriod.length > 1"
                        class="w-24px h-24px rounded-full border border-[#C0C4CC] text-[#C0C4CC] flex items-center justify-center cursor-pointer"
                        @click="handleRemoveTimeLimit(strategyIndex, index)"
                      >
                        <span class="text-12px leading-none mt-[-2px]">一</span>
                      </div>
                    </div>
                    <img v-if="index > 0" :src="deleteIcon" alt="删除" style="width: 16px;height: 16px;cursor: pointer;" @click="handleRemoveTimeLimit(strategyIndex, index)">
                  </div>
                  <NButton
                    type="primary" secondary style="border: 1px solid #7ABDFF;" class="w-509px mt-16px"
                    @click="handleAddTimeLimit(strategyIndex)"
                  >
                    <template #icon>
                      <icon-park-outline-plus style="font-size: 32px;" />
                    </template>
                    新增时间段
                  </NButton>
                </div>
              </NFormItem>
              <!-- 数量和自动使用 -->
              <div class="flex items-start gap-40px">
                <NFormItem label="每人限领数量:" class="flex-1">
              <div class="flex items-start gap-24px mt-16px">
                <NFormItem label="每人限领数量">
                  <NInputNumber
                    v-model:value="strategy.limitNumber" placeholder="最小1张,最大10张" :min="1" :max="10"
                    :show-button="false" style="width: 100%"
                    :show-button="false" style="width: 240px"
                  />
                </NFormItem>
                <NFormItem label="发放总量:" class="flex-1">
                <NFormItem label="发放总量">
                  <NInputNumber
                    v-model:value="strategy.distributionsTotal" placeholder="若不填则不限数量" :min="1"
                    :show-button="false" style="width: 100%"
                    :show-button="false" style="width: 240px"
                  />
                </NFormItem>
              </div>
              <NFormItem label="是否自动使用:">
                <NRadioGroup v-model:value="strategy.startUsing">
              <NFormItem label="是否自动使用" class="mt-8px">
                <NRadioGroup v-model:value="strategy.startUsing" class="h-32px flex items-center pl-8px">
                  <NSpace>
                    <NRadio :value="0" label="不开启" />
                    <NRadio :value="1" label="冒泡发单时自动使用" />
@@ -1296,23 +1292,23 @@
            </NForm>
          </div>
          <div class="flex justify-center mt-24px pb-24px">
            <NButton type="primary" style="width: 400px" @click="handleAddStrategy">
          <div class="flex">
            <NButton type="primary" secondary style="width: 240px;border: 1px solid #7ABDFF;" @click="handleAddStrategy">
              新增策略
            </NButton>
          </div>
        </div>
        <!-- 发放用户 -->
        <div v-show="activeTab === 3" class="flex flex-col gap-32px pb-24px">
        <div v-show="activeTab === 3" class="flex flex-col">
          <div
            v-for="(group, groupIndex) in userGroupList" :key="groupIndex"
            class="flex flex-col gap-24px border-b border-[#EBEEF5] last:border-b-0 pb-24px last:pb-0"
            class="flex flex-col gap-24px border-b border-[#EBEEF5] last:border-b-0 pb-24px last:pb-0 mb-24px"
          >
            <div class="flex items-center gap-40px">
            <div class="flex items-center gap-24px">
              <div class="flex items-center gap-16px">
                <span class="text-[#606266]">用户类型</span>
                <div class="flex items-center gap-8px">
                <div class="flex items-center gap-4px">
                  <NRadioGroup v-model:value="group.userType">
                    <NRadioButton :value="1" label="全部" />
                    <NRadioButton :value="2" label="老用户" />
@@ -1321,7 +1317,7 @@
                    <NRadioButton :value="5" label="指定用户" />
                  </NRadioGroup>
                  <icon-park-outline-help
                    v-if="groupIndex === 0" color="#0256ff" class="cursor-pointer"
                    color="#0256ff" class="cursor-pointer"
                    @click="showUserTypeHelpModal = true"
                  />
                </div>
@@ -1336,22 +1332,33 @@
                  @update:value="(value) => syncUserGroupStrategy(groupIndex, value as number | null)"
                />
              </div>
              <img v-if="groupIndex > 0" :src="deleteIcon" alt="删除" style="width: 16px;height: 16px;cursor: pointer;margin-left: auto;" @click="handleRemoveUserGroup(groupIndex)">
            </div>
            <!-- 指定用户下的表格 -->
            <div v-if="group.userType === 5" class="flex flex-col gap-16px w-full">
              <div>
                <NButton type="primary" style="width: 100px;" @click="handleOpenUserModal(groupIndex)">
            <div v-if="group.userType === 5" class="flex flex-col gap-12px w-full">
              <div class="flex justify-end">
                <NButton type="primary" secondary style="width: 84px;border: 1px solid #7ABDFF;" @click="handleOpenUserModal(groupIndex)">
                  导入用户
                </NButton>
              </div>
              <div class="border border-[#EBEEF5] rounded-4px overflow-hidden">
              <div class="overflow-hidden">
                <NDataTable
                  :columns="createUserColumns(groupIndex)" :data="group.userList" :bordered="false"
                  size="small" style="height: 250px" flex-height
                />
                  :columns="createUserColumns(groupIndex)"
                  :data="group.userList"
                  :bordered="false"
                  flex-height
                  style="min-height: 263px"
                  :pagination="false"
                >
                  <template #empty>
                    <div class="flex-center">
                      <img src="/src/assets/element-img/no-data.png" style="width:123px;height:125px" @error="(e: any) => { e.target.src = 'https://huishou-1323682843.cos.ap-nanjing.myqcloud.com/images/9bed493b-a6aa-4ef6-ac10-7f67f5c6adc5.png' }">
                    </div>
                  </template>
                </NDataTable>
              </div>
              <div class="flex justify-end mt-8px">
              <div v-if="group.pagination.total > 0" class="flex justify-end mt-8px">
                <Pagination
                  :count="group.pagination.total" :page="group.pagination.page"
                  :page-size="group.pagination.pageSize"
@@ -1361,9 +1368,11 @@
            </div>
          </div>
          <div class="flex justify-center mt-24px">
          <div class="flex">
            <NButton
              style="width: 400px; color: #0068FF; border-color: #7ABDFF; background-color: #E6F4FF;"
              style="width: 240px; border: 1px solid #7ABDFF;"
              secondary
              type="primary"
              @click="handleAddUserGroup"
            >
              新增用户群
@@ -1372,11 +1381,11 @@
        </div>
        <!-- 通知方式 -->
        <div v-show="activeTab === 4" class="flex flex-col gap-24px">
          <div class="flex items-center gap-24px">
            <span class="text-[#606266] shrink-0">通知方式:</span>
        <div v-show="activeTab === 4" class="flex flex-col gap-12px">
          <div class="flex items-center gap-16px mb-8px">
            <span>通知方式</span>
            <NCheckboxGroup v-model:value="notifyForm.noticeType">
              <NSpace item-style="display: flex; align-items: center;" :size="40">
              <NSpace item-style="display: flex; align-items: center;" :size="16">
                <NCheckbox :value="1" label="微信消息通知" />
                <NCheckbox :value="2" label="短信通知" />
                <NCheckbox :value="4" label="小程序弹窗通知" />
@@ -1386,16 +1395,16 @@
          <div
            v-if="notifyForm.noticeType.includes(1)"
            class="bg-[#F8F9FA] rounded-8px p-24px flex flex-col gap-24px"
            class="border border-[#EEE9E9] border-solid rounded-6px p-24px flex flex-col gap-16px"
          >
            <div class="text-[#171f26] font-bold text-14px">
            <div class=" font-bold text-14px">
              微信消息配置
            </div>
            <div class="flex items-center gap-24px pl-16px">
              <span class="text-[#606266] shrink-0">触达时机:</span>
            <div class="flex items-center gap-16px">
              <span>触达时机</span>
              <NCheckboxGroup v-model:value="notifyForm.wechatTriggerTiming">
                <NSpace :size="40">
                <NSpace :size="16">
                  <NCheckbox :value="1" label="券到账" />
                  <NCheckbox :value="2" label="即将过期" />
                  <NCheckbox :value="4" label="活动开始" />
@@ -1403,35 +1412,35 @@
              </NCheckboxGroup>
            </div>
            <div class="flex items-center gap-12px pl-16px ml-[70px]">
              <span class="text-[#606266]">临近到期时间前</span>
            <div class="flex items-center gap-8px ml-[70px]">
              <span>临近到期时间前</span>
              <NInputNumber
                v-model:value="notifyForm.wechatDaysBeforeExpiry" placeholder="请输入天数" :show-button="false"
                style="width: 160px;"
                style="width: 109px;"
              />
              <span class="text-[#606266]">天,触达通知</span>
              <span>天,触达通知</span>
              <span class="text-[#606266] ml-24px">临近券生效前</span>
              <span class="text-[#606266] ml-16px">临近券生效前</span>
              <NInputNumber
                v-model:value="notifyForm.wechatMinutesBeforeEffective" placeholder="请输入分钟数" :show-button="false"
                style="width: 160px;"
                style="width: 109px;"
              />
              <span class="text-[#606266]">分钟,触达通知</span>
              <span>分钟,触达通知</span>
            </div>
          </div>
          <div
            v-if="notifyForm.noticeType.includes(2)"
            class="bg-[#F8F9FA] rounded-8px p-24px flex flex-col gap-24px"
            class="border border-[#EEE9E9] border-solid rounded-6px p-24px flex flex-col gap-16px"
          >
            <div class="text-[#171f26] font-bold text-14px">
            <div class="font-bold text-14px">
              短信通知配置
            </div>
            <div class="flex items-center gap-24px pl-16px">
              <span class="text-[#606266] shrink-0">触达时机:</span>
            <div class="flex items-center gap-16px">
              <span>触达时机</span>
              <NCheckboxGroup v-model:value="notifyForm.smsTriggerTiming">
                <NSpace :size="40">
                <NSpace :size="16">
                  <NCheckbox :value="1" label="券到账" />
                  <NCheckbox :value="2" label="即将过期" />
                  <NCheckbox :value="4" label="活动开始" />
@@ -1439,58 +1448,61 @@
              </NCheckboxGroup>
            </div>
            <div class="flex items-center gap-12px pl-16px ml-[70px]">
              <span class="text-[#606266]">临近到期时间前</span>
            <div class="flex items-center gap-8px ml-[70px]">
              <span>临近到期时间前</span>
              <NInputNumber
                v-model:value="notifyForm.smsDaysBeforeExpiry" placeholder="请输入天数" :show-button="false"
                style="width: 160px;"
                style="width: 109px;"
              />
              <span class="text-[#606266]">天,触达通知</span>
              <span>天,触达通知</span>
              <span class="text-[#606266] ml-24px">临近券生效前</span>
              <span class="text-[#606266] ml-16px">临近券生效前</span>
              <NInputNumber
                v-model:value="notifyForm.smsMinutesBeforeEffective" placeholder="请输入分钟数" :show-button="false"
                style="width: 160px;"
                style="width: 109px;"
              />
              <span class="text-[#606266]">分钟,触达通知</span>
              <span>分钟,触达通知</span>
            </div>
            <div class="flex flex-col gap-12px pl-16px">
              <span class="text-[#606266] shrink-0">短信通知屏蔽时间:</span>
              <div
                v-for="(timeLimit, index) in notifyForm.blockTime"
                :key="index"
                class="flex items-center gap-12px"
              >
                <NTimePicker
                  v-model:formatted-value="timeLimit.startTime"
                  format="HH:mm"
                  value-format="HH:mm"
                  placeholder="请选择开始时间"
                  style="width: 200px"
                />
                <span class="text-[#909399]">至</span>
                <NTimePicker
                  v-model:formatted-value="timeLimit.endTime"
                  format="HH:mm"
                  value-format="HH:mm"
                  placeholder="请选择结束时间"
                  style="width: 200px"
                />
                <div class="flex gap-8px ml-8px">
                  <div
                    v-if="index === notifyForm.blockTime.length - 1 && notifyForm.blockTime.length < 10"
                    class="w-24px h-24px rounded-full border border-[#0068FF] text-[#0068FF] flex items-center justify-center cursor-pointer"
                    @click="handleAddBlockTime"
                  >
                    <span class="text-16px leading-none">+</span>
                  </div>
                  <div
                    v-if="notifyForm.blockTime.length > 1"
                    class="w-24px h-24px rounded-full border border-[#C0C4CC] text-[#C0C4CC] flex items-center justify-center cursor-pointer"
                    @click="handleRemoveBlockTime(index)"
                  >
                    <span class="text-12px leading-none mt-[-2px]">一</span>
            <div class="flex gap-8px">
              <span>短信通知屏蔽时间</span>
              <div class="flex flex-col gap-8px">
                <div
                  v-for="(timeLimit, index) in notifyForm.blockTime"
                  :key="index"
                  class="flex flex items-center gap-8px"
                >
                  <NTimePicker
                    v-model:formatted-value="timeLimit.startTime"
                    format="HH:mm"
                    value-format="HH:mm"
                    placeholder="请选择开始时间"
                    style="width: 240px"
                  />
                  <span class="text-[#909399]">至</span>
                  <NTimePicker
                    v-model:formatted-value="timeLimit.endTime"
                    format="HH:mm"
                    value-format="HH:mm"
                    placeholder="请选择结束时间"
                    style="width: 240px"
                  />
                  <img v-if="index > 0" :src="deleteIcon" alt="删除" style="width: 16px;height: 16px;cursor: pointer;margin-left: auto;" @click="handleRemoveBlockTime(index)">
                  <div class="flex gap-8px ml-8px">
                    <div
                      v-if="index === notifyForm.blockTime.length - 1 && notifyForm.blockTime.length < 10"
                      class="w-24px h-24px rounded-full border border-[#0068FF] text-[#0068FF] flex items-center justify-center cursor-pointer"
                      @click="handleAddBlockTime"
                    >
                      <span class="text-16px leading-none">+</span>
                    </div>
                    <div
                      v-if="notifyForm.blockTime.length > 1"
                      class="w-24px h-24px rounded-full border border-[#C0C4CC] text-[#C0C4CC] flex items-center justify-center cursor-pointer"
                      @click="handleRemoveBlockTime(index)"
                    >
                      <span class="text-12px leading-none mt-[-2px]">一</span>
                    </div>
                  </div>
                </div>
              </div>
@@ -1499,9 +1511,9 @@
          <div
            v-if="notifyForm.noticeType.includes(4)"
            class="bg-[#F8F9FA] rounded-8px p-24px flex flex-col gap-24px"
            class="border border-[#EEE9E9] border-solid rounded-6px p-24px flex flex-col gap-16px"
          >
            <div class="text-[#171f26] font-bold text-14px">
            <div class=" font-bold text-14px">
              小程序弹窗配置
            </div>
            <div class="mini-popup-panel">
@@ -1649,6 +1661,8 @@
  :deep(.n-form-item-label) {
    padding-right: 8px !important;
    font-size: 14px;
    font-weight: 500;
  }
  :deep(.n-radio-button:first-child) {
@@ -1784,4 +1798,25 @@
  width: 96px;
  flex-shrink: 0;
}
:deep(.n-tabs-tab-pad) {
  width: 24px !important;
}
:deep(.n-tabs-pane-wrapper) {
  height: 8px !important;
}
:deep(.n-tabs-nav-scroll-content) {
  border: none !important;
}
:deep(.n-tabs-bar) {
  height: 3px !important;
}
:deep(.n-data-table-empty) {
  border-bottom: 1px solid #EBEEF5;
  box-sizing: border-box;
}
</style>