cwg-right-drawer.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <template>
  2. <view class="notice-container">
  3. <cwg-dropdown ref="dropdownRef" :menu-list="[]">
  4. <view class="pc-header-btn">
  5. <cwg-icon name="icon_my" color="#141d22" @click="openNotice" />
  6. </view>
  7. <template #btn>
  8. <view class="right-drawer">
  9. <view class="drawer-header">
  10. <image class="avatar" src="/static/images/avatars.png" mode="aspectFill" />
  11. <view class="user-info">
  12. <text class="name">{{ displayName }}</text>
  13. <text class="cid">CID: {{ displayCid }}</text>
  14. </view>
  15. </view>
  16. <view class="menu-list">
  17. <view v-for="item in menuList" :key="item.key" class="menu-item"
  18. :class="{ active: activePath === item.path }" @click="handleNavigate(item.path)">
  19. <cwg-icon :name="item.icon" :size="16"
  20. :color="activePath === item.path ? '#0f172b' : '#0f172b'" />
  21. <text>{{ item.name }}</text>
  22. </view>
  23. </view>
  24. <view class="logout-wrap">
  25. <view class="logout-btn" @click="handleLogout">
  26. <cwg-icon name="logout" :size="16" color="#ff9800" />
  27. <text>Logout</text>
  28. </view>
  29. </view>
  30. </view>
  31. </template>
  32. </cwg-dropdown>
  33. </view>
  34. </template>
  35. <script setup lang="ts">
  36. import { computed, ref } from 'vue'
  37. import useRoute from '@/hooks/useRoute'
  38. import useUserStore from '@/stores/use-user-store'
  39. import { userApi } from '@/api/user'
  40. import { useI18n } from "vue-i18n";
  41. const { t } = useI18n();
  42. import useRouter from "@/hooks/useRouter";
  43. const router = useRouter();
  44. const dropdownRef = ref(null)
  45. const userStore = useUserStore()
  46. const userInfo = computed<any>(() => userStore.userInfo?.customInfo || {})
  47. const route = useRoute()
  48. const menuList = computed(() => [
  49. {
  50. id: 1, path: '/pages/mine/info?type=1', name: t('PersonalManagement.Title.PersonalInformation'), icon: 'crm-circle-user'
  51. },
  52. {
  53. id: 2, path: '/pages/mine/info?type=2', name: t('PersonalManagement.Title.BankInformation'), icon: 'crm-building-columns'
  54. },
  55. {
  56. id: 3, path: '/pages/mine/info?type=3', name: t('PersonalManagement.Title.FileManagement'), icon: 'crm-file'
  57. },
  58. {
  59. id: 4, path: '/pages/mine/info?type=4', name: t('PersonalManagement.Title.SecurityCenter'), icon: 'crm-lock'
  60. }
  61. ]);
  62. const displayName = computed(() => {
  63. const fullName = `${userInfo.value?.firstName || ''} ${userInfo.value?.lastName || ''}`.trim()
  64. return fullName || userInfo.value?.name || userInfo.value?.email || '--'
  65. })
  66. const displayCid = computed(() => userInfo.value?.cId || userInfo.value?.id || '--')
  67. const activePath = computed(() => route.path + (route.query?.type ? `?type=${route.query.type}` : '') || '')
  68. function close() {
  69. dropdownRef.value?.close()
  70. console.log(userInfo, 1212);
  71. }
  72. function handleNavigate(path: string) {
  73. router.push({ path })
  74. close()
  75. }
  76. async function handleLogout() {
  77. try {
  78. const res = await userApi.logout()
  79. if (res.code === 200) {
  80. userStore.clearUserInfo()
  81. router.push('/pages/login/index')
  82. }
  83. } catch (error) {
  84. userStore.clearUserInfo()
  85. router.push('/pages/login/index')
  86. }
  87. close()
  88. }
  89. defineExpose({
  90. open,
  91. close
  92. })
  93. </script>
  94. <style scoped lang="scss">
  95. @import "@/uni.scss";
  96. .notice-container {
  97. :deep(.cwg-dropdown-menu-container) {
  98. left: px2rpx(-280) !important;
  99. right: px2rpx(0) !important;
  100. }
  101. @media screen and (max-width: 991px) {
  102. :deep(.cwg-dropdown-menu-container) {
  103. left: px2rpx(-270) !important;
  104. max-width: px2rpx(400);
  105. }
  106. }
  107. .pc-header-btn {
  108. position: relative;
  109. }
  110. .right-drawer {
  111. width: px2rpx(300);
  112. background-color: var(--color-white);
  113. display: flex;
  114. flex-direction: column;
  115. padding: 20px 16px;
  116. box-sizing: border-box;
  117. }
  118. .drawer-header {
  119. display: flex;
  120. align-items: center;
  121. gap: 12px;
  122. padding: 20px 16px;
  123. border-bottom: 1px solid #d9dde5;
  124. }
  125. .avatar {
  126. width: 76px;
  127. height: 76px;
  128. border-radius: 12px;
  129. background: #fff;
  130. }
  131. .user-info {
  132. display: flex;
  133. flex-direction: column;
  134. gap: 6px;
  135. }
  136. .name {
  137. font-size: 20px;
  138. font-weight: 600;
  139. color: #334155;
  140. }
  141. .cid {
  142. font-size: 14px;
  143. color: #ef4444;
  144. }
  145. .menu-list {
  146. padding: 12px 0;
  147. }
  148. .menu-item {
  149. height: 48px;
  150. display: flex;
  151. align-items: center;
  152. gap: 10px;
  153. padding: 0 16px;
  154. color: #0f172b;
  155. font-size: 16px;
  156. font-weight: 600;
  157. &:hover {
  158. background-color: rgba(0, 0, 0, 0.05);
  159. }
  160. }
  161. .menu-item.active {
  162. background: rgba(108, 133, 149, 0.12) !important;
  163. border-radius: 0.125rem;
  164. }
  165. .logout-wrap {
  166. margin-top: auto;
  167. padding: 20px 16px;
  168. margin-bottom: 20px;
  169. }
  170. .logout-btn {
  171. height: 44px;
  172. background: #f4eadf;
  173. display: flex;
  174. align-items: center;
  175. justify-content: center;
  176. gap: 8px;
  177. color: #ff9800;
  178. font-weight: 600;
  179. cursor: pointer;
  180. }
  181. }
  182. </style>