336 lines
10 KiB
Vue
336 lines
10 KiB
Vue
<template>
|
|
<view class="container" :class="{ 'container--elder': elderMode }">
|
|
<template v-if="logined">
|
|
<view class="main">
|
|
<scroll-view scroll-y="true" class="main-scroll">
|
|
<view class="card" :class="{ 'card--elder': elderMode }">
|
|
<uni-list>
|
|
<!-- 信息条目 -->
|
|
<uni-list-item direction="column">
|
|
<template v-slot:body>
|
|
<view class="info-item" :class="{ 'info-item--elder': elderMode }">
|
|
<text class="item-label" :class="{ 'item-label--elder': elderMode }">姓名</text>
|
|
<text v-if="id" class="item-value" :class="{ 'item-value--elder': elderMode }">
|
|
{{ currentProfile ? currentProfile.name : '' }}
|
|
</text>
|
|
<input v-else v-model="form.name" :maxlength="10" class="item-value"
|
|
:class="{ 'item-value--elder': elderMode }" type="text" placeholder="请输入姓名" />
|
|
</view>
|
|
<view class="info-item" :class="{ 'info-item--elder': elderMode }">
|
|
<text class="item-label" :class="{ 'item-label--elder': elderMode }">证件类型</text>
|
|
<text class="item-value" :class="{ 'item-value--elder': elderMode }">身份证</text>
|
|
</view>
|
|
<view class="info-item" :class="{ 'info-item--elder': elderMode }">
|
|
<text class="item-label" :class="{ 'item-label--elder': elderMode }">证件号</text>
|
|
<text v-if="id" class="item-value" :class="{ 'item-value--elder': elderMode }">
|
|
{{ currentProfile ? currentProfile.maskCertNo : '' }}
|
|
</text>
|
|
<input v-else v-model="form.socialno" :maxlength="20" class="item-value"
|
|
:class="{ 'item-value--elder': elderMode }" type="idcard" placeholder="请输入证件号" />
|
|
</view>
|
|
<view class="info-item" :class="{ 'info-item--elder': elderMode }">
|
|
<text class="item-label" :class="{ 'item-label--elder': elderMode }">手机号</text>
|
|
<input v-model="form.tel" :maxlength="15" class="item-value"
|
|
:class="{ 'item-value--elder': elderMode }" type="number" placeholder="请输入手机号" />
|
|
</view>
|
|
<view v-if="currentProfile && currentProfile.blhno" class="info-item"
|
|
:class="{ 'info-item--elder': elderMode }">
|
|
<text class="item-label" :class="{ 'item-label--elder': elderMode }">病案号</text>
|
|
<text class="item-value highlight" :class="{ 'item-value--elder': elderMode }">
|
|
{{ currentProfile.blhno }}
|
|
</text>
|
|
</view>
|
|
<view class="info-item" :class="{ 'info-item--elder': elderMode }">
|
|
<text class="item-label" :class="{ 'item-label--elder': elderMode }">地址</text>
|
|
<input v-model="form.address" class="item-value" :class="{ 'item-value--elder': elderMode }"
|
|
type="text" placeholder="请输入地址" />
|
|
</view>
|
|
</template>
|
|
</uni-list-item>
|
|
</uni-list>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
<view class="save-footer" :class="{ 'save-footer--elder': elderMode }" @click="confirm">
|
|
<view class="save-btn" :class="{ 'save-btn--elder': elderMode }">保存</view>
|
|
</view>
|
|
<view class="safearea-bottom"></view>
|
|
</template>
|
|
|
|
<re-login v-else height="80vh" />
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, ref, watch } from 'vue';
|
|
import { onLoad } from "@dcloudio/uni-app";
|
|
import useUser from '@/hooks/useUser';
|
|
import { bindFamilyProfile, updateFamilyProfile, sm4Encrypt } from '@/utils/api';
|
|
import { isChinaId } from "@/utils/validator";
|
|
import { toast } from '@/utils/widget';
|
|
import ybPlugin from "@/utils/insurance-plugin";
|
|
|
|
import reLogin from '@/components/re-login.vue';
|
|
|
|
const id = ref('')
|
|
const form = ref({
|
|
name: '',
|
|
socialno: '',
|
|
tel: '',
|
|
address: '',
|
|
});
|
|
|
|
const loading = ref(false);
|
|
const elderMode = ref(false);
|
|
const { familyProfile, logined, userInfo, getFamilyProfile, myProfile, getAuthCode } = useUser();
|
|
const currentProfile = computed(() => familyProfile.value.find(i => i._id === id.value && id.value));
|
|
const source = ref('')
|
|
|
|
async function confirm() {
|
|
if (loading.value) return;
|
|
if (form.value.name.trim() === '') {
|
|
toast('姓名不能为空');
|
|
return;
|
|
}
|
|
if (form.value.socialno.trim() === '') {
|
|
toast('证件号不能为空');
|
|
return;
|
|
}
|
|
if (!isChinaId(form.value.socialno)[0]) {
|
|
toast('请输入有效的身份证号');
|
|
return;
|
|
}
|
|
if (form.value.tel.trim() === '') {
|
|
toast('手机号不能为空');
|
|
return;
|
|
}
|
|
if (!/^1[3-9]\d{9}$/.test(form.value.tel)) {
|
|
toast('请输入有效的手机号');
|
|
return;
|
|
}
|
|
loading.value = true;
|
|
|
|
try {
|
|
const payload = {
|
|
id: id.value,
|
|
name: form.value.name.trim(),
|
|
socialno: form.value.socialno.trim(),
|
|
tel: form.value.tel.trim(),
|
|
address: form.value.address.trim(),
|
|
userId: userInfo.value.userId,
|
|
};
|
|
uni.setStorageSync('family-profile-form', JSON.stringify(form.value));
|
|
const psnToken = await getPsnToken(payload.name, payload.socialno);
|
|
if (!psnToken) {
|
|
loading.value = false;
|
|
return;
|
|
}
|
|
payload.psnToken = psnToken;
|
|
const api = id.value ? updateFamilyProfile : bindFamilyProfile;
|
|
const { message, success } = await api(payload);
|
|
if (success) {
|
|
toast('保存成功')
|
|
getFamilyProfile()
|
|
const pages = getCurrentPages();
|
|
if (pages.length > 1) {
|
|
uni.navigateBack();
|
|
} else {
|
|
uni.redirectTo({
|
|
url: source.value || '/pages/home/home'
|
|
});
|
|
}
|
|
} else {
|
|
toast(message || '保存失败')
|
|
}
|
|
} catch (e) {
|
|
toast(e.message);
|
|
}
|
|
loading.value = false
|
|
}
|
|
|
|
async function getPsnToken(name, socialno) {
|
|
const res = await sm4Encrypt({ textGroup: [name, socialno] })
|
|
const [anotherName, anotherIdNo] = res && Array.isArray(res.textGroup) ? res.textGroup : [];
|
|
if (!anotherName || !anotherIdNo) {
|
|
toast('获取加密参数失败,请稍后再试');
|
|
return Promise.reject('获取加密参数失败,请稍后再试');
|
|
}
|
|
const authCode = await getAuthCode("nhsamp");
|
|
const psnToken = await ybPlugin.getArchiveToken(authCode, anotherIdNo, anotherName);
|
|
if (!psnToken) {
|
|
return Promise.reject('获取医保信息授权信息失败');
|
|
}
|
|
return psnToken;
|
|
}
|
|
|
|
onLoad((options) => {
|
|
if (options.source) {
|
|
source.value = decodeURIComponent(options.source);
|
|
}
|
|
if (options.type === 'getArchiveTokenRedirect') {
|
|
const cacheForm = uni.getStorageSync('family-profile-form');
|
|
try {
|
|
const obj = JSON.parse(cacheForm);
|
|
Object.keys(form.value).forEach(key => {
|
|
form.value[key] = obj[key] || '';
|
|
});
|
|
} catch (e) { }
|
|
}
|
|
uni.removeStorageSync('family-profile-form');
|
|
id.value = options.id || '';
|
|
ybPlugin.init({
|
|
archiveTokenCallback: () => {
|
|
uni.redirectTo({
|
|
url: `/pages/member/family-profile?type=getArchiveTokenRedirect&id=${id.value}&source=${source.value ? encodeURIComponent(source.value) : ''}`,
|
|
});
|
|
}
|
|
});
|
|
// 读取长辈模式状态
|
|
const savedElderMode = uni.getStorageSync('elderMode')
|
|
if (savedElderMode !== null && savedElderMode !== undefined) {
|
|
elderMode.value = savedElderMode
|
|
}
|
|
});
|
|
|
|
watch(currentProfile, val => {
|
|
if (id.value) {
|
|
form.value = {
|
|
name: val ? val.name : '',
|
|
socialno: val ? val.socialno : '',
|
|
tel: val ? val.tel : '',
|
|
address: val ? val.address : ''
|
|
}
|
|
}
|
|
}, { immediate: true })
|
|
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: #f5f5f5;
|
|
height: 100vh;
|
|
|
|
// 定义CSS变量
|
|
--font-scale: 1;
|
|
--spacing-scale: 1;
|
|
--border-radius-scale: 1;
|
|
--font-weight-scal: 1;
|
|
|
|
@at-root &--elder {
|
|
--font-scale: 1.4;
|
|
--spacing-scale: 1.2;
|
|
--border-radius-scale: 1.25;
|
|
--font-weight-scal: 1.2;
|
|
}
|
|
}
|
|
|
|
.main {
|
|
position: relative;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.main-scroll {
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
top: 0;
|
|
bottom: 0;
|
|
}
|
|
|
|
.card {
|
|
margin: calc(30rpx * var(--spacing-scale));
|
|
border-radius: calc(16rpx * var(--border-radius-scale));
|
|
overflow: hidden;
|
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
|
}
|
|
|
|
.info-item {
|
|
background: #fff;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: calc(24rpx * var(--spacing-scale)) calc(30rpx * var(--spacing-scale));
|
|
border-bottom: 1rpx solid #eee;
|
|
min-height: calc(80rpx * var(--spacing-scale));
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.item-label {
|
|
color: #666;
|
|
font-size: calc(30rpx * var(--font-scale));
|
|
width: calc(200rpx * var(--spacing-scale));
|
|
font-weight: 500;
|
|
|
|
.container--elder & {
|
|
font-weight: calc(600rpx * var(--font-size-scal));
|
|
}
|
|
}
|
|
|
|
.item-value {
|
|
color: #333;
|
|
font-size: calc(30rpx * var(--font-scale));
|
|
font-weight: 500;
|
|
flex: 1;
|
|
text-align: right;
|
|
|
|
&.highlight {
|
|
color: $theme-brown-primary;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.container--elder & {
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
}
|
|
|
|
.save-footer {
|
|
padding: calc(24rpx * var(--spacing-scale)) calc(30rpx * var(--spacing-scale));
|
|
background: white;
|
|
}
|
|
|
|
.save-btn {
|
|
height: calc(80rpx * var(--spacing-scale));
|
|
background: $theme-brown-primary;
|
|
color: white;
|
|
font-size: calc(28rpx * var(--font-scale));
|
|
border-radius: calc(16rpx * var(--border-radius-scale));
|
|
text-align: center;
|
|
line-height: calc(80rpx * var(--spacing-scale));
|
|
font-weight: 500;
|
|
|
|
.container--elder & {
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
/* 交互效果 */
|
|
uni-list-item {
|
|
transition: all 0.2s;
|
|
|
|
&:active {
|
|
background-color: #f8f8f8;
|
|
}
|
|
}
|
|
|
|
.safearea-bottom {
|
|
height: env(safe-area-inset-bottom);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.hint {
|
|
padding: 20rpx 30rpx 40rpx;
|
|
color: red;
|
|
font-size: 28rpx;
|
|
line-height: 50rpx;
|
|
}
|
|
|
|
.hint-large {
|
|
font-size: 40rpx;
|
|
line-height: 70rpx;
|
|
}
|
|
</style> |