Commit 83954241aedf86005c3f25eae8ff5a57421fe516

Authored by xingyu4j
1 parent 1e65b221

style: 切换页面布局

yudao-ui-admin-vue3/src/views/Error/403.vue
  1 +<template>
  2 + <Error type="403" @error-click="errorClick" />
  3 +</template>
1 <script setup lang="ts"> 4 <script setup lang="ts">
2 import { Error } from '@/components/Error' 5 import { Error } from '@/components/Error'
3 import { useRouter } from 'vue-router' 6 import { useRouter } from 'vue-router'
@@ -8,7 +11,3 @@ const errorClick = () =&gt; { @@ -8,7 +11,3 @@ const errorClick = () =&gt; {
8 push('/') 11 push('/')
9 } 12 }
10 </script> 13 </script>
11 -  
12 -<template>  
13 - <Error type="403" @error-click="errorClick" />  
14 -</template>  
yudao-ui-admin-vue3/src/views/Error/404.vue
  1 +<template>
  2 + <Error @error-click="errorClick" />
  3 +</template>
  4 +
1 <script setup lang="ts"> 5 <script setup lang="ts">
2 import { Error } from '@/components/Error' 6 import { Error } from '@/components/Error'
3 import { useRouter } from 'vue-router' 7 import { useRouter } from 'vue-router'
@@ -8,7 +12,3 @@ const errorClick = () =&gt; { @@ -8,7 +12,3 @@ const errorClick = () =&gt; {
8 push('/') 12 push('/')
9 } 13 }
10 </script> 14 </script>
11 -  
12 -<template>  
13 - <Error @error-click="errorClick" />  
14 -</template>  
yudao-ui-admin-vue3/src/views/Error/500.vue
  1 +<template>
  2 + <Error type="500" @error-click="errorClick" />
  3 +</template>
  4 +
1 <script setup lang="ts"> 5 <script setup lang="ts">
2 import { Error } from '@/components/Error' 6 import { Error } from '@/components/Error'
3 import { useRouter } from 'vue-router' 7 import { useRouter } from 'vue-router'
@@ -8,7 +12,3 @@ const errorClick = () =&gt; { @@ -8,7 +12,3 @@ const errorClick = () =&gt; {
8 push('/') 12 push('/')
9 } 13 }
10 </script> 14 </script>
11 -  
12 -<template>  
13 - <Error type="500" @error-click="errorClick" />  
14 -</template>  
yudao-ui-admin-vue3/src/views/Home/Index.vue
  1 +<template>
  2 + <div>
  3 + <el-card shadow="never">
  4 + <el-skeleton :loading="loading" animated>
  5 + <el-row :gutter="20" justify="space-between">
  6 + <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
  7 + <div class="flex items-center">
  8 + <img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" />
  9 + <div>
  10 + <div class="text-20px text-700">
  11 + {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}
  12 + </div>
  13 + <div class="mt-10px text-14px text-gray-500">
  14 + {{ t('workplace.toady') }},20℃ - 32℃!
  15 + </div>
  16 + </div>
  17 + </div>
  18 + </el-col>
  19 + <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">
  20 + <div class="flex h-70px items-center justify-end <sm:mt-10px">
  21 + <div class="px-8px text-right">
  22 + <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>
  23 + <CountTo
  24 + class="text-20px"
  25 + :start-val="0"
  26 + :end-val="totalSate.project"
  27 + :duration="2600"
  28 + />
  29 + </div>
  30 + <el-divider direction="vertical" />
  31 + <div class="px-8px text-right">
  32 + <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.toDo') }}</div>
  33 + <CountTo
  34 + class="text-20px"
  35 + :start-val="0"
  36 + :end-val="totalSate.todo"
  37 + :duration="2600"
  38 + />
  39 + </div>
  40 + <el-divider direction="vertical" border-style="dashed" />
  41 + <div class="px-8px text-right">
  42 + <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.access') }}</div>
  43 + <CountTo
  44 + class="text-20px"
  45 + :start-val="0"
  46 + :end-val="totalSate.access"
  47 + :duration="2600"
  48 + />
  49 + </div>
  50 + </div>
  51 + </el-col>
  52 + </el-row>
  53 + </el-skeleton>
  54 + </el-card>
  55 + </div>
  56 +
  57 + <el-row class="mt-5px" :gutter="20" justify="space-between">
  58 + <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-10px">
  59 + <el-card shadow="never">
  60 + <template #header>
  61 + <div class="flex justify-between h-3">
  62 + <span>{{ t('workplace.project') }}</span>
  63 + <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>
  64 + </div>
  65 + </template>
  66 + <el-skeleton :loading="loading" animated>
  67 + <el-row>
  68 + <el-col
  69 + v-for="(item, index) in projects"
  70 + :key="`card-${index}`"
  71 + :xl="8"
  72 + :lg="8"
  73 + :md="8"
  74 + :sm="24"
  75 + :xs="24"
  76 + >
  77 + <el-card shadow="hover">
  78 + <div class="flex items-center">
  79 + <Icon :icon="item.icon" :size="25" class="mr-10px" />
  80 + <span class="text-16px">{{ item.name }}</span>
  81 + </div>
  82 + <div class="mt-15px text-14px text-gray-400">{{ t(item.message) }}</div>
  83 + <div class="mt-20px text-12px text-gray-400 flex justify-between">
  84 + <span>{{ item.personal }}</span>
  85 + <span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>
  86 + </div>
  87 + </el-card>
  88 + </el-col>
  89 + </el-row>
  90 + </el-skeleton>
  91 + </el-card>
  92 +
  93 + <el-card shadow="never" class="mt-5px">
  94 + <el-skeleton :loading="loading" animated>
  95 + <el-row :gutter="20" justify="space-between">
  96 + <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">
  97 + <el-card shadow="hover" class="mb-10px">
  98 + <el-skeleton :loading="loading" animated>
  99 + <Echart :options="pieOptionsData" :height="280" />
  100 + </el-skeleton>
  101 + </el-card>
  102 + </el-col>
  103 + <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
  104 + <el-card shadow="hover" class="mb-10px">
  105 + <el-skeleton :loading="loading" animated>
  106 + <Echart :options="barOptionsData" :height="280" />
  107 + </el-skeleton>
  108 + </el-card>
  109 + </el-col>
  110 + </el-row>
  111 + </el-skeleton>
  112 + </el-card>
  113 + </el-col>
  114 + <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-10px">
  115 + <el-card shadow="never">
  116 + <template #header>
  117 + <div class="flex justify-between h-3">
  118 + <span>{{ t('workplace.shortcutOperation') }}</span>
  119 + </div>
  120 + </template>
  121 + <el-skeleton :loading="loading" animated>
  122 + <el-row>
  123 + <el-col v-for="item in shortcut" :key="`team-${item.name}`" :span="8" class="mb-10px">
  124 + <div class="flex items-center">
  125 + <Icon :icon="item.icon" class="mr-10px" />
  126 + <el-link type="default" :underline="false" :href="item.url">
  127 + {{ item.name }}
  128 + </el-link>
  129 + </div>
  130 + </el-col>
  131 + </el-row>
  132 + </el-skeleton>
  133 + </el-card>
  134 + <el-card shadow="never" class="mt-10px">
  135 + <template #header>
  136 + <div class="flex justify-between h-3">
  137 + <span>{{ t('workplace.notice') }}</span>
  138 + <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>
  139 + </div>
  140 + </template>
  141 + <el-skeleton :loading="loading" animated>
  142 + <div v-for="(item, index) in notice" :key="`dynamics-${index}`">
  143 + <div class="flex items-center">
  144 + <img :src="avatar" alt="" class="w-35px h-35px rounded-[50%] mr-20px" />
  145 + <div>
  146 + <div class="text-14px">
  147 + <Highlight :keys="item.keys.map((v) => t(v))">
  148 + {{ item.type }} : {{ item.title }}
  149 + </Highlight>
  150 + </div>
  151 + <div class="mt-15px text-12px text-gray-400">
  152 + {{ formatTime(item.date, 'yyyy-MM-dd') }}
  153 + </div>
  154 + </div>
  155 + </div>
  156 + <el-divider />
  157 + </div>
  158 + </el-skeleton>
  159 + </el-card>
  160 + </el-col>
  161 + </el-row>
  162 +</template>
