Files
2026-01-24 17:45:54 +08:00

219 lines
5.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<s-layout title="上传健康证" class="health-cert-page">
<view class="page-body">
<view class="form-row">
<text class="label">编号</text>
<up-input v-model="healthNumber" placeholder="请输入健康证编号" clearable />
</view>
<view class="form-row">
<text class="label">类别</text>
<up-input v-model="healthCategory" placeholder="请输入健康证类别" clearable />
</view>
<view class="form-row date-row">
<text class="label">有效日期</text>
<up-datetime-picker hasInput v-model="healthValidStart" mode="date" placeholder="年/月/日" class="date-input" />
<text class="dash"> </text>
<up-datetime-picker hasInput v-model="healthValidEnd" mode="date" placeholder="年/月/日" class="date-input" />
</view>
<view class="upload-section">
<text class="upload-title">上传健康证</text>
<view class="upload-row">
<view v-for="(img, idx) in healthImages" :key="idx" class="upload-item">
<up-image :src="img" class="upload-thumb" mode="aspectFill" @click="previewImage(idx)" />
<view class="remove-btn" @click.stop="removeHealthImage(idx)">×</view>
</view>
<up-upload :max-count="1" :show-file-list="false" @change="onUploadHealth">
<view class="upload-add" v-if="healthImages.length < 4">
<up-icon name="plus" size="36" color="#999999" />
</view>
</up-upload>
</view>
</view>
<view class="save-row">
<up-button type="primary" block @click="onSave">保存</up-button>
</view>
</view>
</s-layout>
</template>
<script setup>
import { ref, onBeforeMount } from 'vue';
import FileApi from '@/sheep/api/infra/file';
import UserApi from '@/sheep/api/member/user';
import sheep from '@/sheep';
const healthNumber = ref('');
const healthCategory = ref('');
const healthValidStart = ref('');
const healthValidEnd = ref('');
const healthImages = ref([]); // 存放图片 url
// 页面初始化,从用户信息恢复(若已有则填充)
async function init() {
const user = await sheep.$store('user').getInfo();
if (user) {
healthNumber.value = user.healthCertNumber || user.healthCertNo || '';
healthCategory.value = user.healthCertCategory || '';
healthValidStart.value = user.healthCertValidStart || '';
healthValidEnd.value = user.healthCertValidEnd || '';
// 健康证可能只保留首张图片字符串,为兼容性处理成数组
const img = user.healthCert || user.healthCertImage || user.healthCertUrl || '';
if (img) {
healthImages.value = Array.isArray(img) ? img.slice() : [img];
}
}
}
onBeforeMount(() => {
init();
});
function previewImage(index) {
const urls = healthImages.value.slice();
uni.previewImage({
current: index,
urls,
});
}
function removeHealthImage(index) {
if (index >= 0 && index < healthImages.value.length) {
healthImages.value.splice(index, 1);
}
}
function onUploadHealth(event) {
const file = Array.isArray(event) ? event[0] : (event.detail || event);
const url = file?.url || file?.path || file?.thumb || '';
if (url) {
// 限制最多 4 张
if (healthImages.value.length < 4) {
healthImages.value.push(url);
}
// 兼容:在表单保存时取首张
}
}
// 如果用户通过本地选择图片(没有使用 up-upload 的自动上传),也支持手动选择并上传
async function chooseAndUpload() {
const res = await uni.chooseImage({ count: 1 });
if (!res || !res.tempFilePaths || !res.tempFilePaths.length) return;
const tempPath = res.tempFilePaths[0];
const { data } = await FileApi.uploadFile(tempPath);
if (data) {
if (healthImages.value.length < 4) {
healthImages.value.push(data);
}
}
}
async function onSave() {
// 简单校验:至少填写编号或上传图片
if (!healthNumber.value && !healthImages.value.length) {
sheep.$helper && sheep.$helper.toast && sheep.$helper.toast('请填写编号或上传健康证图片');
return;
}
const payload = {
healthCertNumber: healthNumber.value || undefined,
healthCertCategory: healthCategory.value || undefined,
healthCertValidStart: healthValidStart.value || undefined,
healthCertValidEnd: healthValidEnd.value || undefined,
// 为兼容后端,保留首张图片字段 healthCert若后端支持数组可改为数组
healthCert: healthImages.value.length ? healthImages.value[0] : undefined,
};
try {
const res = await UserApi.updateUser(payload);
if (res && res.code === 0) {
// 更新本地用户缓存
await sheep.$store('user').updateUserData();
uni.navigateBack();
}
} catch (err) {
console.warn('保存健康证失败', err);
}
}
</script>
<style scoped>
.health-cert-page .page-body {
padding: 20rpx 30rpx;
background: transparent;
}
.form-row {
display: flex;
align-items: center;
margin-bottom: 35rpx;
}
.label {
width: 140rpx;
color: #333333;
font-size: 28rpx;
}
.date-row .date-input {
width: 260rpx;
}
.dash {
margin: 0 10rpx;
color: #999999;
}
.upload-section {
margin-top: 28rpx;
}
.upload-title {
display: block;
margin-bottom: 12rpx;
color: #333;
font-size: 28rpx;
}
.upload-row {
display: flex;
align-items: center;
gap: 16rpx;
flex-wrap: wrap;
}
.upload-item {
position: relative;
width: 140rpx;
height: 140rpx;
border-radius: 8rpx;
overflow: hidden;
}
.upload-thumb {
width: 100%;
height: 100%;
}
.remove-btn {
position: absolute;
right: 6rpx;
top: 6rpx;
width: 30rpx;
height: 30rpx;
line-height: 30rpx;
text-align: center;
background: rgba(0,0,0,0.6);
color: #fff;
border-radius: 50%;
font-size: 24rpx;
z-index: 5;
}
.upload-add {
width: 140rpx;
height: 140rpx;
display: flex;
justify-content: center;
align-items: center;
border: 1px dashed #e6e6e6;
border-radius: 8rpx;
background: #fafafa;
}
.save-row {
margin-top: 80rpx;
}
</style>