Forráskód Böngészése

feat: 新增优惠券审核功能,包含审核列表和详情页面,优化用户权限管理

laiqi 11 hónapja
szülő
commit
db8a4a79d4

+ 22 - 0
src/App.vue

@@ -3,6 +3,8 @@ import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
 import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only'
 import { useDictStore } from '@/store/dict'
 import { useFileStore } from '@/store/file'
+import { useUserStore } from '@/store/user'
+import { useAppStore } from '@/store/app'
 
 onLaunch(async () => {
   // console.log('App =====> onLaunch')
@@ -16,8 +18,28 @@ onLaunch(async () => {
     const fileHeadUrl = configList[0].substance
     fileStore.setFileHeadUrl(fileHeadUrl)
   }
+
+  // 获取审核权限的openid配置
+  getAuditOpenidConfig()
 })
 
+// 获取审核权限的openid配置
+const getAuditOpenidConfig = async () => {
+  const userStore = useUserStore()
+  const dictStore = useDictStore()
+  const appStore = useAppStore()
+  const configList = await dictStore.getConfigList('audit_openid')
+
+  if (configList.length > 0) {
+    const auditOpenid = configList[0].substance.split(',')
+    if (auditOpenid.includes(appStore.appInfo.openid)) {
+      userStore.setAuditAuth(true)
+    } else {
+      userStore.setAuditAuth(false)
+    }
+  }
+}
+
 onShow(() => {
   // console.log('App =====> onShow')
 })

+ 24 - 0
src/pages.json

@@ -55,6 +55,22 @@
       }
     },
     {
+      "path": "pages/coupon/audit-detail",
+      "type": "page",
+      "layout": "default",
+      "style": {
+        "navigationBarTitleText": "优惠券详情"
+      }
+    },
+    {
+      "path": "pages/coupon/audit-list",
+      "type": "page",
+      "layout": "default",
+      "style": {
+        "navigationBarTitleText": "优惠券审核"
+      }
+    },
+    {
       "path": "pages/coupon/index",
       "type": "page",
       "layout": "default",
@@ -63,6 +79,14 @@
       }
     },
     {
+      "path": "pages/coupon/modify-info",
+      "type": "page",
+      "layout": "default",
+      "style": {
+        "navigationBarTitleText": "修改基本信息"
+      }
+    },
+    {
       "path": "pages/form/formStep1",
       "type": "page",
       "style": {

+ 506 - 0
src/pages/coupon/audit-detail.vue

@@ -0,0 +1,506 @@
+<route lang="json5" type="page">
+{
+  layout: 'default',
+  style: {
+    navigationBarTitleText: '优惠券详情',
+  },
+}
+</route>
+
+<template>
+  <view class="bg-gray-100 min-h-screen pb-20">
+    <!-- 基本信息 -->
+    <view class="bg-white px-4 py-4 mb-3 shadow-sm">
+      <view class="flex items-center mb-4">
+        <view class="text-lg font-bold text-gray-800">基本信息</view>
+        <view class="ml-2 flex-1 h-px bg-gray-100"></view>
+      </view>
+
+      <view class="space-y-3">
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">优惠券编号:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.coupon2code || '-' }}
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">优惠券名称:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.coupon2mc || '-' }}
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">申请时间:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ formatDateTime(couponDetail.coupon2adddatetime) }}
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">当前状态:</view>
+          <view class="flex-1">
+            <wd-tag :type="getStatusTagType(couponDetail.coupon2sype)" size="small">
+              {{ getStatusText(couponDetail.coupon2sype) }}
+            </wd-tag>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 申请人信息 -->
+    <view class="bg-white px-4 py-4 mb-3 shadow-sm">
+      <view class="flex items-center mb-4">
+        <view class="text-lg font-bold text-gray-800">申请人信息</view>
+        <view class="ml-2 flex-1 h-px bg-gray-100"></view>
+      </view>
+
+      <view class="space-y-3">
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">用户类型:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.userstype || '-' }}
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">{{ usersnameLabel }}:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.usersname || '-' }}
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">{{ idNumberLabel }}:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ getIdNumber() }}
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">手机号:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.coupon2phone || '-' }}
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">地址:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.usersaddress || '-' }}
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 证件照片 -->
+    <view class="bg-white px-4 py-4 mb-3 shadow-sm">
+      <view class="flex items-center mb-4">
+        <view class="text-lg font-bold text-gray-800">证件照片</view>
+        <view class="ml-2 flex-1 h-px bg-gray-100"></view>
+      </view>
+
+      <view class="space-y-4">
+        <!-- 身份证/营业执照 -->
+        <view>
+          <view class="text-sm text-gray-600 mb-2">{{ idPhotoLabel }}:</view>
+          <view v-if="identityImages.length > 0" class="flex flex-wrap gap-2">
+            <view
+              v-for="(image, index) in identityImages"
+              :key="index"
+              class="w-20 h-20 rounded border border-gray-200 overflow-hidden"
+              @click="
+                previewImage(
+                  image.url,
+                  identityImages.map((img) => img.url),
+                )
+              "
+            >
+              <image :src="image.url" mode="aspectFill" class="w-full h-full" />
+            </view>
+          </view>
+          <view v-else class="text-sm text-gray-400">暂无照片</view>
+        </view>
+
+        <!-- 购机者照片 -->
+        <view>
+          <view class="text-sm text-gray-600 mb-2">购机者照片:</view>
+          <view v-if="buyerImages.length > 0" class="flex flex-wrap gap-2">
+            <view
+              v-for="(image, index) in buyerImages"
+              :key="index"
+              class="w-20 h-20 rounded border border-gray-200 overflow-hidden"
+              @click="
+                previewImage(
+                  image.url,
+                  buyerImages.map((img) => img.url),
+                )
+              "
+            >
+              <image :src="image.url" mode="aspectFill" class="w-full h-full" />
+            </view>
+          </view>
+          <view v-else class="text-sm text-gray-400">暂无照片</view>
+        </view>
+      </view>
+    </view>
+
+    <!-- 审核信息 -->
+    <view class="bg-white px-4 py-4 mb-3 shadow-sm">
+      <view class="flex items-center mb-4">
+        <view class="text-lg font-bold text-gray-800">审核信息</view>
+        <view class="ml-2 flex-1 h-px bg-gray-100"></view>
+      </view>
+
+      <!-- 已审核状态显示 -->
+      <view v-if="couponDetail.coupon2sype !== 0" class="space-y-3">
+        <view class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">审核状态:</view>
+          <view class="flex-1">
+            <wd-tag :type="getStatusTagType(couponDetail.coupon2sype)" size="small">
+              {{ getStatusText(couponDetail.coupon2sype) }}
+            </wd-tag>
+          </view>
+        </view>
+        <view v-if="couponDetail.coupon2shbz" class="flex items-start">
+          <view class="text-sm text-gray-600 w-24">审核备注:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.coupon2shbz }}
+          </view>
+        </view>
+        <view v-if="couponDetail.coupon2shdate" class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">审核时间:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ formatDateTime(couponDetail.coupon2shdate) }}
+          </view>
+        </view>
+        <view v-if="couponDetail.coupon2shuser" class="flex items-center">
+          <view class="text-sm text-gray-600 w-24">审核人员:</view>
+          <view class="text-sm text-gray-800 flex-1">
+            {{ couponDetail.coupon2shuser }}
+          </view>
+        </view>
+      </view>
+
+      <!-- 待审核状态表单 -->
+      <wd-form v-else ref="auditFormRef" :model="auditForm">
+        <wd-cell-group border>
+          <!-- 审核状态 -->
+          <wd-cell
+            title="审核状态"
+            title-width="100px"
+            prop="coupon2sype"
+            required
+            custom-class="custom-cell"
+          >
+            <wd-radio-group
+              v-model="auditForm.coupon2sype"
+              @change="handleAuditStatusChange"
+              inline
+              shape="dot"
+              :rules="[{ required: true, message: '请选择审核状态' }]"
+            >
+              <wd-radio :value="1">审核通过</wd-radio>
+              <wd-radio :value="2">驳回</wd-radio>
+            </wd-radio-group>
+          </wd-cell>
+
+          <!-- 审核备注 -->
+          <wd-textarea
+            label="审核备注"
+            label-width="100px"
+            prop="coupon2shbz"
+            v-model="auditForm.coupon2shbz"
+            placeholder="请输入审核备注(驳回时必填)"
+            :maxlength="200"
+            show-word-limit
+            :required="auditForm.coupon2sype === 2"
+            :rules="
+              auditForm.coupon2sype === 2 ? [{ required: true, message: '驳回时审核备注必填' }] : []
+            "
+          />
+        </wd-cell-group>
+      </wd-form>
+    </view>
+
+    <!-- 提交按钮 -->
+    <view
+      v-if="couponDetail.coupon2sype === 0"
+      class="fixed-bottom bg-white p-4 border-t border-gray-100"
+    >
+      <wd-button
+        type="primary"
+        block
+        size="large"
+        @click="handleSubmitAudit"
+        :loading="submitLoading"
+      >
+        提交审核
+      </wd-button>
+    </view>
+
+    <!-- loading -->
+    <wd-overlay :show="overlayShow">
+      <view class="wrapper w-full h-full flex items-center justify-center">
+        <wd-loading />
+      </view>
+    </wd-overlay>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { reactive, ref, computed } from 'vue'
+import { useMessage } from 'wot-design-uni'
+import { onLoad } from '@dcloudio/uni-app'
+import { useCouponStore } from '@/store/coupon'
+import { useUserStore } from '@/store/user'
+import { useFileStore } from '@/store/file'
+
+const message = useMessage()
+const couponStore = useCouponStore()
+const userStore = useUserStore()
+const fileStore = useFileStore()
+
+// 页面参数
+const coupon2sid = ref('')
+
+// 优惠券详情数据
+const couponDetail = ref<any>({})
+
+// 图片数据
+const identityImages = ref([])
+const buyerImages = ref([])
+
+// 审核表单
+const auditFormRef = ref<any>()
+const auditForm = reactive({
+  coupon2sype: 1, // 默认审核通过
+  coupon2shbz: '', // 审核备注
+})
+
+const overlayShow = ref(false)
+const submitLoading = ref(false)
+
+// 计算属性
+const usersnameLabel = computed(() =>
+  couponDetail.value.userstype === '个人' ? '姓名' : '企业名称',
+)
+const idNumberLabel = computed(() =>
+  couponDetail.value.userstype === '个人' ? '身份证号' : '统一社会信用代码',
+)
+const idPhotoLabel = computed(() =>
+  couponDetail.value.userstype === '个人' ? '身份证正面' : '营业执照',
+)
+
+// 格式化日期时间
+const formatDateTime = (dateTime: string) => {
+  if (!dateTime) return '-'
+  const date = new Date(dateTime)
+  return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
+}
+
+// 获取状态文本
+const getStatusText = (status: number) => {
+  switch (status) {
+    case 0:
+      return '待审核'
+    case 1:
+      return '已通过'
+    case 2:
+      return '已驳回'
+    default:
+      return '未知'
+  }
+}
+
+// 获取状态标签类型
+const getStatusTagType = (status: number) => {
+  switch (status) {
+    case 0:
+      return 'warning'
+    case 1:
+      return 'success'
+    case 2:
+      return 'danger'
+    default:
+      return 'primary'
+  }
+}
+
+// 获取证件号
+const getIdNumber = () => {
+  if (couponDetail.value.userstype === '个人') {
+    return couponDetail.value.usersidcardnumber || '-'
+  } else {
+    return couponDetail.value.usersshtyxydm || '-'
+  }
+}
+
+// 预览图片
+const previewImage = (current: string, urls: string[]) => {
+  uni.previewImage({
+    current,
+    urls,
+  })
+}
+
+// 审核状态变化处理
+const handleAuditStatusChange = () => {
+  // 如果选择审核通过,清空备注
+  if (auditForm.coupon2sype === 1) {
+    auditForm.coupon2shbz = ''
+  }
+}
+
+// 获取图片信息
+const loadImageFiles = async () => {
+  try {
+    // 获取身份证/营业执照图片
+    const identityResult = await fileStore.getAttachmentList({
+      attlsh: coupon2sid.value,
+      attmodel: 'coupon_identity',
+    })
+    identityImages.value = identityResult || []
+
+    // 获取购机者照片
+    const buyerResult = await fileStore.getAttachmentList({
+      attlsh: coupon2sid.value,
+      attmodel: 'coupon_buyer',
+    })
+    buyerImages.value = buyerResult || []
+
+    console.log('获取到的图片信息:', {
+      identityImages: identityImages.value,
+      buyerImages: buyerImages.value,
+    })
+  } catch (error) {
+    console.error('获取图片信息失败:', error)
+  }
+}
+
+// 提交审核
+const handleSubmitAudit = async () => {
+  try {
+    const valid = await auditFormRef.value.validate()
+    if (!valid) {
+      return
+    }
+
+    // 如果是驳回状态,检查备注是否填写
+    if (auditForm.coupon2sype === 2 && !auditForm.coupon2shbz.trim()) {
+      uni.showToast({ title: '驳回时审核备注必填', icon: 'none' })
+      return
+    }
+
+    submitLoading.value = true
+    overlayShow.value = true
+
+    try {
+      // 准备提交参数
+      const submitParams = {
+        coupon2sid: coupon2sid.value,
+        coupon2sype: auditForm.coupon2sype,
+        coupon2shbz: auditForm.coupon2shbz.trim(),
+      }
+
+      console.log('提交审核参数:', submitParams)
+
+      // 调用审核接口
+      const result = await couponStore.submitCoupon2Audit(submitParams)
+
+      console.log('审核结果:', result)
+
+      submitLoading.value = false
+      overlayShow.value = false
+
+      message
+        .confirm({
+          msg: '审核提交成功!',
+          title: '提示',
+          confirmButtonText: '确定',
+          showCancelButton: false,
+        })
+        .then(() => {
+          // 跳转回审核列表页面
+          uni.navigateBack()
+        })
+    } catch (error) {
+      console.error('提交审核失败:', error)
+      submitLoading.value = false
+      overlayShow.value = false
+
+      message.alert({
+        title: '提示',
+        msg: '提交失败,请稍后重试',
+      })
+    }
+  } catch (error) {
+    console.error('审核表单验证失败:', error)
+  }
+}
+
+onLoad(async (query: any) => {
+  coupon2sid.value = query.coupon2sid || ''
+
+  // 检查审核权限
+  if (!userStore.audit_auth) {
+    message
+      .alert({
+        title: '提示',
+        msg: '您没有审核权限',
+      })
+      .then(() => {
+        uni.navigateBack()
+      })
+    return
+  }
+
+  if (coupon2sid.value) {
+    try {
+      overlayShow.value = true
+
+      // 获取优惠券详情
+      const couponDetailResult = await couponStore.getCoupon2AuditDetail({
+        coupon2sid: coupon2sid.value,
+      })
+
+      if (couponDetailResult) {
+        couponDetail.value = couponDetailResult
+
+        // 注意:所有状态的优惠券都可以查看详情
+
+        // 获取并显示图片信息
+        await loadImageFiles()
+      }
+    } catch (error) {
+      console.error('获取优惠券详情失败:', error)
+      message
+        .alert({
+          title: '提示',
+          msg: '获取优惠券信息失败,请稍后重试',
+        })
+        .then(() => {
+          uni.navigateBack()
+        })
+    } finally {
+      overlayShow.value = false
+    }
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.fixed-bottom {
+  position: fixed;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 100;
+}
+
+// 针对 wd-cell 内的自定义样式
+:deep(.custom-cell .wd-cell__value) {
+  flex: 1;
+}
+
+.wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+}
+</style>

+ 315 - 0
src/pages/coupon/audit-list.vue

@@ -0,0 +1,315 @@
+<route lang="json5" type="page">
+{
+  layout: 'default',
+  style: {
+    navigationBarTitleText: '优惠券审核',
+  },
+}
+</route>
+
+<template>
+  <view class="bg-gray-100 min-h-screen">
+    <!-- 筛选条件 -->
+    <view class="filter-section sticky top-0 z-10 bg-gray-50 p-3">
+      <view class="filter-row flex items-center gap-2">
+        <wd-drop-menu custom-style="flex: 0 0 120px;">
+          <wd-drop-menu-item
+            v-model="filterForm.type"
+            :title="getFilterTypeLabel()"
+            :options="filterTypeOptions"
+            @change="onFilterTypeChange"
+          />
+        </wd-drop-menu>
+        <wd-drop-menu v-if="filterForm.type === 'status'" custom-style="flex: 1">
+          <wd-drop-menu-item
+            v-model="filterForm.value"
+            :title="getStatusLabel()"
+            :options="statusOptions"
+          />
+        </wd-drop-menu>
+        <wd-input
+          v-else
+          v-model="filterForm.value"
+          :placeholder="getInputPlaceholder()"
+          :disabled="!filterForm.type"
+          custom-style="flex: 1"
+          clearable
+        />
+        <wd-button type="primary" size="small" @click="handleSearch">搜索</wd-button>
+      </view>
+    </view>
+
+    <!-- 列表 -->
+    <view class="px-4">
+      <view v-if="loading" class="flex justify-center py-8">
+        <wd-loading />
+      </view>
+
+      <view v-else-if="couponList.length === 0" class="text-center py-8 text-gray-500">
+        暂无数据
+      </view>
+
+      <view v-else class="space-y-3">
+        <view
+          v-for="item in couponList"
+          :key="item.coupon2sid"
+          class="bg-white rounded-lg p-4 shadow-sm"
+          @click="handleItemClick(item)"
+        >
+          <!-- 头部信息 -->
+          <view class="flex justify-between items-start mb-3">
+            <view class="flex-1">
+              <view class="text-lg font-bold text-gray-800 mb-1">
+                {{ item.coupon2mc || '优惠券' }}
+              </view>
+              <view class="text-sm text-gray-500">优惠劵编号:{{ item.coupon2code || '-' }}</view>
+              <view class="text-sm text-gray-500">
+                申请时间:{{ formatDateTime(item.coupon2adddatetime) }}
+              </view>
+            </view>
+            <view class="ml-3">
+              <wd-tag :type="getStatusTagType(item.coupon2sype)" size="small">
+                {{ getStatusText(item.coupon2sype) }}
+              </wd-tag>
+            </view>
+          </view>
+
+          <!-- 用户信息 -->
+          <view class="border-t border-gray-100 pt-3 space-y-2">
+            <view class="flex items-center">
+              <view class="text-sm text-gray-600 w-20">申请人:</view>
+              <view class="text-sm text-gray-800 flex-1">
+                {{ item.usersname || '-' }}
+              </view>
+            </view>
+            <view class="flex items-center">
+              <view class="text-sm text-gray-600 w-20">用户类型:</view>
+              <view class="text-sm text-gray-800 flex-1">
+                {{ item.userstype || '-' }}
+              </view>
+            </view>
+            <view class="flex items-center">
+              <view class="text-sm text-gray-600 w-20">手机号:</view>
+              <view class="text-sm text-gray-800 flex-1">
+                {{ item.coupon2phone || '-' }}
+              </view>
+            </view>
+            <view v-if="item.coupon2sype === 2 && item.coupon2shbz" class="flex items-start">
+              <view class="text-sm text-gray-600 w-20">驳回原因:</view>
+              <view class="text-sm text-red-600 flex-1">
+                {{ item.coupon2shbz }}
+              </view>
+            </view>
+          </view>
+
+          <!-- 操作提示 -->
+          <view class="mt-3 pt-3 border-t border-gray-100">
+            <view class="text-xs text-blue-600 text-center">
+              {{ item.coupon2sype === 0 ? '点击进入审核详情' : '点击查看详情' }}
+            </view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import { useCouponStore } from '@/store/coupon'
+import { useUserStore } from '@/store/user'
+import { useMessage } from 'wot-design-uni'
+import dayjs from 'dayjs'
+
+const message = useMessage()
+const couponStore = useCouponStore()
+const userStore = useUserStore()
+
+// 筛选表单数据
+const filterForm = ref({
+  type: '',
+  value: '',
+})
+
+// 下拉选项数据
+const filterTypeOptions = ref([
+  { label: '手机号', value: 'phone' },
+  { label: '姓名', value: 'name' },
+  { label: '审核状态', value: 'status' },
+])
+
+// 审核状态选项
+const statusOptions = ref([
+  { label: '全部', value: '' },
+  { label: '待审核', value: '0' },
+  { label: '已通过', value: '1' },
+  { label: '已驳回', value: '2' },
+])
+
+// 列表数据
+const couponList = ref([])
+const originalCouponList = ref([])
+const loading = ref(false)
+
+// 格式化日期时间
+const formatDateTime = (dateTime: string) => {
+  if (!dateTime) return '-'
+  return dayjs(dateTime).format('YYYY-MM-DD HH:mm:ss')
+}
+
+// 获取状态文本
+const getStatusText = (status: number) => {
+  switch (status) {
+    case 0:
+      return '待审核'
+    case 1:
+      return '已通过'
+    case 2:
+      return '已驳回'
+    default:
+      return '未知'
+  }
+}
+
+// 获取状态标签类型
+const getStatusTagType = (status: number) => {
+  switch (status) {
+    case 0:
+      return 'warning'
+    case 1:
+      return 'success'
+    case 2:
+      return 'danger'
+    default:
+      return 'primary'
+  }
+}
+
+// 获取当前筛选类型的标签
+const getFilterTypeLabel = () => {
+  if (!filterForm.value.type) return '筛选类型'
+
+  const selectedOption = filterTypeOptions.value.find(
+    (option) => option.value === filterForm.value.type,
+  )
+  return selectedOption ? selectedOption.label : '筛选类型'
+}
+
+// 获取当前选中状态的标签
+const getStatusLabel = () => {
+  if (!filterForm.value.value) return '选择状态'
+
+  const selectedOption = statusOptions.value.find(
+    (option) => option.value === filterForm.value.value,
+  )
+  return selectedOption ? selectedOption.label : '选择状态'
+}
+
+// 获取输入框占位符
+const getInputPlaceholder = () => {
+  if (!filterForm.value.type) return '请先选择筛选类型'
+
+  const placeholderMap = {
+    phone: '请输入手机号',
+    name: '请输入姓名',
+    status: '请选择审核状态',
+  }
+  return placeholderMap[filterForm.value.type] || '请输入查询条件'
+}
+
+// 筛选类型变化处理
+const onFilterTypeChange = () => {
+  // 清空筛选值
+  filterForm.value.value = ''
+}
+
+// 获取列表数据
+const loadCouponList = async () => {
+  try {
+    loading.value = true
+
+    const result = await couponStore.getCoupon2AuditList({})
+
+    if (result && result.Data) {
+      originalCouponList.value = result.Data
+      couponList.value = [...originalCouponList.value]
+    } else {
+      originalCouponList.value = []
+      couponList.value = []
+    }
+  } catch (error) {
+    console.error('获取审核列表失败:', error)
+    message.alert({
+      title: '提示',
+      msg: '获取数据失败,请稍后重试',
+    })
+  } finally {
+    loading.value = false
+  }
+}
+
+// 处理搜索
+const handleSearch = () => {
+  // 从原始数据中筛选
+  let filteredList = [...originalCouponList.value]
+
+  if (filterForm.value.type && filterForm.value.value) {
+    if (filterForm.value.type === 'phone') {
+      filteredList = filteredList.filter(
+        (item) => item.coupon2phone && item.coupon2phone.includes(filterForm.value.value),
+      )
+    } else if (filterForm.value.type === 'name') {
+      filteredList = filteredList.filter(
+        (item) => item.usersname && item.usersname.includes(filterForm.value.value),
+      )
+    } else if (filterForm.value.type === 'status') {
+      if (filterForm.value.value !== '') {
+        filteredList = filteredList.filter(
+          (item) => item.coupon2sype.toString() === filterForm.value.value,
+        )
+      }
+    }
+  }
+
+  couponList.value = filteredList
+}
+
+// 点击列表项
+const handleItemClick = (item: any) => {
+  // 所有状态都可以进入详情页查看
+  uni.navigateTo({
+    url: `/pages/coupon/audit-detail?coupon2sid=${item.coupon2sid}`,
+  })
+}
+
+onLoad(() => {
+  // 检查审核权限
+  if (!userStore.audit_auth) {
+    message
+      .alert({
+        title: '提示',
+        msg: '您没有审核权限',
+      })
+      .then(() => {
+        uni.navigateBack()
+      })
+    return
+  }
+
+  loadCouponList()
+})
+</script>
+
+<style lang="scss" scoped>
+.filter-section {
+  border-radius: 0 0 8px 8px;
+  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+}
+
+.filter-row {
+  display: flex;
+  gap: 8px;
+  align-items: center;
+}
+</style>

+ 150 - 2
src/pages/coupon/index.vue

@@ -10,6 +10,28 @@
 <template>
   <view class="bg-white min-h-screen">
     <view class="space-y-4">
+      <!-- 筛选条件 -->
+      <view class="filter-section bg-gray-50 p-3">
+        <view class="filter-row flex items-center gap-2">
+          <wd-drop-menu custom-style="flex: 0 0 120px;">
+            <wd-drop-menu-item
+              v-model="filterForm.type"
+              :title="getFilterTypeLabel()"
+              :options="filterTypeOptions"
+              @change="onFilterTypeChange"
+            />
+          </wd-drop-menu>
+          <wd-input
+            v-model="filterForm.value"
+            :placeholder="getInputPlaceholder()"
+            :disabled="!filterForm.type"
+            custom-style="flex: 1"
+            clearable
+          />
+          <wd-button type="primary" size="small" @click="handleSearch">搜索</wd-button>
+        </view>
+      </view>
+
       <!-- 优惠券列表 -->
       <view class="sticky-box-content w-100vw" v-if="couponList.length">
         <view class="coupon-list">
@@ -36,7 +58,7 @@
                       : item.coupon2sype === 1
                         ? '审核通过'
                         : item.coupon2sype === 2
-                          ? '审核失败'
+                          ? '审核不通过'
                           : '未知状态'
                   }}
                 </wd-tag>