1 <script setup lang="ts"> 163 <script setup lang="ts">
2 import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus' 164 import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus'
3 import { useI18n } from '@/hooks/web/useI18n' 165 import { useI18n } from '@/hooks/web/useI18n'
@@ -217,166 +379,3 @@ const getAllApi = async () =&gt; { @@ -217,166 +379,3 @@ const getAllApi = async () =&gt; {
217 379
218 getAllApi() 380 getAllApi()
219 </script> 381 </script>
220 -  
221 -<template>  
222 - <div>  
223 - <el-card shadow="never">  
224 - <el-skeleton :loading="loading" animated>  
225 - <el-row :gutter="20" justify="space-between">  
226 - <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">  
227 - <div class="flex items-center">  
228 - <img :src="avatar" alt="" class="w-70px h-70px rounded-[50%] mr-20px" />  
229 - <div>  
230 - <div class="text-20px text-700">  
231 - {{ t('workplace.welcome') }} {{ username }} {{ t('workplace.happyDay') }}  
232 - </div>  
233 - <div class="mt-10px text-14px text-gray-500">  
234 - {{ t('workplace.toady') }},20℃ - 32℃!  
235 - </div>  
236 - </div>  
237 - </div>  
238 - </el-col>  
239 - <el-col :xl="12" :lg="12" :md="12" :sm="24" :xs="24">  
240 - <div class="flex h-70px items-center justify-end <sm:mt-10px">  
241 - <div class="px-8px text-right">  
242 - <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.project') }}</div>  
243 - <CountTo  
244 - class="text-20px"  
245 - :start-val="0"  
246 - :end-val="totalSate.project"  
247 - :duration="2600"  
248 - />  
249 - </div>  
250 - <el-divider direction="vertical" />  
251 - <div class="px-8px text-right">  
252 - <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.toDo') }}</div>  
253 - <CountTo  
254 - class="text-20px"  
255 - :start-val="0"  
256 - :end-val="totalSate.todo"  
257 - :duration="2600"  
258 - />  
259 - </div>  
260 - <el-divider direction="vertical" border-style="dashed" />  
261 - <div class="px-8px text-right">  
262 - <div class="text-14px text-gray-400 mb-20px">{{ t('workplace.access') }}</div>  
263 - <CountTo  
264 - class="text-20px"  
265 - :start-val="0"  
266 - :end-val="totalSate.access"  
267 - :duration="2600"  
268 - />  
269 - </div>  
270 - </div>  
271 - </el-col>  
272 - </el-row>  
273 - </el-skeleton>  
274 - </el-card>  
275 - </div>  
276 -  
277 - <el-row class="mt-5px" :gutter="20" justify="space-between">  
278 - <el-col :xl="16" :lg="16" :md="24" :sm="24" :xs="24" class="mb-10px">  
279 - <el-card shadow="never">  
280 - <template #header>  
281 - <div class="flex justify-between h-3">  
282 - <span>{{ t('workplace.project') }}</span>  
283 - <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>  
284 - </div>  
285 - </template>  
286 - <el-skeleton :loading="loading" animated>  
287 - <el-row>  
288 - <el-col  
289 - v-for="(item, index) in projects"  
290 - :key="`card-${index}`"  
291 - :xl="8"  
292 - :lg="8"  
293 - :md="8"  
294 - :sm="24"  
295 - :xs="24"  
296 - >  
297 - <el-card shadow="hover">  
298 - <div class="flex items-center">  
299 - <Icon :icon="item.icon" :size="25" class="mr-10px" />  
300 - <span class="text-16px">{{ item.name }}</span>  
301 - </div>  
302 - <div class="mt-15px text-14px text-gray-400">{{ t(item.message) }}</div>  
303 - <div class="mt-20px text-12px text-gray-400 flex justify-between">  
304 - <span>{{ item.personal }}</span>  
305 - <span>{{ formatTime(item.time, 'yyyy-MM-dd') }}</span>  
306 - </div>  
307 - </el-card>  
308 - </el-col>  
309 - </el-row>  
310 - </el-skeleton>  
311 - </el-card>  
312 -  
313 - <el-card shadow="never" class="mt-5px">  
314 - <el-skeleton :loading="loading" animated>  
315 - <el-row :gutter="20" justify="space-between">  
316 - <el-col :xl="10" :lg="10" :md="24" :sm="24" :xs="24">  
317 - <el-card shadow="hover" class="mb-10px">  
318 - <el-skeleton :loading="loading" animated>  
319 - <Echart :options="pieOptionsData" :height="280" />  
320 - </el-skeleton>  
321 - </el-card>  
322 - </el-col>  
323 - <el-col :xl="14" :lg="14" :md="24" :sm="24" :xs="24">  
324 - <el-card shadow="hover" class="mb-10px">  
325 - <el-skeleton :loading="loading" animated>  
326 - <Echart :options="barOptionsData" :height="280" />  
327 - </el-skeleton>  
328 - </el-card>  
329 - </el-col>  
330 - </el-row>  
331 - </el-skeleton>  
332 - </el-card>  
333 - </el-col>  
334 - <el-col :xl="8" :lg="8" :md="24" :sm="24" :xs="24" class="mb-10px">  
335 - <el-card shadow="never">  
336 - <template #header>  
337 - <div class="flex justify-between h-3">  
338 - <span>{{ t('workplace.shortcutOperation') }}</span>  
339 - </div>  
340 - </template>  
341 - <el-skeleton :loading="loading" animated>  
342 - <el-row>  
343 - <el-col v-for="item in shortcut" :key="`team-${item.name}`" :span="8" class="mb-10px">  
344 - <div class="flex items-center">  
345 - <Icon :icon="item.icon" class="mr-10px" />  
346 - <el-link type="default" :underline="false" :href="item.url">  
347 - {{ item.name }}  
348 - </el-link>  
349 - </div>  
350 - </el-col>  
351 - </el-row>  
352 - </el-skeleton>  
353 - </el-card>  
354 - <el-card shadow="never" class="mt-10px">  
355 - <template #header>  
356 - <div class="flex justify-between h-3">  
357 - <span>{{ t('workplace.notice') }}</span>  
358 - <el-link type="primary" :underline="false">{{ t('workplace.more') }}</el-link>  
359 - </div>  
360 - </template>  
361 - <el-skeleton :loading="loading" animated>  
362 - <div v-for="(item, index) in notice" :key="`dynamics-${index}`">  
363 - <div class="flex items-center">  
364 - <img :src="avatar" alt="" class="w-35px h-35px rounded-[50%] mr-20px" />  
365 - <div>  
366 - <div class="text-14px">  
367 - <Highlight :keys="item.keys.map((v) => t(v))">  
368 - {{ item.type }} : {{ item.title }}  
369 - </Highlight>  
370 - </div>  
371 - <div class="mt-15px text-12px text-gray-400">  
372 - {{ formatTime(item.date, 'yyyy-MM-dd') }}  
373 - </div>  
374 - </div>  
375 - </div>  
376 - <el-divider />  
377 - </div>  
378 - </el-skeleton>  
379 - </el-card>  
380 - </el-col>  
381 - </el-row>  
382 -</template>  
yudao-ui-admin-vue3/src/views/Home/Index2.vue
1 -<script setup lang="ts">  
2 -import { ref, reactive } from 'vue'  
3 -import { set } from 'lodash-es'  
4 -import { EChartsOption } from 'echarts'  
5 -import { Echart } from '@/components/Echart'  
6 -import { useI18n } from '@/hooks/web/useI18n'  
7 -import { CountTo } from '@/components/CountTo'  
8 -import type { AnalysisTotalTypes } from './types'  
9 -import { useDesign } from '@/hooks/web/useDesign'  
10 -import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'  
11 -import { pieOptions, barOptions, lineOptions } from './echarts-data'  
12 -  
13 -const { t } = useI18n()  
14 -const loading = ref(true)  
15 -const { getPrefixCls } = useDesign()  
16 -const prefixCls = getPrefixCls('panel')  
17 -const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption  
18 -  
19 -let totalState = reactive<AnalysisTotalTypes>({  
20 - users: 0,  
21 - messages: 0,  
22 - moneys: 0,  
23 - shoppings: 0  
24 -})  
25 -  
26 -const getCount = async () => {  
27 - const data = {  
28 - users: 102400,  
29 - messages: 81212,  
30 - moneys: 9280,  
31 - shoppings: 13600  
32 - }  
33 - totalState = Object.assign(totalState, data)  
34 -}  
35 -  
36 -// 用户来源  
37 -const getUserAccessSource = async () => {  
38 - const data = [  
39 - { value: 335, name: 'analysis.directAccess' },  
40 - { value: 310, name: 'analysis.mailMarketing' },  
41 - { value: 234, name: 'analysis.allianceAdvertising' },  
42 - { value: 135, name: 'analysis.videoAdvertising' },  
43 - { value: 1548, name: 'analysis.searchEngines' }  
44 - ]  
45 - set(  
46 - pieOptionsData,  
47 - 'legend.data',  
48 - data.map((v) => t(v.name))  
49 - )  
50 - set(pieOptionsData, 'series.data', data)  
51 -}  
52 -const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption  
53 -  
54 -// 周活跃量  
55 -const getWeeklyUserActivity = async () => {  
56 - const data = [  
57 - { value: 13253, name: 'analysis.monday' },  
58 - { value: 34235, name: 'analysis.tuesday' },  
59 - { value: 26321, name: 'analysis.wednesday' },  
60 - { value: 12340, name: 'analysis.thursday' },  
61 - { value: 24643, name: 'analysis.friday' },  
62 - { value: 1322, name: 'analysis.saturday' },  
63 - { value: 1324, name: 'analysis.sunday' }  
64 - ]  
65 - set(  
66 - barOptionsData,  
67 - 'xAxis.data',  
68 - data.map((v) => t(v.name))  
69 - )  
70 - set(barOptionsData, 'series', [  
71 - {  
72 - name: t('analysis.activeQuantity'),  
73 - data: data.map((v) => v.value),  
74 - type: 'bar'  
75 - }  
76 - ])  
77 -}  
78 -  
79 -const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption  
80 -  
81 -// 每月销售总额  
82 -const getMonthlySales = async () => {  
83 - const data = [  
84 - { estimate: 100, actual: 120, name: 'analysis.january' },  
85 - { estimate: 120, actual: 82, name: 'analysis.february' },  
86 - { estimate: 161, actual: 91, name: 'analysis.march' },  
87 - { estimate: 134, actual: 154, name: 'analysis.april' },  
88 - { estimate: 105, actual: 162, name: 'analysis.may' },  
89 - { estimate: 160, actual: 140, name: 'analysis.june' },  
90 - { estimate: 165, actual: 145, name: 'analysis.july' },  
91 - { estimate: 114, actual: 250, name: 'analysis.august' },  
92 - { estimate: 163, actual: 134, name: 'analysis.september' },  
93 - { estimate: 185, actual: 56, name: 'analysis.october' },  
94 - { estimate: 118, actual: 99, name: 'analysis.november' },  
95 - { estimate: 123, actual: 123, name: 'analysis.december' }  
96 - ]  
97 - set(  
98 - lineOptionsData,  
99 - 'xAxis.data',  
100 - data.map((v) => t(v.name))  
101 - )  
102 - set(lineOptionsData, 'series', [  
103 - {  
104 - name: t('analysis.estimate'),  
105 - smooth: true,  
106 - type: 'line',  
107 - data: data.map((v) => v.estimate),  
108 - animationDuration: 2800,  
109 - animationEasing: 'cubicInOut'  
110 - },  
111 - {  
112 - name: t('analysis.actual'),  
113 - smooth: true,  
114 - type: 'line',  
115 - itemStyle: {},  
116 - data: data.map((v) => v.actual),  
117 - animationDuration: 2800,  
118 - animationEasing: 'quadraticOut'  
119 - }  
120 - ])  
121 -}  
122 -  
123 -const getAllApi = async () => {  
124 - await Promise.all([getCount(), getUserAccessSource(), getWeeklyUserActivity(), getMonthlySales()])  
125 - loading.value = false  
126 -}  
127 -  
128 -getAllApi()  
129 -</script>  
130 -  
131 <template> 1 <template>
132 <el-row :gutter="20" justify="space-between" :class="prefixCls"> 2 <el-row :gutter="20" justify="space-between" :class="prefixCls">
133 <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24"> 3 <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
@@ -270,6 +140,136 @@ getAllApi() @@ -270,6 +140,136 @@ getAllApi()
270 </el-col> 140 </el-col>
271 </el-row> 141 </el-row>
272 </template> 142 </template>
  143 +<script setup lang="ts">
  144 +import { ref, reactive } from 'vue'
  145 +import { set } from 'lodash-es'
  146 +import { EChartsOption } from 'echarts'
  147 +import { Echart } from '@/components/Echart'
  148 +import { useI18n } from '@/hooks/web/useI18n'
  149 +import { CountTo } from '@/components/CountTo'
  150 +import type { AnalysisTotalTypes } from './types'
  151 +import { useDesign } from '@/hooks/web/useDesign'
  152 +import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
  153 +import { pieOptions, barOptions, lineOptions } from './echarts-data'
  154 +
  155 +const { t } = useI18n()
  156 +const loading = ref(true)
  157 +const { getPrefixCls } = useDesign()
  158 +const prefixCls = getPrefixCls('panel')
  159 +const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
  160 +
  161 +let totalState = reactive<AnalysisTotalTypes>({
  162 + users: 0,
  163 + messages: 0,
  164 + moneys: 0,
  165 + shoppings: 0
  166 +})
  167 +
  168 +const getCount = async () => {
  169 + const data = {
  170 + users: 102400,
  171 + messages: 81212,
  172 + moneys: 9280,
  173 + shoppings: 13600
  174 + }
  175 + totalState = Object.assign(totalState, data)
  176 +}
  177 +
  178 +// 用户来源
  179 +const getUserAccessSource = async () => {
  180 + const data = [
  181 + { value: 335, name: 'analysis.directAccess' },
  182 + { value: 310, name: 'analysis.mailMarketing' },
  183 + { value: 234, name: 'analysis.allianceAdvertising' },
  184 + { value: 135, name: 'analysis.videoAdvertising' },
  185 + { value: 1548, name: 'analysis.searchEngines' }
  186 + ]
  187 + set(
  188 + pieOptionsData,
  189 + 'legend.data',
  190 + data.map((v) => t(v.name))
  191 + )
  192 + set(pieOptionsData, 'series.data', data)
  193 +}
  194 +const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
  195 +
  196 +// 周活跃量
  197 +const getWeeklyUserActivity = async () => {
  198 + const data = [
  199 + { value: 13253, name: 'analysis.monday' },
  200 + { value: 34235, name: 'analysis.tuesday' },
  201 + { value: 26321, name: 'analysis.wednesday' },
  202 + { value: 12340, name: 'analysis.thursday' },
  203 + { value: 24643, name: 'analysis.friday' },
  204 + { value: 1322, name: 'analysis.saturday' },
  205 + { value: 1324, name: 'analysis.sunday' }
  206 + ]
  207 + set(
  208 + barOptionsData,
  209 + 'xAxis.data',
  210 + data.map((v) => t(v.name))
  211 + )
  212 + set(barOptionsData, 'series', [
  213 + {
  214 + name: t('analysis.activeQuantity'),
  215 + data: data.map((v) => v.value),
  216 + type: 'bar'
  217 + }
  218 + ])
  219 +}
  220 +
  221 +const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
  222 +
  223 +// 每月销售总额
  224 +const getMonthlySales = async () => {
  225 + const data = [
  226 + { estimate: 100, actual: 120, name: 'analysis.january' },
  227 + { estimate: 120, actual: 82, name: 'analysis.february' },
  228 + { estimate: 161, actual: 91, name: 'analysis.march' },
  229 + { estimate: 134, actual: 154, name: 'analysis.april' },
  230 + { estimate: 105, actual: 162, name: 'analysis.may' },
  231 + { estimate: 160, actual: 140, name: 'analysis.june' },
  232 + { estimate: 165, actual: 145, name: 'analysis.july' },
  233 + { estimate: 114, actual: 250, name: 'analysis.august' },
  234 + { estimate: 163, actual: 134, name: 'analysis.september' },
  235 + { estimate: 185, actual: 56, name: 'analysis.october' },
  236 + { estimate: 118, actual: 99, name: 'analysis.november' },
  237 + { estimate: 123, actual: 123, name: 'analysis.december' }
  238 + ]
  239 + set(
  240 + lineOptionsData,
  241 + 'xAxis.data',
  242 + data.map((v) => t(v.name))
  243 + )
  244 + set(lineOptionsData, 'series', [
  245 + {
  246 + name: t('analysis.estimate'),
  247 + smooth: true,
  248 + type: 'line',
  249 + data: data.map((v) => v.estimate),
  250 + animationDuration: 2800,
  251 + animationEasing: 'cubicInOut'
  252 + },
  253 + {
  254 + name: t('analysis.actual'),
  255 + smooth: true,
  256 + type: 'line',
  257 + itemStyle: {},
  258 + data: data.map((v) => v.actual),
  259 + animationDuration: 2800,
  260 + animationEasing: 'quadraticOut'
  261 + }
  262 + ])
  263 +}
  264 +
  265 +const getAllApi = async () => {
  266 + await Promise.all([getCount(), getUserAccessSource(), getWeeklyUserActivity(), getMonthlySales()])
  267 + loading.value = false
  268 +}
  269 +
  270 +getAllApi()
  271 +</script>
  272 +
273 <style lang="less" scoped> 273 <style lang="less" scoped>
274 @prefix-cls: ~'@{namespace}-panel'; 274 @prefix-cls: ~'@{namespace}-panel';
275 275
yudao-ui-admin-vue3/src/views/Login/Login.vue
1 -<script setup lang="ts">  
2 -import { LoginForm, MobileForm, RegisterForm, QrCodeForm } from './components'  
3 -import { ThemeSwitch } from '@/components/ThemeSwitch'  
4 -import { LocaleDropdown } from '@/components/LocaleDropdown'  
5 -import { useI18n } from '@/hooks/web/useI18n'  
6 -import { underlineToHump } from '@/utils'  
7 -import { useAppStore } from '@/store/modules/app'  
8 -import { useDesign } from '@/hooks/web/useDesign'  
9 -  
10 -const { t } = useI18n()  
11 -  
12 -const { getPrefixCls } = useDesign()  
13 -  
14 -const prefixCls = getPrefixCls('login')  
15 -  
16 -const appStore = useAppStore()  
17 -</script>  
18 -  
19 <template> 1 <template>
20 <div 2 <div
21 :class="prefixCls" 3 :class="prefixCls"
@@ -76,6 +58,23 @@ const appStore = useAppStore() @@ -76,6 +58,23 @@ const appStore = useAppStore()
76 </div> 58 </div>
77 </div> 59 </div>
78 </template> 60 </template>
  61 +<script setup lang="ts">
  62 +import { LoginForm, MobileForm, RegisterForm, QrCodeForm } from './components'
  63 +import { ThemeSwitch } from '@/components/ThemeSwitch'
  64 +import { LocaleDropdown } from '@/components/LocaleDropdown'
  65 +import { useI18n } from '@/hooks/web/useI18n'
  66 +import { underlineToHump } from '@/utils'
  67 +import { useAppStore } from '@/store/modules/app'
  68 +import { useDesign } from '@/hooks/web/useDesign'
  69 +
  70 +const { t } = useI18n()
  71 +
  72 +const { getPrefixCls } = useDesign()
  73 +
  74 +const prefixCls = getPrefixCls('login')
  75 +
  76 +const appStore = useAppStore()
  77 +</script>
79 78
80 <style lang="less" scoped> 79 <style lang="less" scoped>
81 @prefix-cls: ~'@{namespace}-login'; 80 @prefix-cls: ~'@{namespace}-login';
yudao-ui-admin-vue3/src/views/Login/components/LoginForm.vue
  1 +<template>
  2 + <el-form
  3 + :model="loginData.loginForm"
  4 + :rules="LoginRules"
  5 + label-position="top"
  6 + class="login-form"
  7 + label-width="120px"
  8 + size="large"
  9 + v-show="getShow"
  10 + ref="formLogin"
  11 + >
  12 + <el-row style="maring-left: -10px; maring-right: -10px">
  13 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  14 + <el-form-item>
  15 + <LoginFormTitle style="width: 100%" />
  16 + </el-form-item>
  17 + </el-col>
  18 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  19 + <el-form-item prop="tenantName">
  20 + <el-input
  21 + type="text"
  22 + v-model="loginData.loginForm.tenantName"
  23 + :placeholder="t('login.tenantNamePlaceholder')"
  24 + :prefix-icon="iconHouse"
  25 + />
  26 + </el-form-item>
  27 + </el-col>
  28 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  29 + <el-form-item prop="username">
  30 + <el-input
  31 + v-model="loginData.loginForm.username"
  32 + :placeholder="t('login.usernamePlaceholder')"
  33 + :prefix-icon="iconAvatar"
  34 + />
  35 + </el-form-item>
  36 + </el-col>
  37 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  38 + <el-form-item prop="password">
  39 + <el-input
  40 + v-model="loginData.loginForm.password"
  41 + type="password"
  42 + :placeholder="t('login.passwordPlaceholder')"
  43 + show-password
  44 + @keyup.enter="getCode()"
  45 + :prefix-icon="iconLock"
  46 + />
  47 + </el-form-item>
  48 + </el-col>
  49 + <el-col
  50 + :span="24"
  51 + style="padding-left: 10px; padding-right: 10px; margin-top: -20px; margin-bottom: -20px"
  52 + >
  53 + <el-form-item>
  54 + <el-row justify="space-between" style="width: 100%">
  55 + <el-col :span="6">
  56 + <el-checkbox v-model="loginData.loginForm.rememberMe">
  57 + {{ t('login.remember') }}
  58 + </el-checkbox>
  59 + </el-col>
  60 + <el-col :span="12" :offset="6">
  61 + <el-link type="primary" style="float: right">{{ t('login.forgetPassword') }}</el-link>
  62 + </el-col>
  63 + </el-row>
  64 + </el-form-item>
  65 + </el-col>
  66 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  67 + <el-form-item>
  68 + <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="getCode()">
  69 + {{ t('login.login') }}
  70 + </el-button>
  71 + </el-form-item>
  72 + </el-col>
  73 + <Verify
  74 + ref="verify"
  75 + mode="pop"
  76 + :captchaType="captchaType"
  77 + :imgSize="{ width: '400px', height: '200px' }"
  78 + @success="handleLogin"
  79 + />
  80 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  81 + <el-form-item>
  82 + <el-row justify="space-between" style="width: 100%" :gutter="5">
  83 + <el-col :span="8">
  84 + <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.MOBILE)">
  85 + {{ t('login.btnMobile') }}
  86 + </el-button>
  87 + </el-col>
  88 + <el-col :span="8">
  89 + <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.QR_CODE)">
  90 + {{ t('login.btnQRCode') }}
  91 + </el-button>
  92 + </el-col>
  93 + <el-col :span="8">
  94 + <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.REGISTER)">
  95 + {{ t('login.btnRegister') }}
  96 + </el-button>
  97 + </el-col>
  98 + </el-row>
  99 + </el-form-item>
  100 + </el-col>
  101 + <el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>
  102 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  103 + <el-form-item>
  104 + <div class="flex justify-between w-[100%]">
  105 + <Icon
  106 + icon="ant-design:github-filled"
  107 + :size="iconSize"
  108 + class="cursor-pointer anticon"
  109 + :color="iconColor"
  110 + @click="doSocialLogin('github')"
  111 + />
  112 + <Icon
  113 + icon="ant-design:wechat-filled"
  114 + :size="iconSize"
  115 + class="cursor-pointer anticon"
  116 + :color="iconColor"
  117 + @click="doSocialLogin('wechat')"
  118 + />
  119 + <Icon
  120 + icon="ant-design:alipay-circle-filled"
  121 + :size="iconSize"
  122 + :color="iconColor"
  123 + class="cursor-pointer anticon"
  124 + @click="doSocialLogin('alipay')"
  125 + />
  126 + <Icon
  127 + icon="ant-design:dingtalk-circle-filled"
  128 + :size="iconSize"
  129 + :color="iconColor"
  130 + class="cursor-pointer anticon"
  131 + @click="doSocialLogin('dingtalk')"
  132 + />
  133 + </div>
  134 + </el-form-item>
  135 + </el-col>
  136 + </el-row>
  137 + </el-form>
  138 +</template>
