ActivityApplyHistoryPopup.vue 8.53 KB
<template>
  <van-popup
    :show="show"
    @update:show="(v) => emit('update:show', v)"
    position="bottom"
    :style="{ width: '100%', height: '100%' }"
    :lock-scroll="true"
  >
    <div class="h-full w-full flex flex-col bg-[#F7F8FA]">
      <div class="bg-white px-4 py-3 flex items-center justify-between shadow-sm">
        <div class="flex items-center gap-3">
          <!-- <van-icon name="arrow-left" class="text-[#333]" @click="emit('update:show', false)" /> -->
          <div class="text-[#333] font-bold text-base">遗失的星球活动</div>
        </div>
        <van-icon name="cross" class="text-[#999]" @click="emit('update:show', false)" />
      </div>

      <div class="bg-white px-4 py-3 flex justify-between items-center sticky top-0 z-20 shadow-sm">
        <span class="text-[#333] font-medium text-sm">已补充</span>
        <div class="flex items-center text-[#666] text-sm">
          <span>{{ apply_records.length }}条</span>
        </div>
      </div>

      <div class="flex-1 overflow-y-auto px-4 py-4 space-y-4">
        <div
          v-for="item in apply_records"
          :key="item.id"
          class="bg-white rounded-xl py-4 pr-4 pl-0 shadow-sm relative overflow-hidden flex"
        >
          <div class="w-1 h-4 bg-[#0052D9] rounded-r-sm mt-1 shrink-0 self-start"></div>

          <div class="pl-3 flex-1">
            <h3 class="text-[#333] font-bold text-base leading-snug">
              {{ item.name }}
            </h3>

            <div class="border-t border-dashed border-gray-200 my-3"></div>

            <div class="flex justify-between items-center text-xs text-[#666] mb-2">
              <span>活动年份: {{ item.year }}</span>
              <span class="text-[#FF3B30] font-bold">实付金额: {{ format_paid_amount(item.paid_amount) }}</span>
            </div>

            <div class="flex justify-between items-center text-xs text-[#666] mb-4">
              <span>活动地点: {{ item.location }}</span>
            </div>

            <div class="flex justify-end gap-2">
              <van-button
                size="small"
                plain
                color="#0052D9"
                class="!rounded-full !px-4 !h-[28px] !text-xs"
                @click="open_edit(item)"
              >
                修改
              </van-button>
              <van-button
                size="small"
                plain
                color="#FF3B30"
                class="!rounded-full !px-4 !h-[28px] !text-xs"
                @click="confirm_delete(item)"
              >
                删除
              </van-button>
            </div>
          </div>
        </div>

        <div v-if="!apply_records.length" class="py-10 text-center text-sm text-[#999]">
          暂无申请记录
        </div>
      </div>

      <div class="bg-white/60 backdrop-blur-md p-4 pb-8 shadow-[0_-2px_10px_rgba(0,0,0,0.05)]">
        <van-button
          block
          color="#0052D9"
          class="!rounded-lg !h-[44px] !text-base !font-bold"
          @click="open_add"
        >
          新增
        </van-button>
      </div>
    </div>

    <van-popup
      v-model:show="show_form_popup"
      round
      position="bottom"
      :style="{ height: '70%' }"
      class="flex flex-col"
    >
      <div class="p-4 flex-1 flex flex-col">
        <div class="flex items-center justify-between mb-5">
          <h3 class="text-center font-bold text-lg text-[#333]">{{ form_mode === 'add' ? '新增' : '编辑' }}</h3>
          <van-icon name="cross" class="text-[#999]" @click="close_form_popup" />
        </div>

        <div class="bg-white rounded-xl overflow-hidden">
          <van-field
            v-model="form.name"
            label="活动名称"
            placeholder="例如: 2025年北京市海淀区活动"
            class="!py-3"
            type="textarea"
          />
          <van-field
            v-model="form.year"
            label="活动年份"
            placeholder="例如: 2025"
            class="!py-3"
          />
          <van-field
            v-model="form.location"
            label="活动地点"
            placeholder="例如: 北京市海淀区"
            class="!py-3"
          />
          <van-field
            v-model="form.paid_amount"
            label="实付金额"
            placeholder="例如: 1000"
            class="!py-3"
          />
        </div>

        <div class="mt-auto pt-6 flex gap-3">
          <van-button
            block
            plain
            color="#0052D9"
            class="!rounded-lg !h-[44px] !text-base !font-medium flex-1"
            @click="close_form_popup"
          >
            取消
          </van-button>
          <van-button
            block
            color="#0052D9"
            class="!rounded-lg !h-[44px] !text-base !font-bold flex-1"
            @click="submit_form"
          >
            保存
          </van-button>
        </div>
      </div>
    </van-popup>
  </van-popup>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { showToast, showConfirmDialog } from 'vant'