@@ -59,6 +81,12 @@
               <view class="coupon-info">
                 <text>领劵时间: {{ formatDate(item.coupon2adddatetime) }}</text>
               </view>
+              <view class="coupon-info">
+                <text>用户名: {{ item.usersname || '暂无用户名' }}</text>
+              </view>
+              <view class="coupon-info">
+                <text>电话: {{ item.usersphone || '暂无电话' }}</text>
+              </view>
               <view class="coupon-info" v-if="item.coupon2sype === 2">
                 <text>审核备注: {{ item.coupon2shbz || '暂无审核备注' }}</text>
               </view>
@@ -74,6 +102,17 @@
                 </wd-button>
               </view>
             </view>
+            <!-- 修改信息按钮 - 审核中或审核不通过时显示 -->
+            <view
+              class="coupon-footer flex justify-end"
+              v-if="item.coupon2sype === 0 || item.coupon2sype === 2"
+            >
+              <view>
+                <wd-button type="warning" size="small" @click="handleModifyInfo(item)">
+                  修改信息
+                </wd-button>
+              </view>
+            </view>
           </view>
         </view>
       </view>
@@ -109,12 +148,99 @@ const couponList = ref([])
 const overlayShow = ref(false)
 const message = useMessage()
 
+// 筛选表单数据
+const filterForm = ref({
+  type: '',
+  value: '',
+})
+
+// 下拉选项数据
+const filterTypeOptions = ref([
+  { label: '用户名', value: 'username' },
+  { label: '电话', value: 'phone' },
+  { label: '身份证后4位', value: 'idCardLast4' },
+])
+
+// 各类型对应的选项数据
+const usernameOptions = ref([])
+const phoneOptions = ref([])
+const idCardOptions = ref([])
+
+// 原始优惠券数据(用于筛选)
+const originalCouponList = ref([])
+
 // 格式化日期
 function formatDate(dateStr) {
   if (!dateStr) return '--'
   return dayjs(dateStr).format('YYYY-MM-DD HH:mm:ss')
 }
 
