Commit 844ae2b7c1eba09053d9c17439a637516f9b6d80

Authored by “wangming”
1 parent 112e2f9a

优化个人中心页面:调整用户信息展示样式、个人服务区域布局和间距

Showing 1 changed file with 847 additions and 726 deletions
绿纤uni-app/pages/me/me.vue
1 <template> 1 <template>
2 <view class="page"> 2 <view class="page">
3 <!-- 自定义导航栏 --> 3 <!-- 自定义导航栏 -->
4 - <custom-navbar  
5 - title="个人中心"  
6 - :show-background="true"  
7 - background-image="https://zhgw.028wlkj.com/cdwlMall/zsfwzxt/test/file/static/bg.png"  
8 - @height-change="handleNavbarHeightChange"  
9 - ></custom-navbar>  
10 -  
11 - <view class="main">  
12 - <!-- 用户信息卡片 - 结合my.vue样式和me copy.vue功能 -->  
13 - <view class="user-card">  
14 - <view class="user-card-bg"></view> 4 + <custom-navbar title="个人中心" :show-background="false" @height-change="handleNavbarHeightChange"></custom-navbar>
  5 +
  6 + <view class="warpbox">
  7 + <view :style="{ 'height': contentTopMargin }"></view>
  8 +
  9 + <!-- 用户信息卡片 -->
  10 + <view class="warpboxss user-card">
15 <view class="user-card-content"> 11 <view class="user-card-content">
16 <view class="user-main"> 12 <view class="user-main">
17 <view class="avatar-container"> 13 <view class="avatar-container">
18 - <view class="avatar-ring"></view>  
19 - <image class="avatar" :src="newuserInfo.avatar || '/static/head.png'" mode="aspectFill"></image> 14 + <image class="avatar" :src="newuserInfo.avatar || '/static/head.png'" mode="aspectFill">
  15 + </image>
20 </view> 16 </view>
21 <view class="user-info-wrapper"> 17 <view class="user-info-wrapper">
22 <view class="user-name">{{ newuserInfo.realName || newuserInfo.userName || '用户' }}</view> 18 <view class="user-name">{{ newuserInfo.realName || newuserInfo.userName || '用户' }}</view>
23 <view class="user-meta"> 19 <view class="user-meta">
24 - <view class="role-badge">  
25 - <text>{{ newuserInfo.gw || '员工' }}</text>  
26 - </view>  
27 - <view class="store-badge"> 20 + <view class="user-badge user-badge-store">
28 <u-icon name="home" size="20" color="#409EFF"></u-icon> 21 <u-icon name="home" size="20" color="#409EFF"></u-icon>
29 - <text>{{ jsjinfo.storeName || '暂无' }}</text> 22 + <text class="user-badge-text">{{ jsjinfo.storeName || '暂无' }}</text>
30 </view> 23 </view>
31 - <view class="store-badge jsj-badge"> 24 + <view class="user-badge user-badge-role">
  25 + <u-icon name="account" size="20" color="#43a047"></u-icon>
  26 + <text class="user-badge-text">{{ newuserInfo.gw || '员工' }}</text>
  27 + </view>
  28 + <view v-if="jsjinfo.jsjName" class="user-badge user-badge-jsj">
32 <u-icon name="star" size="20" color="#ff9800"></u-icon> 29 <u-icon name="star" size="20" color="#ff9800"></u-icon>
33 - <text>{{ jsjinfo.jsjName || '暂无' }}</text> 30 + <text class="user-badge-text">{{ jsjinfo.jsjName || '暂无' }}</text>
34 </view> 31 </view>
35 </view> 32 </view>
36 </view> 33 </view>
@@ -38,72 +35,94 @@ @@ -38,72 +35,94 @@
38 </view> 35 </view>
39 </view> 36 </view>
40 37
41 - <!-- 统计数据区域 - 来自me copy.vue -->  
42 - <view class="stats-section">  
43 - <view class="stats-container">  
44 - <view v-if="iskjb" class="stat-item" @click="goToPage('/pages/expansion-list/expansion-list')">  
45 - <view class="stat-icon icon-circle-bg-1"> 38 + <!-- KPI卡片区域 -->
  39 + <view class="kpi-section">
  40 + <view class="kpi-card kpi-card-1">
  41 + <view class="kpi-title">本月总业绩</view>
  42 + <view class="kpi-value">¥{{ (performanceData.BillingAmount || 0).toFixed(2) }}</view>
  43 + </view>
  44 + <view class="kpi-card kpi-card-2">
  45 + <view class="kpi-title">本月订单数</view>
  46 + <view class="kpi-value">{{ summaryData.hkCount || 0 }}单</view>
  47 + </view>
  48 + </view>
  49 +
  50 + <!-- 四个小数据卡片 -->
  51 + <view class="warpboxss small-stats-section">
  52 + <view class="small-stats-container">
  53 + <view v-if="iskjb" class="small-stat-item"
  54 + @click="goToPage('/pages/expansion-list/expansion-list')">
  55 + <view class="small-stat-icon icon-circle-bg-1">
46 <image src="/static/home/expansion.png" mode="heightFix"></image> 56 <image src="/static/home/expansion.png" mode="heightFix"></image>
47 </view> 57 </view>
48 - <view class="stat-info">  
49 - <view class="stat-num">{{ summaryData.expansionCount || 0 }}</view>  
50 - <view class="stat-name">拓客数</view>  
51 - </view> 58 + <view class="small-stat-num">{{ summaryData.expansionCount || 0 }}</view>
  59 + <view class="small-stat-name">拓客数</view>
52 </view> 60 </view>
53 - <view v-if="iskjb" class="stat-item" @click="goToPage('/pages/user-invite-list/user-invite-list')">  
54 - <view class="stat-icon icon-circle-bg-2"> 61 + <view v-if="iskjb" class="small-stat-item"
  62 + @click="goToPage('/pages/user-invite-list/user-invite-list')">
  63 + <view class="small-stat-icon icon-circle-bg-2">
55 <image src="/static/home/member.png" mode="heightFix"></image> 64 <image src="/static/home/member.png" mode="heightFix"></image>
56 </view> 65 </view>
57 - <view class="stat-info">  
58 - <view class="stat-num">{{ summaryData.inviteCount || 0 }}</view>  
59 - <view class="stat-name">邀约数</view>  
60 - </view> 66 + <view class="small-stat-num">{{ summaryData.inviteCount || 0 }}</view>
  67 + <view class="small-stat-name">邀约数</view>
61 </view> 68 </view>
62 - <view v-if="iskjb" class="stat-item" @click="goToPage('/pages/user-appointment-list/user-appointment-list')">  
63 - <view class="stat-icon icon-circle-bg-3"> 69 + <view v-if="iskjb" class="small-stat-item"
  70 + @click="goToPage('/pages/user-appointment-list/user-appointment-list')">
  71 + <view class="small-stat-icon icon-circle-bg-3">
64 <image src="/static/home/member.png" mode="heightFix"></image> 72 <image src="/static/home/member.png" mode="heightFix"></image>
65 </view> 73 </view>
66 - <view class="stat-info">  
67 - <view class="stat-num">{{ summaryData.appointmentCount || 0 }}</view>  
68 - <view class="stat-name">预约数</view>  
69 - </view> 74 + <view class="small-stat-num">{{ summaryData.appointmentCount || 0 }}</view>
  75 + <view class="small-stat-name">预约数</view>
70 </view> 76 </view>
71 - <view class="stat-item" @click="goToPage('/pages/lx-list/lx-list')">  
72 - <view class="stat-icon icon-circle-bg-4">  
73 - <image src="/static/home/order.png" mode="heightFix"></image>  
74 - </view>  
75 - <view class="stat-info">  
76 - <view class="stat-num">{{ summaryData.hkCount || 0 }}</view>  
77 - <view class="stat-name">开单数</view> 77 + <view class="small-stat-item" @click="goToPage('/pages/refund-list/refund-list')">
  78 + <view class="small-stat-icon icon-circle-bg-4">
  79 + <image src="/static/home/refund-card.png" mode="heightFix"></image>
78 </view> 80 </view>
  81 + <view class="small-stat-num">{{ summaryData.refundCount || 0 }}</view>
  82 + <view class="small-stat-name">退卡数</view>
79 </view> 83 </view>
80 - <view class="stat-item" @click="goToPage('/pages/consume-list/consume-list')">  
81 - <view class="stat-icon icon-circle-bg-5">  
82 - <image src="/static/home/consume-card.png" mode="heightFix"></image> 84 + </view>
  85 + </view>
  86 +
  87 + <!-- 今日数据和耗卡数据卡片 -->
  88 + <view class="data-section">
  89 + <view class="data-card">
  90 + <view class="data-card-title">今日数据</view>
  91 + <view class="data-card-content">
  92 + <view class="data-item">
  93 + <view class="data-label">今日:</view>
  94 + <view class="data-value">{{ todayData.today || 0 }}</view>
