feat(approval): 添加用户信息和开柜功能

在审批页面中新增了用户信息展示(姓名、手机号、用户ID),并添加了打开柜子的功能按钮。同时优化了代码结构和样式,提升了用户体验。
This commit is contained in:
dzq 2025-04-17 16:40:04 +08:00
parent 5ad9456a0f
commit e777d1e931
4 changed files with 82 additions and 69 deletions

BIN
public/cover.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

View File

@ -61,6 +61,14 @@ export interface ReturnApprovalEntity {
goodsName: string goodsName: string
/** 封面图URL */ /** 封面图URL */
coverImg: string coverImg: string
/** 手机号 */
mobile: string
/** 用户id */
userid: string
/** 用户姓名 */
name: string
/** 是否内部用户0否 1汇邦云用户 2企业微信用户 */
isInternal: number
} }
export type SubmitApprovalResponseData = ApiResponseMsgData<{ export type SubmitApprovalResponseData = ApiResponseMsgData<{

View File

@ -1,23 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref } from 'vue'
import { showConfirmDialog, showSuccessToast, showToast, UploaderFileListItem, Popup, Picker } from 'vant' import { showConfirmDialog, showSuccessToast, showFailToast, showToast, UploaderFileListItem, Popup, Picker } from 'vant'
const showStatusPicker = ref(false)
const showPreview = ref(false)
const currentPreviewImage = ref('')
const statusMap: { [key: number]: string } = {
1: '待审核',
2: '已通过',
3: '已驳回'
}
const statusOptions = [
{ text: '待审核', value: 1 },
{ text: '通过', value: 2 },
{ text: '驳回', value: 3 }
]
import axios from "axios" import axios from "axios"
import { handleApprovalApi } from '@/common/apis/approval' import { handleApprovalApi } from '@/common/apis/approval'
import { openCabinetApi } from '@/common/apis/shop'
import type { HandleApprovalRequestData } from '@/common/apis/approval/type' import type { HandleApprovalRequestData } from '@/common/apis/approval/type'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter } from 'vue-router'
import { useApprovalStore } from '@/pinia/stores/approval' import { useApprovalStore } from '@/pinia/stores/approval'
@ -38,7 +25,22 @@ const formData = ref<HandleApprovalRequestData>({
const submitting = ref(false) const submitting = ref(false)
const fileList = ref<UploaderFileListItem[]>([]) const fileList = ref<UploaderFileListItem[]>([])
const uploading = ref(false) const uploading = ref(false)
const isButtonDisabled = ref(false)
const showStatusPicker = ref(false)
const showPreview = ref(false)
const currentPreviewImage = ref('')
const statusMap: { [key: number]: string } = {
1: '待审核',
2: '已通过',
3: '已驳回'
}
const statusOptions = [
{ text: '待审核', value: 1 },
{ text: '通过', value: 2 },
{ text: '驳回', value: 3 }
]
const validateForm = () => { const validateForm = () => {
if (!formData.value.approvalId || isNaN(formData.value.approvalId)) { if (!formData.value.approvalId || isNaN(formData.value.approvalId)) {
showConfirmDialog({ title: '错误', message: '审批单ID参数错误' }) showConfirmDialog({ title: '错误', message: '审批单ID参数错误' })
@ -56,7 +58,7 @@ const validateForm = () => {
if (!formData.value.auditImages) { if (!formData.value.auditImages) {
showConfirmDialog({ title: '提示', message: '请上传审核图片' }) showConfirmDialog({ title: '提示', message: '请上传审核图片' })
return false return false
} }
if (formData.value.status === 3 && !formData.value.auditRemark) { if (formData.value.status === 3 && !formData.value.auditRemark) {
showConfirmDialog({ title: '提示', message: '驳回时必须填写审核说明' }) showConfirmDialog({ title: '提示', message: '驳回时必须填写审核说明' })
@ -141,7 +143,7 @@ onMounted(() => {
auditRemark: approvalStore.currentApproval.auditRemark, auditRemark: approvalStore.currentApproval.auditRemark,
auditImages: approvalStore.currentApproval.auditImages auditImages: approvalStore.currentApproval.auditImages
} }
// //
if (approvalStore.currentApproval.auditImages) { if (approvalStore.currentApproval.auditImages) {
fileList.value = approvalStore.currentApproval.auditImages.split(',').map(url => ({ fileList.value = approvalStore.currentApproval.auditImages.split(',').map(url => ({
@ -153,6 +155,32 @@ onMounted(() => {
} }
}) })
const handleOpenCabinet = async () => {
if (!approvalStore.currentApproval?.orderId || !approvalStore.currentApproval?.orderGoodsId) {
showFailToast('缺少订单信息')
return
}
isButtonDisabled.value = true
try {
const result = await openCabinetApi(
approvalStore.currentApproval.orderId,
approvalStore.currentApproval.orderGoodsId
)
if (result.code !== 0) {
showFailToast(result.msg || '开启失败')
return
}
showSuccessToast('柜口已开启')
} catch (error) {
showFailToast('请求失败')
} finally {
setTimeout(() => {
isButtonDisabled.value = false
}, 5000)
}
}
const handleSubmit = async () => { const handleSubmit = async () => {
if (!validateForm()) return if (!validateForm()) return
@ -192,16 +220,13 @@ const handleSubmit = async () => {
<div class="content-wrapper"> <div class="content-wrapper">
<van-cell-group> <van-cell-group>
<van-cell title="姓名" :value="approvalStore.currentApproval?.name" />
<van-cell title="手机号" :value="approvalStore.currentApproval?.mobile" />
<van-cell title="用户id" :value="approvalStore.currentApproval?.userid" />
<van-cell title="商品名称" :value="approvalStore.currentApproval?.goodsName" /> <van-cell title="商品名称" :value="approvalStore.currentApproval?.goodsName" />
<van-cell title="商品封面" v-if="approvalStore.currentApproval?.coverImg"> <van-cell title="商品封面" v-if="approvalStore.currentApproval?.coverImg">
<van-image <van-image :src="approvalStore.currentApproval.coverImg" fit="cover" width="80" height="80"
:src="approvalStore.currentApproval.coverImg" @click="previewImage(approvalStore.currentApproval.coverImg)" style="margin-top: 8px" />
fit="cover"
width="80"
height="80"
@click="previewImage(approvalStore.currentApproval.coverImg)"
style="margin-top: 8px"
/>
</van-cell> </van-cell>
<van-cell title="退还数量" :value="approvalStore.currentApproval?.returnQuantity" /> <van-cell title="退还数量" :value="approvalStore.currentApproval?.returnQuantity" />
<van-cell title="商品单价" :value="`¥${approvalStore.currentApproval?.goodsPrice}`" /> <van-cell title="商品单价" :value="`¥${approvalStore.currentApproval?.goodsPrice}`" />
@ -222,30 +247,17 @@ const handleSubmit = async () => {
<van-cell-group> <van-cell-group>
<!-- 原有表单字段保持不变 --> <!-- 原有表单字段保持不变 -->
<van-field <van-button type="primary" size="small"
v-model="formData.returnAmount" @click="handleOpenCabinet" :disabled="isButtonDisabled" style="margin-bottom: 12px">
:readonly="approvalStore.currentApproval?.status !== 1" 打开柜子
label="退款金额" </van-button>
type="number" <van-field v-model="formData.returnAmount" :readonly="approvalStore.currentApproval?.status !== 1"
class="audit-remark-field" label="退款金额" type="number" class="audit-remark-field" :min="0" />
:min="0" <van-field :model-value="statusOptions.find(opt => opt.value === formData.status)?.text || ''"
/> label="审批结果" readonly @click="showStatusPicker = true"
<van-field :disabled="approvalStore.currentApproval?.status !== 1" class="clickable-status-field" />
:model-value="statusOptions.find(opt => opt.value === formData.status)?.text || ''" <van-field v-model="formData.auditRemark" label="审核说明" type="textarea" rows="2" autosize
label="审批结果" class="audit-remark-field" />
readonly
@click="showStatusPicker = true"
:disabled="approvalStore.currentApproval?.status !== 1"
class="clickable-status-field"
/>
<van-field
v-model="formData.auditRemark"
label="审核说明"
type="textarea"
rows="2"
autosize
class="audit-remark-field"
/>
</van-cell-group> </van-cell-group>
<van-popup v-model:show="showStatusPicker" position="bottom"> <van-popup v-model:show="showStatusPicker" position="bottom">
@ -267,15 +279,8 @@ const handleSubmit = async () => {
</van-cell> </van-cell>
</van-cell-group> </van-cell-group>
<div class="submit-bar" <div class="submit-bar" v-if="approvalStore.currentApproval?.status !== 2">
v-if="approvalStore.currentApproval?.status !== 2"> <van-button type="primary" block :loading="submitting" loading-text="提交中..." @click="handleSubmit">
<van-button
type="primary"
block
:loading="submitting"
loading-text="提交中..."
@click="handleSubmit"
>
提交审批 提交审批
</van-button> </van-button>
</div> </div>
@ -335,24 +340,24 @@ const handleSubmit = async () => {
} }
.audit-remark-field::v-deep .van-field__control { .audit-remark-field::v-deep .van-field__control {
background-color: #fffbe6; background-color: #fffbe6;
padding: 8px; padding: 8px;
border-radius: 4px; border-radius: 4px;
} }
.clickable-status-field:not(:disabled)::v-deep .van-field__control { .clickable-status-field:not(:disabled)::v-deep .van-field__control {
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
background-color: #f7f8fa; background-color: #f7f8fa;
} }
.clickable-status-field:not(:disabled):hover::v-deep .van-field__control { .clickable-status-field:not(:disabled):hover::v-deep .van-field__control {
background-color: #f2f3f5; background-color: #f2f3f5;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
} }
.clickable-status-field:not(:disabled):active::v-deep .van-field__control { .clickable-status-field:not(:disabled):active::v-deep .van-field__control {
background-color: #ebedf0; background-color: #ebedf0;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
} }
</style> </style>

View File

@ -123,7 +123,7 @@ function handleCheckout() {
<template> <template>
<div class="shop"> <div class="shop">
<div class="shop-header" :style="{ height: `${headerHeight}px` }"> <div class="shop-header" :style="{ height: `${headerHeight}px` }">
<van-image :src="`${publicPath}c63.png`" class="shop-cover" fit="cover" /> <van-image :src="`${publicPath}cover.png`" class="shop-cover" fit="cover" />
</div> </div>
<div class="product-container"> <div class="product-container">
<!-- 左侧分类导航 --> <!-- 左侧分类导航 -->