my.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. <template>
  2. <view class="page">
  3. <!-- 导航栏 -->
  4. <NavBar title="我的" />
  5. <!-- 用户卡片 -->
  6. <view class="user-section">
  7. <view class="user-card">
  8. <view class="user-header">
  9. <view class="avatar">
  10. <view class="avatar-icon">
  11. <text class="avatar-text">{{ userInfo.nickname?.charAt(0) || 'A' }}</text>
  12. </view>
  13. </view>
  14. <view class="user-info">
  15. <text class="user-name">{{ userInfo.nickname || '未登录' }}</text>
  16. <text class="user-role">{{ userInfo.roleName || '管理员' }}</text>
  17. </view>
  18. </view>
  19. <view class="user-stats">
  20. <view class="stat-item">
  21. <text class="stat-value">12</text>
  22. <text class="stat-label">管理门店</text>
  23. </view>
  24. <view class="stat-divider"></view>
  25. <view class="stat-item">
  26. <text class="stat-value">48</text>
  27. <text class="stat-label">设备数量</text>
  28. </view>
  29. <view class="stat-divider"></view>
  30. <view class="stat-item">
  31. <text class="stat-value">156</text>
  32. <text class="stat-label">今日订单</text>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. <!-- 菜单区域 -->
  38. <view class="menu-section">
  39. <view class="menu-card">
  40. <text class="menu-title">业务管理</text>
  41. <view class="menu-list">
  42. <view class="menu-item" @click="navigateTo('/pages/shop/list')">
  43. <view class="menu-icon amber">
  44. <view class="icon-shop"></view>
  45. </view>
  46. <view class="menu-content">
  47. <text class="menu-name">门店管理</text>
  48. <text class="menu-desc">查看和管理门店信息</text>
  49. </view>
  50. <view class="menu-arrow"></view>
  51. </view>
  52. <view class="menu-item" @click="navigateTo('/pages/products/list')">
  53. <view class="menu-icon purple">
  54. <view class="icon-product"></view>
  55. </view>
  56. <view class="menu-content">
  57. <text class="menu-name">商品管理</text>
  58. <text class="menu-desc">管理商品和价格</text>
  59. </view>
  60. <view class="menu-arrow"></view>
  61. </view>
  62. <view class="menu-item" @click="navigateTo('/pages/inventory/query')">
  63. <view class="menu-icon cyan">
  64. <view class="icon-chart"></view>
  65. </view>
  66. <view class="menu-content">
  67. <text class="menu-name">库存查询</text>
  68. <text class="menu-desc">查看库存情况</text>
  69. </view>
  70. <view class="menu-arrow"></view>
  71. </view>
  72. </view>
  73. </view>
  74. <view class="menu-card">
  75. <text class="menu-title">系统设置</text>
  76. <view class="menu-list">
  77. <view class="menu-item" @click="handleChangePassword">
  78. <view class="menu-icon green">
  79. <view class="icon-lock"></view>
  80. </view>
  81. <view class="menu-content">
  82. <text class="menu-name">修改密码</text>
  83. <text class="menu-desc">更改登录密码</text>
  84. </view>
  85. <view class="menu-arrow"></view>
  86. </view>
  87. <view class="menu-item" @click="handleAbout">
  88. <view class="menu-icon blue">
  89. <view class="icon-info"></view>
  90. </view>
  91. <view class="menu-content">
  92. <text class="menu-name">关于我们</text>
  93. <text class="menu-desc">版本信息</text>
  94. </view>
  95. <view class="menu-arrow"></view>
  96. </view>
  97. </view>
  98. </view>
  99. </view>
  100. <!-- 退出登录 -->
  101. <view class="logout-section">
  102. <button class="logout-btn" @click="handleLogout">
  103. <text>退出登录</text>
  104. </button>
  105. </view>
  106. <!-- 版本信息 -->
  107. <view class="version-info">
  108. <text>版本 1.0.0</text>
  109. </view>
  110. <!-- 自定义TabBar -->
  111. <CustomTabBar />
  112. </view>
  113. </template>
  114. <script setup lang="ts">
  115. import { ref, onMounted } from 'vue';
  116. import NavBar from '@/components/NavBar.vue';
  117. import CustomTabBar from '@/components/CustomTabBar.vue';
  118. import { getUserInfo, clearAuth } from '@/utils/auth';
  119. import { showConfirm, showToast } from '@/utils/common';
  120. const userInfo = ref<any>({});
  121. const loadUserInfo = () => {
  122. const info = getUserInfo();
  123. if (info) {
  124. userInfo.value = info;
  125. }
  126. };
  127. const navigateTo = (url: string) => {
  128. uni.navigateTo({ url });
  129. };
  130. const handleChangePassword = () => {
  131. showToast('修改密码功能开发中');
  132. };
  133. const handleAbout = () => {
  134. showToast('哈哈运营平台 v1.0.0');
  135. };
  136. const handleLogout = async () => {
  137. const confirmed = await showConfirm('确定要退出登录吗?');
  138. if (confirmed) {
  139. clearAuth();
  140. uni.reLaunch({ url: '/pages/login/login' });
  141. }
  142. };
  143. onMounted(() => {
  144. loadUserInfo();
  145. });
  146. </script>
  147. <style lang="scss" scoped>
  148. .page {
  149. min-height: 100vh;
  150. background: #f8fafc;
  151. padding-bottom: 200rpx;
  152. }
  153. /* 用户区域 */
  154. .user-section {
  155. padding: 16rpx 24rpx;
  156. }
  157. .user-card {
  158. background: #ffffff;
  159. border: 1rpx solid #e2e8f0;
  160. border-radius: 20rpx;
  161. padding: 32rpx;
  162. }
  163. .user-header {
  164. display: flex;
  165. align-items: center;
  166. margin-bottom: 24rpx;
  167. .avatar {
  168. width: 96rpx;
  169. height: 96rpx;
  170. background: #ecfdf5;
  171. border-radius: 24rpx;
  172. display: flex;
  173. align-items: center;
  174. justify-content: center;
  175. margin-right: 24rpx;
  176. border: 2rpx solid #10b981;
  177. .avatar-icon {
  178. width: 100%;
  179. height: 100%;
  180. display: flex;
  181. align-items: center;
  182. justify-content: center;
  183. }
  184. .avatar-text {
  185. font-size: 40rpx;
  186. font-weight: 700;
  187. color: #10b981;
  188. }
  189. }
  190. .user-info {
  191. flex: 1;
  192. .user-name {
  193. display: block;
  194. font-size: 34rpx;
  195. font-weight: 700;
  196. color: #1e293b;
  197. margin-bottom: 4rpx;
  198. }
  199. .user-role {
  200. font-size: 26rpx;
  201. color: #64748b;
  202. }
  203. }
  204. }
  205. .user-stats {
  206. display: flex;
  207. background: #f8fafc;
  208. border-radius: 12rpx;
  209. padding: 20rpx 0;
  210. .stat-item {
  211. flex: 1;
  212. display: flex;
  213. flex-direction: column;
  214. align-items: center;
  215. justify-content: center;
  216. .stat-value {
  217. display: flex;
  218. align-items: center;
  219. justify-content: center;
  220. font-size: 32rpx;
  221. font-weight: 700;
  222. color: #1e293b;
  223. margin-bottom: 4rpx;
  224. }
  225. .stat-label {
  226. display: flex;
  227. align-items: center;
  228. justify-content: center;
  229. font-size: 22rpx;
  230. color: #64748b;
  231. }
  232. }
  233. .stat-divider {
  234. width: 1rpx;
  235. background: #e2e8f0;
  236. }
  237. }
  238. /* 菜单区域 */
  239. .menu-section {
  240. padding: 0 24rpx;
  241. }
  242. .menu-card {
  243. background: #ffffff;
  244. border: 1rpx solid #e2e8f0;
  245. border-radius: 20rpx;
  246. margin-bottom: 16rpx;
  247. overflow: hidden;
  248. .menu-title {
  249. display: block;
  250. padding: 20rpx 24rpx 12rpx;
  251. font-size: 24rpx;
  252. color: #94a3b8;
  253. font-weight: 600;
  254. }
  255. }
  256. .menu-list {
  257. .menu-item {
  258. display: flex;
  259. align-items: center;
  260. padding: 20rpx 24rpx;
  261. border-bottom: 1rpx solid #f1f5f9;
  262. transition: background 0.15s;
  263. &:last-child {
  264. border-bottom: none;
  265. }
  266. &:active {
  267. background: #f8fafc;
  268. }
  269. }
  270. }
  271. .menu-icon {
  272. width: 56rpx;
  273. height: 56rpx;
  274. border-radius: 14rpx;
  275. display: flex;
  276. align-items: center;
  277. justify-content: center;
  278. margin-right: 16rpx;
  279. &.green { background: #ecfdf5; }
  280. &.blue { background: #f0f9ff; }
  281. &.amber { background: #fff7ed; }
  282. &.purple { background: #faf5ff; }
  283. &.cyan { background: #ecfeff; }
  284. /* 图标 - 纯CSS几何图形 */
  285. .icon-shop {
  286. width: 22rpx;
  287. height: 22rpx;
  288. background: #f97316;
  289. position: relative;
  290. &::before {
  291. content: '';
  292. position: absolute;
  293. top: -8rpx;
  294. left: 50%;
  295. transform: translateX(-50%);
  296. width: 0;
  297. height: 0;
  298. border-left: 14rpx solid transparent;
  299. border-right: 14rpx solid transparent;
  300. border-bottom: 10rpx solid #f97316;
  301. }
  302. }
  303. .icon-product {
  304. width: 20rpx;
  305. height: 18rpx;
  306. background: #a855f7;
  307. border-radius: 4rpx;
  308. position: relative;
  309. &::before {
  310. content: '';
  311. position: absolute;
  312. top: -8rpx;
  313. left: 50%;
  314. transform: translateX(-50%);
  315. width: 0;
  316. height: 0;
  317. border-left: 8rpx solid transparent;
  318. border-right: 8rpx solid transparent;
  319. border-bottom: 10rpx solid #a855f7;
  320. }
  321. }
  322. .icon-chart {
  323. display: flex;
  324. align-items: flex-end;
  325. width: 24rpx;
  326. height: 20rpx;
  327. &::before, &, &::after {
  328. content: '';
  329. width: 6rpx;
  330. background: #0ea5e9;
  331. border-radius: 3rpx;
  332. margin-right: 3rpx;
  333. }
  334. &::before { height: 10rpx; }
  335. & { height: 18rpx; }
  336. &::after { height: 14rpx; margin-right: 0; }
  337. }
  338. .icon-lock {
  339. width: 16rpx;
  340. height: 20rpx;
  341. background: #10b981;
  342. border-radius: 4rpx;
  343. position: relative;
  344. &::before {
  345. content: '';
  346. position: absolute;
  347. top: -6rpx;
  348. left: 50%;
  349. transform: translateX(-50%);
  350. width: 10rpx;
  351. height: 8rpx;
  352. border: 3rpx solid #10b981;
  353. border-bottom: none;
  354. border-radius: 8rpx 8rpx 0 0;
  355. }
  356. }
  357. .icon-info {
  358. width: 20rpx;
  359. height: 20rpx;
  360. border: 3rpx solid #0ea5e9;
  361. border-radius: 50%;
  362. position: relative;
  363. &::before {
  364. content: '';
  365. position: absolute;
  366. top: 4rpx;
  367. left: 50%;
  368. transform: translateX(-50%);
  369. width: 3rpx;
  370. height: 3rpx;
  371. background: #0ea5e9;
  372. border-radius: 50%;
  373. }
  374. &::after {
  375. content: '';
  376. position: absolute;
  377. top: 10rpx;
  378. left: 50%;
  379. transform: translateX(-50%);
  380. width: 3rpx;
  381. height: 6rpx;
  382. background: #0ea5e9;
  383. border-radius: 2rpx;
  384. }
  385. }
  386. }
  387. .menu-content {
  388. flex: 1;
  389. .menu-name {
  390. display: block;
  391. font-size: 30rpx;
  392. color: #1e293b;
  393. font-weight: 500;
  394. margin-bottom: 2rpx;
  395. }
  396. .menu-desc {
  397. font-size: 24rpx;
  398. color: #94a3b8;
  399. }
  400. }
  401. .menu-arrow {
  402. width: 12rpx;
  403. height: 12rpx;
  404. border-top: 3rpx solid #cbd5e1;
  405. border-right: 3rpx solid #cbd5e1;
  406. transform: rotate(45deg);
  407. }
  408. /* 退出登录 */
  409. .logout-section {
  410. padding: 24rpx 24rpx 0;
  411. .logout-btn {
  412. width: 100%;
  413. height: 100rpx;
  414. background: #fef2f2;
  415. border: 1rpx solid #fecaca;
  416. border-radius: 16rpx;
  417. font-size: 32rpx;
  418. font-weight: 600;
  419. color: #ef4444;
  420. display: flex;
  421. align-items: center;
  422. justify-content: center;
  423. transition: all 0.2s;
  424. &::after {
  425. border: none;
  426. }
  427. &:active {
  428. background: #fee2e2;
  429. transform: scale(0.98);
  430. }
  431. }
  432. }
  433. /* 版本信息 */
  434. .version-info {
  435. text-align: center;
  436. padding: 24rpx 0;
  437. text {
  438. font-size: 24rpx;
  439. color: #cbd5e1;
  440. }
  441. }
  442. </style>