83 </view> 95 </view>
84 - <view class="stat-info">  
85 - <view class="stat-num">{{ summaryData.consumeCount || 0 }}</view>  
86 - <view class="stat-name">耗卡数</view> 96 + <view class="data-item">
  97 + <view class="data-label">本月:</view>
  98 + <view class="data-value">{{ todayData.month || 0 }}</view>
87 </view> 99 </view>
88 </view> 100 </view>
89 - <view class="stat-item" @click="goToPage('/pages/refund-list/refund-list')">  
90 - <view class="stat-icon icon-circle-bg-6">  
91 - <image src="/static/home/refund-card.png" mode="heightFix"></image> 101 + </view>
  102 + <view class="data-card">
  103 + <view class="data-card-title">耗卡数据</view>
  104 + <view class="data-card-content">
  105 + <view class="data-item">
  106 + <view class="data-label">今日:</view>
  107 + <view class="data-value">{{ consumeData.today || 0 }}</view>
92 </view> 108 </view>
93 - <view class="stat-info">  
94 - <view class="stat-num">{{ summaryData.refundCount || 0 }}</view>  
95 - <view class="stat-name">退卡数</view> 109 + <view class="data-item">
  110 + <view class="data-label">本月:</view>
  111 + <view class="data-value">{{ consumeData.month || 0 }}</view>
96 </view> 112 </view>
97 </view> 113 </view>
98 </view> 114 </view>
99 </view> 115 </view>
100 116
101 - <!-- 账户设置区域 - 来自me copy.vue -->  
102 - <view class="settings-section">  
103 - <view class="settings-card"> 117 + <!-- 个人服务区域 -->
  118 + <view class="warpboxss settings-section">
  119 + <view class="warpboxs-small-title">
  120 + <view><text class="warpboxs-small-title-line"></text>个人服务</view>
  121 + </view>
  122 + <view class="settings-list">
104 <view class="settings-item" @click="showChangePasswordDialog"> 123 <view class="settings-item" @click="showChangePasswordDialog">
105 <view class="settings-left"> 124 <view class="settings-left">
106 - <view class="settings-icon-wrapper" > 125 + <view class="settings-icon-wrapper">
107 <image src="/static/icon1.png" mode="aspectFit"></image> 126 <image src="/static/icon1.png" mode="aspectFit"></image>
108 </view> 127 </view>
109 <text class="settings-text">修改密码</text> 128 <text class="settings-text">修改密码</text>
@@ -112,7 +131,7 @@ @@ -112,7 +131,7 @@
112 </view> 131 </view>
113 <view class="settings-item" @click="handleLogout"> 132 <view class="settings-item" @click="handleLogout">
114 <view class="settings-left"> 133 <view class="settings-left">
115 - <view class="settings-icon-wrapper" > 134 + <view class="settings-icon-wrapper">
116 <image src="/static/icon2.png" mode="aspectFit"></image> 135 <image src="/static/icon2.png" mode="aspectFit"></image>
117 </view> 136 </view>
118 <text class="settings-text">退出登录</text> 137 <text class="settings-text">退出登录</text>
@@ -121,42 +140,29 @@ @@ -121,42 +140,29 @@
121 </view> 140 </view>
122 </view> 141 </view>
123 </view> 142 </view>
  143 +
  144 + <view style="height: 140rpx;"></view>
124 </view> 145 </view>
125 146
126 - <!-- 修改密码弹窗 - 来自me copy.vue --> 147 + <!-- 修改密码弹窗 -->
127 <u-popup :show="showPasswordDialog" @close="cancelChangePassword" mode="center" border-radius="20"> 148 <u-popup :show="showPasswordDialog" @close="cancelChangePassword" mode="center" border-radius="20">
128 <view class="password-dialog"> 149 <view class="password-dialog">
129 <view class="dialog-title">修改密码</view> 150 <view class="dialog-title">修改密码</view>
130 <view class="dialog-content"> 151 <view class="dialog-content">
131 <view class="form-item"> 152 <view class="form-item">
132 <text class="form-label">原密码</text> 153 <text class="form-label">原密码</text>
133 - <input  
134 - class="form-input"  
135 - type="password"  
136 - placeholder="请输入原密码"  
137 - v-model="passwordForm.oldPassword"  
138 - :password="true"  
139 - /> 154 + <input class="form-input" type="password" placeholder="请输入原密码"
  155 + v-model="passwordForm.oldPassword" :password="true" />
140 </view> 156 </view>
141 <view class="form-item"> 157 <view class="form-item">
142 <text class="form-label">新密码</text> 158 <text class="form-label">新密码</text>
143 - <input  
144 - class="form-input"  
145 - type="password"  
146 - placeholder="请输入新密码"  
147 - v-model="passwordForm.newPassword"  
148 - :password="true"  
149 - /> 159 + <input class="form-input" type="password" placeholder="请输入新密码"
  160 + v-model="passwordForm.newPassword" :password="true" />
150 </view> 161 </view>
151 <view class="form-item"> 162 <view class="form-item">
152 <text class="form-label">确认密码</text> 163 <text class="form-label">确认密码</text>
153 - <input  
154 - class="form-input"  
155 - type="password"  
156 - placeholder="请再次输入新密码"  
157 - v-model="passwordForm.confirmPassword"  
158 - :password="true"  
159 - /> 164 + <input class="form-input" type="password" placeholder="请再次输入新密码"
  165 + v-model="passwordForm.confirmPassword" :password="true" />
