Commit 67af4c8eabfb3b83000026a0a78b26ba26875cbb

Authored by 刘淇
1 parent 48ff5b95

工作台 如果没有子节点就不渲染父节点

pages/mine/index.vue
... ... @@ -8,19 +8,19 @@
8 8 <view class="user-info-wrap">
9 9 <!-- 头像 -->
10 10 <up-avatar
11   - :src="'/static/imgs/default-avatar.png'"
  11 + :src="userStore.isLogin ? userInfo.avatar : '/static/imgs/default-avatar.png'"
12 12 size="100rpx"
13 13 shape="circle"
14 14 class="user-avatar"
15 15 ></up-avatar>
16 16  
17   - <!-- 用户名+手机号+角色 -->
  17 + <!-- 用户名+手机号 -->
18 18 <view class="user-info-content">
19   - <view class="user-name">{{ userInfo.username || '未登录' }}</view>
20   - <view class="user-phone">{{ userInfo.nickname || '--------' }}</view>
  19 + <view class="user-name">{{ userStore.isLogin ? userInfo.username : '未登录' }}</view>
  20 + <view class="user-phone">{{ userStore.isLogin ? userInfo.nickname : '--------' }}</view>
21 21 </view>
22 22  
23   - <!-- 登录/编辑入口 -->
  23 + <!-- 登录入口 -->
24 24 <up-button
25 25 v-if="!userStore.isLogin"
26 26 type="primary"
... ... @@ -32,9 +32,8 @@
32 32 </view>
33 33 </view>
34 34  
35   -
36 35 <!-- 退出登录按钮 (仅登录状态显示) -->
37   - <view v-if="userStore.isLogin" class="logout-btn-wrap ">
  36 + <view v-if="userStore.isLogin" class="logout-btn-wrap">
38 37 <up-button
39 38 type="primary"
40 39 size="large"
... ... @@ -43,77 +42,64 @@
43 42 退出登录
44 43 </up-button>
45 44 </view>
46   -
47   -
48 45 </view>
49 46 </template>
50 47  
51 48 <script setup lang="ts">
52   -import { ref } from 'vue'
53   -import { useUserStore } from '@/pinia/user' // 匹配你的 Pinia 路径
54   -import { onShow } from '@dcloudio/uni-app'
55   -
  49 +import { computed } from 'vue'
  50 +import { useUserStore } from '@/pinia/user'
  51 +import { showModal, onShow } from '@dcloudio/uni-app'
56 52 // 初始化Pinia仓库
57 53 const userStore = useUserStore()
58   -const userInfo = userStore.userInfo.user
59   -import { getDictList, getDictLabel, getDictSimpleList } from '@/common/utils/dict';
60   -// 示例1:获取ai_image_status的完整字典列表
61   -const aiImageStatusList = ref([]);
62   -// 示例2:获取ai_image_status中value=10的label
63   -const aiImageStatus10Label = ref('');
64   -
65   -// 获取ai_image_status的完整列表(包含所有字段)
66   -aiImageStatusList.value = getDictList('ai_image_status');
67   -// 获取ai_image_status中value=10的label
68   -aiImageStatus10Label.value = getDictLabel('ai_image_status', 10);
69   -console.log('13')
70   -console.log(aiImageStatusList.value)
71   -console.log(aiImageStatus10Label.value)
72   -
73   -// 可选:获取仅包含value和label的简化列表
74   -const simpleList = getDictSimpleList('ai_image_status');
75   -console.log('简化列表:', simpleList);
76   -console.log('24')
77   -
78   -
79 54  
  55 +// 计算属性获取用户信息(响应式)
  56 +const userInfo = computed(() => userStore.userInfo.user || {})
80 57  
81   -// 页面显示时检查登录状态(同步缓存)
82   -onShow(() => {
83   - // 触发登录状态检查,确保缓存和Pinia同步
84   - userStore.checkLogin()
85   -})
86   -
87   -// 处理登录(跳转到登录页)
  58 +/**
  59 + * 处理登录跳转
  60 + */