import { getSupplementListAPI, supplementAddAPI, supplementEditAPI, supplementDelAPI } from '@/api/recall_users'

const props = defineProps({
  show: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:show'])

const apply_records = ref([])

const show_form_popup = ref(false)
const form_mode = ref('add')
const editing_id = ref(null)
const form = ref({
  name: '',
  year: '',
  location: '',
  paid_amount: ''
})

const reset_form = () => {
  form.value = {
    name: '',
    year: '',
    location: '',
    paid_amount: ''
  }
  editing_id.value = null
}

const fetch_records = async () => {
  const res = await getSupplementListAPI()
  if (res && res.code) {
    const list = Array.isArray(res.data) ? res.data : []
    apply_records.value = list.map((item) => ({
      id: item.id,
      name: item.title || '',
      year: item.year || '',
      location: item.address || '',
      paid_amount: item.amount ?? ''
    }))
  } else if (res && res.msg) {
    showToast(res.msg)
  }
}

const open_add = () => {
  form_mode.value = 'add'
  reset_form()
  show_form_popup.value = true
}

const open_edit = (item) => {
  form_mode.value = 'edit'
  editing_id.value = item.id
  form.value = {
    name: item.name || '',
    year: item.year || '',
    location: item.location || '',
    paid_amount: item.paid_amount || ''
  }
  show_form_popup.value = true
}

const close_form_popup = () => {
  show_form_popup.value = false
}

const submit_form = async () => {
  if (!String(form.value.name || '').trim()) {
    showToast('请输入活动名称')
    return
  }
  if (!String(form.value.year || '').trim()) {
    showToast('请输入活动年份')
    return
  }
  if (!String(form.value.location || '').trim()) {
    showToast('请输入活动地点')
    return
  }
  if (!String(form.value.paid_amount || '').trim()) {
    showToast('请输入实付金额')
    return
  }

  const params = {
    title: form.value.name,
    year: form.value.year,
    address: form.value.location,
    amount: form.value.paid_amount
  }

  if (form_mode.value === 'add') {
    const res = await supplementAddAPI(params)
    if (res && res.code) {
      showToast('新增成功')
      show_form_popup.value = false
      fetch_records()
    } else if (res && res.msg) {
      showToast(res.msg)
    } else {
      showToast('新增失败,请稍后重试')
    }
  } else {
    const res = await supplementEditAPI({
      id: editing_id.value,
      ...params
    })
    if (res && res.code) {
      showToast('修改成功')
      show_form_popup.value = false
      fetch_records()
    } else if (res && res.msg) {
      showToast(res.msg)
    } else {
      showToast('修改失败,请稍后重试')
    }
  }
}

const confirm_delete = async (item) => {
  try {
    await showConfirmDialog({
      title: '温馨提示',
      message: `确定要删除“${item.name || '该记录'}”吗?`,
      confirmButtonColor: '#FF3B30'
    })
  } catch (e) {
    return
  }

  const res = await supplementDelAPI({ id: item.id })
  if (res && res.code) {
    showToast('删除成功')
    fetch_records()
  } else if (res && res.msg) {
    showToast(res.msg)
  } else {
    showToast('删除失败,请稍后重试')
  }
}

const format_paid_amount = (val) => {
  const str = String(val ?? '').trim()
  if (!str) return '¥0.00'

  const pure = str.replace(/^¥/, '').trim()
  const num = Number(pure)
  if (Number.isFinite(num) && pure !== '') {
    return `¥${num.toFixed(2)}`
  }
  return str.startsWith('¥') ? str : `¥${str}`
}

onMounted(() => {
  fetch_records()
})
</script>