160 </view> 166 </view>
161 </view> 167 </view>
162 <view class="dialog-footer"> 168 <view class="dialog-footer">
@@ -165,441 +171,564 @@ @@ -165,441 +171,564 @@
165 </view> 171 </view>
166 </view> 172 </view>
167 </u-popup> 173 </u-popup>
168 - 174 +
169 <!-- 自定义 tabBar --> 175 <!-- 自定义 tabBar -->
170 <custom-tab-bar /> 176 <custom-tab-bar />
171 </view> 177 </view>
172 </template> 178 </template>
173 179
174 <script> 180 <script>
175 - import {  
176 - mapState,  
177 - mapMutations  
178 - } from 'vuex'  
179 - import memberApi from '@/apis/modules/member.js'  
180 - import oauthApi from '@/apis/modules/oauth.js'  
181 - import CustomTabBar from '@/components/custom-tab-bar/index.vue'  
182 - import CustomNavbar from '@/components/custom-navbar/custom-navbar.vue'  
183 -  
184 - export default {  
185 - components: {  
186 - CustomTabBar,  
187 - CustomNavbar  
188 - },  
189 - data() {  
190 - return {  
191 - navbarHeightRpx: 0, // 导航栏高度(rpx)  
192 - scrollTop: 0,  
193 - userInfo: {},  
194 - newuserInfo: {},  
195 - jsjinfo: {  
196 - storeName:'',  
197 - jsjName:''  
198 - },  
199 - summaryData: {  
200 - appointmentCount: 0,  
201 - inviteCount: 0,  
202 - expansionCount: 0,  
203 - hkCount: 0,  
204 - consumeCount: 0,  
205 - refundCount: 0  
206 - },  
207 - showPasswordDialog: false,  
208 - passwordForm: {  
209 - oldPassword: '',  
210 - newPassword: '',  
211 - confirmPassword: ''  
212 - } 181 +import {
  182 + mapState,
  183 + mapMutations
  184 +} from 'vuex'
  185 +import memberApi from '@/apis/modules/member.js'
  186 +import oauthApi from '@/apis/modules/oauth.js'
  187 +import performanceApi from '@/apis/modules/performance.js'
  188 +import CustomTabBar from '@/components/custom-tab-bar/index.vue'
  189 +import CustomNavbar from '@/components/custom-navbar/custom-navbar.vue'
  190 +
  191 +export default {
  192 + components: {
  193 + CustomTabBar,
  194 + CustomNavbar
  195 + },
  196 + data() {
  197 + return {
  198 + navbarHeightRpx: 0,
  199 + scrollTop: 0,
  200 + userInfo: {},
  201 + newuserInfo: {},
  202 + jsjinfo: {
  203 + storeName: '',
  204 + jsjName: ''
  205 + },
  206 + summaryData: {
  207 + appointmentCount: 0,
  208 + inviteCount: 0,
  209 + expansionCount: 0,
  210 + hkCount: 0,
  211 + consumeCount: 0,
  212 + refundCount: 0
  213 + },
  214 + performanceData: {
  215 + BillingAmount: 0,
  216 + OrderCount: 0
  217 + },
  218 + todayData: {
  219 + today: 0,
  220 + month: 0
  221 + },
  222 + consumeData: {
  223 + today: 0,
  224 + month: 0
  225 + },
  226 + showPasswordDialog: false,
  227 + passwordForm: {
  228 + oldPassword: '',
  229 + newPassword: '',
  230 + confirmPassword: ''
213 } 231 }
214 - }, 232 + }
  233 + },
215 234
216 - computed: {  
217 - iskjb() {  
218 - if (this.newuserInfo.gw == '科技老师') {  
219 - return false  
220 - }  
221 - return true  
222 - },  
223 - // 主内容区域顶部间距  
224 - mainMarginTop() {  
225 - if (this.navbarHeightRpx > 0) {  
226 - // 小程序:导航栏高度 + 背景图高度 + 额外间距  
227 - return (this.navbarHeightRpx + 290 + 40) + 'rpx'  
228 - }  
229 - // H5/APP:固定间距(背景图高度 + 导航栏高度)  
230 - return '370rpx' 235 + computed: {
  236 + iskjb() {
  237 + if (this.newuserInfo.gw == '科技老师') {
  238 + return false
231 } 239 }
  240 + return true
232 }, 241 },
  242 + contentTopMargin() {
  243 + const info = uni.getSystemInfoSync()
  244 + const pxToRpx = 750 / info.windowWidth
  245 + const safeSpacingPx = 20
  246 + const safeSpacingRpx = Math.ceil(safeSpacingPx * pxToRpx)
  247 + if (this.navbarHeightRpx > 0) {
  248 + return (this.navbarHeightRpx + safeSpacingRpx) + 'rpx'
  249 + }
  250 + return (100 + safeSpacingRpx) + 'rpx'
  251 + }
  252 + },
233 253
234 - async onLoad() {  
235 - this.checkLoginStatus()  
236 - await this.init()  
237 - }, 254 + async onLoad() {
  255 + this.checkLoginStatus()
  256 + await this.init()
  257 + },
238 258
239 - async onShow() {  
240 - // 页面显示时刷新数据  
241 - if (this.userInfo && this.userInfo.userId) {  
242 - await this.init()  
243 - }  
244 - }, 259 + async onShow() {
  260 + if (this.userInfo && this.userInfo.userId) {
  261 + await this.init()
  262 + }
  263 + },
245 264
246 - onPageScroll(e) {  
247 - this.scrollTop = e.scrollTop;  
248 - }, 265 + onPageScroll(e) {
  266 + this.scrollTop = e.scrollTop;
  267 + },
249 268
250 - methods: {  
251 - // 初始化  
252 - async init() {  
253 - if (!this.userInfo || !this.userInfo.userId) {  
254 - return  
255 - } 269 + methods: {
  270 + // 初始化
  271 + async init() {
  272 + if (!this.userInfo || !this.userInfo.userId) {
  273 + return
  274 + }
256 275
257 - // 获取用户信息  
258 - this.API.getUsers(this.userInfo.userId).then(res => {  
259 - if (res.code === 200) {  
260 - this.newuserInfo = res.data  
261 - if (this.newuserInfo.enabledMark != '1') {  
262 - uni.showToast({  
263 - title: '您的账号已被禁用',  
264 - icon: 'none'  
265 - })  
266 - // 清除本地存储  
267 - uni.clearStorageSync()  
268 - // 跳转到登录页  
269 - setTimeout(() => {  
270 - uni.reLaunch({  
271 - url: '/pages/login/login'  
272 - })  
273 - }, 1500)  
274 - } else {  
275 - let formattedDate = this.utils.gettime()  
276 - memberApi.getJsjInfoByUserMonth(this.userInfo.userId, formattedDate).then((resjsj) => {  
277 - if (resjsj.code == 200) {  
278 - this.jsjinfo = resjsj.data  
279 - } 276 + // 获取用户信息
  277 + this.API.getUsers(this.userInfo.userId).then(res => {
  278 + if (res.code === 200) {
  279 + this.newuserInfo = res.data
  280 + if (this.newuserInfo.enabledMark != '1') {
  281 + uni.showToast({
  282 + title: '您的账号已被禁用',
  283 + icon: 'none'
  284 + })
  285 + uni.clearStorageSync()
  286 + setTimeout(() => {
  287 + uni.reLaunch({
  288 + url: '/pages/login/login'
280 }) 289 })
281 - uni.setStorageSync('newuserInfo', this.newuserInfo)  
282 - this.getSummaryData()  
283 - } 290 + }, 1500)
  291 + } else {
  292 + let formattedDate = this.utils.gettime()
  293 + memberApi.getJsjInfoByUserMonth(this.userInfo.userId, formattedDate).then((resjsj) => {
  294 + if (resjsj.code == 200) {
  295 + this.jsjinfo = resjsj.data
  296 + }
  297 + })
  298 + uni.setStorageSync('newuserInfo', this.newuserInfo)
  299 + this.getSummaryData()
  300 + this.getPerformanceData()
  301 + this.getTodayAndConsumeData()
284 } 302 }
285 - })  
286 - }, 303 + }
  304 + })
  305 + },
287 306
288 - // 处理导航栏高度变化  
289 - handleNavbarHeightChange(heightInfo) {  
290 - this.navbarHeightRpx = heightInfo.rpx || 0  
291 - }, 307 + // 处理导航栏高度变化
  308 + handleNavbarHeightChange(heightInfo) {
  309 + this.navbarHeightRpx = heightInfo.rpx || 0
  310 + },
292 311
293 - // 检查登录状态  
294 - checkLoginStatus() {  
295 - const token = uni.getStorageSync('token') 312 + // 检查登录状态
  313 + checkLoginStatus() {
  314 + const token = uni.getStorageSync('token')
296 315
297 - if (!token) {  
298 - uni.reLaunch({  
299 - url: '/pages/login/login'  
300 - })  
301 - return  
302 - } else {  
303 - this.userInfo = uni.getStorageSync('userInfo')  
304 - this.newuserInfo = uni.getStorageSync('newuserInfo') || {}  
305 - }  
306 - }, 316 + if (!token) {
  317 + uni.reLaunch({
  318 + url: '/pages/login/login'
  319 + })
  320 + return
  321 + } else {
  322 + this.userInfo = uni.getStorageSync('userInfo')
  323 + this.newuserInfo = uni.getStorageSync('newuserInfo') || {}
  324 + }
  325 + },
307 326
308 - // 获取统计数据  
309 - async getSummaryData() {  
310 - try {  
311 - const currentMonthRange = this.utils.getCurrentMonthRange()  
312 - if (this.iskjb) {  
313 - let yyinfo = {  
314 - pageSize: 1,  
315 - currentPage: 1,  
316 - yysj: `${currentMonthRange[0]},${currentMonthRange[1]}`  
317 - }  
318 - let yayinfo = {  
319 - pageSize: 1,  
320 - yysj: `${currentMonthRange[0]},${currentMonthRange[1]}`  
321 - }  
322 - let tkinfo = {  
323 - pageSize: 1,  
324 - expansionTime: `${currentMonthRange[0]},${currentMonthRange[1]}`  
325 - }  
326 - if (this.newuserInfo.gw == '店助' || this.newuserInfo.gw == '店长') {  
327 - yyinfo.djmd = this.newuserInfo.mdid || '暂无'  
328 - yayinfo.storeId = this.newuserInfo.mdid || '暂无'  
329 - tkinfo.storeId = this.newuserInfo.mdid || '暂无'  
330 - } else {  
331 - yyinfo.yyr = this.userInfo.userId  
332 - yayinfo.yyr = this.userInfo.userId  
333 - tkinfo.expansionUserId = this.userInfo.userId  
334 - }  
335 - // 获取预约数  
336 - const appointmentRes = await this.API.getAppointmentList(yyinfo)  
337 -  
338 - if (appointmentRes.code === 200) {  
339 - this.summaryData.appointmentCount = appointmentRes.data.pagination?.total || 0  
340 - }  
341 -  
342 - // 获取邀请数  
343 - const inviteRes = await this.API.getInviteList(yayinfo)  
344 -  
345 - if (inviteRes.code === 200) {  
346 - this.summaryData.inviteCount = inviteRes.data.pagination?.total || 0  
347 - }  
348 -  
349 - // 获取拓客数  
350 - const expansionRes = await this.API.getExpansionList(tkinfo)  
351 -  
352 - if (expansionRes.code === 200) {  
353 - this.summaryData.expansionCount = expansionRes.data.pagination?.total || 0  
354 - }  
355 - }  
356 - let kainfo = { 327 + // 获取统计数据
  328 + async getSummaryData() {
  329 + try {
  330 + const currentMonthRange = this.utils.getCurrentMonthRange()
  331 + if (this.iskjb) {
  332 + let yyinfo = {
357 pageSize: 1, 333 pageSize: 1,
358 - kdrq: `${currentMonthRange[0]},${currentMonthRange[1]}` 334 + currentPage: 1,
  335 + yysj: `${currentMonthRange[0]},${currentMonthRange[1]}`
359 } 336 }
360 - let hkinfo = { 337 + let yayinfo = {
361 pageSize: 1, 338 pageSize: 1,
362 - hksj: `${currentMonthRange[0]},${currentMonthRange[1]}` 339 + yysj: `${currentMonthRange[0]},${currentMonthRange[1]}`
363 } 340 }
364 - let tkinfonew = { 341 + let tkinfo = {
365 pageSize: 1, 342 pageSize: 1,
366 - tksj: `${currentMonthRange[0]},${currentMonthRange[1]}` 343 + expansionTime: `${currentMonthRange[0]},${currentMonthRange[1]}`
367 } 344 }
368 - if (this.newuserInfo.gw == '科技老师') {  
369 - kainfo.kjblsId = this.userInfo.userId  
370 - hkinfo.kjblsId = this.userInfo.userId  
371 - tkinfonew.kjblsId = this.userInfo.userId  
372 - } else if (this.newuserInfo.gw == '健康师') {  
373 - kainfo.jksId = this.userInfo.userId  
374 - hkinfo.jksId = this.userInfo.userId  
375 - tkinfonew.jksId = this.userInfo.userId  
376 - } else if (this.newuserInfo.gw == '店助' || this.newuserInfo.gw == '店长') {  
377 - kainfo.djmd = this.newuserInfo.mdid || '暂无'  
378 - hkinfo.md = this.newuserInfo.mdid || '暂无'  
379 - tkinfonew.md = this.newuserInfo.mdid || '暂无' 345 + if (this.newuserInfo.gw == '店助' || this.newuserInfo.gw == '店长') {
  346 + yyinfo.djmd = this.newuserInfo.mdid || '暂无'
  347 + yayinfo.storeId = this.newuserInfo.mdid || '暂无'
  348 + tkinfo.storeId = this.newuserInfo.mdid || '暂无'
380 } else { 349 } else {
381 - kainfo.CreateUser = this.userInfo.userId  
382 - hkinfo.czry = this.userInfo.userId  
383 - tkinfonew.czry = this.userInfo.userId 350 + yyinfo.yyr = this.userInfo.userId
  351 + yayinfo.yyr = this.userInfo.userId
  352 + tkinfo.expansionUserId = this.userInfo.userId
384 } 353 }
385 - // 获取开单数(本月)  
386 - const hkRes = await this.API.getLxList(kainfo)  
387 -  
388 - if (hkRes.code === 200) {  
389 - this.summaryData.hkCount = hkRes.data.pagination?.total || 0 354 + // 获取预约数
  355 + const appointmentRes = await this.API.getAppointmentList(yyinfo)
  356 + if (appointmentRes.code === 200) {
  357 + this.summaryData.appointmentCount = appointmentRes.data.pagination?.total || 0
390 } 358 }
391 - // 获取耗卡数  
392 -  
393 - const consumeRes = await this.API.getConsumeList(hkinfo)  
394 -  
395 - if (consumeRes.code === 200) {  
396 - this.summaryData.consumeCount = consumeRes.data.pagination?.total || 0 359 + // 获取邀请数
  360 + const inviteRes = await this.API.getInviteList(yayinfo)
  361 + if (inviteRes.code === 200) {
  362 + this.summaryData.inviteCount = inviteRes.data.pagination?.total || 0
397 } 363 }
398 - // 获取退卡数 364 + // 获取拓客数
  365 + const expansionRes = await this.API.getExpansionList(tkinfo)
  366 + if (expansionRes.code === 200) {
  367 + this.summaryData.expansionCount = expansionRes.data.pagination?.total || 0
  368 + }
  369 + }
  370 + let kainfo = {
  371 + pageSize: 1,
  372 + kdrq: `${currentMonthRange[0]},${currentMonthRange[1]}`
  373 + }
  374 + let hkinfo = {
  375 + pageSize: 1,
  376 + hksj: `${currentMonthRange[0]},${currentMonthRange[1]}`
  377 + }
  378 + let tkinfonew = {
  379 + pageSize: 1,
  380 + tksj: `${currentMonthRange[0]},${currentMonthRange[1]}`
  381 + }
  382 + if (this.newuserInfo.gw == '科技老师') {
  383 + kainfo.kjblsId = this.userInfo.userId
  384 + hkinfo.kjblsId = this.userInfo.userId
  385 + tkinfonew.kjblsId = this.userInfo.userId
  386 + } else if (this.newuserInfo.gw == '健康师') {
  387 + kainfo.jksId = this.userInfo.userId
  388 + hkinfo.jksId = this.userInfo.userId
  389 + tkinfonew.jksId = this.userInfo.userId
  390 + } else if (this.newuserInfo.gw == '店助' || this.newuserInfo.gw == '店长') {
  391 + kainfo.djmd = this.newuserInfo.mdid || '暂无'
  392 + hkinfo.md = this.newuserInfo.mdid || '暂无'
  393 + tkinfonew.md = this.newuserInfo.mdid || '暂无'
  394 + } else {
  395 + kainfo.CreateUser = this.userInfo.userId
  396 + hkinfo.czry = this.userInfo.userId
  397 + tkinfonew.czry = this.userInfo.userId
  398 + }
  399 + // 获取开单数(本月)
  400 + const hkRes = await this.API.getLxList(kainfo)
  401 + if (hkRes.code === 200) {
  402 + this.summaryData.hkCount = hkRes.data.pagination?.total || 0
  403 + }
  404 + // 获取耗卡数
  405 + const consumeRes = await this.API.getConsumeList(hkinfo)
  406 + if (consumeRes.code === 200) {
  407 + this.summaryData.consumeCount = consumeRes.data.pagination?.total || 0
  408 + }
  409 + // 获取退卡数
  410 + const refundRes = await this.API.getRefundList(tkinfonew)
  411 + if (refundRes.code === 200) {
  412 + this.summaryData.refundCount = refundRes.data.pagination?.total || 0
  413 + }
399 414
400 - const refundRes = await this.API.getRefundList(tkinfonew) 415 + } catch (error) {
  416 + console.error('获取统计数据失败:', error)
  417 + }
  418 + },
401 419
402 - if (refundRes.code === 200) {  
403 - this.summaryData.refundCount = refundRes.data.pagination?.total || 0 420 + // 获取业绩数据
  421 + async getPerformanceData() {
  422 + try {
  423 + const statisticsMonth = this.getCurrentMonthStr()
  424 + const currentMonthRange = this.utils.getCurrentMonthRange()
  425 + if (this.newuserInfo.gw == '科技老师') {
  426 + const res = await performanceApi.GetTechTeacherStatistics({
  427 + teacherId: this.userInfo.userId,
  428 + startDate: this.formatDateToISO(currentMonthRange[0]),
  429 + endDate: this.formatDateToISO(currentMonthRange[1])
  430 + })
  431 + if (res.code === 200 && res.data) {
  432 + const data = res.data.length > 0 ? res.data[0] : {}
  433 + this.performanceData.BillingAmount = data.OrderAchievement || 0
  434 + }
  435 + } else {
  436 + const res = await performanceApi.getEmployeePerformanceStatistics({
  437 + userId: this.userInfo.userId,
  438 + statisticsMonth: statisticsMonth
  439 + })
  440 + if (res.code === 200 && res.data) {
  441 + this.performanceData.BillingAmount = res.data.BillingAmount || 0
404 } 442 }
405 -  
406 - } catch (error) {  
407 - console.error('获取统计数据失败:', error)  
408 } 443 }
409 - }, 444 + } catch (error) {
  445 + console.error('获取业绩数据失败:', error)
  446 + }
  447 + },
410 448
411 - // 页面跳转  
412 - goToPage(url) {  
413 - uni.navigateTo({  
414 - url: url  
415 - })  
416 - }, 449 + // 获取今日和耗卡数据
  450 + async getTodayAndConsumeData() {
  451 + try {
  452 + const today = this.utils.gettime()
  453 + const currentMonthRange = this.utils.getCurrentMonthRange()
417 454
418 - // 显示修改密码弹窗  
419 - showChangePasswordDialog() {  
420 - this.passwordForm = {  
421 - oldPassword: '',  
422 - newPassword: '',  
423 - confirmPassword: '' 455 + // 今日数据(开单数)
  456 + let todayKainfo = {
  457 + pageSize: 1,
  458 + kdrq: `${today},${today}`
  459 + }
  460 + let monthKainfo = {
  461 + pageSize: 1,
  462 + kdrq: `${currentMonthRange[0]},${currentMonthRange[1]}`
424 } 463 }
425 - this.showPasswordDialog = true  
426 - },  
427 464
428 - // 取消修改密码  
429 - cancelChangePassword() {  
430 - this.showPasswordDialog = false  
431 - this.passwordForm = {  
432 - oldPassword: '',  
433 - newPassword: '',  
434 - confirmPassword: '' 465 + // 耗卡数据
  466 + let todayHkinfo = {
  467 + pageSize: 1,
  468 + hksj: `${today},${today}`
  469 + }
  470 + let monthHkinfo = {
  471 + pageSize: 1,
  472 + hksj: `${currentMonthRange[0]},${currentMonthRange[1]}`
435 } 473 }
436 - },  
437 474
438 - // 确认修改密码  
439 - confirmChangePassword() {  
440 - // 验证输入  
441 - if (!this.passwordForm.oldPassword) {  
442 - uni.showToast({  
443 - title: '请输入原密码',  
444 - icon: 'none'  
445 - })  
446 - return 475 + // 根据角色设置筛选条件
  476 + if (this.newuserInfo.gw == '科技老师') {
  477 + todayKainfo.kjblsId = this.userInfo.userId
  478 + monthKainfo.kjblsId = this.userInfo.userId
  479 + todayHkinfo.kjblsId = this.userInfo.userId
  480 + monthHkinfo.kjblsId = this.userInfo.userId
  481 + } else if (this.newuserInfo.gw == '健康师') {
  482 + todayKainfo.jksId = this.userInfo.userId
  483 + monthKainfo.jksId = this.userInfo.userId
  484 + todayHkinfo.jksId = this.userInfo.userId
  485 + monthHkinfo.jksId = this.userInfo.userId
  486 + } else if (this.newuserInfo.gw == '店助' || this.newuserInfo.gw == '店长') {
  487 + todayKainfo.djmd = this.newuserInfo.mdid || '暂无'
  488 + monthKainfo.djmd = this.newuserInfo.mdid || '暂无'
  489 + todayHkinfo.md = this.newuserInfo.mdid || '暂无'
  490 + monthHkinfo.md = this.newuserInfo.mdid || '暂无'
  491 + } else {
  492 + todayKainfo.CreateUser = this.userInfo.userId
  493 + monthKainfo.CreateUser = this.userInfo.userId
  494 + todayHkinfo.czry = this.userInfo.userId
  495 + monthHkinfo.czry = this.userInfo.userId
447 } 496 }
448 497
449 - if (!this.passwordForm.newPassword) {  
450 - uni.showToast({  
451 - title: '请输入新密码',  
452 - icon: 'none'  
453 - })  
454 - return 498 + // 获取今日开单数
  499 + const todayKdRes = await this.API.getLxList(todayKainfo)
  500 + if (todayKdRes.code === 200) {
  501 + this.todayData.today = todayKdRes.data.pagination?.total || 0
455 } 502 }
456 503
457 - if (this.passwordForm.newPassword.length < 6) {  
458 - uni.showToast({  
459 - title: '新密码长度不能少于6位',  
460 - icon: 'none'  
461 - })  
462 - return 504 + // 获取本月开单数
  505 + const monthKdRes = await this.API.getLxList(monthKainfo)
  506 + if (monthKdRes.code === 200) {
  507 + this.todayData.month = monthKdRes.data.pagination?.total || 0
463 } 508 }
464 509
465 - if (this.passwordForm.newPassword !== this.passwordForm.confirmPassword) {  
466 - uni.showToast({  
467 - title: '两次输入的新密码不一致',  
468 - icon: 'none'  
469 - })  
470 - return 510 + // 获取今日耗卡数
  511 + const todayHkRes = await this.API.getConsumeList(todayHkinfo)
  512 + if (todayHkRes.code === 200) {
  513 + this.consumeData.today = todayHkRes.data.pagination?.total || 0
471 } 514 }
472 515
473 - if (this.passwordForm.oldPassword === this.passwordForm.newPassword) {  
474 - uni.showToast({  
475 - title: '新密码不能与原密码相同',  
476 - icon: 'none'  
477 - })  
478 - return 516 + // 获取本月耗卡数
  517 + const monthHkRes = await this.API.getConsumeList(monthHkinfo)
  518 + if (monthHkRes.code === 200) {
  519 + this.consumeData.month = monthHkRes.data.pagination?.total || 0
479 } 520 }
  521 + } catch (error) {
  522 + console.error('获取今日和耗卡数据失败:', error)
  523 + }
  524 + },
480 525
481 - // 调用修改密码接口  
482 - this.changePassword()  
483 - }, 526 + // 获取当前月份字符串(格式:YYYYMM)
  527 + getCurrentMonthStr() {
  528 + const now = new Date()
  529 + return uni.$u.timeFormat(now, 'yyyymm')
  530 + },
484 531
485 - // 修改密码  
486 - async changePassword() {  
487 - try {  
488 - uni.showLoading({  
489 - title: '修改中...'  
490 - }) 532 + // 格式化日期为 ISO 8601 格式(YYYY-MM-DDTHH:mm:ss)
  533 + formatDateToISO(timestamp) {
  534 + const date = new Date(timestamp)
  535 + return uni.$u.timeFormat(date, 'yyyy-mm-dd hh:MM:ss')
  536 + },
491 537
492 - // 调用修改密码 API  
493 - const res = await oauthApi.changePassword({  
494 - userId: this.userInfo.userId,  
495 - oldPassword: this.passwordForm.oldPassword,  
496 - newPassword: this.passwordForm.newPassword  
497 - }) 538 + // 页面跳转
  539 + goToPage(url) {
  540 + uni.navigateTo({
  541 + url: url
  542 + })
  543 + },
498 544
499 - uni.hideLoading() 545 + // 显示修改密码弹窗
  546 + showChangePasswordDialog() {
  547 + this.passwordForm = {
  548 + oldPassword: '',
  549 + newPassword: '',
  550 + confirmPassword: ''
  551 + }
  552 + this.showPasswordDialog = true
  553 + },
500 554
501 - if (res.code === 200) {  
502 - uni.showToast({  
503 - title: '密码修改成功',  
504 - icon: 'success'  
505 - })  
506 - this.showPasswordDialog = false  
507 - this.passwordForm = {  
508 - oldPassword: '',  
509 - newPassword: '',  
510 - confirmPassword: ''  
511 - }  
512 - } else {  
513 - uni.showToast({  
514 - title: res.msg || '密码修改失败',  
515 - icon: 'none'  
516 - }) 555 + // 取消修改密码
  556 + cancelChangePassword() {
  557 + this.showPasswordDialog = false
  558 + this.passwordForm = {
  559 + oldPassword: '',
  560 + newPassword: '',
  561 + confirmPassword: ''
  562 + }
  563 + },
  564 +
  565 + // 确认修改密码
  566 + confirmChangePassword() {
  567 + if (!this.passwordForm.oldPassword) {
  568 + uni.showToast({
  569 + title: '请输入原密码',
  570 + icon: 'none'
  571 + })
  572 + return
  573 + }
  574 +
  575 + if (!this.passwordForm.newPassword) {
  576 + uni.showToast({
  577 + title: '请输入新密码',
  578 + icon: 'none'
  579 + })
  580 + return
  581 + }
  582 +
  583 + if (this.passwordForm.newPassword.length < 6) {
  584 + uni.showToast({
  585 + title: '新密码长度不能少于6位',
  586 + icon: 'none'
  587 + })
  588 + return
  589 + }
  590 +
  591 + if (this.passwordForm.newPassword !== this.passwordForm.confirmPassword) {
  592 + uni.showToast({
  593 + title: '两次输入的新密码不一致',
  594 + icon: 'none'
  595 + })
  596 + return
  597 + }
  598 +
  599 + if (this.passwordForm.oldPassword === this.passwordForm.newPassword) {
  600 + uni.showToast({
  601 + title: '新密码不能与原密码相同',
  602 + icon: 'none'
  603 + })
  604 + return
  605 + }
  606 +
  607 + this.changePassword()
  608 + },
  609 +
  610 + // 修改密码
  611 + async changePassword() {
  612 + try {
  613 + uni.showLoading({
  614 + title: '修改中...'
  615 + })
  616 +
  617 + const res = await oauthApi.changePassword({
  618 + userId: this.userInfo.userId,
  619 + oldPassword: this.passwordForm.oldPassword,
  620 + newPassword: this.passwordForm.newPassword
  621 + })
  622 +
  623 + uni.hideLoading()
  624 +
  625 + if (res.code === 200) {
  626 + uni.showToast({
  627 + title: '密码修改成功',
  628 + icon: 'success'
  629 + })
  630 + this.showPasswordDialog = false
  631 + this.passwordForm = {
  632 + oldPassword: '',
  633 + newPassword: '',
  634 + confirmPassword: ''
517 } 635 }
518 - } catch (error) {  
519 - uni.hideLoading()  
520 - console.error('修改密码失败:', error) 636 + } else {
521 uni.showToast({ 637 uni.showToast({
522 - title: '修改密码失败,请稍后重试', 638 + title: res.msg || '密码修改失败',
523 icon: 'none' 639 icon: 'none'
524 }) 640 })
525 } 641 }
526 - },  
527 -  
528 - // 退出登录  
529 - handleLogout() {  
530 - uni.showModal({  
531 - title: '提示',  
532 - content: '确定要退出登录吗?',  
533 - success: (res) => {  
534 - if (res.confirm) {  
535 - this.API.logout().then(res => {  
536 - if (res.code == 200) {  
537 - // 清除本地存储  
538 - uni.clearStorageSync()  
539 - // 跳转到登录页  
540 - uni.reLaunch({  
541 - url: '/pages/login/login'  
542 - })  
543 - }  
544 - })  
545 - }  
546 - } 642 + } catch (error) {
  643 + uni.hideLoading()
  644 + console.error('修改密码失败:', error)
  645 + uni.showToast({
  646 + title: '修改密码失败,请稍后重试',
  647 + icon: 'none'
547 }) 648 })
548 } 649 }
  650 + },
  651 +
  652 + // 退出登录
  653 + handleLogout() {
  654 + uni.showModal({
  655 + title: '提示',
  656 + content: '确定要退出登录吗?',
  657 + success: (res) => {
  658 + if (res.confirm) {
  659 + this.API.logout().then(res => {
  660 + if (res.code == 200) {
  661 + uni.clearStorageSync()
  662 + uni.reLaunch({
  663 + url: '/pages/login/login'
  664 + })
  665 + }
  666 + })
  667 + }
  668 + }
  669 + })
549 } 670 }
550 } 671 }
  672 +}
