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 4 <script setup lang="ts">
2 5 import { Error } from '@/components/Error'
3 6 import { useRouter } from 'vue-router'
... ... @@ -8,7 +11,3 @@ const errorClick = () =&gt; {
8 11 push('/')
9 12 }
10 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 5 <script setup lang="ts">
2 6 import { Error } from '@/components/Error'
3 7 import { useRouter } from 'vue-router'
... ... @@ -8,7 +12,3 @@ const errorClick = () =&gt; {
8 12 push('/')
9 13 }
10 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 5 <script setup lang="ts">
2 6 import { Error } from '@/components/Error'
3 7 import { useRouter } from 'vue-router'
... ... @@ -8,7 +12,3 @@ const errorClick = () =&gt; {
8 12 push('/')
9 13 }
10 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 163 <script setup lang="ts">
2 164 import { ElRow, ElCol, ElSkeleton, ElCard, ElDivider, ElLink } from 'element-plus'
3 165 import { useI18n } from '@/hooks/web/useI18n'
... ... @@ -217,166 +379,3 @@ const getAllApi = async () =&gt; {
217 379  
218 380 getAllApi()
219 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 1 <template>
132 2 <el-row :gutter="20" justify="space-between" :class="prefixCls">
133 3 <el-col :xl="6" :lg="6" :md="12" :sm="12" :xs="24">
... ... @@ -270,6 +140,136 @@ getAllApi()
270 140 </el-col>
271 141 </el-row>
272 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 273 <style lang="less" scoped>
274 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 1 <template>
20 2 <div
21 3 :class="prefixCls"
... ... @@ -76,6 +58,23 @@ const appStore = useAppStore()
76 58 </div>
77 59 </div>
78 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 79 <style lang="less" scoped>
81 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 139 <script setup lang="ts">
2 140 import { useIcon } from '@/hooks/web/useIcon'
3 141 import LoginFormTitle from './LoginFormTitle.vue'
... ... @@ -153,144 +291,7 @@ onMounted(() =&gt; {
153 291 getCookie()
154 292 })
155 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 295 <style lang="less" scoped>
295 296 :deep(.anticon) {
296 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 6 <script setup lang="ts">
2 7 import { computed, unref } from 'vue'
3 8 import { useI18n } from '@/hooks/web/useI18n'
... ... @@ -18,8 +23,3 @@ const getFormTitle = computed(() =&gt; {
18 23 return titleObj[unref(getLoginState)]
19 24 })
20 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 87 <script setup lang="ts">
2 88 import { useIcon } from '@/hooks/web/useIcon'
3 89 import { reactive, ref, unref, watch, computed } from 'vue'
... ... @@ -111,92 +197,7 @@ const signIn = async () =&gt; {
111 197 })
112 198 }
113 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 201 <style lang="less" scoped>
201 202 :deep(.anticon) {
202 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 1 <template>
16 2 <el-row v-show="getShow" style="maring-left: -10px; maring-right: -10px">
17 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 18 </el-col>
33 19 </el-row>
34 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 37 <script setup lang="ts">
2 38 import { Form } from '@/components/Form'
3 39 import { computed, reactive, ref, unref } from 'vue'
... ... @@ -104,39 +140,3 @@ const loginRegister = async () =&gt; {
104 140 })
105 141 }
106 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>
... ...