88 61 const handleLogin = () => {
89   - navigateTo({
90   - url: '/pages/login/index' // 替换为你的实际登录页路径
  62 + uni.navigateTo({
  63 + url: '/pages/login/index'
91 64 })
92 65 }
93 66  
94   -
95   -
96   -// 确认退出登录
  67 +/**
  68 + * 确认退出登录(带二次确认)
  69 + */
97 70 const confirmLogout = async () => {
  71 + console.log('13213')
98 72 try {
99   - // 调用Pinia自带的logout方法(你的仓库已实现清空状态+跳转)
100   - await userStore.logout()
  73 + console.log('434')
  74 + const res = await uni.showModal({
  75 + title: '提示',
  76 + content: '确定要退出登录吗?',
  77 + confirmText: '退出',
  78 + cancelText: '取消'
  79 + })
101 80  
  81 + if (res.confirm) {
  82 + await userStore.logout()
  83 + uni.showToast({ title: '退出登录成功', type: 'success' })
  84 + }
102 85 } catch (error) {
103 86 console.error('退出登录失败:', error)
104   - uni.showToast({
105   - title: '退出登录失败,请重试',
106   - type: 'error'
107   - })
108   -
  87 + uni.showToast({ title: '退出登录失败,请重试', type: 'error' })
109 88 }
110 89 }
111 90  
  91 +// 页面显示时检查登录状态
  92 +onShow(() => {
  93 + userStore.checkLogin()
  94 +})
112 95 </script>
113 96  
114 97 <script lang="ts">
115 98 export default {
116   - name: 'UserCenter'
  99 + name: 'UserCenter',
  100 + options: {
  101 + navigationBarTitleText: '个人中心'
  102 + }
117 103 }
118 104 </script>
119 105  
... ... @@ -149,6 +135,10 @@ export default {
149 135 .user-avatar {
150 136 border: 4rpx solid #ffffff;
151 137 box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
  138 + transition: transform 0.2s ease;
  139 + &:active {
  140 + transform: scale(0.95);
  141 + }
152 142 }
153 143  
154 144 .user-info-content {
... ... @@ -166,25 +156,13 @@ export default {
166 156 .user-phone {
167 157 font-size: 26rpx;
168 158 color: rgba(255, 255, 255, 0.9);
169   - margin-bottom: 10rpx;
170   - }
171   -
172   - .user-role-tag {
173   - background-color: rgba(255, 255, 255, 0.2);
174   - color: #ffffff;
175   - border: none;
176 159 }
177 160 }
178 161 }
179 162 }
180 163  
181   -
182 164 // 退出登录按钮
183 165 .logout-btn-wrap {
184 166 margin: 200rpx 20rpx 20rpx;
185   - padding: 20rpx;
186   -
187   -
188 167 }
189   -
190 168 </style>
191 169 \ No newline at end of file
... ...
pages/workbench/index.vue
1 1 <template>
2   - <!-- 外层容器:包含蓝色块 + 原始内容 -->
3 2 <view class="page-container">
4   - <!-- 加载页:覆盖整个容器,渲染完成后隐藏 -->
  3 + <!-- 加载页 -->
5 4 <up-loading-page
6   -
7 5 :loading="loading"
8 6 loading-text="加载中..."
9 7 color="#577ee3"
10 8 zIndex="1000"
11 9 ></up-loading-page>
12 10  
13   - <!-- 蓝色装饰块:#577ee3 -->
  11 + <!-- 蓝色装饰块 -->
14 12 <view class="blue-decor-block" v-show="!loading"></view>
15 13  
16   - <!-- 原始内容容器 -->
  14 + <!-- 内容容器 -->
17 15 <view class="content-wrap">
18   - <!-- uview-plus空状态组件 -->
  16 + <!-- 空状态:过滤后无数据且非加载中时显示 -->
19 17 <u-empty
20   - v-if="!moduleList.length && !loading"
  18 + v-if="!filteredModuleList.length && !loading"
21 19 mode="permission"
22 20 ></u-empty>
23 21  
24   - <!-- 菜单卡片列表(替换grid为flex布局) -->
25   - <view class="menu-card-wrap">
  22 + <!-- 菜单卡片列表:仅渲染有子节点的父模块 -->
  23 + <view class="menu-card-wrap">
26 24 <up-card
27 25 :title-size="18"
28 26 :border="false"
29 27 :shadow="true"
30 28 :foot-border-top="false"
31   - v-for="(parentModule, index) in moduleList"
  29 + v-for="(parentModule, index) in filteredModuleList"
32 30 :key="`$parentModule.id_${index}`"
33 31 :title="parentModule.name"
34 32 class="card-container"
35 33 >
36 34 <template #body>
37   - <!-- 替换up-grid:改用flex流式布局容器 -->
38 35 <view class="card-content">
39 36 <view
40 37 v-for="(listItem, listIndex) in parentModule.children"
... ... @@ -62,8 +59,7 @@
62 59 </template>
63 60  
64 61 <script setup lang="ts">
65   -// 原始代码完全保留,无任何修改
66   -import { ref, nextTick } from 'vue';
  62 +import { ref, computed } from 'vue'; // 新增 computed
67 63 import { onShow } from '@dcloudio/uni-app';
68 64 import { useUserStore } from '@/pinia/user';
69 65 import globalConfig from '@/common/config/global';
... ... @@ -91,60 +87,50 @@ const loading = ref(true);
91 87 const userStore = useUserStore();
92 88 const moduleList = ref<MenuItem[]>([]);
93 89  
  90 +// 计算属性:过滤出有子节点的父模块(children 存在且长度 > 0)
  91 +const filteredModuleList = computed(() => {
  92 + return moduleList.value.filter(item => {
  93 + // 确保 children 是数组且长度大于 0
  94 + return Array.isArray(item.children) && item.children.length > 0;
  95 + });
  96 +});
  97 +
94 98 onShow(async () => {
95 99 try {
96 100 loading.value = true;
97   -
98 101 const rawMenuData = userStore.moduleListInfo || cache.get(globalConfig.cache.moduleListKey);
99   - const menuData = rawMenuData || [];
100   - moduleList.value = menuData;
101   - //
102   - // // await nextTick();
103   - // setTimeout(() => {
104   - // loading.value = false;
105   - // }, 500);
  102 + moduleList.value = rawMenuData || [];
106 103 loading.value = false;
107   - console.log('菜单数据:', moduleList.value);
  104 + console.log('原始菜单数据:', moduleList.value);
  105 + console.log('过滤后有子节点的父模块:', filteredModuleList.value);
108 106 } catch (error) {
109 107 console.error('获取菜单数据失败:', error);
110 108 moduleList.value = [];
111   - await nextTick();
112 109 loading.value = false;
113 110 }
114 111 });
115 112  
116 113 const handleMenuClick = (item: MenuItem) => {
117 114 if (!item.jumpUrl) {
118   - uni.showToast({
119   - title: '暂无跳转链接',
120   - icon: 'none',
121   - duration: 2000
122   - });
  115 + uni.showToast({ title: '暂无跳转链接', icon: 'none', duration: 2000 });
123 116 return;
124 117 }
125   - console.log(item.jumpUrl);
126 118 uni.navigateTo({
127 119 url: item.jumpUrl,
128 120 fail: (err) => {
129 121 console.error('页面跳转失败:', err);
130   - uni.showToast({
131   - title: '页面路径错误',
132   - icon: 'none',
133   - duration: 2000
134   - });
  122 + uni.showToast({ title: '页面路径错误', icon: 'none', duration: 2000 });
135 123 }
136 124 });
137 125 };
138 126 </script>
139 127  
140 128 <style scoped lang="scss">
141   -/* 原有样式保留 + 新增/调整图片居中样式 */
142 129 .page-container {
143   - position: relative; // 新增:让蓝色块绝对定位生效
144   - min-height: 100vh; // 新增:防止内容高度不足
  130 + position: relative;
  131 + min-height: 100vh;
145 132 }
146 133  
147   -/* 蓝色块样式(保留) */
148 134 .blue-decor-block {
149 135 position: absolute;
150 136 top: 0;
... ... @@ -155,70 +141,57 @@ const handleMenuClick = (item: MenuItem) =&gt; {
155 141 z-index: 1;
156 142 }
157 143  
158   -/* 内容容器样式(保留 + 微调) */
159 144 .content-wrap {
160 145 position: relative;
161 146 z-index: 2;
162   - padding: 120px 0 0 ; // 新增左右内边距,避免卡片贴边
  147 + padding: 120px 0 0;
163 148 display: flex;
164 149 flex-direction: column;
165   - gap: 20rpx; // 新增:卡片之间的上下间距
  150 + gap: 20rpx;
166 151 }
167 152  
168   -/* 菜单卡片容器(新增:统一卡片外层间距) */
169 153 .menu-card-wrap {
170 154 width: 100%;
171 155 }
172 156  
173   -/* 卡片容器:重置up-card默认样式 */
174 157 .card-container {
175   - --u-card-content-padding: 0; // 取消卡片默认内边距
176   - border-radius: 8rpx; // 新增:卡片圆角
177   - overflow: hidden; // 新增:裁剪内部元素
  158 + --u-card-content-padding: 0;
  159 + border-radius: 8rpx;
  160 + overflow: hidden;
178 161 }
179 162  
180   -/* 核心:小块容器(Flex 流式布局) */
181 163 .card-content {
182 164 display: flex;
183   - flex-wrap: wrap; // 自动换行
184   - gap: 20rpx; // 关键:小块之间的上下+左右间距统一
185   -
  165 + flex-wrap: wrap;
  166 + gap: 20rpx;
186 167 }
187 168  
188   -/* 小块样式:一行最多4个,宽度自适应 + 内部flex布局 */
189 169 .content-block {
190   - // 宽度计算:(100% - 3*间距) / 4 (4个元素有3个间距)
191 170 width: calc((100% - 3 * 20rpx) / 4);
192   - // 小块内部样式:改用flex布局,确保子元素居中
193 171 display: flex;
194 172 flex-direction: column;
195   - align-items: center; // 水平居中(核心:解决图片不居中问题)
196   - justify-content: center; // 垂直居中(可选,优化视觉)
197   - padding: 24rpx 0;
  173 + align-items: center;
  174 + justify-content: center;
  175 + padding: 14rpx 0;
198 176 border-radius: 8rpx;
199   - text-align: center;
200   - // 点击反馈
201 177 touch-action: manipulation;
202 178 transition: background-color 0.2s;
203 179 }
204 180  
205   -/* 小块点击态 */
206 181 .content-block:active {
207 182 background-color: #e9ecef;
208 183 }
209 184  
210   -/* 新增:图片居中样式(兜底保障) */
211 185 .block-icon {
212   - display: block; // 转为块级元素
213   - margin: 0 auto; // 水平居中(双重保障)
  186 + display: block;
  187 + margin: 0 auto;
214 188 }
215 189  
216   -/* 网格文字样式(保留 + 微调) */
217 190 .grid-text {
218 191 font-size: 26rpx;
219 192 color: #333;
220 193 text-align: center;
221 194 margin-top: 10rpx;
222   - display: block; // 新增:确保文字换行
  195 + display: block;
223 196 }
224 197 </style>
225 198 \ No newline at end of file
... ...