551 </script> 673 </script>
552 674
553 <style lang="scss" scoped> 675 <style lang="scss" scoped>
554 - .page {  
555 - position: absolute;  
556 - left: 0;  
557 - top: 0;  
558 - width: 100%;  
559 - height: 100%;  
560 - background-color: #f5f7fa;  
561 - }  
562 -  
563 -  
564 - .main {  
565 - position: relative;  
566 - z-index: 111;  
567 - padding: 0 40rpx;  
568 - top: 90rpx;  
569 - /* #ifdef MP-WEIXIN */  
570 - top: 120rpx;  
571 - /* #endif */  
572 -  
573 - }  
574 -  
575 - /* 用户信息卡片 - 结合my.vue和me copy.vue的设计 */  
576 - .user-card {  
577 - position: relative;  
578 - margin: 24rpx 0;  
579 - border-radius: 20rpx;  
580 - overflow: hidden;  
581 - animation: slideDown 0.4s ease-out;  
582 - box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);  
583 - padding: 30rpx 0;  
584 - margin-bottom: 24rpx; 676 +.page {
  677 + position: relative;
  678 + width: 100%;
  679 + min-height: 100vh;
  680 + background: linear-gradient(135deg, #e8f5e9 0%, #b2dfdb 100%);
  681 + background-repeat: no-repeat;
  682 + background-size: 100% 100%;
  683 + font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Helvetica Neue", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  684 + -webkit-overflow-scrolling: touch;
  685 + overscroll-behavior-y: auto;
  686 +}
  687 +
  688 +.warpbox {
  689 + padding: 0 30rpx;
  690 + padding-bottom: 40rpx;
  691 +}
  692 +
  693 +.warpboxss {
  694 + background-color: rgba(255, 255, 255, 0.4);
  695 + backdrop-filter: blur(16px) saturate(180%);
  696 + -webkit-backdrop-filter: blur(16px) saturate(180%);
  697 + padding: 30rpx;
  698 + border-radius: 24rpx;
  699 + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
  700 + border: 1px solid rgba(255, 255, 255, 0.125);
  701 + margin-bottom: 24rpx;
  702 +}
  703 +
  704 +.warpboxs-small-title {
  705 + display: flex;
  706 + justify-content: space-between;
  707 + align-items: center;
  708 + font-size: 30rpx;
  709 + font-weight: 600;
  710 + color: #1f2937;
  711 + margin-bottom: 24rpx;
  712 +
  713 + view {
  714 + display: flex;
  715 + align-items: center;
585 } 716 }
586 717
587 - .user-card-bg {  
588 - position: absolute;  
589 - top: 0;  
590 - left: 0;  
591 - right: 0;  
592 - bottom: 0;  
593 - // background: linear-gradient(135deg, #e8f4f8 0%, #f0e8f5 50%, #f5f0e8 100%);  
594 - background: #fff; 718 + .warpboxs-small-title-line {
  719 + display: inline-block;
  720 + width: 6rpx;
  721 + height: 28rpx;
  722 + background: linear-gradient(180deg, #43a047 0%, #66bb6a 100%);
  723 + border-radius: 3rpx;
  724 + margin-right: 12rpx;
595 } 725 }
  726 +}
