Commit f59c101f authored by tao.huang's avatar tao.huang

Merge branch '20250528-dev-ht' of gitlab2.dui88.com:sparkprojects/20250528_FHQ1 into dev

parents 51fc5054 0c78a851
<template> <template>
<view class="my-container"> <view class="my-container">
<!-- 用户信息区域 --> <view class="bg-container">
<view class="user-info"> <image
<view class="user-header"> class="bg-img"
<image class="avatar" :src="userInfo.avatar || '/static/my/avatar.png'" mode="aspectFill" /> src="/static/my/cover_white_bg.png"
<view class="user-detail"> mode="aspectFit"
<text class="nickname">{{ userInfo.nickname || '未登录' }}</text> lazy-load="false"
<view class="user-level"> binderror=""
<image class="level-icon" src="/static/my/level.png" mode="aspectFit" /> bindload=""
<text class="level-text">Lv.{{ userInfo.level || 1 }}</text> />
</view> </view>
</view> <!-- 用户信息区域 -->
<view class="edit-btn" @tap="handleEditProfile"> <view class="user-info">
<image src="/static/my/edit.png" mode="aspectFit" /> <view class="user-header">
</view> <image
</view> class="avatar"
</view> :src="userInfo.avatar || '/static/my/avatar.png'"
</view> mode="aspectFill"
/>
<view class="user-detail">
<text class="nickname">{{ userInfo.nickname || "未登录" }}</text>
<view class="user-level">
<image
class="level-icon"
src="/static/my/level.png"
mode="aspectFit"
/>
<text class="level-text">Lv.{{ userInfo.level || 1 }}</text>
</view>
</view>
<view class="edit-btn" @tap="handleEditProfile">
<image src="/static/my/edit.png" mode="aspectFit" />
</view>
</view>
<!-- user desc -->
<view class="user-desc">
<text class="desc-text"> </text>
</view>
</view>
<!-- 工具 -->
<view class="tool-container">
<text class="tool-title" selectable="false" space="false" decode="false">
工具
</text>
<view class="tool-list">
<view class="tool-item" v-for="item in toolList" :key="item.title">
<image class="tool-icon" :src="item.icon" mode="aspectFit" />
</view>
</view>
</view>
</view>
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted } from "vue";
const toolList = ref([
{
icon: "/static/my/code.png",
title: "扫码积分",
url: "",
},
{
icon: "/static/my/suyuan.png",
title: "产品溯源",
url: "",
},
{
icon: "/static/my/book.png",
title: "奶娃宝典",
url: "",
},
{
icon: "/static/my/doctor.png",
title: "医生问诊",
url: "",
},
{
icon: "/static/my/literature.png",
title: "育儿百科",
url: "",
},
]);
// 用户信息 // 用户信息
const userInfo = ref({ const userInfo = ref({
avatar: '', avatar: "",
nickname: '', nickname: "",
level: 1, level: 1,
points: 0, points: 0,
coupons: 0, coupons: 0,
collects: 0 collects: 0,
}) });
// 订单数量统计 // 订单数量统计
const orderCounts = ref({ const orderCounts = ref({
pending: 0, pending: 0,
shipping: 0, shipping: 0,
receiving: 0, receiving: 0,
comment: 0, comment: 0,
after: 0 after: 0,
}) });
// 页面跳转 // 页面跳转
const navigateTo = (url) => { const navigateTo = (url) => {
uni.navigateTo({ uni.navigateTo({
url, url,
fail: (err) => { fail: (err) => {
console.error('页面跳转失败:', err) console.error("页面跳转失败:", err);
uni.showToast({ uni.showToast({
title: '页面跳转失败', title: "页面跳转失败",
icon: 'none' icon: "none",
}) });
} },
}) });
} };
// 编辑个人资料 // 编辑个人资料
const handleEditProfile = () => { const handleEditProfile = () => {
navigateTo('/pages/user/profile') navigateTo("/pages/user/profile");
} };
// 联系客服 // 联系客服
const handleContactService = () => { const handleContactService = () => {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
uni.openCustomerServiceChat({ uni.openCustomerServiceChat({
extInfo: { url: 'YOUR_CUSTOMER_SERVICE_URL' }, extInfo: { url: "YOUR_CUSTOMER_SERVICE_URL" },
corpId: 'YOUR_CORP_ID', corpId: "YOUR_CORP_ID",
success(res) { success(res) {
console.log('打开客服会话成功') console.log("打开客服会话成功");
}, },
fail(err) { fail(err) {
console.error('打开客服会话失败:', err) console.error("打开客服会话失败:", err);
uni.showToast({ uni.showToast({
title: '打开客服会话失败', title: "打开客服会话失败",
icon: 'none' icon: "none",
}) });
} },
}) });
// #endif // #endif
// #ifdef H5 // #ifdef H5
window.open('YOUR_CUSTOMER_SERVICE_URL', '_blank') window.open("YOUR_CUSTOMER_SERVICE_URL", "_blank");
// #endif // #endif
} };
// 获取用户信息 // 获取用户信息
const getUserInfo = async () => { const getUserInfo = async () => {
try { try {
// TODO: 调用获取用户信息接口 // TODO: 调用获取用户信息接口
const res = await uni.request({ const res = await uni.request({
url: '/api/user/info', url: "/api/user/info",
method: 'GET' method: "GET",
}) });
if (res.data.code === 0) { if (res.data.code === 0) {
userInfo.value = res.data.data userInfo.value = res.data.data;
} }
} catch (error) { } catch (error) {
console.error('获取用户信息失败:', error) console.error("获取用户信息失败:", error);
uni.showToast({ uni.showToast({
title: '获取用户信息失败', title: "获取用户信息失败",
icon: 'none' icon: "none",
}) });
} }
} };
// 获取订单数量 // 获取订单数量
const getOrderCounts = async () => { const getOrderCounts = async () => {
try { try {
// TODO: 调用获取订单数量接口 // TODO: 调用获取订单数量接口
const res = await uni.request({ const res = await uni.request({
url: '/api/order/counts', url: "/api/order/counts",
method: 'GET' method: "GET",
}) });
if (res.data.code === 0) { if (res.data.code === 0) {
orderCounts.value = res.data.data orderCounts.value = res.data.data;
} }
} catch (error) { } catch (error) {
console.error('获取订单数量失败:', error) console.error("获取订单数量失败:", error);
} }
} };
// 下拉刷新
const onPullDownRefresh = async () => {
return
try {
await Promise.all([
getUserInfo(),
getOrderCounts()
])
uni.stopPullDownRefresh()
} catch (error) {
console.error('刷新数据失败:', error)
uni.stopPullDownRefresh()
}
}
// 页面加载 // 页面加载
onMounted(() => { onMounted(() => {
// getUserInfo() // getUserInfo()
// getOrderCounts() // getOrderCounts()
}) });
// 定义页面配置 // 定义页面配置
defineExpose({ defineExpose({});
onPullDownRefresh
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.my-container { .my-container {
min-height: 100vh; min-height: 100vh;
background-color: #f5f5f5; background-color: #f5f5f5;
padding-bottom: 100rpx; padding-bottom: 100rpx;
overflow: hidden;
.user-info {
background-color: #fff; .bg-container {
padding: 40rpx 30rpx; width: 750rpx;
margin-bottom: 20rpx; height: 840rpx;
position: absolute;
.user-header { top: 0;
display: flex; left: 0;
align-items: center; z-index: 0;
margin-bottom: 40rpx;
.bg-img {
.avatar { width: 100%;
width: 120rpx; height: 100%;
height: 120rpx; display: block;
border-radius: 60rpx; }
margin-right: 20rpx; }
}
.user-info {
.user-detail { background-color: #fef7f2;
flex: 1; padding: 30rpx;
.nickname { width: 686rpx;
font-size: 32rpx; height: 343rpx;
font-weight: 500; box-sizing: border-box;
color: #333; border-radius: 32rpx;
margin-bottom: 10rpx; position: relative;
} margin: 0 auto;
margin-top: 676rpx;
.user-level {
display: flex; .user-header {
align-items: center; display: flex;
align-items: center;
.level-icon { margin-bottom: 40rpx;
width: 32rpx;
height: 32rpx; .avatar {
margin-right: 8rpx; width: 120rpx;
} height: 120rpx;
border-radius: 60rpx;
.level-text { margin-right: 20rpx;
font-size: 24rpx; }
color: #666;
} .user-detail {
} flex: 1;
}
.nickname {
.edit-btn { font-size: 32rpx;
image { font-weight: 500;
width: 40rpx; color: #333;
height: 40rpx; margin-bottom: 10rpx;
} }
}
} .user-level {
display: flex;
.user-stats { align-items: center;
display: flex;
justify-content: space-around; .level-icon {
width: 32rpx;
.stat-item { height: 32rpx;
display: flex; margin-right: 8rpx;
flex-direction: column; }
align-items: center;
.level-text {
.num { font-size: 24rpx;
font-size: 36rpx; color: #666;
font-weight: 500; }
color: #333; }
margin-bottom: 8rpx; }
}
.edit-btn {
.label { image {
font-size: 24rpx; width: 40rpx;
color: #666; height: 40rpx;
} }
} }
} }
}
.user-stats {
display: flex;
justify-content: space-around;
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
.num {
font-size: 36rpx;
font-weight: 500;
color: #333;
margin-bottom: 8rpx;
}
.label {
font-size: 24rpx;
color: #666;
}
}
}
.user-desc {
width: 100%;
height: 182rpx;
background-color: #fff;
border-radius: 32rpx;
padding: 30rpx 32rpx;
box-sizing: border-box;
position: absolute;
bottom: 0;
left: 0;
}
}
.tool-container {
margin: 0 auto;
margin-top: 48rpx;
width: 686rpx;
.tool-list {
display: flex;
flex-wrap: wrap;
margin: 32rpx 0;
}
.order-section { .tool-title {
background-color: #fff; font-size: 32rpx;
padding: 30rpx; font-weight: 500;
margin-bottom: 20rpx; color: #1d1e25;
margin-left: 21rpx;
.section-header { }
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
.title {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
.more {
display: flex;
align-items: center;
text {
font-size: 24rpx;
color: #666;
margin-right: 8rpx;
}
image {
width: 32rpx;
height: 32rpx;
}
}
}
.order-types {
display: flex;
justify-content: space-between;
.type-item {
display: flex;
flex-direction: column;
align-items: center;
image {
width: 48rpx;
height: 48rpx;
margin-bottom: 12rpx;
}
text {
font-size: 24rpx;
color: #666;
}
}
}
}
.function-list { .tool-item {
background-color: #fff; width: 152rpx;
padding: 0 30rpx; height: 152rpx;
margin-left: 26rpx;
.function-item { margin-bottom: 24rpx;
display: flex; .tool-icon {
align-items: center; width: 100%;
height: 100rpx; height: 100%;
border-bottom: 1rpx solid #f5f5f5; display: block;
};
&:last-child { &:nth-child(4n+1) {
border-bottom: none; margin-left: 0;
}
image {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
&.arrow {
width: 32rpx;
height: 32rpx;
margin-right: 0;
margin-left: auto;
}
}
text {
font-size: 28rpx;
color: #333;
}
}
} }
} }
}
.order-section {
background-color: #fff;
padding: 30rpx;
margin-bottom: 20rpx;
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
.title {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
.more {
display: flex;
align-items: center;
text {
font-size: 24rpx;
color: #666;
margin-right: 8rpx;
}
image {
width: 32rpx;
height: 32rpx;
}
}
}
.order-types {
display: flex;
justify-content: space-between;
.type-item {
display: flex;
flex-direction: column;
align-items: center;
image {
width: 48rpx;
height: 48rpx;
margin-bottom: 12rpx;
}
text {
font-size: 24rpx;
color: #666;
}
}
}
}
.function-list {
background-color: #fff;
padding: 0 30rpx;
.function-item {
display: flex;
align-items: center;
height: 100rpx;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
image {
width: 40rpx;
height: 40rpx;
margin-right: 20rpx;
&.arrow {
width: 32rpx;
height: 32rpx;
margin-right: 0;
margin-left: auto;
}
}
text {
font-size: 28rpx;
color: #333;
}
}
}
}
.badge { .badge {
position: absolute; position: absolute;
top: -8rpx; top: -8rpx;
right: -8rpx; right: -8rpx;
background-color: #ff4d4f; background-color: #ff4d4f;
color: #fff; color: #fff;
font-size: 20rpx; font-size: 20rpx;
padding: 2rpx 8rpx; padding: 2rpx 8rpx;
border-radius: 16rpx; border-radius: 16rpx;
min-width: 32rpx; min-width: 32rpx;
text-align: center; text-align: center;
} }
.type-item { .type-item {
position: relative; position: relative;
} }
</style> </style>
...@@ -47,11 +47,15 @@ const props = defineProps({ ...@@ -47,11 +47,15 @@ const props = defineProps({
}, },
], ],
}, },
curTabIndex: {
type: Number,
default: 0,
},
}); });
const emit = defineEmits(["tabClick"]); const emit = defineEmits(["tabClick"]);
const currentIndex = ref(0); const currentIndex = ref(props.curTabIndex);
const handleTabClick = (index, item) => { const handleTabClick = (index, item) => {
currentIndex.value = index; currentIndex.value = index;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<Brand v-if="curTabIndex == 1"></Brand> <Brand v-if="curTabIndex == 1"></Brand>
<Integral v-if="curTabIndex == 2"></Integral> <Integral v-if="curTabIndex == 2"></Integral>
<My v-if="curTabIndex == 3"></My> <My v-if="curTabIndex == 3"></My>
<TabBar @tabClick="handleTabClick" /> <TabBar :curTabIndex="curTabIndex" @tabClick="handleTabClick" />
</view> </view>
</template> </template>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment