hookehuyr

feat: 统一图片显示模式为aspectFill并添加隐私弹窗

将多处图片显示模式从aspectFit改为aspectFill以更好展示头像
在Welcome页面添加个人信息收集说明和年龄限制提示弹窗
更新components.d.ts以支持新增的NutDialog等组件
......@@ -14,11 +14,14 @@ declare module 'vue' {
NavBar: typeof import('./src/components/navBar.vue')['default']
NutActionSheet: typeof import('@nutui/nutui-taro')['ActionSheet']
NutButton: typeof import('@nutui/nutui-taro')['Button']
NutCol: typeof import('@nutui/nutui-taro')['Col']
NutDatePicker: typeof import('@nutui/nutui-taro')['DatePicker']
NutDialog: typeof import('@nutui/nutui-taro')['Dialog']
NutImagePreview: typeof import('@nutui/nutui-taro')['ImagePreview']
NutInput: typeof import('@nutui/nutui-taro')['Input']
NutPicker: typeof import('@nutui/nutui-taro')['Picker']
NutPopup: typeof import('@nutui/nutui-taro')['Popup']
NutRow: typeof import('@nutui/nutui-taro')['Row']
NutSearchbar: typeof import('@nutui/nutui-taro')['Searchbar']
NutToast: typeof import('@nutui/nutui-taro')['Toast']
Picker: typeof import('./src/components/time-picker-data/picker.vue')['default']
......
......@@ -3,7 +3,7 @@
<!-- Avatar -->
<view class="flex flex-col items-center py-8" @click="changeAvatar">
<view class="w-24 h-24 rounded-full bg-gray-100 flex items-center justify-center mb-2 overflow-hidden">
<image :src="formData.avatar_url || defaultAvatar" class="w-full h-full" mode="aspectFit" />
<image :src="formData.avatar_url || defaultAvatar" class="w-full h-full" mode="aspectFill" />
</view>
<text class="text-gray-500 text-sm">上传头像</text>
</view>
......
......@@ -85,7 +85,7 @@
</view>
<view class="grid grid-cols-4 gap-2">
<view v-for="member in familyMembers" :key="member.user_id" class="flex flex-col items-center">
<image :src="member.avatar_url || defaultAvatar" mode="aspectFit" :alt="member.role" class="w-16 h-16 rounded-full mb-1" />
<image :src="member.avatar_url || defaultAvatar" mode="aspectFill" :alt="member.role" class="w-16 h-16 rounded-full mb-1" />
<span class="text-sm text-gray-700">
{{ member?.today_step?.toLocaleString() }}步
</span>
......
......@@ -3,7 +3,7 @@
<!-- Avatar -->
<view class="flex flex-col items-center py-8" @click="changeAvatar">
<view class="w-24 h-24 rounded-full bg-gray-100 flex items-center justify-center mb-2 overflow-hidden">
<image :src="formData.avatar_url || defaultAvatar" class="w-full h-full" mode="aspectFit" />
<image :src="formData.avatar_url || defaultAvatar" class="w-full h-full" mode="aspectFill" />
</view>
<text class="text-gray-500 text-sm">上传头像</text>
</view>
......
<!--
* @Date: 2025-09-01 13:07:52
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-02 13:13:17
* @LastEditTime: 2025-09-06 12:51:49
* @FilePath: /lls_program/src/pages/FamilyRank/index.vue
* @Description: 文件描述
-->
......@@ -40,7 +40,7 @@
<view class="rank-item second">
<view class="crown crown-silver">👑</view>
<view class="avatar">
<image :src="topRanks[1]?.avatar" class="avatar-img" />
<image :src="topRanks[1]?.avatar" class="avatar-img" mode="aspectFill" />
</view>
<view class="family-name">{{ topRanks[1]?.familyName }}</view>
<view class="leader-name">大家长:{{ topRanks[1]?.leaderName }}</view>
......@@ -54,7 +54,7 @@
<view class="rank-item first">
<view class="crown crown-gold">👑</view>
<view class="avatar">
<image :src="topRanks[0]?.avatar" class="avatar-img" />
<image :src="topRanks[0]?.avatar" class="avatar-img" mode="aspectFill" />
</view>
<view class="family-name">{{ topRanks[0]?.familyName }}</view>
<view class="leader-name">大家长:{{ topRanks[0]?.leaderName }}</view>
......@@ -68,7 +68,7 @@
<view class="rank-item third">
<view class="crown crown-bronze">👑</view>
<view class="avatar">
<image :src="topRanks[2]?.avatar" class="avatar-img" />
<image :src="topRanks[2]?.avatar" class="avatar-img" mode="aspectFill" />
</view>
<view class="family-name">{{ topRanks[2]?.familyName }}</view>
<view class="leader-name">大家长:{{ topRanks[2]?.leaderName }}</view>
......@@ -109,7 +109,7 @@
<view class="my-rank-left">
<view class="my-rank-number">{{ myRank.rank }}+</view>
<view class="my-avatar">
<image :src="myRank.avatar" class="my-avatar-img" />
<image :src="myRank.avatar" class="my-avatar-img" mode="aspectFill" />
</view>
<view class="my-family-info">
<view class="my-family-name">{{ myRank.familyName }}</view>
......
<!--
* @Date: 2025-08-27 17:43:45
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-09-06 01:21:51
* @LastEditTime: 2025-09-06 12:49:17
* @FilePath: /lls_program/src/pages/Welcome/index.vue
* @Description: 文件描述
-->
......@@ -67,6 +67,71 @@
</view>
<!-- Bottom Navigation -->
<BottomNav />
<!-- Dialog Components -->
<!-- 个人信息收集说明弹窗 -->
<nut-dialog
v-model:visible="showPrivacyDialog"
title="个人信息收集说明"
>
<template #default>
<view class=" text-gray-700 leading-loose text-sm text-left">
{{ privacyContent }}
</view>
</template>
<template #footer>
<nut-row :gutter="10">
<nut-col :span="12">
<nut-button
@click="onPrivacyCancel"
type="default"
size="normal"
block
>
取消操作
</nut-button>
</nut-col>
<nut-col :span="12">
<nut-button
@click="onPrivacyConfirm"
type="primary"
size="normal"
color="#007AFF"
block
>
同意搜集
</nut-button>
</nut-col>
</nut-row>
</template>
</nut-dialog>
<!-- 年龄限制提示弹窗 -->
<nut-dialog
v-model:visible="showAgeDialog"
title="温馨提示"
>
<template #default>
<view class="text-center text-gray-700 text-sm leading-loose">
您需要年满60岁才能创建家庭
</view>
</template>
<template #footer>
<nut-row>
<nut-col :span="24">
<nut-button
@click="onAgeConfirm"
type="primary"
size="normal"
color="#007AFF"
block
>
了解
</nut-button>
</nut-col>
</nut-row>
</template>
</nut-dialog>
</view>
</template>
......@@ -84,6 +149,14 @@ const userInfo = ref({});
const canCreateFamily = ref(true);
const hasProfile = ref(false);
// Dialog相关响应式数据
const showPrivacyDialog = ref(false);
const showAgeDialog = ref(false);
const pendingNavigateUrl = ref('');
// 个人信息收集说明内容
const privacyContent = `为了提供更好的服务,我们需要收集您的基本信息:1.头像和昵称:用于家庭成员识别 2.出生年月:验证年龄资格,60岁以上可创建家庭。我们承诺严格保护您的个人隐私,仅用于家庭功能和活动服务。`;
const navigateTo = (url) => {
Taro.navigateTo({ url });
};
......@@ -109,32 +182,39 @@ useDidShow(async () => {
});
const handleNavigate = (url) => {
// 检查个人信息是否完善
if (!hasProfile.value) {
// 先显示隐私提醒
Taro.showModal({
title: '个人信息收集说明',
content: `为了提供更好的服务,我们需要收集您的基本信息:1.头像和昵称:用于家庭成员识别 2.出生年月:验证年龄资格,60岁以上可创建家庭 3.轮椅出行信息:为您提供无障碍活动推荐。我们承诺严格保护您的个人隐私,仅用于家庭功能和活动服务。`,
confirmText: '同意搜集',
cancelText: '取消操作',
success: (res) => {
if (res.confirm) {
Taro.navigateTo({ url: '/pages/AddProfile/index' });
}
},
});
} else {
// 检查用户是否年满60岁
if (canCreateFamily.value) {
navigateTo(url);
} else {
Taro.showModal({
title: '提示',
content: '您需要年满60岁才能创建家庭',
cancelText: '关闭',
confirmText: '了解',
});
if (url === '/pages/CreateFamily/index') {
if (!hasProfile.value) {
// 显示个人信息收集说明弹窗
pendingNavigateUrl.value = '/pages/AddProfile/index';
showPrivacyDialog.value = true;
return;
}
if (!canCreateFamily.value) {
// 显示年龄限制提示弹窗
showAgeDialog.value = true;
return;
}
}
navigateTo(url);
};
// Dialog事件处理方法
const onPrivacyCancel = () => {
showPrivacyDialog.value = false;
pendingNavigateUrl.value = '';
};
const onPrivacyConfirm = () => {
showPrivacyDialog.value = false;
if (pendingNavigateUrl.value) {
navigateTo(pendingNavigateUrl.value);
pendingNavigateUrl.value = '';
}
};
const onAgeConfirm = () => {
showAgeDialog.value = false;
};
</script>
......