596 727
  728 +/* 用户信息卡片 */
  729 +.user-card {
597 .user-card-content { 730 .user-card-content {
598 - position: relative;  
599 - padding: 24rpx;  
600 - background: rgba(255, 255, 255, 0.6);  
601 - backdrop-filter: blur(10rpx);  
602 - -webkit-backdrop-filter: blur(10rpx); 731 + padding: 0;
603 } 732 }
604 733
605 .user-main { 734 .user-main {
@@ -608,30 +737,46 @@ @@ -608,30 +737,46 @@
608 } 737 }
609 738
610 .avatar-container { 739 .avatar-container {
611 - position: relative;  
612 - margin-right: 20rpx; 740 + margin-right: 24rpx;
613 flex-shrink: 0; 741 flex-shrink: 0;
  742 + position: relative;
  743 +
  744 + .avatar {
  745 + width: 120rpx;
  746 + height: 120rpx;
  747 + border-radius: 60rpx;
  748 + border: 4rpx solid rgba(67, 160, 71, 0.2);
  749 + box-shadow: 0 4rpx 16rpx rgba(67, 160, 71, 0.2);
  750 + position: relative;
  751 + z-index: 1;
  752 + }
  753 +
  754 + &::after {
  755 + content: '';
  756 + position: absolute;
  757 + top: -4rpx;
  758 + left: -4rpx;
  759 + right: -4rpx;
  760 + bottom: -4rpx;
  761 + border-radius: 50%;
  762 + background: linear-gradient(135deg, rgba(67, 160, 71, 0.3) 0%, rgba(102, 187, 106, 0.3) 100%);
  763 + z-index: 0;
  764 + animation: pulse 2s ease-in-out infinite;
  765 + }
614 } 766 }
615 767
616 - .avatar-ring {  
617 - position: absolute;  
618 - top: -3rpx;  
619 - left: -3rpx;  
620 - width: 100rpx;  
621 - height: 100rpx;  
622 - border-radius: 50rpx;  
623 - border: 2rpx solid rgba(67, 160, 71, 0.3);  
624 - animation: rotate 3s linear infinite;  
625 - }  
626 -  
627 - .avatar {  
628 - width: 94rpx;  
629 - height: 94rpx;  
630 - border-radius: 47rpx;  
631 - border: 2rpx solid rgba(255, 255, 255, 0.9);  
632 - position: relative;  
633 - z-index: 1;  
634 - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1); 768 + @keyframes pulse {
  769 +
  770 + 0%,
  771 + 100% {
  772 + opacity: 0.6;
  773 + transform: scale(1);
  774 + }
  775 +
  776 + 50% {
  777 + opacity: 0.8;
  778 + transform: scale(1.05);
  779 + }
635 } 780 }
636 781
637 .user-info-wrapper { 782 .user-info-wrapper {
@@ -640,351 +785,327 @@ @@ -640,351 +785,327 @@
640 } 785 }
641 786
642 .user-name { 787 .user-name {
643 - font-size: 32rpx; 788 + font-size: 36rpx;
644 font-weight: 600; 789 font-weight: 600;
645 color: #303133; 790 color: #303133;
646 - margin-bottom: 8rpx;  
647 - overflow: hidden;  
648 - text-overflow: ellipsis;  
649 - white-space: nowrap; 791 + margin-bottom: 20rpx;
650 } 792 }
651 793
652 .user-meta { 794 .user-meta {
653 display: flex; 795 display: flex;
654 - align-items: center;  
655 flex-wrap: wrap; 796 flex-wrap: wrap;
656 - gap: 8rpx;  
657 - margin-top: 8rpx; 797 + gap: 12rpx;
658 } 798 }
659 799
660 - .role-badge { 800 + .user-badge {
661 display: inline-flex; 801 display: inline-flex;
662 align-items: center; 802 align-items: center;
663 - background: rgba(67, 160, 71, 0.1);  
664 - border-radius: 12rpx;  
665 - padding: 6rpx 12rpx;  
666 - border: 1rpx solid rgba(67, 160, 71, 0.2);  
667 - font-size: 24rpx;  
668 - color: #43a047; 803 + padding: 6rpx 16rpx;
  804 + border-radius: 16rpx;
  805 + font-size: 22rpx;
669 font-weight: 500; 806 font-weight: 500;
670 - } 807 + backdrop-filter: blur(10rpx);
  808 + -webkit-backdrop-filter: blur(10rpx);
  809 + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);
  810 + transition: all 0.3s ease;
  811 + margin-left: 10rpx;
  812 +
  813 + .user-badge-text {
  814 + margin-left: 6rpx;
  815 + max-width: 180rpx;
  816 + overflow: hidden;
  817 + text-overflow: ellipsis;
  818 + white-space: nowrap;
  819 + }