1 <script setup lang="ts"> 139 <script setup lang="ts">
2 import { useIcon } from '@/hooks/web/useIcon' 140 import { useIcon } from '@/hooks/web/useIcon'
3 import LoginFormTitle from './LoginFormTitle.vue' 141 import LoginFormTitle from './LoginFormTitle.vue'
@@ -153,144 +291,7 @@ onMounted(() =&gt; { @@ -153,144 +291,7 @@ onMounted(() =&gt; {
153 getCookie() 291 getCookie()
154 }) 292 })
155 </script> 293 </script>
156 -<template>  
157 - <el-form  
158 - :model="loginData.loginForm"  
159 - :rules="LoginRules"  
160 - label-position="top"  
161 - class="login-form"  
162 - label-width="120px"  
163 - size="large"  
164 - v-show="getShow"  
165 - ref="formLogin"  
166 - >  
167 - <el-row style="maring-left: -10px; maring-right: -10px">  
168 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
169 - <el-form-item>  
170 - <LoginFormTitle style="width: 100%" />  
171 - </el-form-item>  
172 - </el-col>  
173 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
174 - <el-form-item prop="tenantName">  
175 - <el-input  
176 - type="text"  
177 - v-model="loginData.loginForm.tenantName"  
178 - :placeholder="t('login.tenantNamePlaceholder')"  
179 - :prefix-icon="iconHouse"  
180 - />  
181 - </el-form-item>  
182 - </el-col>  
183 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
184 - <el-form-item prop="username">  
185 - <el-input  
186 - v-model="loginData.loginForm.username"  
187 - :placeholder="t('login.usernamePlaceholder')"  
188 - :prefix-icon="iconAvatar"  
189 - />  
190 - </el-form-item>  
191 - </el-col>  
192 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
193 - <el-form-item prop="password">  
194 - <el-input  
195 - v-model="loginData.loginForm.password"  
196 - type="password"  
197 - :placeholder="t('login.passwordPlaceholder')"  
198 - show-password  
199 - @keyup.enter="getCode()"  
200 - :prefix-icon="iconLock"  
201 - />  
202 - </el-form-item>  
203 - </el-col>  
204 - <el-col  
205 - :span="24"  
206 - style="padding-left: 10px; padding-right: 10px; margin-top: -20px; margin-bottom: -20px"  
207 - >  
208 - <el-form-item>  
209 - <el-row justify="space-between" style="width: 100%">  
210 - <el-col :span="6">  
211 - <el-checkbox v-model="loginData.loginForm.rememberMe">  
212 - {{ t('login.remember') }}  
213 - </el-checkbox>  
214 - </el-col>  
215 - <el-col :span="12" :offset="6">  
216 - <el-link type="primary" style="float: right">{{ t('login.forgetPassword') }}</el-link>  
217 - </el-col>  
218 - </el-row>  
219 - </el-form-item>  
220 - </el-col>  
221 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
222 - <el-form-item>  
223 - <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="getCode()">  
224 - {{ t('login.login') }}  
225 - </el-button>  
226 - </el-form-item>  
227 - </el-col>  
228 - <Verify  
229 - ref="verify"  
230 - mode="pop"  
231 - :captchaType="captchaType"  
232 - :imgSize="{ width: '400px', height: '200px' }"  
233 - @success="handleLogin"  
234 - />  
235 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
236 - <el-form-item>  
237 - <el-row justify="space-between" style="width: 100%" :gutter="5">  
238 - <el-col :span="8">  
239 - <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.MOBILE)">  
240 - {{ t('login.btnMobile') }}  
241 - </el-button>  
242 - </el-col>  
243 - <el-col :span="8">  
244 - <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.QR_CODE)">  
245 - {{ t('login.btnQRCode') }}  
246 - </el-button>  
247 - </el-col>  
248 - <el-col :span="8">  
249 - <el-button class="w-[100%]" @click="setLoginState(LoginStateEnum.REGISTER)">  
250 - {{ t('login.btnRegister') }}  
251 - </el-button>  
252 - </el-col>  
253 - </el-row>  
254 - </el-form-item>  
255 - </el-col>  
256 - <el-divider content-position="center">{{ t('login.otherLogin') }}</el-divider>  
257 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
258 - <el-form-item>  
259 - <div class="flex justify-between w-[100%]">  
260 - <Icon  
261 - icon="ant-design:github-filled"  
262 - :size="iconSize"  
263 - class="cursor-pointer anticon"  
264 - :color="iconColor"  
265 - @click="doSocialLogin('github')"  
266 - />  
267 - <Icon  
268 - icon="ant-design:wechat-filled"  
269 - :size="iconSize"  
270 - class="cursor-pointer anticon"  
271 - :color="iconColor"  
272 - @click="doSocialLogin('wechat')"  
273 - />  
274 - <Icon  
275 - icon="ant-design:alipay-circle-filled"  
276 - :size="iconSize"  
277 - :color="iconColor"  
278 - class="cursor-pointer anticon"  
279 - @click="doSocialLogin('alipay')"  
280 - />  
281 - <Icon  
282 - icon="ant-design:dingtalk-circle-filled"  
283 - :size="iconSize"  
284 - :color="iconColor"  
285 - class="cursor-pointer anticon"  
286 - @click="doSocialLogin('dingtalk')"  
287 - />  
288 - </div>  
289 - </el-form-item>  
290 - </el-col>  
291 - </el-row>  
292 - </el-form>  
293 -</template> 294 +
294 <style lang="less" scoped> 295 <style lang="less" scoped>
295 :deep(.anticon) { 296 :deep(.anticon) {
296 &:hover { 297 &:hover {
yudao-ui-admin-vue3/src/views/Login/components/LoginFormTitle.vue
  1 +<template>
  2 + <h2 class="mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-center">
  3 + {{ getFormTitle }}
  4 + </h2>
  5 +</template>
1 <script setup lang="ts"> 6 <script setup lang="ts">
2 import { computed, unref } from 'vue' 7 import { computed, unref } from 'vue'
3 import { useI18n } from '@/hooks/web/useI18n' 8 import { useI18n } from '@/hooks/web/useI18n'
@@ -18,8 +23,3 @@ const getFormTitle = computed(() =&gt; { @@ -18,8 +23,3 @@ const getFormTitle = computed(() =&gt; {
18 return titleObj[unref(getLoginState)] 23 return titleObj[unref(getLoginState)]
19 }) 24 })
20 </script> 25 </script>
21 -<template>  
22 - <h2 class="mb-3 text-2xl font-bold text-center xl:text-3xl enter-x xl:text-center">  
23 - {{ getFormTitle }}  
24 - </h2>  
25 -</template>  
yudao-ui-admin-vue3/src/views/Login/components/MobileForm.vue
  1 +<template>
  2 + <el-form
  3 + :model="loginData.loginForm"
  4 + :rules="rules"
  5 + label-position="top"
  6 + class="login-form"
  7 + label-width="120px"
  8 + size="large"
  9 + v-show="getShow"
  10 + ref="formSmsLogin"
  11 + >
  12 + <el-row style="margin-left: -10px; margin-right: -10px">
  13 + <!-- 租户名 -->
  14 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  15 + <el-form-item>
  16 + <LoginFormTitle style="width: 100%" />
  17 + </el-form-item>
  18 + </el-col>
  19 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  20 + <el-form-item prop="tenantName">
  21 + <el-input
  22 + type="text"
  23 + v-model="loginData.loginForm.tenantName"
  24 + :placeholder="t('login.tenantNamePlaceholder')"
  25 + :prefix-icon="iconHouse"
  26 + />
  27 + </el-form-item>
  28 + </el-col>
  29 + <!-- 手机号 -->
  30 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  31 + <el-form-item prop="mobileNumber">
  32 + <el-input
  33 + v-model="loginData.loginForm.mobileNumber"
  34 + :placeholder="t('login.mobileNumberPlaceholder')"
  35 + :prefix-icon="iconCellphone"
  36 + />
  37 + </el-form-item>
  38 + </el-col>
  39 + <!-- 验证码 -->
  40 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  41 + <el-form-item prop="code">
  42 + <el-row justify="space-between" style="width: 100%" :gutter="5">
  43 + <el-col :span="24">
  44 + <el-input
  45 + v-model="loginData.loginForm.code"
  46 + :placeholder="t('login.codePlaceholder')"
  47 + :prefix-icon="iconCircleCheck"
  48 + >
  49 + <!-- <el-button class="w-[100%]"> -->
  50 + <template #append>
  51 + <span
  52 + v-if="mobileCodeTimer <= 0"
  53 + @click="getSmsCode"
  54 + class="getMobileCode"
  55 + style="cursor: pointer"
  56 + >
  57 + {{ t('login.getSmsCode') }}
  58 + </span>
  59 + <span v-if="mobileCodeTimer > 0" class="getMobileCode" style="cursor: pointer">
  60 + {{ mobileCodeTimer }}秒后可重新获取
  61 + </span>
  62 + </template>
  63 + </el-input>
  64 + <!-- </el-button> -->
  65 + </el-col>
  66 + </el-row>
  67 + </el-form-item>
  68 + </el-col>
  69 + <!-- 登录按钮 / 返回按钮 -->
  70 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  71 + <el-form-item>
  72 + <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="signIn">
  73 + {{ t('login.login') }}
  74 + </el-button>
  75 + </el-form-item>
  76 + </el-col>
  77 + <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
  78 + <el-form-item>
  79 + <el-button :loading="loginLoading" class="w-[100%]" @click="handleBackLogin">
  80 + {{ t('login.backLogin') }}
  81 + </el-button>
  82 + </el-form-item>
  83 + </el-col>
  84 + </el-row>
  85 + </el-form>
  86 +</template>
1 <script setup lang="ts"> 87 <script setup lang="ts">
2 import { useIcon } from '@/hooks/web/useIcon' 88 import { useIcon } from '@/hooks/web/useIcon'
3 import { reactive, ref, unref, watch, computed } from 'vue' 89 import { reactive, ref, unref, watch, computed } from 'vue'
@@ -111,92 +197,7 @@ const signIn = async () =&gt; { @@ -111,92 +197,7 @@ const signIn = async () =&gt; {
111 }) 197 })
112 } 198 }
113 </script> 199 </script>
114 -<template>  
115 - <el-form  
116 - :model="loginData.loginForm"  
117 - :rules="rules"  
118 - label-position="top"  
119 - class="login-form"  
120 - label-width="120px"  
121 - size="large"  
122 - v-show="getShow"  
123 - ref="formSmsLogin"  
124 - >  
125 - <el-row style="margin-left: -10px; margin-right: -10px">  
126 - <!-- 租户名 -->  
127 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
128 - <el-form-item>  
129 - <LoginFormTitle style="width: 100%" />  
130 - </el-form-item>  
131 - </el-col>  
132 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
133 - <el-form-item prop="tenantName">  
134 - <el-input  
135 - type="text"  
136 - v-model="loginData.loginForm.tenantName"  
137 - :placeholder="t('login.tenantNamePlaceholder')"  
138 - :prefix-icon="iconHouse"  
139 - />  
140 - </el-form-item>  
141 - </el-col>  
142 - <!-- 手机号 -->  
143 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
144 - <el-form-item prop="mobileNumber">  
145 - <el-input  
146 - v-model="loginData.loginForm.mobileNumber"  
147 - :placeholder="t('login.mobileNumberPlaceholder')"  
148 - :prefix-icon="iconCellphone"  
149 - />  
150 - </el-form-item>  
151 - </el-col>  
152 - <!-- 验证码 -->  
153 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
154 - <el-form-item prop="code">  
155 - <el-row justify="space-between" style="width: 100%" :gutter="5">  
156 - <el-col :span="24">  
157 - <el-input  
158 - v-model="loginData.loginForm.code"  
159 - :placeholder="t('login.codePlaceholder')"  
160 - :prefix-icon="iconCircleCheck"  
161 - >  
162 - <!-- <el-button class="w-[100%]"> -->  
163 - <template #append>  
164 - <span  
165 - v-if="mobileCodeTimer <= 0"  
166 - @click="getSmsCode"  
167 - class="getMobileCode"  
168 - style="cursor: pointer"  
169 - >  
170 - {{ t('login.getSmsCode') }}  
171 - </span>  
172 - <span v-if="mobileCodeTimer > 0" class="getMobileCode" style="cursor: pointer">  
173 - {{ mobileCodeTimer }}秒后可重新获取  
174 - </span>  
175 - </template>  
176 - </el-input>  
177 - <!-- </el-button> -->  
178 - </el-col>  
179 - </el-row>  
180 - </el-form-item>  
181 - </el-col>  
182 - <!-- 登录按钮 / 返回按钮 -->  
183 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
184 - <el-form-item>  
185 - <el-button :loading="loginLoading" type="primary" class="w-[100%]" @click="signIn">  
186 - {{ t('login.login') }}  
187 - </el-button>  
188 - </el-form-item>  
189 - </el-col>  
190 - <el-col :span="24" style="padding-left: 10px; padding-right: 10px">  
191 - <el-form-item>  
192 - <el-button :loading="loginLoading" class="w-[100%]" @click="handleBackLogin">  
193 - {{ t('login.backLogin') }}  
194 - </el-button>  
195 - </el-form-item>  
196 - </el-col>  
197 - </el-row>  
198 - </el-form>  
199 -</template> 200 +
200 <style lang="less" scoped> 201 <style lang="less" scoped>
201 :deep(.anticon) { 202 :deep(.anticon) {
202 &:hover { 203 &:hover {
yudao-ui-admin-vue3/src/views/Login/components/QrCodeForm.vue
1 -<script setup lang="ts">  
2 -import { computed, unref } from 'vue'  
3 -import { ElRow, ElCol, ElCard, ElDivider } from 'element-plus'  
4 -import { useI18n } from '@/hooks/web/useI18n'  
5 -import { useLoginState, LoginStateEnum } from './useLogin'  
6 -import LoginFormTitle from './LoginFormTitle.vue'  
7 -import { Qrcode } from '@/components/Qrcode'  
8 -import logoImg from '@/assets/imgs/logo.png'  
9 -  
10 -const { t } = useI18n()  
11 -const { handleBackLogin, getLoginState } = useLoginState()  
12 -const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE)  
13 -</script>  
14 -  
15 <template> 1 <template>
16 <el-row v-show="getShow" style="maring-left: -10px; maring-right: -10px"> 2 <el-row v-show="getShow" style="maring-left: -10px; maring-right: -10px">
17 <el-col :span="24" style="padding-left: 10px; padding-right: 10px"> 3 <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
@@ -32,3 +18,16 @@ const getShow = computed(() =&gt; unref(getLoginState) === LoginStateEnum.QR_CODE) @@ -32,3 +18,16 @@ const getShow = computed(() =&gt; unref(getLoginState) === LoginStateEnum.QR_CODE)
32 </el-col> 18 </el-col>
33 </el-row> 19 </el-row>
34 </template> 20 </template>
  21 +<script setup lang="ts">
  22 +import { computed, unref } from 'vue'
  23 +import { ElRow, ElCol, ElCard, ElDivider } from 'element-plus'
  24 +import { useI18n } from '@/hooks/web/useI18n'
  25 +import { useLoginState, LoginStateEnum } from './useLogin'
  26 +import LoginFormTitle from './LoginFormTitle.vue'
  27 +import { Qrcode } from '@/components/Qrcode'
  28 +import logoImg from '@/assets/imgs/logo.png'
  29 +
  30 +const { t } = useI18n()
  31 +const { handleBackLogin, getLoginState } = useLoginState()
  32 +const getShow = computed(() => unref(getLoginState) === LoginStateEnum.QR_CODE)
  33 +</script>
yudao-ui-admin-vue3/src/views/Login/components/RegisterForm.vue
  1 +<template>
  2 + <Form
  3 + :schema="schema"
  4 + :rules="rules"
  5 + label-position="top"
  6 + hide-required-asterisk
  7 + size="large"
  8 + v-show="getShow"
  9 + class="dark:(border-1 border-[var(--el-border-color)] border-solid)"
  10 + @register="register"
  11 + >
  12 + <template #title>
  13 + <LoginFormTitle style="width: 100%" />
  14 + </template>
  15 +
  16 + <template #code="form">
  17 + <div class="w-[100%] flex">
  18 + <el-input v-model="form['code']" :placeholder="t('login.codePlaceholder')" />
  19 + </div>
  20 + </template>
  21 +
  22 + <template #register>
  23 + <div class="w-[100%]">
  24 + <el-button type="primary" class="w-[100%]" :loading="loading" @click="loginRegister">
  25 + {{ t('login.register') }}
  26 + </el-button>
  27 + </div>
  28 + <div class="w-[100%] mt-15px">
  29 + <el-button class="w-[100%]" @click="handleBackLogin">
  30 + {{ t('login.hasUser') }}
  31 + </el-button>
  32 + </div>
  33 + </template>
  34 + </Form>
  35 +</template>
  36 +
1 <script setup lang="ts"> 37 <script setup lang="ts">
2 import { Form } from '@/components/Form' 38 import { Form } from '@/components/Form'
3 import { computed, reactive, ref, unref } from 'vue' 39 import { computed, reactive, ref, unref } from 'vue'
@@ -104,39 +140,3 @@ const loginRegister = async () =&gt; { @@ -104,39 +140,3 @@ const loginRegister = async () =&gt; {
104 }) 140 })
105 } 141 }
106 </script> 142 </script>
107 -  
108 -<template>  
109 - <Form  
110 - :schema="schema"  
111 - :rules="rules"  
112 - label-position="top"  
113 - hide-required-asterisk  
114 - size="large"  
115 - v-show="getShow"  
116 - class="dark:(border-1 border-[var(--el-border-color)] border-solid)"  
117 - @register="register"  
118 - >  
119 - <template #title>  
120 - <LoginFormTitle style="width: 100%" />  
121 - </template>  
122 -  
123 - <template #code="form">  
124 - <div class="w-[100%] flex">  
125 - <el-input v-model="form['code']" :placeholder="t('login.codePlaceholder')" />  
126 - </div>  
127 - </template>  
128 -  
129 - <template #register>  
130 - <div class="w-[100%]">  
131 - <el-button type="primary" class="w-[100%]" :loading="loading" @click="loginRegister">  
132 - {{ t('login.register') }}  
133 - </el-button>  
134 - </div>  
135 - <div class="w-[100%] mt-15px">  
136 - <el-button class="w-[100%]" @click="handleBackLogin">  
137 - {{ t('login.hasUser') }}  
138 - </el-button>  
139 - </div>  
140 - </template>  
141 - </Form>  
142 -</template>