verce-vue-test 0.0.19 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,3 +64,162 @@ const rows = [
64
64
  </div>
65
65
  </article>
66
66
  </template>
67
+
68
+ <style scoped>
69
+ .table-board {
70
+ --blue: #1267f2;
71
+ --line: #dce4ef;
72
+ min-width: 0;
73
+ height: calc(100vh - 190px);
74
+ min-height: 700px;
75
+ padding: 14px 14px 17px;
76
+ display: grid;
77
+ grid-template-rows: auto 1fr auto;
78
+ background: rgba(255, 255, 255, .96);
79
+ border-radius: 10px;
80
+ box-shadow: 0 10px 22px rgba(34, 67, 123, .16);
81
+ }
82
+
83
+ .board-head {
84
+ height: 38px;
85
+ display: flex;
86
+ align-items: flex-start;
87
+ justify-content: space-between;
88
+ }
89
+
90
+ .board-head h2 {
91
+ display: flex;
92
+ align-items: center;
93
+ gap: 10px;
94
+ font-size: 20px;
95
+ line-height: 1.1;
96
+ font-weight: 900;
97
+ }
98
+
99
+ .board-head h2 span {
100
+ width: 13px;
101
+ height: 14px;
102
+ border-radius: 4px;
103
+ background: var(--blue);
104
+ box-shadow: inset 0 0 4px rgba(255, 255, 255, .35);
105
+ }
106
+
107
+ .actions {
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 16px;
111
+ color: #6c7480;
112
+ font-size: 15px;
113
+ }
114
+
115
+ .actions button {
116
+ height: 26px;
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 3px;
120
+ border: 0;
121
+ background: transparent;
122
+ color: #6c7480;
123
+ font-size: 13px;
124
+ font-weight: 600;
125
+ }
126
+
127
+ .actions button.active {
128
+ padding: 0 13px;
129
+ border-radius: 14px;
130
+ background: var(--blue);
131
+ color: #fff;
132
+ }
133
+
134
+ .warning-table {
135
+ width: 100%;
136
+ height: 100%;
137
+ border-collapse: separate;
138
+ border-spacing: 0;
139
+ overflow: hidden;
140
+ border: 1px solid var(--line);
141
+ border-radius: 0 0 8px 8px;
142
+ font-size: 12px;
143
+ text-align: center;
144
+ }
145
+
146
+ .warning-table th {
147
+ height: 32px;
148
+ border-right: 1px solid rgba(255, 255, 255, .36);
149
+ border-bottom: 1px solid rgba(255, 255, 255, .36);
150
+ background: var(--blue);
151
+ color: #fff;
152
+ font-weight: 700;
153
+ }
154
+
155
+ .warning-table td {
156
+ height: 40px;
157
+ border-right: 1px solid #e1e7ef;
158
+ border-bottom: 1px solid #e1e7ef;
159
+ background: #fff;
160
+ }
161
+
162
+ .warning-table tr:last-child td {
163
+ border-bottom: 0;
164
+ }
165
+
166
+ .pager {
167
+ height: 54px;
168
+ display: flex;
169
+ align-items: flex-end;
170
+ justify-content: center;
171
+ gap: 16px;
172
+ color: #1e2735;
173
+ font-size: 14px;
174
+ }
175
+
176
+ .pager button {
177
+ min-width: 28px;
178
+ height: 28px;
179
+ border: 0;
180
+ border-radius: 5px;
181
+ background: #fff;
182
+ color: #0d1625;
183
+ font-weight: 700;
184
+ }
185
+
186
+ .pager button.selected {
187
+ background: var(--blue);
188
+ color: #fff;
189
+ }
190
+
191
+ .pager input {
192
+ width: 48px;
193
+ height: 30px;
194
+ border: 1px solid #dbe3ef;
195
+ border-radius: 5px;
196
+ text-align: center;
197
+ }
198
+
199
+ @media (max-width: 1200px) {
200
+ .table-board {
201
+ height: auto;
202
+ }
203
+ }
204
+
205
+ @media (max-width: 720px) {
206
+ .actions {
207
+ gap: 10px;
208
+ }
209
+
210
+ .board-head {
211
+ height: auto;
212
+ gap: 12px;
213
+ flex-wrap: wrap;
214
+ margin-bottom: 12px;
215
+ }
216
+
217
+ .warning-table {
218
+ min-width: 720px;
219
+ }
220
+
221
+ .table-board {
222
+ overflow-x: auto;
223
+ }
224
+ }
225
+ </style>
@@ -3,7 +3,6 @@ import ExecutiveAccountPanel from './components/ExecutiveAccountPanel.vue'
3
3
  import ExecutiveReliablePanel from './components/ExecutiveReliablePanel.vue'
4
4
  import ExecutiveWarningOverview from './components/ExecutiveWarningOverview.vue'
5
5
  import ExecutiveWarningTablePanel from './components/ExecutiveWarningTablePanel.vue'
6
- import './executive-management.css'
7
6
  </script>
8
7
 
9
8
  <template>
@@ -23,3 +22,77 @@ import './executive-management.css'
23
22
  </section>
24
23
  </main>
25
24
  </template>
25
+
26
+ <style scoped>
27
+ .executive-page {
28
+ width: 100%;
29
+ height: 100vh;
30
+ min-height: 100vh;
31
+ overflow-x: hidden;
32
+ overflow-y: auto;
33
+ color: #05070b;
34
+ background:
35
+ linear-gradient(90deg, #f8f9fb 0 31.4%, transparent 31.4%),
36
+ linear-gradient(142deg, #2688ff 0%, #0063ee 43%, #005ce9 100%);
37
+ font-family: "Microsoft YaHei", "PingFang SC", "Helvetica Neue", sans-serif;
38
+ }
39
+
40
+ .hero {
41
+ width: 100%;
42
+ height: 128px;
43
+ display: flex;
44
+ align-items: flex-start;
45
+ justify-content: flex-start;
46
+ padding: 23px 31px 0;
47
+ }
48
+
49
+ .hero-title h1 {
50
+ font-size: 36px;
51
+ line-height: 1.16;
52
+ font-weight: 900;
53
+ }
54
+
55
+ .hero-title p {
56
+ margin-top: 16px;
57
+ color: #91959b;
58
+ font-size: 16px;
59
+ }
60
+
61
+ .dashboard-grid {
62
+ width: 100%;
63
+ display: grid;
64
+ grid-template-columns: 1fr;
65
+ gap: 14px;
66
+ padding: 0 31px 39px;
67
+ }
68
+
69
+ @media (max-width: 1200px) {
70
+ .hero {
71
+ height: auto;
72
+ min-height: 128px;
73
+ flex-wrap: wrap;
74
+ gap: 16px;
75
+ padding-right: 24px;
76
+ padding-left: 24px;
77
+ }
78
+
79
+ .dashboard-grid {
80
+ padding-right: 24px;
81
+ padding-left: 24px;
82
+ }
83
+ }
84
+
85
+ @media (max-width: 720px) {
86
+ .hero {
87
+ padding: 18px 16px 0;
88
+ }
89
+
90
+ .hero-title h1 {
91
+ font-size: 30px;
92
+ }
93
+
94
+ .dashboard-grid {
95
+ padding: 0 16px 24px;
96
+ }
97
+ }
98
+ </style>
@@ -0,0 +1,127 @@
1
+ <script setup lang="ts">
2
+ import { ref, reactive } from 'vue'
3
+ import type { FormInstance, FormRules } from 'element-plus'
4
+ import { User, Lock } from '@element-plus/icons-vue'
5
+ import { useLoginStore } from '@/stores/login'
6
+
7
+ const loginStore = useLoginStore()
8
+ const formRef = ref<FormInstance>()
9
+
10
+ const rules = reactive<FormRules>({
11
+ username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
12
+ password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
13
+ })
14
+
15
+ const handleLogin = async () => {
16
+ if (!formRef.value) return
17
+ await formRef.value.validate((valid) => {
18
+ if (valid) {
19
+ loginStore.login()
20
+ }
21
+ })
22
+ }
23
+ </script>
24
+
25
+ <template>
26
+ <div class="login-container">
27
+ <div class="login-left">
28
+ <div class="login-left-content">
29
+ <h1 class="login-title">管理系统</h1>
30
+ <p class="login-subtitle">高效、智能的企业管理平台</p>
31
+ </div>
32
+ </div>
33
+ <div class="login-right">
34
+ <div class="login-form-wrapper">
35
+ <h2 class="form-title">登录</h2>
36
+ <el-form ref="formRef" :model="loginStore" :rules="rules" size="large">
37
+ <el-form-item prop="username">
38
+ <el-input
39
+ v-model="loginStore.username"
40
+ placeholder="请输入用户名"
41
+ :prefix-icon="User"
42
+ />
43
+ </el-form-item>
44
+ <el-form-item prop="password">
45
+ <el-input
46
+ v-model="loginStore.password"
47
+ type="password"
48
+ placeholder="请输入密码"
49
+ :prefix-icon="Lock"
50
+ show-password
51
+ />
52
+ </el-form-item>
53
+ <el-form-item>
54
+ <el-checkbox v-model="loginStore.remember">记住我</el-checkbox>
55
+ </el-form-item>
56
+ <el-form-item>
57
+ <el-button type="primary" class="login-btn" :loading="loginStore.loading" @click="handleLogin">登录</el-button>
58
+ </el-form-item>
59
+ </el-form>
60
+ </div>
61
+ </div>
62
+ </div>
63
+ </template>
64
+
65
+ <style scoped>
66
+ .login-container {
67
+ display: flex;
68
+ height: 100vh;
69
+ width: 100vw;
70
+ }
71
+
72
+ .login-left {
73
+ flex: 6;
74
+ background: linear-gradient(135deg, #2b5876 0%, #4e4376 100%);
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ color: #fff;
79
+ }
80
+
81
+ .login-left-content {
82
+ text-align: center;
83
+ }
84
+
85
+ .login-title {
86
+ font-size: 42px;
87
+ font-weight: 700;
88
+ margin-bottom: 16px;
89
+ }
90
+
91
+ .login-subtitle {
92
+ font-size: 18px;
93
+ opacity: 0.85;
94
+ }
95
+
96
+ .login-right {
97
+ flex: 4;
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+ background: #fff;
102
+ }
103
+
104
+ .login-form-wrapper {
105
+ width: 360px;
106
+ }
107
+
108
+ .form-title {
109
+ font-size: 28px;
110
+ font-weight: 600;
111
+ margin-bottom: 32px;
112
+ color: #303133;
113
+ }
114
+
115
+ .login-btn {
116
+ width: 100%;
117
+ }
118
+
119
+ @media (max-width: 768px) {
120
+ .login-left {
121
+ display: none;
122
+ }
123
+ .login-right {
124
+ flex: 1;
125
+ }
126
+ }
127
+ </style>
@@ -1,116 +0,0 @@
1
- import { nextTick, onUnmounted } from 'vue'
2
- import * as echarts from 'echarts'
3
- import type { ECharts, EChartsOption } from 'echarts'
4
-
5
- export function useChartRegistry() {
6
- const charts: ECharts[] = []
7
-
8
- function panelChart(el: HTMLElement | undefined, option: EChartsOption) {
9
- if (!el) return
10
- const chart = echarts.init(el)
11
- chart.setOption(option)
12
- charts.push(chart)
13
- }
14
-
15
- function resizeCharts() {
16
- charts.forEach((chart) => chart.resize())
17
- }
18
-
19
- async function mountCharts(render: () => void) {
20
- await nextTick()
21
- render()
22
- window.addEventListener('resize', resizeCharts)
23
- }
24
-
25
- onUnmounted(() => {
26
- window.removeEventListener('resize', resizeCharts)
27
- charts.forEach((chart) => chart.dispose())
28
- })
29
-
30
- return { panelChart, mountCharts }
31
- }
32
-
33
- export function ringOption(
34
- centerText: string,
35
- data: Array<{ value: number; name: string; itemStyle?: object }>,
36
- ): EChartsOption {
37
- return {
38
- color: ['#1267f2', '#e7f0ff'],
39
- animationDuration: 900,
40
- title: {
41
- text: centerText,
42
- left: 'center',
43
- top: '42%',
44
- textStyle: { color: '#05070b', fontSize: 30, fontWeight: 800 },
45
- },
46
- series: [
47
- {
48
- type: 'pie',
49
- radius: ['57%', '77%'],
50
- center: ['50%', '51%'],
51
- startAngle: 90,
52
- avoidLabelOverlap: false,
53
- label: { show: false },
54
- labelLine: { show: false },
55
- itemStyle: { borderColor: '#fff', borderWidth: 4 },
56
- data,
57
- },
58
- ],
59
- }
60
- }
61
-
62
- export function lineOption(series: echarts.SeriesOption[], yMin = 0, yMax = 200): EChartsOption {
63
- return {
64
- grid: { left: 56, right: 28, top: 46, bottom: 42 },
65
- legend: {
66
- top: 4,
67
- right: 8,
68
- icon: 'path://M0,4 L12,4',
69
- itemWidth: 16,
70
- itemHeight: 7,
71
- textStyle: { color: '#6e7787', fontSize: 11 },
72
- },
73
- xAxis: {
74
- type: 'category',
75
- boundaryGap: false,
76
- data: ['05-15', '05-16', '05-17', '05-18', '05-20', '05-21'],
77
- axisTick: { show: false },
78
- axisLine: { lineStyle: { color: '#d6dde8' } },
79
- axisLabel: { color: '#6b7280', fontSize: 12 },
80
- },
81
- yAxis: {
82
- type: 'value',
83
- min: yMin,
84
- max: yMax,
85
- splitNumber: 4,
86
- axisLabel: { color: '#6b7280', fontSize: 12 },
87
- splitLine: { lineStyle: { color: '#e7ecf3' } },
88
- },
89
- series,
90
- }
91
- }
92
-
93
- export function sparkOption(values: number[]): EChartsOption {
94
- return {
95
- animationDuration: 700,
96
- grid: { left: 2, right: 2, top: 8, bottom: 7 },
97
- xAxis: { type: 'category', show: false, data: values.map((_, index) => index) },
98
- yAxis: { type: 'value', show: false },
99
- series: [
100
- {
101
- type: 'line',
102
- data: values,
103
- symbol: 'none',
104
- smooth: false,
105
- lineStyle: { color: '#1267f2', width: 2 },
106
- },
107
- ],
108
- }
109
- }
110
-
111
- export function chartGradient(start: string, end: string) {
112
- return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
113
- { offset: 0, color: start },
114
- { offset: 1, color: end },
115
- ])
116
- }