+// 获取当前筛选类型的标签
+function getFilterTypeLabel() {
+  if (!filterForm.value.type) return '筛选类型'
+
+  const selectedOption = filterTypeOptions.value.find(
+    (option) => option.value === filterForm.value.type,
+  )
+  return selectedOption ? selectedOption.label : '筛选类型'
+}
+
+// 获取输入框占位符
+function getInputPlaceholder() {
+  if (!filterForm.value.type) return '请先选择筛选类型'
+
+  const placeholderMap = {
+    username: '请输入用户名',
+    phone: '请输入电话',
+    idCardLast4: '请输入身份证后4位',
+  }
+  return placeholderMap[filterForm.value.type] || '请输入查询条件'
+}
+
+// 筛选类型变化处理
+function onFilterTypeChange() {
+  // 清空筛选值
+  filterForm.value.value = ''
+}
+
+// 提取筛选选项(现在用于生成选项数据,虽然不直接使用但保留用于数据统计)
+function extractFilterOptions(data) {
+  const usernames = Array.from(new Set(data.map((item) => item.usersname).filter(Boolean)))
+  const phones = Array.from(new Set(data.map((item) => item.usersphone).filter(Boolean)))
+  const idCards = Array.from(
+    new Set(data.map((item) => item.usersidcardnumber?.slice(-4)).filter(Boolean)),
+  )
+
+  usernameOptions.value = usernames.map((name) => ({ label: name, value: name }))
+  phoneOptions.value = phones.map((phone) => ({ label: phone, value: phone }))
+  idCardOptions.value = idCards.map((id) => ({ label: id, value: id }))
+}
+
+// 处理搜索
+function handleSearch() {
+  // 从原始数据中筛选
+  let filteredList = [...originalCouponList.value]
+
+  if (filterForm.value.type && filterForm.value.value) {
+    if (filterForm.value.type === 'username') {
+      filteredList = filteredList.filter(
+        (item) => item.usersname && item.usersname.includes(filterForm.value.value),
+      )
+    } else if (filterForm.value.type === 'phone') {
+      filteredList = filteredList.filter(
+        (item) => item.usersphone && item.usersphone.includes(filterForm.value.value),
+      )
+    } else if (filterForm.value.type === 'idCardLast4') {
+      filteredList = filteredList.filter(
+        (item) =>
+          item.usersidcardnumber && item.usersidcardnumber.slice(-4) === filterForm.value.value,
+      )
+    }
+  }
+
+  couponList.value = filteredList
+}
+
 function handleBack() {
   uni.switchTab({
     url: '/pages/index/index',
@@ -128,7 +254,10 @@ onLoad(() => {
   couponStore
     .getCoupon2List({ coupon2userid: appStore.appInfo.userid })
     .then((res) => {
-      couponList.value = res.Data
+      originalCouponList.value = res.Data || []
+      couponList.value = [...originalCouponList.value]
+      // 提取筛选选项
+      extractFilterOptions(originalCouponList.value)
       overlayShow.value = false
     })
     .finally(() => {
@@ -152,9 +281,28 @@ function handleCouponOrder(item) {
     url: `/pages/form/formStep4?productsid=${item.coupon2productids}&couponcode=${item.coupon2code}&usersid=${item.coupon2merchantid}`,
   })
 }
+
+// 修改信息
+function handleModifyInfo(item) {
+  // 跳转到基本信息修改页面,传递优惠券信息
+  uni.navigateTo({
+    url: `/pages/coupon/modify-info?coupon2sid=${item.coupon2sid}`,
+  })
+}
 </script>
 
 <style lang="scss" scoped>
+.filter-section {
+  margin-bottom: 8px;
+  border-radius: 8px;
+}
+
+.filter-row {
+  display: flex;
+  gap: 8px;
+  align-items: center;
+}
+
 .coupon-list {
   padding: 0 12px;
 }

+ 531 - 0
src/pages/coupon/modify-info.vue

@@ -0,0 +1,531 @@
+<route lang="json5" type="page">
+{
+  layout: 'default',
+  style: {
+    navigationBarTitleText: '修改基本信息',
+  },
+}
+</route>
+
+<template>
+  <view class="bg-gray-100 min-h-screen pb-20">
+    <!-- 修改说明 -->
+    <view class="bg-white px-4 py-4 mb-3 shadow-sm">
+      <view class="flex items-center mb-3">
+        <view class="text-lg font-bold text-gray-800">修改说明</view>
+        <view class="ml-2 flex-1 h-px bg-gray-100"></view>
+      </view>
+      <view class="rules-text text-sm text-gray-600 space-y-1">
+        <view>1. 请根据审核反馈,修改相关信息;</view>
+        <view>2. 修改完成后,系统将重新进行审核;</view>
+        <view>3. 审核通过后,您可以使用优惠券进行下单。</view>
+        <view class="text-orange-600">
+          4. 系统将自动回显您的手机号,其他信息按审核反馈修改,请重新填写。
+        </view>
+      </view>
+    </view>
+
+    <!-- 表单区域 -->
+    <view class="bg-white px-4 py-4 shadow-sm">
+      <view class="flex items-center mb-4">
+        <view class="text-lg font-bold text-gray-800">基本信息</view>
+        <view class="ml-2 flex-1 h-px bg-gray-100"></view>
+      </view>
+      <wd-form ref="formRef" :model="formData">
+        <wd-cell-group border>
+          <!-- 用户类型 -->
+          <wd-cell
+            title="用户类型"
+            title-width="100px"
+            prop="userstype"
+            required
+            custom-class="custom-cell"
+          >
+            <wd-radio-group
+              v-model="formData.userstype"
+              @change="handleUserTypeChange"
+              inline
+              shape="dot"
+              :rules="[{ required: true, message: '请选择用户类型' }]"
+            >
+              <wd-radio value="个人">个人</wd-radio>
+              <wd-radio value="企业">企业</wd-radio>
+            </wd-radio-group>
+          </wd-cell>
+
+          <!-- 姓名/企业名称 -->
+          <wd-input
+            :label="usersnameLabel"
+            label-width="100px"
+            prop="usersname"
+            required
+            v-model="formData.usersname"
+            :placeholder="`请输入${usersnameLabel}`"
+            clearable
+            no-border
+            :rules="[{ required: true, message: `请输入${usersnameLabel}` }]"
+          />
+
+          <!-- 证件号 -->
+          <wd-input
+            :label="idNumberLabel"
+            label-width="100px"
+            prop="idNumber"
+            required
+            v-model="formData.idNumber"
+            :placeholder="`请输入${idNumberLabel}`"
+            clearable
+            no-border
+            :rules="[{ required: true, message: `请输入${idNumberLabel}` }]"
+          />
+
+          <!-- 证件照片上传 -->
+          <wd-cell
+            :title="idPhotoLabel"
+            title-width="100px"
+            prop="idPhotoIds"
+            required
+            custom-class="custom-cell"
+          >
+            <view class="flex-1">
+              <!-- 个人身份证上传 -->
+              <template v-if="formData.userstype === '个人'">
+                <UploadComponent
+                  v-model="formData.idCardFiles"
+                  v-model:fileIds="formData.idCardIds"
+                  :limit="1"
+                  attmodel="coupon_identity"
+                  attpath="/coupon_identity/"
+                  modelStats="idCardIds"
+                  message="请上传身份证照片"
+                  tips="请上传身份证正面照片"
+                />
+              </template>
+
+              <!-- 企业营业执照上传 -->
+              <template v-else>
+                <UploadComponent
+                  v-model="formData.businessLicenseFiles"
+                  v-model:fileIds="formData.businessLicenseIds"
+                  :limit="1"
+                  attmodel="coupon_identity"
+                  attpath="/coupon_identity/"
+                  modelStats="businessLicenseIds"
+                  message="请上传营业执照照片"
+                />
+              </template>
+            </view>
+          </wd-cell>
+
+          <!-- 购机者照片上传 (可选) -->
+          <wd-cell title="购机者照片" title-width="100px" custom-class="custom-cell">
+            <view class="flex-1">
+              <UploadComponent
+                v-model="formData.buyerPhoto"
+                v-model:fileIds="formData.buyerPhotoIds"
+                :limit="1"
+                :required="false"
+                attmodel="coupon_buyer"
+                attpath="/coupon_buyer/"
+                modelStats="buyerPhotoIds"
+                message="请上传购机者照片"
+                tips="用于确认购机者身份"
+              />
+            </view>
+          </wd-cell>
+
+          <!-- 手机号 -->
+          <wd-input
+            label="手机号"
+            label-width="100px"
+            prop="phone"
+            required
+            v-model="formData.phone"
+            placeholder="请输入您的手机号码"
+            clearable
+            no-border
+            :rules="[
+              { required: true, message: '请输入手机号码' },
+              { required: false, pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码' },
+            ]"
+            @blur="validatePhone"
+          />
+        </wd-cell-group>
+      </wd-form>
+    </view>
+
+    <!-- 提交按钮 -->
+    <view class="fixed-bottom bg-white p-4 border-t border-gray-100">
+      <wd-button type="primary" block size="large" @click="handleSubmit" :loading="submitLoading">
+        确认保存
+      </wd-button>
+    </view>
+
+    <!-- loading -->
+    <wd-overlay :show="overlayShow">
+      <view class="wrapper w-full h-full flex items-center justify-center">
+        <wd-loading />
+      </view>
+    </wd-overlay>
+  </view>
+</template>
+
+<script lang="ts" setup>
+import { reactive, ref, computed, onMounted } from 'vue'
+import { useMessage } from 'wot-design-uni'
+import { onLoad } from '@dcloudio/uni-app'
+import UploadComponent from '@/components/UploadComponent.vue'
+import { useCouponStore } from '@/store/coupon'
+import { useUserStore } from '@/store/user'
+import { useFileStore } from '@/store/file'
+
+const message = useMessage()
+const couponStore = useCouponStore()
+const userStore = useUserStore()
+const fileStore = useFileStore()
+
+// 页面参数
+const coupon2sid = ref('')
+
+const formRef = ref<any>()
+const formData = reactive({
+  userstype: '个人', // 用户类型,默认个人
+  usersname: '', // 姓名或企业名称
+  idNumber: '', // 证件号
+
+  // 身份证照片(个人用户)
+  idCardFiles: [], // 身份证照片文件列表
+  idCardIds: [], // 身份证照片ID列表
+
+  // 营业执照(企业用户)
+  businessLicenseFiles: [], // 营业执照照片文件列表
+  businessLicenseIds: [], // 营业执照照片ID列表
+
+  // 购机者照片(可选)
+  buyerPhoto: [], // 购机者照片文件列表
+  buyerPhotoIds: [], // 购机者照片ID列表
+
+  phone: '', // 手机号
+})
+
+// 优惠券详情数据
+const couponDetail = ref<any>(null)
+
+const usersnameLabel = computed(() => (formData.userstype === '个人' ? '姓名' : '企业名称'))
+const idNumberLabel = computed(() =>
+  formData.userstype === '个人' ? '身份证号' : '统一社会信用代码',
+)
+const idPhotoLabel = computed(() => (formData.userstype === '个人' ? '身份证正面' : '营业执照'))
+
+const overlayShow = ref(false)
+const submitLoading = ref(false)
+
+// 手机号验证相关
+const isPhoneValid = ref(false)
+const phoneReg = /^1[3-9]\d{9}$/
+
+function validatePhone() {
+  if (!formData.phone) {
+    isPhoneValid.value = false
+    return
+  }
+  isPhoneValid.value = phoneReg.test(formData.phone)
+  if (!isPhoneValid.value && formData.phone) {
+    uni.showToast({ title: '请输入正确的手机号码', icon: 'none' })
+  }
+}
+
+// 用户类型切换
+function handleUserTypeChange() {
+  // 清空相关字段以便用户重新输入和校验
+  formData.usersname = ''
+  formData.idNumber = ''
+
+  // 清空证件照片上传
+  if (formData.userstype === '个人') {
+    formData.idCardFiles = []
+    formData.idCardIds = []
+    formData.businessLicenseFiles = []
+    formData.businessLicenseIds = []
+  } else {
+    formData.idCardFiles = []
+    formData.idCardIds = []
+    formData.businessLicenseFiles = []
+    formData.businessLicenseIds = []
+  }
+
+  // 清空购机者照片
+  formData.buyerPhoto = []
+  formData.buyerPhotoIds = []
+}
+
+// 获取并回显图片信息
+async function loadImageFiles() {
+  try {
+    // 获取身份证/营业执照图片
+    const identityImages = await fileStore.getAttachmentList({
+      attlsh: coupon2sid.value,
+      attmodel: 'coupon_identity',
+    })
+
+    console.log('获取到的身份证/营业执照图片:', identityImages)
+
+    // 获取购机者照片
+    const buyerImages = await fileStore.getAttachmentList({
+      attlsh: coupon2sid.value,
+      attmodel: 'coupon_buyer',
+    })
+
+    console.log('获取到的购机者照片:', buyerImages)
+
+    // 回显身份证/营业执照图片
+    if (identityImages.length > 0) {
+      if (formData.userstype === '个人') {
+        // 个人用户回显身份证
+        formData.idCardFiles = identityImages.map((img) => ({
+          url: img.url,
+          name: img.attorginname || '身份证照片',
+        }))
+        formData.idCardIds = identityImages.map((img) => ({
+          url: img.url,
+          id: img.attid,
+        }))
+      } else {
+        // 企业用户回显营业执照
+        formData.businessLicenseFiles = identityImages.map((img) => ({
+          url: img.url,
+          name: img.attorginname || '营业执照照片',
+        }))
+        formData.businessLicenseIds = identityImages.map((img) => ({
+          url: img.url,
+          id: img.attid,
+        }))
+      }
+    }
+
+    // 回显购机者照片
+    if (buyerImages.length > 0) {
+      formData.buyerPhoto = buyerImages.map((img) => ({
+        url: img.url,
+        name: img.attorginname || '购机者照片',
+      }))
+      formData.buyerPhotoIds = buyerImages.map((img) => ({
+        url: img.url,
+        id: img.attid,
+      }))
+    }
+
+    console.log('回显的图片信息:', {
+      identityImages,
+      buyerImages,
+      formData: {
+        idCardFiles: formData.idCardFiles,
+        idCardIds: formData.idCardIds,
+        businessLicenseFiles: formData.businessLicenseFiles,
+        businessLicenseIds: formData.businessLicenseIds,
+        buyerPhoto: formData.buyerPhoto,
+        buyerPhotoIds: formData.buyerPhotoIds,
+      },
+    })
+  } catch (error) {
+    console.error('获取图片信息失败:', error)
+  }
+}
+
+// 提交表单
+async function handleSubmit() {
+  try {
+    const valid = await formRef.value.validate()
+    if (!valid) {
+      return
+    }
+
+    validatePhone()
+    if (!isPhoneValid.value) {
+      uni.showToast({ title: '请输入正确的手机号码', icon: 'none' })
+      return
+    }
+
+    // 验证证件照片上传
+    const hasUploadedFiles =
+      formData.userstype === '个人'
+        ? formData.idCardIds.length > 0
+        : formData.businessLicenseIds.length > 0
+
+    if (!hasUploadedFiles) {
+      uni.showToast({
+        title: `请上传${formData.userstype === '个人' ? '身份证照片' : '营业执照照片'}`,
+        icon: 'none',
+      })
+      return
+    }
+
+    submitLoading.value = true
+    overlayShow.value = true
+
+    try {
+      // 准备提交参数
+      const submitParams: any = {
+        coupon2sid: coupon2sid.value, // 优惠券ID
+        userstype: formData.userstype, // 用户类型
+        usersname: formData.usersname, // 姓名或企业名称
+        coupon2phone: formData.phone, // 手机号
+      }
+
+      // 根据用户类型添加证件号
+      if (formData.userstype === '个人') {
+        submitParams.usersidcardnumber = formData.idNumber // 身份证号
+      } else {
+        submitParams.usersshtyxydm = formData.idNumber // 统一社会信用代码
+      }
+
+      // 添加文件ID
+      const fileIds = []
+
+      // 添加身份证/营业执照文件ID
+      if (formData.userstype === '个人' && formData.idCardIds.length > 0) {
+        fileIds.push(...formData.idCardIds.map((item) => item.id))
+      } else if (formData.userstype === '企业' && formData.businessLicenseIds.length > 0) {
+        fileIds.push(...formData.businessLicenseIds.map((item) => item.id))
+      }
+
+      // 添加购机者照片文件ID(可选)
+      if (formData.buyerPhotoIds.length > 0) {
+        fileIds.push(...formData.buyerPhotoIds.map((item) => item.id))
+      }
+
+      if (fileIds.length > 0) {
+        submitParams.filesid = fileIds.join(',')
+      }
+
+      console.log('提交参数:', submitParams)
+
+      // 调用修改接口
+      const result = await couponStore.getCoupon2Modify(submitParams)
+
+      console.log('修改结果:', result)
+
+      submitLoading.value = false
+      overlayShow.value = false
+
+      message
+        .confirm({
+          msg: '信息修改成功!系统将重新审核您的优惠券。',
+          title: '提示',
+          confirmButtonText: '确定',
+          showCancelButton: false,
+        })
+        .then(() => {
+          // 跳转回优惠券列表页面
+          uni.navigateBack()
+        })
+    } catch (error) {
+      console.error('提交修改失败:', error)
+      submitLoading.value = false
+      overlayShow.value = false
+
+      message.alert({
+        title: '提示',
+        msg: '提交失败,请稍后重试',
+      })
+    }
+  } catch (error) {
+    console.error('修改信息出错:', error)
+    submitLoading.value = false
+    overlayShow.value = false
+  }
+}
+
+onLoad(async (query: any) => {
+  coupon2sid.value = query.coupon2sid || ''
+
+  if (coupon2sid.value) {
+    try {
+      overlayShow.value = true
+
+      // 获取优惠券详情
+      const couponDetailResult = await couponStore.getCoupon2ViewDetailBySid({
+        coupon2sid: coupon2sid.value,
+      })
+
+      if (couponDetailResult) {
+        couponDetail.value = couponDetailResult
+
+        // 回显表单数据
+        if (couponDetail.value.usersphone) {
+          formData.phone = couponDetail.value.usersphone
+        }
+
+        // 回显用户类型
+        if (couponDetail.value.userstype) {
+          formData.userstype = couponDetail.value.userstype
+        }
+
+        // 回显姓名/企业名称
+        if (couponDetail.value.usersname) {
+          formData.usersname = couponDetail.value.usersname
+        }
+
+        // 回显证件号
+        if (couponDetail.value.usersidcardnumber) {
+          formData.idNumber = couponDetail.value.usersidcardnumber
+        } else if (couponDetail.value.usersshtyxydm) {
+          formData.idNumber = couponDetail.value.usersshtyxydm
+        }
+
+        // 获取并回显图片信息
+        await loadImageFiles()
+      }
+    } catch (error) {
+      console.error('获取优惠券详情失败:', error)
+      message.alert({
+        title: '提示',
+        msg: '获取优惠券信息失败,请稍后重试',
+      })
+    } finally {
+      overlayShow.value = false
+    }
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.rules-text {
+  line-height: 1.6;
+}
+
+.fixed-bottom {
+  position: fixed;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 100;
+}
+
+// 针对 wd-field 内的 wd-input, wd-radio-group 等组件去除边框或调整样式
+:deep(.wd-cell-group .wd-input) {
+  // If they don't have a border by default or if no-border is not working as expected
+  // Example:
+  // border-bottom: 1px solid #eee;
+}
+:deep(.wd-cell-group .wd-input__inner) {
+  // If no-border was intended to remove internal padding/borders of wd-input for wd-field
+  // We might not need this if wd-input itself looks fine as a direct child of wd-cell-group.
+  // The no-border prop on wd-input might be sufficient.
+}
+
+// For wd-cell containing radio group or other custom layouts
+:deep(.custom-cell .wd-cell__value) {
+  flex: 1; // Allow radio group or other content to take full width
+}
+:deep(.custom-cell .wd-radio-group) {
+  // specific styles for radio group if needed
+}
+
+.wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+}
+</style>

+ 1 - 1
src/pages/form/formStep3.vue

@@ -77,7 +77,7 @@
       </view>
       <!-- 领取优惠劵 -->
       <view class="mt-4 px-2">
-        <wd-button type="primary" plain block @tap="navigateToReceiveCoupon">领取优惠劵</wd-button>
+        <wd-button type="primary" block @tap="navigateToReceiveCoupon">领取优惠劵</wd-button>
       </view>
     </view>
 

+ 33 - 1
src/pages/form/formStep3a.vue

@@ -113,6 +113,23 @@
             </view>
           </wd-cell>
 
+          <!-- 购机者照片上传 (可选) -->
+          <wd-cell title="购机者照片" title-width="100px" custom-class="custom-cell">
+            <view class="flex-1">
+              <UploadComponent
+                v-model="formData.buyerPhoto"
+                v-model:fileIds="formData.buyerPhotoIds"
+                :limit="1"
+                :required="false"
+                attmodel="coupon_buyer"
+                attpath="/coupon_buyer/"
+                modelStats="buyerPhotoIds"
+                message="请上传购机者照片"
+                tips="用于确认购机者身份"
+              />
+            </view>
+          </wd-cell>
+
           <!-- 手机号 -->
           <wd-input
             label="手机号"
@@ -177,6 +194,10 @@ const formData = reactive({
   businessLicenseFiles: [], // 营业执照照片文件列表
   businessLicenseIds: [], // 营业执照照片ID列表
 
+  // 购机者照片(可选)
+  buyerPhoto: [], // 购机者照片文件列表
+  buyerPhotoIds: [], // 购机者照片ID列表
+
   phone: '', // 手机号
 })
 
@@ -222,6 +243,10 @@ function handleUserTypeChange() {
     formData.businessLicenseFiles = []
     formData.businessLicenseIds = []
   }
+
+  // 清空购机者照片
+  formData.buyerPhoto = []
+  formData.buyerPhotoIds = []
 }
 
 // 提交表单
@@ -261,6 +286,13 @@ async function handleSubmit() {
         ? formData.idCardIds.map((item) => item.id).join(',')
         : formData.businessLicenseIds.map((item) => item.id).join(',')
 
+    // 收集所有上传文件的ID(包括购机者照片)
+    const allFileIds = [
+      ...fileIds.split(',').filter((id) => id), // 证件照片ID
+      ...formData.buyerPhotoIds.map((item) => item.id), // 购机者照片ID
+    ]
+    const finalFileIds = allFileIds.join(',')
+
     // 调用领取优惠券API
     const res = await couponStore.receiveCouponNew({
       couponid: couponid.value,
@@ -270,7 +302,7 @@ async function handleSubmit() {
       usersname: formData.usersname,
       coupon2productids: productsid.value,
       coupon2phone: formData.phone,
-      filesid: fileIds, // 上传的文件ID字符串
+      filesid: finalFileIds, // 上传的文件ID字符串(包含证件和购机者照片)
       coupon2merchantid: usersid.value,
       // smsCode: formData.smsCode,
       // ... 其他可能需要的参数

+ 16 - 87
src/pages/form/formStep4.vue

@@ -92,74 +92,28 @@
         </wd-cell-group>
       </view>
 
-      <!-- 证件上传 -->
+      <!-- 发票上传 -->
       <view class="bg-white px-4 py-4 mb-3 shadow-sm">
         <view class="flex items-center mb-4">
-          <view class="text-lg font-bold text-gray-800">证件上传</view>
+          <view class="text-lg font-bold text-gray-800">发票上传</view>
           <view class="ml-2 flex-1 h-px bg-gray-100"></view>
         </view>
 
         <view class="mb-4">
           <view class="text-gray-700 mb-2 text-base flex items-center">
-            <text>证件类型</text>
-            <text class="text-red-500 ml-1">*</text>
-          </view>
-          <wd-radio-group v-model="formData.idType" shape="button">
-            <wd-radio value="personal">个人身份证</wd-radio>
-            <wd-radio value="business">企业营业执照</wd-radio>
-          </wd-radio-group>
-        </view>
-
-        <!-- 个人身份证上传 -->
-        <view v-if="formData.idType === 'personal'" class="mb-4">
-          <view class="text-gray-700 mb-2 text-base flex items-center">
-            <text>身份证照片</text>
-            <text class="text-red-500 ml-1">*</text>
-          </view>
-          <UploadComponent
-            v-model="formData.idCardFront"
-            v-model:fileIds="formData.idCardFrontIds"
-            :limit="2"
-            attmodel="orders_identity"
-            attpath="/orders_identity/"
-            modelStats="idCardFrontIds"
-            message="请上传身份证照片"
-            tips="请上传身份证正面和反面"
-          />
-        </view>
-
-        <!-- 营业执照上传 -->
-        <view v-if="formData.idType === 'business'" class="mb-4">
-          <view class="text-gray-700 mb-2 text-base flex items-center">
-            <text>营业执照照片</text>
-            <text class="text-red-500 ml-1">*</text>
-          </view>
-          <UploadComponent
-            v-model="formData.businessLicense"
-            v-model:fileIds="formData.businessLicenseIds"
-            :limit="1"
-            attmodel="orders_identity"
-            attpath="/orders_identity/"
-            modelStats="businessLicenseIds"
-            message="请上传营业执照照片"
-          />
-        </view>
-
-        <!-- 购买人照片上传 (可选) -->
-        <view class="mb-4">
-          <view class="text-gray-700 mb-2 text-base flex items-center">
-            <text>购买人照片</text>
+            <text>发票照片</text>
             <text class="text-gray-400 ml-1">(可选)</text>
           </view>
           <UploadComponent
-            v-model="formData.buyerPhoto"
-            v-model:fileIds="formData.buyerPhotoIds"
+            v-model="formData.invoiceFiles"
+            v-model:fileIds="formData.invoiceFileIds"
             :limit="1"
             :required="false"
-            attmodel="orders_buyer"
-            attpath="/orders_buyer/"
-            modelStats="buyerPhotoIds"
-            message="请上传购买人照片"
+            attmodel="orders_invoice"
+            attpath="/orders_invoice/"
+            modelStats="invoiceFileIds"
+            message="请上传发票照片"
+            tips="请上传清晰的发票照片"
           />
         </view>
       </view>
@@ -212,19 +166,9 @@ const formData = reactive({
   sn: '', // SN码
   phone: '', // 手机号
   couponCode: '', // 优惠码
-  idType: 'personal', // 证件类型:personal - 个人身份证,business - 营业执照
-
-  // 身份证正反面
-  idCardFront: [], // 身份证照片列表
-  idCardFrontIds: [], // 身份证照片ID列表
-
-  // 营业执照
-  businessLicense: [], // 营业执照照片列表
-  businessLicenseIds: [], // 营业执照照片ID列表
-
-  // 购买人照片(可选)
-  buyerPhoto: [], // 购买人照片列表
-  buyerPhotoIds: [], // 购买人照片ID列表
+  // 新增发票相关字段
+  invoiceFiles: [], // 发票照片文件列表
+  invoiceFileIds: [], // 发票照片ID列表
 })
 
 // 表单验证状态
@@ -346,22 +290,8 @@ function validateForm() {
   if (!validateSn()) return false
   if (!validatePhone()) return false
 
-  // 验证证件上传
-  if (formData.idType === 'personal' && !formData.idCardFrontIds.length) {
-    message.alert({
-      title: '提示',
-      msg: '请上传身份证照片',
-    })
-    return false
-  }
-
-  if (formData.idType === 'business' && !formData.businessLicenseIds.length) {
-    message.alert({
-      title: '提示',
-      msg: '请上传营业执照照片',
-    })
-    return false
-  }
+  // 证件上传相关的验证已移除
+  // 发票上传是可选的,此处不添加验证
 
   return true
 }
@@ -376,8 +306,7 @@ async function handleSubmit() {
 
     // 收集所有上传文件的ID
     const allFileIds = [
-      ...(formData.idType === 'personal' ? formData.idCardFrontIds : formData.businessLicenseIds),
-      ...formData.buyerPhotoIds,
+      ...formData.invoiceFileIds, // 包含发票文件ID
     ]
 
     // 提取ID字段

+ 14 - 1
src/pages/mine/index.vue

@@ -56,7 +56,7 @@
       <view class="menu-item" @click="handleToAuthPage('/pages/coupon/index')">
         <view class="flex items-center">
           <wd-icon name="creditcard" class="text-gray-500" />
-          <text class="ml-3">优惠劵</text>
+          <text class="ml-3">我的优惠劵</text>
         </view>
         <wd-icon name="arrow-right" size="18" class="text-gray-400" />
       </view>
@@ -88,6 +88,19 @@
         <wd-icon name="arrow-right" size="18" class="text-gray-400" />
       </view> -->
 
+      <!-- 优惠劵审核 -->
+      <view
+        class="menu-item"
+        @click="handleToAuthPage('/pages/coupon/audit-list')"
+        v-if="userStore.audit_auth"
+      >
+        <view class="flex items-center">
+          <wd-icon name="creditcard" class="text-gray-500" />
+          <text class="ml-3">优惠劵审核</text>
+        </view>
+        <wd-icon name="arrow-right" size="18" class="text-gray-400" />
+      </view>
+
       <!-- 关于 -->
       <view class="menu-item" @click="handleNavigate('/pages/about/index')">
         <view class="flex items-center">

+ 31 - 67
src/pages/order/detail.vue

@@ -31,19 +31,24 @@
             <wd-img :width="100" :height="100" :src="item.url" :enable-preview="true" />
           </view>
         </view>
-        <!-- 发票信息上传按钮 -->
-        <view class="flex flex-wrap justify-end" v-else>
-          <wd-button type="primary" size="small" @click="showUploadDialog = true">
-            上传发票
-          </wd-button>
-        </view>
+        <!-- 无发票信息时的提示 -->
+        <view v-else class="text-gray-500 text-sm">暂无发票信息</view>
       </wd-cell>
-      <wd-cell title="证件信息">
-        <view class="flex flex-wrap">
+      <wd-cell title="购机者证件照片">
+        <view class="flex flex-wrap" v-if="identityImg.length">
           <view class="flex-1" v-for="item in identityImg" :key="item.id">
             <wd-img :width="100" :height="100" :src="item.url" :enable-preview="true" />
           </view>
         </view>
+        <view v-else class="text-gray-500 text-sm">暂无购机者证件照片</view>
+      </wd-cell>
+      <wd-cell title="购机者照片">
+        <view class="flex flex-wrap" v-if="buyerImg.length">
+          <view class="flex-1" v-for="item in buyerImg" :key="item.id">
+            <wd-img :width="100" :height="100" :src="item.url" :enable-preview="true" />
+          </view>
+        </view>
+        <view v-else class="text-gray-500 text-sm">暂无购机者照片</view>
       </wd-cell>
     </wd-cell-group>
 
@@ -51,41 +56,6 @@
     <view class="sticky-box-content w-full box-border px-2 pb-2 mt-4">
       <wd-button type="primary" block @click="handleBack">回到订单列表</wd-button>
     </view>
-
-    <!-- 上传发票弹窗 -->
-    <wd-popup
-      v-model="showUploadDialog"
-      round
-      closable
-      custom-class="upload-popup w-[80%]"
-      class="w-[80%]"
-    >
-      <view class="p-5">
-        <view class="text-lg font-medium text-center mb-5">上传发票</view>
-        <view class="upload-container mb-6">
-          <UploadComponent
-            v-model="invoiceUpload.fileList"
-            v-model:fileIds="invoiceUpload.fileIds"
-            :limit="1"
-            :attlsh="currentOrdersId"
-            attmodel="orders_invoice"
-            attpath="/orders_invoice/"
-            modelStats="invoiceFileIds"
-            message="请上传发票照片"
-          />
-          <view class="text-xs text-gray-500 mt-2 text-center">
-            上传清晰的发票照片,以便于核对信息
-          </view>
-          <!-- 如果上传成功,展示上传成功的文字 -->
-          <view v-if="invoiceUpload.fileIds.length" class="text-center text-green-500 mt-2">
-            上传成功
-          </view>
-        </view>
-        <view class="px-2">
-          <wd-button type="primary" block @click="handleConfirmUpload">确认</wd-button>
-        </view>
-      </view>
-    </wd-popup>
   </view>
 </template>
 
@@ -93,26 +63,20 @@
 import { useOrderStore } from '@/store/order'
 import { useFileStore } from '@/store/file'
 import { useMessage } from 'wot-design-uni'
-import UploadComponent from '@/components/UploadComponent.vue'
 import type { OrderType } from '@/types/order'
 
 const orderStore = useOrderStore()
 const fileStore = useFileStore()
 const message = useMessage()
 const currentOrdersId = ref('')
+const orderscouponid = ref('')
 const orderDetail = ref<OrderType>({} as OrderType)
-const showUploadDialog = ref(false)
-
-// 上传发票文件相关
-const invoiceUpload = reactive({
-  fileList: [],
-  fileIds: [],
-})
 
 // 获取订单详情
 const getOrderDetail = async () => {
   const res = await orderStore.getOrderDetail(currentOrdersId.value)
   orderDetail.value = res
+  orderscouponid.value = res.orderscouponid
 }
 
 // 获取订单状态
@@ -143,42 +107,42 @@ function handleBack() {
 }
 
 const invoiceImg = ref([]) // 发票图片
-const identityImg = ref([]) // 证件信息图片
+const identityImg = ref([]) // 购机者证件照片
+const buyerImg = ref([]) // 购机者照片
 
 // 获取发票图片附件
 const getInvoiceImg = async () => {
   const res = await fileStore.getAttachmentList({
-    attlsh: currentOrdersId.value,
+    attlsh: currentOrdersId.value, // 关联id为订单id
     attmodel: 'orders_invoice',
   })
   invoiceImg.value = res
 }
 
-// 获取证件信息图片附件
+// 获取购机者证件照片附件
 const getIdentityImg = async () => {
   const res = await fileStore.getAttachmentList({
-    attlsh: currentOrdersId.value,
-    attmodel: 'orders_identity',
+    attlsh: orderscouponid.value, // 关联id为优惠劵id
+    attmodel: 'coupon_identity',
   })
   identityImg.value = res
 }
 
-// 确认上传并关闭弹窗
-function handleConfirmUpload() {
-  showUploadDialog.value = false
-  // 重新请求订单详情和发票图片
-  getOrderDetail()
-  getInvoiceImg()
-  // 清空上传数据
-  invoiceUpload.fileList = []
-  invoiceUpload.fileIds = []
+// 获取购机者照片附件
+const getBuyerImg = async () => {
+  const res = await fileStore.getAttachmentList({
+    attlsh: orderscouponid.value, // 关联id为优惠劵id
+    attmodel: 'coupon_buyer',
+  })
+  buyerImg.value = res
 }
 
-onLoad((query) => {
+onLoad(async (query) => {
   currentOrdersId.value = query.ordersid
-  getOrderDetail()
+  await getOrderDetail()
   getInvoiceImg()
   getIdentityImg()
+  getBuyerImg()
 })
 </script>
 

+ 3 - 1
src/pages/order/index.vue

@@ -46,6 +46,8 @@
                 <text class="order-info">订单总金额:</text>
                 <text class="price-text">¥{{ Number(item.orderstotalprice).toFixed(2) }}</text>
               </view>
+              <text class="order-info">用户名: {{ item.usersname }}</text>
+              <text class="order-info">电话: {{ item.ordersphone }}</text>
             </view>
             <view class="order-footer">
               <wd-icon name="arrow-right" />
@@ -145,7 +147,7 @@ function handleBack() {
 onLoad((query) => {
   overlayShow.value = true
   orderStore
-    .getOrderList(appStore.appInfo.userid)
+    .getOrderViewList({ ordersuserid: appStore.appInfo.userid }, { pageindex: 1, rows: 999 })
     .then((res) => {
       orderListAll.value = res
       orderListShow.value = res

+ 49 - 0
src/service/coupon2/index.ts

@@ -10,3 +10,52 @@ export const getCoupon2ViewmListApi = (params: Partial<Coupon2Type>, page: Parti
     ...parseQueryValues(params),
   })
 }
+
+/** 获取优惠券详情 */
+export const getCoupon2DetailApi = (params: Partial<Coupon2Type>) => {
+  return http.get<Coupon2Type>(
+    '/api/query/view?pagevalue=105',
+    {
+      ...parseQueryValues(params),
+    },
+    {
+      formatData: true,
+    },
+  )
+}
+
+/** 优惠劵审核修改 */
+export const getCoupon2ModifyApi = (params: Partial<Coupon2Type>) => {
+  return http.get<any>('/api/nlua/call?pagevalue=106', {
+    ...params,
+  })
+}
+
+/** 优惠劵审核_列表 **/
+export const getCoupon2AuditListApi = (params: Partial<any>, page: Partial<ListType>) => {
+  return http.get<any>('/api/query/list?pagevalue=109', {
+    ...page,
+    ...parseQueryValues(params),
+    'coupon2adddatetime.Sort': '1', // desc
+  })
+}
+
+/** 优惠劵审核_详情 **/
+export const getCoupon2AuditDetailApi = (params: Partial<any>) => {
+  return http.get<any>(
+    '/api/query/view?pagevalue=110',
+    {
+      ...parseQueryValues(params),
+    },
+    {
+      formatData: true,
+    },
+  )
+}
+
+/** 优惠劵审核_提交 **/
+export const submitCoupon2AuditApi = (params: Partial<any>) => {
+  return http.get<any>('/api/nlua/call?pagevalue=111', {
+    ...params,
+  })
+}

+ 22 - 0
src/service/order/index.ts

@@ -34,3 +34,25 @@ export const submitOrderApi = (params: { ordersproductid: string; orderscouponid
 export const submitOrderTelApi = (params: { ordersproductid: string; orderscouponid: string }) => {
   return http.get<any>('/api/nlua/call?pagevalue=99', params)
 }
+
+/** 订单_产品_用户_我的优惠劵_列表 */
+export const getOrderViewListApi2 = (params: Partial<OrderType>, page: Partial<ListType>) => {
+  return http.get<any>('/api/query/list?pagevalue=107', {
+    ...page,
+    ...parseQueryValues(params),
+    'ordersorderdate.Sort': '1', // desc
+  })
+}
+
+/** 订单_产品_用户_我的优惠劵_详情 */
+export const getOrderViewDetailApi2 = (params) => {
+  return http.get<any>(
+    '/api/query/view?pagevalue=108',
+    {
+      ...parseQueryValues(params),
+    },
+    {
+      formatData: true,
+    },
+  )
+}

+ 91 - 3
src/store/coupon.ts

@@ -6,7 +6,14 @@ import {
   getCoupon2idApi,
   getCoupon2ListApi,
 } from '@/service/coupon1'
-import { getCoupon2ViewmListApi } from '@/service/coupon2'
+import {
+  getCoupon2ViewmListApi,
+  getCoupon2DetailApi,
+  getCoupon2ModifyApi,
+  getCoupon2AuditListApi,
+  getCoupon2AuditDetailApi,
+  submitCoupon2AuditApi,
+} from '@/service/coupon2'
 import { until } from '@vueuse/core'
 
 export const useCouponStore = defineStore(
@@ -93,7 +100,7 @@ export const useCouponStore = defineStore(
       return couponList.value
     }
 
-    // 通过优惠券id获取产品信息(视图)
+    // 通过优惠券code获取产品信息(视图)
     const getCoupon2ViewmList = async (params: { coupon2code: string }) => {
       const { data: couponList, loading } = useRequest(
         () => getCoupon2ViewmListApi(params, { pageindex: 1, rows: 999 }),
@@ -107,7 +114,7 @@ export const useCouponStore = defineStore(
     }
 
     // 获取已关联到当前用户的优惠券列表
-    const getCoupon2List = async (params: { coupon2userid: string }) => {
+    const getCoupon2List = async (params) => {
       const { data: couponList, loading } = useRequest(
         () => getCoupon2ListApi(params, { pageindex: 1, rows: 999 }),
         {
@@ -119,6 +126,82 @@ export const useCouponStore = defineStore(
       return couponList.value
     }
 
+    // 通过优惠券id获取产品信息(视图)
+    const getCoupon2ViewDetailBySid = async (params: { coupon2sid: string }) => {
+      const { data: couponList, loading } = useRequest(() => getCoupon2DetailApi(params), {
+        immediate: true,
+      })
+
+      await until(loading).toBe(false)
+      return couponList.value
+    }
+
+    // 优惠劵审核修改
+    // coupon2sid: 优惠券id 必传
+    const getCoupon2Modify = async (params) => {
+      // eslint-disable-next-line no-async-promise-executor
+      return new Promise(async (resolve, reject) => {
+        const {
+          data: couponList,
+          loading,
+          error,
+        } = useRequest(() => getCoupon2ModifyApi(params), {
+          immediate: true,
+        })
+
+        await until(loading).toBe(false)
+
+        if (error.value) {
+          reject(new Error('优惠劵审核修改失败'))
+        }
+        resolve(couponList.value)
+      })
+    }
+
+    // 优惠劵审核_列表
+    const getCoupon2AuditList = async (params) => {
+      const { data: couponList, loading } = useRequest(
+        () => getCoupon2AuditListApi(params, { pageindex: 1, rows: 9999 }),
+        {
+          immediate: true,
+        },
+      )
+
+      await until(loading).toBe(false)
+      return couponList.value
+    }
+
+    // 优惠劵审核_详情
+    const getCoupon2AuditDetail = async (params) => {
+      const { data: couponList, loading } = useRequest(() => getCoupon2AuditDetailApi(params), {
+        immediate: true,
+      })
+
+      await until(loading).toBe(false)
+      return couponList.value
+    }
+
+    // 优惠劵审核_提交
+    const submitCoupon2Audit = async (params) => {
+      // eslint-disable-next-line no-async-promise-executor
+      return new Promise(async (resolve, reject) => {
+        const {
+          data: couponList,
+          loading,
+          error,
+        } = useRequest(() => submitCoupon2AuditApi(params), {
+          immediate: true,
+        })
+
+        await until(loading).toBe(false)
+
+        if (error.value) {
+          reject(new Error('优惠劵审核提交失败'))
+        }
+        resolve(couponList.value)
+      })
+    }
+
     return {
       getCouponList,
       receiveCoupon,
@@ -126,6 +209,11 @@ export const useCouponStore = defineStore(
       getCoupon2id,
       getCoupon2ViewmList,
       getCoupon2List,
+      getCoupon2ViewDetailBySid,
+      getCoupon2Modify,
+      getCoupon2AuditList,
+      getCoupon2AuditDetail,
+      submitCoupon2Audit,
     }
   },
   {

+ 28 - 0
src/store/order.ts

@@ -4,8 +4,11 @@ import {
   getOrderListApi,
   submitOrderApi,
   submitOrderTelApi,
+  getOrderViewListApi2,
+  getOrderViewDetailApi2,
 } from '@/service/order'
 import { until } from '@vueuse/core'
+import type { ListType } from '@/types/list'
 
 export const useOrderStore = defineStore(
   'order',
@@ -67,11 +70,36 @@ export const useOrderStore = defineStore(
       return order.value
     }
 
+    // 订单_产品_用户_我的优惠劵_列表(视图)
+    const getOrderViewList = async (params, page: Partial<ListType>) => {
+      const { data: orderViewList, loading } = useRequest(
+        () => getOrderViewListApi2(params, page),
+        {
+          immediate: true,
+        },
+      )
+
+      await until(loading).toBe(false)
+      return orderViewList.value.Data
+    }
+
+    // 订单_产品_用户_我的优惠劵_详情(视图)
+    const getOrderViewDetail = async (params) => {
+      const { data: orderViewDetail, loading } = useRequest(() => getOrderViewDetailApi2(params), {
+        immediate: true,
+      })
+
+      await until(loading).toBe(false)
+      return orderViewDetail.value
+    }
+
     return {
       getOrderList,
       getOrderDetail,
       submitOrder,
       submitOrderTel,
+      getOrderViewList,
+      getOrderViewDetail,
     }
   },
   {

+ 5 - 0
src/store/user.ts

@@ -14,6 +14,7 @@ const initState = {
   country: '',
   avatarUrl: '',
   is_demote: true,
+  audit_auth: false, // 当前用户是否具有审核优惠劵权限
 }
 
 export const useUserStore = defineStore(
@@ -93,6 +94,10 @@ export const useUserStore = defineStore(
       updateUser,
       getSellUserList,
       getUserType,
+      audit_auth: computed(() => userInfo.value.audit_auth),
+      setAuditAuth: (value: boolean) => {
+        userInfo.value.audit_auth = value
+      },
     }
   },
   {

+ 3 - 0
src/types/uni-pages.d.ts

@@ -6,7 +6,10 @@
 interface NavigateToOptions {
   url: "/pages/index/index" |
        "/pages/about/index" |
+       "/pages/coupon/audit-detail" |
+       "/pages/coupon/audit-list" |
        "/pages/coupon/index" |
+       "/pages/coupon/modify-info" |
        "/pages/form/formStep1" |
        "/pages/form/formStep2" |
        "/pages/form/formStep3" |

+ 2 - 0
src/typings.d.ts

@@ -29,6 +29,8 @@ declare global {
     province?: string
     country?: string
     is_demote?: boolean
+    /** 是否具有审核优惠券权限 */
+    audit_auth?: boolean
   }
 
   type IAppInfo = {