671 820
672 - .role-badge text {  
673 - margin-left: 6rpx;  
674 - } 821 + &.user-badge-store {
  822 + background: linear-gradient(135deg, rgba(64, 158, 255, 0.15) 0%, rgba(64, 158, 255, 0.25) 100%);
  823 + border: 1rpx solid rgba(64, 158, 255, 0.3);
  824 + color: #409EFF;
  825 + }
675 826
676 - .store-badge {  
677 - display: inline-flex;  
678 - align-items: center;  
679 - background: rgba(64, 158, 255, 0.1);  
680 - border-radius: 12rpx;  
681 - padding: 6rpx 12rpx;  
682 - border: 1rpx solid rgba(64, 158, 255, 0.2);  
683 - font-size: 24rpx;  
684 - color: #409EFF;  
685 - font-weight: 500;  
686 - gap: 6rpx;  
687 - } 827 + &.user-badge-role {
  828 + background: linear-gradient(135deg, rgba(67, 160, 71, 0.15) 0%, rgba(67, 160, 71, 0.25) 100%);
  829 + border: 1rpx solid rgba(67, 160, 71, 0.3);
  830 + color: #43a047;
  831 + }
688 832
689 - .store-badge.jsj-badge {  
690 - background: rgba(255, 152, 0, 0.1);  
691 - border: 1rpx solid rgba(255, 152, 0, 0.2);  
692 - color: #ff9800; 833 + &.user-badge-jsj {
  834 + background: linear-gradient(135deg, rgba(255, 152, 0, 0.15) 0%, rgba(255, 152, 0, 0.25) 100%);
  835 + border: 1rpx solid rgba(255, 152, 0, 0.3);
  836 + color: #ff9800;
  837 + }
  838 + }
  839 +}
  840 +
  841 +/* KPI卡片区域 */
  842 +.kpi-section {
  843 + display: grid;
  844 + grid-template-columns: repeat(2, 1fr);
  845 + gap: 30rpx;
  846 + margin-bottom: 24rpx;
  847 +}
  848 +
  849 +.kpi-card {
  850 + background: linear-gradient(135deg, #4caf50 0%, #66bb6a 100%);
  851 + border-radius: 24rpx;
  852 + padding: 40rpx 30rpx;
  853 + box-shadow: 0 8rpx 24rpx rgba(76, 175, 80, 0.3);
  854 + position: relative;
  855 + overflow: hidden;
  856 +
  857 + &::before {
  858 + content: '';
  859 + position: absolute;
  860 + top: -50%;
  861 + right: -50%;
  862 + width: 200%;
  863 + height: 200%;
  864 + background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
693 } 865 }
694 866
695 - .store-badge text {  
696 - overflow: hidden;  
697 - text-overflow: ellipsis;  
698 - white-space: nowrap;  
699 - max-width: 120rpx; 867 + .kpi-title {
  868 + font-size: 26rpx;
  869 + color: rgba(255, 255, 255, 0.9);
  870 + margin-bottom: 16rpx;
700 } 871 }
701 872
702 - /* 统计数据区域 */  
703 - .stats-section {  
704 - margin: 24rpx 0;  
705 - animation: slideDown 0.5s ease-out; 873 + .kpi-value {
  874 + font-size: 48rpx;
  875 + font-weight: 700;
  876 + color: #ffffff;
  877 + line-height: 1.2;
706 } 878 }
  879 +}
  880 +
  881 +.kpi-card-2 {
  882 + background: linear-gradient(135deg, #43a047 0%, #66bb6a 100%);
  883 +}
707 884
708 - .stats-container {  
709 - background: #ffffff;  
710 - border-radius: 20rpx;  
711 - padding: 18rpx;  
712 - border: 1rpx solid rgba(0, 0, 0, 0.06);  
713 - box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08); 885 +/* 四个小数据卡片 */
  886 +.small-stats-section {
  887 + .small-stats-container {
714 display: grid; 888 display: grid;
715 - grid-template-columns: repeat(3, 1fr);  
716 - gap: 14rpx; 889 + grid-template-columns: repeat(4, 1fr);
  890 + gap: 20rpx;
717 } 891 }
718 892
719 - .stat-item {  
720 - background: #fff;  
721 - border-radius: 16rpx;  
722 - padding: 18rpx 14rpx; 893 + .small-stat-item {
723 display: flex; 894 display: flex;
  895 + flex-direction: column;
724 align-items: center; 896 align-items: center;
725 - // border: 1rpx solid #f0f2f5;  
726 - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);  
727 - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);  
728 - cursor: pointer;  
729 - }  
730 -  
731 - .stat-item:active {  
732 - transform: translateY(-2rpx) scale(0.98);  
733 - box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1); 897 + text-align: center;
734 } 898 }
735 899
736 - .stat-icon {  
737 - width: 56rpx;  
738 - height: 56rpx;  
739 - border-radius: 90%; 900 + .small-stat-icon {
  901 + width: 80rpx;
  902 + height: 80rpx;
  903 + border-radius: 16rpx;
740 display: flex; 904 display: flex;
741 align-items: center; 905 align-items: center;
742 justify-content: center; 906 justify-content: center;
743 - margin-right: 12rpx;  
744 - flex-shrink: 0;  
745 - 907 + margin-bottom: 12rpx;
  908 + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
  909 +
746 image { 910 image {
747 - height: 32rpx;  
748 - margin: 0 auto;  
749 - vertical-align: middle;  
750 - }  
751 -  
752 - &.icon-circle-bg-1 {  
753 - background: linear-gradient(135deg, #E3F2FD 0%, #2196F3 100%); // 蓝色渐变  
754 - }  
755 -  
756 - &.icon-circle-bg-2 {  
757 - background: linear-gradient(135deg, #F3E5F5 0%, #9C27B0 100%); // 紫色渐变  
758 - }  
759 -  
760 - &.icon-circle-bg-3 {  
761 - background: linear-gradient(135deg, #E8F5E9 0%, #4CAF50 100%); // 绿色渐变  
762 - }  
763 -  
764 - &.icon-circle-bg-4 {  
765 - background: linear-gradient(135deg, #FFF3E0 0%, #FF9800 100%); // 橙色渐变  
766 - }  
767 -  
768 - &.icon-circle-bg-5 {  
769 - background: linear-gradient(135deg, #E1F5FE 0%, #03A9F4 100%); // 青色渐变  
770 - }  
771 -  
772 - &.icon-circle-bg-6 {  
773 - background: linear-gradient(135deg, #FFEBEE 0%, #F44336 100%); // 红色渐变 911 + width: 40rpx;
  912 + height: 40rpx;
774 } 913 }
775 } 914 }
776 915
777 - .stat-info {  
778 - flex: 1;  
779 - min-width: 0;  
780 - }  
781 -  
782 - .stat-num {  
783 - font-size: 28rpx; 916 + .small-stat-num {
  917 + font-size: 32rpx;
784 font-weight: 600; 918 font-weight: 600;
785 color: #303133; 919 color: #303133;
786 - line-height: 1.2;  
787 - margin-bottom: 4rpx; 920 + margin-bottom: 6rpx;
788 } 921 }
789 922
790 - .stat-name { 923 + .small-stat-name {
791 font-size: 24rpx; 924 font-size: 24rpx;
792 color: #909399; 925 color: #909399;
793 } 926 }
794 927
795 - /* 账户设置区域 */  
796 - .settings-section {  
797 - margin: 24rpx 0;  
798 - animation: slideDown 0.6s ease-out; 928 + .icon-circle-bg-1 {
  929 + background-color: #43a047;
799 } 930 }
800 931
801 - .settings-card {  
802 - background: #ffffff;  
803 - border-radius: 20rpx;  
804 - overflow: hidden;  
805 - border: 1rpx solid rgba(0, 0, 0, 0.06);  
806 - box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08); 932 + .icon-circle-bg-2 {
  933 + background-color: #2196f3;
  934 + }
  935 +
  936 + .icon-circle-bg-3 {
  937 + background-color: #ff9800;
  938 + }
  939 +
  940 + .icon-circle-bg-4 {
  941 + background-color: #f44336;
  942 + }
  943 +}
  944 +
  945 +/* 数据卡片区域 */
  946 +.data-section {
  947 + display: grid;
  948 + grid-template-columns: repeat(2, 1fr);
  949 + gap: 30rpx;
  950 + margin-bottom: 24rpx;
  951 +}
  952 +
  953 +.data-card {
  954 + background-color: rgba(255, 255, 255, 0.4);
  955 + backdrop-filter: blur(16px) saturate(180%);
  956 + -webkit-backdrop-filter: blur(16px) saturate(180%);
  957 + border-radius: 24rpx;
  958 + padding: 30rpx;
  959 + box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.08);
  960 + border: 1px solid rgba(255, 255, 255, 0.125);
  961 +}
  962 +
  963 +.data-card-title {
  964 + font-size: 28rpx;
  965 + font-weight: 600;
  966 + color: #303133;
  967 + margin-bottom: 20rpx;
  968 +}
  969 +
  970 +.data-card-content {
  971 + display: flex;
  972 + flex-direction: column;
  973 + gap: 12rpx;
  974 +}
  975 +
  976 +.data-item {
  977 + display: flex;
  978 + justify-content: space-between;
  979 + align-items: center;
  980 +}
  981 +
  982 +.data-label {
  983 + font-size: 26rpx;
  984 + color: #909399;
  985 +}
  986 +
  987 +.data-value {
  988 + font-size: 32rpx;
  989 + font-weight: 600;
  990 + color: #303133;
  991 +}
  992 +
  993 +/* 设置区域 */
  994 +.settings-section {
  995 + .settings-list {
  996 + background: transparent;
807 } 997 }
808 998
809 .settings-item { 999 .settings-item {
810 display: flex; 1000 display: flex;
811 align-items: center; 1001 align-items: center;
812 justify-content: space-between; 1002 justify-content: space-between;
813 - padding: 28rpx 32rpx;  
814 - border-bottom: 1rpx solid #f0f2f5; 1003 + padding: 20rpx 0;
  1004 + border-bottom: 1rpx solid rgba(0, 0, 0, 0.06);
815 cursor: pointer; 1005 cursor: pointer;
816 transition: all 0.3s ease; 1006 transition: all 0.3s ease;
817 - background-color: #ffffff;  
818 - }  
819 1007
820 - .settings-item:last-child {  
821 - border-bottom: none;  
822 - } 1008 + &:last-child {
  1009 + border-bottom: none;
  1010 + }
823 1011
824 - .settings-item:active {  
825 - background-color: #f8f9fa;  
826 - transform: translateX(4rpx); 1012 + &:active {
  1013 + opacity: 0.7;
  1014 + }
827 } 1015 }
828 1016
829 .settings-left { 1017 .settings-left {
830 display: flex; 1018 display: flex;
831 - // align-items: center; 1019 + align-items: center;
832 flex: 1; 1020 flex: 1;
833 } 1021 }
834 1022
835 .settings-icon-wrapper { 1023 .settings-icon-wrapper {
836 - // width: 72rpx;  
837 - // height: 72rpx;  
838 - // border-radius: 16rpx;  
839 - // display: flex;  
840 - // align-items: center;  
841 - // justify-content: center; 1024 + display: flex;
  1025 + align-items: center;
  1026 + justify-content: center;
842 margin-right: 16rpx; 1027 margin-right: 16rpx;
  1028 + flex-shrink: 0;
  1029 +
843 image { 1030 image {
844 - width: 48rpx;  
845 - height: 48rpx; 1031 + width: 40rpx;
  1032 + height: 40rpx;
846 } 1033 }
847 } 1034 }
848 1035
849 .settings-text { 1036 .settings-text {
850 font-size: 28rpx; 1037 font-size: 28rpx;
851 color: #303133; 1038 color: #303133;
852 - font-weight: 500;  
853 - }  
854 -  
855 - /* 动画效果 */  
856 - @keyframes slideDown {  
857 - from {  
858 - opacity: 0;  
859 - transform: translateY(-20rpx);  
860 - }  
861 - to {  
862 - opacity: 1;  
863 - transform: translateY(0);  
864 - }  
865 - }  
866 -  
867 - @keyframes rotate {  
868 - from {  
869 - transform: rotate(0deg);  
870 - }  
871 - to {  
872 - transform: rotate(360deg);  
873 - }  
874 - }  
875 -  
876 - /* 修改密码弹窗样式 */  
877 - .password-dialog {  
878 - padding: 40rpx;  
879 - background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);  
880 - border-radius: 20rpx;  
881 - box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.12);  
882 - min-width: 600rpx;  
883 - }  
884 -  
885 - .dialog-title {  
886 - font-size: 32rpx;  
887 - font-weight: 600;  
888 - color: #303133;  
889 - text-align: center;  
890 - margin-bottom: 40rpx;  
891 - position: relative;  
892 - padding-bottom: 20rpx;  
893 - }  
894 -  
895 - .dialog-title::after {  
896 - content: '';  
897 - position: absolute;  
898 - bottom: 0;  
899 - left: 50%;  
900 - transform: translateX(-50%);  
901 - width: 60rpx;  
902 - height: 4rpx;  
903 - background: linear-gradient(90deg, #43a047 0%, #66bb6a 100%);  
904 - border-radius: 2rpx;  
905 - }  
906 -  
907 - .dialog-content {  
908 - margin-bottom: 40rpx;  
909 - }  
910 -  
911 - .form-item {  
912 - margin-bottom: 28rpx;  
913 - }  
914 -  
915 - .form-item:last-child {  
916 - margin-bottom: 0; 1039 + line-height: 1.5;
917 } 1040 }
  1041 +}
  1042 +
  1043 +/* 修改密码弹窗 */
  1044 +.password-dialog {
  1045 + width: 600rpx;
  1046 + background: #ffffff;
  1047 + border-radius: 24rpx;
  1048 + overflow: hidden;
  1049 +}
  1050 +
  1051 +.dialog-title {
  1052 + font-size: 36rpx;
  1053 + font-weight: 600;
  1054 + color: #303133;
  1055 + text-align: center;
  1056 + padding: 40rpx 40rpx 30rpx;
  1057 +}
  1058 +
  1059 +.dialog-content {
  1060 + padding: 0 40rpx;
  1061 +}
  1062 +
  1063 +.form-item {
  1064 + margin-bottom: 32rpx;
918 1065
919 .form-label { 1066 .form-label {
920 display: block; 1067 display: block;
921 font-size: 28rpx; 1068 font-size: 28rpx;
922 color: #606266; 1069 color: #606266;
923 margin-bottom: 12rpx; 1070 margin-bottom: 12rpx;
924 - font-weight: 500;  
925 } 1071 }
926 1072
927 .form-input { 1073 .form-input {
928 width: 100%; 1074 width: 100%;
929 - height: 80rpx;  
930 - padding: 0 24rpx;  
931 - border: 2rpx solid #e4e7ed; 1075 + height: 88rpx;
  1076 + background: #f5f7fa;
932 border-radius: 12rpx; 1077 border-radius: 12rpx;
  1078 + padding: 0 24rpx;
933 font-size: 28rpx; 1079 font-size: 28rpx;
934 color: #303133; 1080 color: #303133;
935 box-sizing: border-box; 1081 box-sizing: border-box;
936 - background-color: #ffffff;  
937 - transition: all 0.3s ease;  
938 - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);  
939 - }  
940 -  
941 - .form-input:focus {  
942 - border-color: #43a047;  
943 - background-color: #fff;  
944 - box-shadow: 0 2rpx 12rpx rgba(67, 160, 71, 0.15);  
945 - }  
946 -  
947 - .dialog-footer {  
948 - display: flex;  
949 - justify-content: space-between;  
950 - gap: 20rpx;  
951 - margin-top: 40rpx;  
952 - }  
953 -  
954 - .dialog-btn {  
955 - flex: 1;  
956 - height: 80rpx;  
957 - line-height: 80rpx;  
958 - text-align: center;  
959 - border-radius: 12rpx;  
960 - font-size: 28rpx;  
961 - font-weight: 500;  
962 - cursor: pointer;  
963 - transition: all 0.3s ease;  
964 - box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.08);  
965 } 1082 }
966 -  
967 - .cancel-btn {  
968 - background-color: #f5f7fa; 1083 +}
  1084 +
  1085 +.dialog-footer {
  1086 + display: flex;
  1087 + border-top: 1rpx solid #ebeef5;
  1088 + padding: 24rpx 40rpx;
  1089 + gap: 20rpx;
  1090 +}
  1091 +
  1092 +.dialog-btn {
  1093 + flex: 1;
  1094 + height: 80rpx;
  1095 + line-height: 80rpx;
  1096 + text-align: center;
  1097 + border-radius: 12rpx;
  1098 + font-size: 30rpx;
  1099 + font-weight: 500;
  1100 +
  1101 + &.cancel-btn {
  1102 + background: #f5f7fa;
969 color: #606266; 1103 color: #606266;
970 - border: 1rpx solid #e4e7ed;  
971 - }  
972 -  
973 - .cancel-btn:active {  
974 - background-color: #e4e7ed;  
975 - transform: scale(0.98);  
976 - box-shadow: 0 1rpx 4rpx rgba(0, 0, 0, 0.1);  
977 } 1104 }
978 1105
979 - .confirm-btn { 1106 + &.confirm-btn {
980 background: linear-gradient(135deg, #43a047 0%, #66bb6a 100%); 1107 background: linear-gradient(135deg, #43a047 0%, #66bb6a 100%);
981 - color: #fff;  
982 - border: none;  
983 - }  
984 -  
985 - .confirm-btn:active {  
986 - background: linear-gradient(135deg, #388e3c 0%, #43a047 100%);  
987 - transform: scale(0.98);  
988 - box-shadow: 0 1rpx 4rpx rgba(67, 160, 71, 0.3); 1108 + color: #ffffff;
989 } 1109 }
  1110 +}
990 </style> 1111 </style>