vue2server7 7.0.18 → 7.0.20
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.
- package/frontEnd/src/components/NumberRange.vue +95 -202
- package/frontEnd/src/pages/TablePage.vue +228 -162
- package/package.json +1 -1
- package/test/777 +24 -0
- package/test/1/main.ts +0 -52
- package/test/1/utils/charts.ts +0 -38
- package/test/1/utils/color.ts +0 -110
- package/test/1/utils/date.ts +0 -9
- package/test/1/utils/request/Axios.ts +0 -294
- package/test/1/utils/request/AxiosCancel.ts +0 -67
- package/test/1/utils/request/AxiosTransform.ts +0 -63
- package/test/1/utils/request/index.ts +0 -231
- package/test/1/utils/request/utils.ts +0 -53
- package/test/1/utils/route/constant.ts +0 -14
- package/test/1/utils/route/index.ts +0 -110
- package/test/1/utils/version-check.worker.ts +0 -58
- package/test/1/utils/version-update.ts +0 -150
- package/test/1/version-hot-update.md +0 -277
- package/test/1/vite-plugin-version.ts +0 -35
- package/test/1/vite.config.ts +0 -46
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
<el-option label="晨夕会" value="MORNING" />
|
|
12
12
|
</el-select>
|
|
13
13
|
</el-form-item>
|
|
14
|
-
<el-form-item
|
|
15
|
-
<NumberRange v-model="searchForm.amountRange" min-placeholder="最小金额" max-placeholder="最大金额" :precision="2" />
|
|
14
|
+
<el-form-item label="金额范围">
|
|
15
|
+
<NumberRange ref="amountRangeRef" v-model="searchForm.amountRange" min-placeholder="最小金额" max-placeholder="最大金额" :precision="2" error-message="结束金额不能小于起始金额" @validate="onAmountValidate" />
|
|
16
16
|
</el-form-item>
|
|
17
|
-
<el-form-item
|
|
18
|
-
<NumberRange v-model:start="searchForm.ageMin" v-model:end="searchForm.ageMax" min-placeholder="最小年龄" max-placeholder="最大年龄" :precision="0" />
|
|
17
|
+
<el-form-item label="年龄范围">
|
|
18
|
+
<NumberRange ref="ageRangeRef" v-model:start="searchForm.ageMin" v-model:end="searchForm.ageMax" min-placeholder="最小年龄" max-placeholder="最大年龄" :precision="0" error-message="结束年龄不能小于起始年龄" @validate="onAgeValidate" />
|
|
19
19
|
</el-form-item>
|
|
20
20
|
<el-form-item>
|
|
21
21
|
<el-button type="primary" @click="onSearch">查询</el-button>
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
<template v-else-if="col.type === 'action'">
|
|
66
66
|
<el-button type="text" size="small" @click="onView(row)">详情</el-button>
|
|
67
67
|
<el-button type="text" size="small" @click="onDelete(row)">删除</el-button>
|
|
68
|
-
|
|
68
|
+
x x </template>
|
|
69
69
|
<template v-else>
|
|
70
70
|
{{ row[col.prop] }}
|
|
71
71
|
</template>
|
|
@@ -81,168 +81,234 @@
|
|
|
81
81
|
</section>
|
|
82
82
|
</template>
|
|
83
83
|
|
|
84
|
-
<script>
|
|
84
|
+
<script setup lang="ts">
|
|
85
|
+
import { ref, reactive, onMounted, watch } from 'vue'
|
|
86
|
+
import { ElMessage, ElMessageBox } from 'element-plus'
|
|
87
|
+
import type { FormInstance } from 'element-plus'
|
|
85
88
|
import { get } from '../utils/request'
|
|
86
89
|
import ColumnSettings from '../components/ColumnSettings.vue'
|
|
87
|
-
import NumberRange
|
|
90
|
+
import NumberRange from '../components/NumberRange.vue'
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
`创建人:${row.displayName || ''}`,
|
|
188
|
-
`创建日期:${this.formatDate(row.createTm)}`,
|
|
189
|
-
`最近编辑时间:${this.formatDateTime(row.updateTm)}`
|
|
190
|
-
]
|
|
191
|
-
this.$alert(lines.join('\n'), '会议详情', { confirmButtonText: '确定' })
|
|
192
|
-
},
|
|
193
|
-
onDelete(row) {
|
|
194
|
-
this.$confirm(`确定删除会议「${row.meetSubj || ''}」吗?`, '提示', {
|
|
195
|
-
type: 'warning',
|
|
196
|
-
confirmButtonText: '确定',
|
|
197
|
-
cancelButtonText: '取消'
|
|
198
|
-
})
|
|
199
|
-
.then(() => {
|
|
200
|
-
this.rows = this.rows.filter(item => item.id !== row.id)
|
|
201
|
-
this.$message({ type: 'success', message: '删除成功' })
|
|
202
|
-
})
|
|
203
|
-
.catch(() => {})
|
|
204
|
-
},
|
|
205
|
-
formatType(code) {
|
|
206
|
-
if (code === 'TRAINING') return '培训'
|
|
207
|
-
if (code === 'MORNING') return '晨夕会'
|
|
208
|
-
return code || ''
|
|
209
|
-
},
|
|
210
|
-
getTypeTag(code) {
|
|
211
|
-
if (code === 'TRAINING') return 'primary'
|
|
212
|
-
if (code === 'MORNING') return 'warning'
|
|
213
|
-
return 'info'
|
|
214
|
-
},
|
|
215
|
-
formatDate(value) {
|
|
216
|
-
if (!value) return ''
|
|
217
|
-
if (value.length === 10) return value
|
|
218
|
-
const d = new Date(value)
|
|
219
|
-
if (Number.isNaN(d.getTime())) return ''
|
|
220
|
-
const yyyy = d.getFullYear()
|
|
221
|
-
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
|
222
|
-
const dd = String(d.getDate()).padStart(2, '0')
|
|
223
|
-
return `${yyyy}-${mm}-${dd}`
|
|
224
|
-
},
|
|
225
|
-
formatDateTime(value) {
|
|
226
|
-
if (!value) return ''
|
|
227
|
-
if (value.length >= 16 && value.includes(' ')) return value
|
|
228
|
-
const d = new Date(value)
|
|
229
|
-
if (Number.isNaN(d.getTime())) return ''
|
|
230
|
-
const yyyy = d.getFullYear()
|
|
231
|
-
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
|
232
|
-
const dd = String(d.getDate()).padStart(2, '0')
|
|
233
|
-
const hh = String(d.getHours()).padStart(2, '0')
|
|
234
|
-
const mi = String(d.getMinutes()).padStart(2, '0')
|
|
235
|
-
const ss = String(d.getSeconds()).padStart(2, '0')
|
|
236
|
-
return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}`
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
,
|
|
240
|
-
watch: {
|
|
241
|
-
visibleKeys() {
|
|
242
|
-
this.bumpTableKey()
|
|
243
|
-
}
|
|
92
|
+
// 类型定义
|
|
93
|
+
interface SearchForm {
|
|
94
|
+
keyword: string
|
|
95
|
+
type: string
|
|
96
|
+
amountRange: [number | null, number | null]
|
|
97
|
+
ageMin: number | null
|
|
98
|
+
ageMax: number | null
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
interface ColumnConfig {
|
|
102
|
+
key: string
|
|
103
|
+
prop: string
|
|
104
|
+
label: string
|
|
105
|
+
width?: number
|
|
106
|
+
minWidth?: number
|
|
107
|
+
align?: 'left' | 'center' | 'right'
|
|
108
|
+
headerAlign?: 'left' | 'center' | 'right'
|
|
109
|
+
sortable?: boolean | 'custom'
|
|
110
|
+
fixed?: boolean | 'left' | 'right'
|
|
111
|
+
type?: string
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface MeetingRow {
|
|
115
|
+
id: string | number
|
|
116
|
+
organizationName?: string
|
|
117
|
+
meetSubj?: string
|
|
118
|
+
meetNo?: string
|
|
119
|
+
displayName?: string
|
|
120
|
+
meetTypeCd?: string
|
|
121
|
+
createTm?: string
|
|
122
|
+
updateTm?: string
|
|
123
|
+
plainContent?: string
|
|
124
|
+
[key: string]: any
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
interface SortChangeParams {
|
|
128
|
+
prop?: string
|
|
129
|
+
order?: 'ascending' | 'descending' | null
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 组件引用
|
|
133
|
+
const searchFormRef = ref<FormInstance>()
|
|
134
|
+
const amountRangeRef = ref<InstanceType<typeof NumberRange>>()
|
|
135
|
+
const ageRangeRef = ref<InstanceType<typeof NumberRange>>()
|
|
136
|
+
|
|
137
|
+
// 校验状态
|
|
138
|
+
const amountValid = ref(true)
|
|
139
|
+
const ageValid = ref(true)
|
|
140
|
+
|
|
141
|
+
const onAmountValidate = (valid: boolean) => {
|
|
142
|
+
amountValid.value = valid
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const onAgeValidate = (valid: boolean) => {
|
|
146
|
+
ageValid.value = valid
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 响应式数据
|
|
150
|
+
const searchForm = reactive<SearchForm>({
|
|
151
|
+
keyword: '',
|
|
152
|
+
type: '',
|
|
153
|
+
amountRange: [null, null],
|
|
154
|
+
ageMin: null,
|
|
155
|
+
ageMax: null
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
const searchRules = {
|
|
159
|
+
type: [{ required: true, message: '请选择类型', trigger: 'change' }]
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const columns: ColumnConfig[] = [
|
|
163
|
+
{ key: 'organizationName', prop: 'organizationName', label: '所属机构', minWidth: 160 },
|
|
164
|
+
{ key: 'meetSubj', prop: 'meetSubj', label: '会议主题', minWidth: 240 },
|
|
165
|
+
{ key: 'meetNo', prop: 'meetNo', label: '会议编号', minWidth: 180 },
|
|
166
|
+
{ key: 'displayName', prop: 'displayName', label: '创建人', width: 120 },
|
|
167
|
+
{ key: 'meetTypeCd', prop: 'meetTypeCd', label: '类型', width: 120, align: 'center', type: 'type' },
|
|
168
|
+
{ key: 'createTm', prop: 'createTm', label: '创建日期', width: 160, align: 'center', type: 'date', sortable: 'custom' },
|
|
169
|
+
{ key: 'updateTm', prop: 'updateTm', label: '最近编辑时间', width: 190, align: 'center', type: 'datetime', sortable: 'custom' },
|
|
170
|
+
{ key: 'action', prop: '', label: '操作', width: 140, align: 'center', fixed: 'right', type: 'action' }
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
const visibleKeys = ref<string[]>([])
|
|
174
|
+
const rows = ref<MeetingRow[]>([])
|
|
175
|
+
const total = ref(0)
|
|
176
|
+
const page = ref(1)
|
|
177
|
+
const pageSize = ref(10)
|
|
178
|
+
const sortField = ref('createTm')
|
|
179
|
+
const sortOrder = ref<'ascending' | 'descending' | ''>('descending')
|
|
180
|
+
const tableKey = ref(0)
|
|
181
|
+
|
|
182
|
+
// 方法
|
|
183
|
+
const fetch = async () => {
|
|
184
|
+
const { keyword, type, amountRange, ageMin, ageMax } = searchForm
|
|
185
|
+
const params: Record<string, any> = {
|
|
186
|
+
page: page.value,
|
|
187
|
+
pageSize: pageSize.value,
|
|
188
|
+
sortField: sortField.value,
|
|
189
|
+
sortOrder: sortOrder.value
|
|
244
190
|
}
|
|
191
|
+
if (keyword) params.meetSubj = keyword
|
|
192
|
+
if (type) params.meetTypeCd = type
|
|
193
|
+
if (amountRange[0] !== null) params.amountMin = amountRange[0]
|
|
194
|
+
if (amountRange[1] !== null) params.amountMax = amountRange[1]
|
|
195
|
+
if (ageMin !== null) params.ageMin = ageMin
|
|
196
|
+
if (ageMax !== null) params.ageMax = ageMax
|
|
197
|
+
const res = await get('/meeting/list', params)
|
|
198
|
+
rows.value = Array.isArray(res.list) ? res.list : []
|
|
199
|
+
total.value = Number.isFinite(res.total) ? res.total : rows.value.length
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const onSearch = () => {
|
|
203
|
+
// 校验 NumberRange 组件
|
|
204
|
+
const isAmountValid = amountRangeRef.value?.validate() ?? true
|
|
205
|
+
const isAgeValid = ageRangeRef.value?.validate() ?? true
|
|
206
|
+
|
|
207
|
+
searchFormRef.value?.validate((valid: boolean) => {
|
|
208
|
+
if (!valid || !isAmountValid || !isAgeValid) return
|
|
209
|
+
page.value = 1
|
|
210
|
+
fetch()
|
|
211
|
+
})
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const onReset = () => {
|
|
215
|
+
searchFormRef.value?.resetFields()
|
|
216
|
+
amountRangeRef.value?.reset()
|
|
217
|
+
ageRangeRef.value?.reset()
|
|
218
|
+
page.value = 1
|
|
219
|
+
fetch()
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const onPageChange = (p: number) => {
|
|
223
|
+
page.value = p
|
|
224
|
+
fetch()
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const onSortChange = ({ prop, order }: SortChangeParams) => {
|
|
228
|
+
sortField.value = prop || ''
|
|
229
|
+
sortOrder.value = order || ''
|
|
230
|
+
page.value = 1
|
|
231
|
+
fetch()
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// 通过改变 key 强制表格重渲染,确保动态列显示/隐藏立即生效
|
|
235
|
+
const bumpTableKey = () => {
|
|
236
|
+
tableKey.value += 1
|
|
245
237
|
}
|
|
238
|
+
|
|
239
|
+
const onView = (row: MeetingRow) => {
|
|
240
|
+
const lines = [
|
|
241
|
+
`会议主题:${row.meetSubj || ''}`,
|
|
242
|
+
`内容:${row.plainContent || ''}`,
|
|
243
|
+
`所属机构:${row.organizationName || ''}`,
|
|
244
|
+
`会议类型:${formatType(row.meetTypeCd)}`,
|
|
245
|
+
`创建人:${row.displayName || ''}`,
|
|
246
|
+
`创建日期:${formatDate(row.createTm)}`,
|
|
247
|
+
`最近编辑时间:${formatDateTime(row.updateTm)}`
|
|
248
|
+
]
|
|
249
|
+
ElMessageBox.alert(lines.join('\n'), '会议详情', { confirmButtonText: '确定' })
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const onDelete = (row: MeetingRow) => {
|
|
253
|
+
ElMessageBox.confirm(`确定删除会议「${row.meetSubj || ''}」吗?`, '提示', {
|
|
254
|
+
type: 'warning',
|
|
255
|
+
confirmButtonText: '确定',
|
|
256
|
+
cancelButtonText: '取消'
|
|
257
|
+
})
|
|
258
|
+
.then(() => {
|
|
259
|
+
rows.value = rows.value.filter(item => item.id !== row.id)
|
|
260
|
+
ElMessage({ type: 'success', message: '删除成功' })
|
|
261
|
+
})
|
|
262
|
+
.catch(() => {})
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const formatType = (code?: string): string => {
|
|
266
|
+
if (code === 'TRAINING') return '培训'
|
|
267
|
+
if (code === 'MORNING') return '晨夕会'
|
|
268
|
+
return code || ''
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const getTypeTag = (code?: string): string => {
|
|
272
|
+
if (code === 'TRAINING') return 'primary'
|
|
273
|
+
if (code === 'MORNING') return 'warning'
|
|
274
|
+
return 'info'
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const formatDate = (value?: string): string => {
|
|
278
|
+
if (!value) return ''
|
|
279
|
+
if (value.length === 10) return value
|
|
280
|
+
const d = new Date(value)
|
|
281
|
+
if (Number.isNaN(d.getTime())) return ''
|
|
282
|
+
const yyyy = d.getFullYear()
|
|
283
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
|
284
|
+
const dd = String(d.getDate()).padStart(2, '0')
|
|
285
|
+
return `${yyyy}-${mm}-${dd}`
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const formatDateTime = (value?: string): string => {
|
|
289
|
+
if (!value) return ''
|
|
290
|
+
if (value.length >= 16 && value.includes(' ')) return value
|
|
291
|
+
const d = new Date(value)
|
|
292
|
+
if (Number.isNaN(d.getTime())) return ''
|
|
293
|
+
const yyyy = d.getFullYear()
|
|
294
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
|
295
|
+
const dd = String(d.getDate()).padStart(2, '0')
|
|
296
|
+
const hh = String(d.getHours()).padStart(2, '0')
|
|
297
|
+
const mi = String(d.getMinutes()).padStart(2, '0')
|
|
298
|
+
const ss = String(d.getSeconds()).padStart(2, '0')
|
|
299
|
+
return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}`
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// 监听器
|
|
303
|
+
watch(visibleKeys, () => {
|
|
304
|
+
bumpTableKey()
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
// 生命周期
|
|
308
|
+
onMounted(() => {
|
|
309
|
+
visibleKeys.value = columns.map(c => c.key)
|
|
310
|
+
fetch()
|
|
311
|
+
})
|
|
246
312
|
</script>
|
|
247
313
|
|
|
248
314
|
<style scoped>
|
package/package.json
CHANGED
package/test/777
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
|
|
3
|
+
const downloadFile = async (url: string, filename = 'file.zip') => {
|
|
4
|
+
const res = await axios.get(url, {
|
|
5
|
+
responseType: 'blob',
|
|
6
|
+
onDownloadProgress: (e) => {
|
|
7
|
+
if (e.total) {
|
|
8
|
+
const percent = Math.round((e.loaded / e.total) * 100)
|
|
9
|
+
console.log('下载进度:', percent + '%')
|
|
10
|
+
} else {
|
|
11
|
+
console.log('已下载:', e.loaded)
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
// 创建下载
|
|
17
|
+
const blob = new Blob([res.data])
|
|
18
|
+
const link = document.createElement('a')
|
|
19
|
+
link.href = URL.createObjectURL(blob)
|
|
20
|
+
link.download = filename
|
|
21
|
+
link.click()
|
|
22
|
+
|
|
23
|
+
URL.revokeObjectURL(link.href)
|
|
24
|
+
}
|
package/test/1/main.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 应用入口文件
|
|
3
|
-
*
|
|
4
|
-
* 职责:
|
|
5
|
-
* 1. 创建 Vue 应用实例
|
|
6
|
-
* 2. 注册全局插件(UI 库、状态管理、路由、国际化)
|
|
7
|
-
* 3. 加载全局样式
|
|
8
|
-
* 4. 挂载到 DOM
|
|
9
|
-
* 5. 启动版本热更新检测
|
|
10
|
-
*
|
|
11
|
-
* 导入顺序说明(eslint simple-import-sort 已禁用):
|
|
12
|
-
* - 框架核心 → 第三方库 → 业务模块 → 样式 → 副作用模块
|
|
13
|
-
* 此处手动控制顺序以确保 permission 等副作用模块在路由注册之后加载
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/* eslint-disable simple-import-sort/imports */
|
|
17
|
-
import { createApp } from 'vue';
|
|
18
|
-
import TDesign from 'tdesign-vue-next';
|
|
19
|
-
|
|
20
|
-
import App from './App.vue';
|
|
21
|
-
import router from './router';
|
|
22
|
-
import { store } from './store';
|
|
23
|
-
import i18n from './locales';
|
|
24
|
-
|
|
25
|
-
/** TDesign 组件库全局样式 */
|
|
26
|
-
import 'tdesign-vue-next/es/style/index.css';
|
|
27
|
-
/** 项目自定义全局样式(变量覆盖、通用布局等) */
|
|
28
|
-
import '@/style/index.less';
|
|
29
|
-
/**
|
|
30
|
-
* 路由权限守卫(副作用模块)
|
|
31
|
-
* 导入即执行 router.beforeEach,必须在 router 创建之后引入
|
|
32
|
-
*/
|
|
33
|
-
import './permission';
|
|
34
|
-
|
|
35
|
-
const app = createApp(App);
|
|
36
|
-
|
|
37
|
-
app.use(TDesign); // TDesign 组件全局注册(Dialog、Message 等可通过插件式 API 调用)
|
|
38
|
-
app.use(store); // Pinia 状态管理
|
|
39
|
-
app.use(router); // Vue Router
|
|
40
|
-
app.use(i18n); // Vue I18n 国际化
|
|
41
|
-
|
|
42
|
-
/** 挂载到 public/index.html 中的 #app 节点 */
|
|
43
|
-
app.mount('#app');
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* 版本热更新检测
|
|
47
|
-
* 放在 mount 之后执行,确保 DOM 中的 <meta name="app-version"> 已就绪
|
|
48
|
-
* 详见 @/utils/version-update.ts
|
|
49
|
-
*/
|
|
50
|
-
import { initVersionCheck } from './utils/version-update';
|
|
51
|
-
|
|
52
|
-
initVersionCheck();
|
package/test/1/utils/charts.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import dayjs from 'dayjs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 获取表头数据
|
|
5
|
-
*
|
|
6
|
-
* @export
|
|
7
|
-
* @param {string[]} dateTime
|
|
8
|
-
* @param {number} divideNum
|
|
9
|
-
* @returns {string[]} timeArray
|
|
10
|
-
*/
|
|
11
|
-
export function getDateArray(dateTime: string[] = [], divideNum = 10): string[] {
|
|
12
|
-
const timeArray: string[] = [];
|
|
13
|
-
if (dateTime.length > 0) {
|
|
14
|
-
for (let i = 0; i < divideNum; i++) {
|
|
15
|
-
const dateAbsTime: number = (new Date(dateTime[1]).getTime() - new Date(dateTime[0]).getTime()) / divideNum;
|
|
16
|
-
const enhandTime: number = new Date(dateTime[0]).getTime() + dateAbsTime * i;
|
|
17
|
-
timeArray.push(dayjs(enhandTime).format('YYYY-MM-DD'));
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return timeArray;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* 获取随机数
|
|
26
|
-
*
|
|
27
|
-
* @param {number} [num]
|
|
28
|
-
* @returns {number} resultNum
|
|
29
|
-
*/
|
|
30
|
-
export function getRandomArray(num = 100): number {
|
|
31
|
-
let resultNum = Number((Math.random() * num).toFixed(0));
|
|
32
|
-
|
|
33
|
-
if (resultNum <= 1) {
|
|
34
|
-
resultNum = 1;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return resultNum;
|
|
38
|
-
}
|
package/test/1/utils/color.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import type * as echarts from 'echarts/core';
|
|
2
|
-
import trim from 'lodash/trim';
|
|
3
|
-
import { Color } from 'tvision-color';
|
|
4
|
-
|
|
5
|
-
import type { TColorToken } from '@/config/color';
|
|
6
|
-
import type { ModeType } from '@/types/interface';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 依据主题类型获取颜色
|
|
10
|
-
*
|
|
11
|
-
* @export
|
|
12
|
-
* @returns {Array<string>} themeColorList
|
|
13
|
-
*/
|
|
14
|
-
export function getColorFromTheme(): Array<string> {
|
|
15
|
-
const theme = trim(getComputedStyle(document.documentElement).getPropertyValue('--td-brand-color'));
|
|
16
|
-
const themeColorList = Color.getRandomPalette({
|
|
17
|
-
color: theme,
|
|
18
|
-
colorGamut: 'bright',
|
|
19
|
-
number: 8,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
return themeColorList;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** 图表颜色 */
|
|
26
|
-
export function getChartListColor(): Array<string> {
|
|
27
|
-
return getColorFromTheme();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* 更改图表主题颜色
|
|
32
|
-
*
|
|
33
|
-
* @export
|
|
34
|
-
* @param {Array<string>} chartsList
|
|
35
|
-
*/
|
|
36
|
-
export function changeChartsTheme(chartsList: echarts.EChartsType[]): void {
|
|
37
|
-
if (chartsList && chartsList.length) {
|
|
38
|
-
const chartChangeColor = getChartListColor();
|
|
39
|
-
|
|
40
|
-
for (let index = 0; index < chartsList.length; index++) {
|
|
41
|
-
const elementChart = chartsList[index];
|
|
42
|
-
|
|
43
|
-
if (elementChart) {
|
|
44
|
-
const optionVal = elementChart.getOption();
|
|
45
|
-
|
|
46
|
-
// 更改主题颜色
|
|
47
|
-
optionVal.color = chartChangeColor;
|
|
48
|
-
|
|
49
|
-
elementChart.setOption(optionVal, true);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* 根据当前主题色、模式等情景 计算最后生成的色阶
|
|
57
|
-
*/
|
|
58
|
-
export function generateColorMap(theme: string, colorPalette: Array<string>, mode: ModeType, brandColorIdx: number) {
|
|
59
|
-
const isDarkMode = mode === 'dark';
|
|
60
|
-
|
|
61
|
-
if (isDarkMode) {
|
|
62
|
-
colorPalette.reverse().map((color) => {
|
|
63
|
-
const [h, s, l] = Color.colorTransform(color, 'hex', 'hsl');
|
|
64
|
-
return Color.colorTransform([h, Number(s) - 4, l], 'hsl', 'hex');
|
|
65
|
-
});
|
|
66
|
-
brandColorIdx = 5;
|
|
67
|
-
colorPalette[0] = `${colorPalette[brandColorIdx]}20`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const colorMap: TColorToken = {
|
|
71
|
-
'--td-brand-color': colorPalette[brandColorIdx], // 主题色
|
|
72
|
-
'--td-brand-color-1': colorPalette[0], // light
|
|
73
|
-
'--td-brand-color-2': colorPalette[1], // focus
|
|
74
|
-
'--td-brand-color-3': colorPalette[2], // disabled
|
|
75
|
-
'--td-brand-color-4': colorPalette[3],
|
|
76
|
-
'--td-brand-color-5': colorPalette[4],
|
|
77
|
-
'--td-brand-color-6': colorPalette[5],
|
|
78
|
-
'--td-brand-color-7': brandColorIdx > 0 ? colorPalette[brandColorIdx - 1] : theme, // hover
|
|
79
|
-
'--td-brand-color-8': colorPalette[brandColorIdx], // 主题色
|
|
80
|
-
'--td-brand-color-9': brandColorIdx > 8 ? theme : colorPalette[brandColorIdx + 1], // click
|
|
81
|
-
'--td-brand-color-10': colorPalette[9],
|
|
82
|
-
};
|
|
83
|
-
return colorMap;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* 将生成的样式嵌入头部
|
|
88
|
-
*/
|
|
89
|
-
export function insertThemeStylesheet(theme: string, colorMap: TColorToken, mode: ModeType) {
|
|
90
|
-
const isDarkMode = mode === 'dark';
|
|
91
|
-
const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;
|
|
92
|
-
|
|
93
|
-
const styleSheet = document.createElement('style');
|
|
94
|
-
styleSheet.type = 'text/css';
|
|
95
|
-
styleSheet.textContent = `${root}{
|
|
96
|
-
--td-brand-color: ${colorMap['--td-brand-color']};
|
|
97
|
-
--td-brand-color-1: ${colorMap['--td-brand-color-1']};
|
|
98
|
-
--td-brand-color-2: ${colorMap['--td-brand-color-2']};
|
|
99
|
-
--td-brand-color-3: ${colorMap['--td-brand-color-3']};
|
|
100
|
-
--td-brand-color-4: ${colorMap['--td-brand-color-4']};
|
|
101
|
-
--td-brand-color-5: ${colorMap['--td-brand-color-5']};
|
|
102
|
-
--td-brand-color-6: ${colorMap['--td-brand-color-6']};
|
|
103
|
-
--td-brand-color-7: ${colorMap['--td-brand-color-7']};
|
|
104
|
-
--td-brand-color-8: ${colorMap['--td-brand-color-8']};
|
|
105
|
-
--td-brand-color-9: ${colorMap['--td-brand-color-9']};
|
|
106
|
-
--td-brand-color-10: ${colorMap['--td-brand-color-10']};
|
|
107
|
-
}`;
|
|
108
|
-
|
|
109
|
-
document.head.appendChild(styleSheet);
|
|
110
|
-
}
|
package/test/1/utils/date.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
// 获取常用时间
|
|
2
|
-
import dayjs from 'dayjs';
|
|
3
|
-
|
|
4
|
-
export const LAST_7_DAYS = [dayjs().subtract(6, 'day').format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')];
|
|
5
|
-
|
|
6
|
-
export const LAST_30_DAYS = [
|
|
7
|
-
dayjs().subtract(30, 'day').format('YYYY-MM-DD'),
|
|
8
|
-
dayjs().subtract(1, 'day').format('YYYY-MM-DD'),
|
|
9
|
-
];
|