vue2server7 1.0.1 → 2.1.0
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/index.html +12 -0
- package/frontEnd/package-lock.json +2143 -17256
- package/frontEnd/package.json +12 -30
- package/frontEnd/src/App.vue +8 -2
- package/frontEnd/src/components/AppMenu.vue +1 -7
- package/frontEnd/src/components/ColumnSettings.vue +46 -0
- package/frontEnd/src/components/NameScroller.vue +1 -1
- package/frontEnd/src/main.js +7 -10
- package/frontEnd/src/pages/CascaderPage.vue +33 -0
- package/frontEnd/src/pages/TablePage.vue +231 -0
- package/frontEnd/src/router/index.js +4 -7
- package/frontEnd/src/router/routes.js +11 -48
- package/frontEnd/src/utils/request.js +1 -1
- package/frontEnd/vite.config.js +25 -0
- package/package.json +3 -2
- package/test/1.js +24 -0
- package/frontEnd/public/index.html +0 -17
- package/frontEnd/src/pages/LineChartPage.vue +0 -573
- package/frontEnd/src/pages/MedalIssueDialog.vue +0 -558
- package/frontEnd/src/pages/MedalSetting.vue +0 -571
- package/frontEnd/src/pages/MeetingListPage.vue +0 -493
- package/frontEnd/src/pages/NameScrollPage.vue +0 -30
- package/frontEnd/vue.config.js +0 -8
- package/test/d.txt +0 -49
package/frontEnd/package.json
CHANGED
|
@@ -1,43 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "
|
|
3
|
-
"version": "
|
|
2
|
+
"name": "vue3-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"scripts": {
|
|
6
|
-
"
|
|
7
|
-
"build": "
|
|
8
|
-
"
|
|
6
|
+
"dev": "vite",
|
|
7
|
+
"build": "vite build",
|
|
8
|
+
"preview": "vite preview"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
+
"@element-plus/icons-vue": "^2.3.1",
|
|
11
12
|
"axios": "^1.13.2",
|
|
12
|
-
"core-js": "^3.6.5",
|
|
13
13
|
"echarts": "^5.5.1",
|
|
14
|
-
"element-
|
|
14
|
+
"element-plus": "^2.8.4",
|
|
15
15
|
"sortablejs": "^1.15.6",
|
|
16
|
-
"vue": "^
|
|
17
|
-
"vue-router": "^
|
|
16
|
+
"vue": "^3.5.13",
|
|
17
|
+
"vue-router": "^4.4.5"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"babel-eslint": "^10.1.0",
|
|
24
|
-
"eslint": "^6.7.2",
|
|
25
|
-
"eslint-plugin-vue": "^6.2.2",
|
|
26
|
-
"vue-template-compiler": "^2.6.11"
|
|
27
|
-
},
|
|
28
|
-
"eslintConfig": {
|
|
29
|
-
"root": true,
|
|
30
|
-
"env": {
|
|
31
|
-
"node": true
|
|
32
|
-
},
|
|
33
|
-
"extends": [
|
|
34
|
-
"plugin:vue/essential",
|
|
35
|
-
"eslint:recommended"
|
|
36
|
-
],
|
|
37
|
-
"parserOptions": {
|
|
38
|
-
"parser": "babel-eslint"
|
|
39
|
-
},
|
|
40
|
-
"rules": {}
|
|
20
|
+
"@vitejs/plugin-vue": "^6.0.0",
|
|
21
|
+
"vite": "^6.0.0",
|
|
22
|
+
"vite-plugin-vue-devtools": "^8.0.6"
|
|
41
23
|
},
|
|
42
24
|
"browserslist": [
|
|
43
25
|
"> 1%",
|
package/frontEnd/src/App.vue
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
type="text"
|
|
9
9
|
@click="isMenuCollapsed = !isMenuCollapsed"
|
|
10
10
|
>
|
|
11
|
-
<
|
|
11
|
+
<el-icon>
|
|
12
|
+
<Expand v-if="isMenuCollapsed" />
|
|
13
|
+
<Fold v-else />
|
|
14
|
+
</el-icon>
|
|
12
15
|
</el-button>
|
|
13
16
|
</div>
|
|
14
17
|
<AppMenu :collapse="isMenuCollapsed" />
|
|
@@ -22,6 +25,7 @@
|
|
|
22
25
|
|
|
23
26
|
<script>
|
|
24
27
|
import AppMenu from './components/AppMenu.vue'
|
|
28
|
+
import { Expand, Fold } from '@element-plus/icons-vue'
|
|
25
29
|
|
|
26
30
|
export default {
|
|
27
31
|
name: 'App',
|
|
@@ -33,7 +37,9 @@ export default {
|
|
|
33
37
|
}
|
|
34
38
|
},
|
|
35
39
|
components: {
|
|
36
|
-
AppMenu
|
|
40
|
+
AppMenu,
|
|
41
|
+
Expand,
|
|
42
|
+
Fold
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
45
|
</script>
|
|
@@ -12,8 +12,7 @@
|
|
|
12
12
|
:key="item.path + '-submenu'"
|
|
13
13
|
:index="item.path"
|
|
14
14
|
>
|
|
15
|
-
<template
|
|
16
|
-
<i :class="getIcon(item)"></i>
|
|
15
|
+
<template #title>
|
|
17
16
|
<span class="menu-title-text">{{ getTitle(item) }}</span>
|
|
18
17
|
</template>
|
|
19
18
|
<el-menu-item
|
|
@@ -21,7 +20,6 @@
|
|
|
21
20
|
:key="child.path"
|
|
22
21
|
:index="child.path"
|
|
23
22
|
>
|
|
24
|
-
<i :class="getIcon(child)"></i>
|
|
25
23
|
<span class="menu-title-text">{{ getTitle(child) }}</span>
|
|
26
24
|
</el-menu-item>
|
|
27
25
|
</el-submenu>
|
|
@@ -31,7 +29,6 @@
|
|
|
31
29
|
:key="item.path + '-item'"
|
|
32
30
|
:index="item.path"
|
|
33
31
|
>
|
|
34
|
-
<i :class="getIcon(item)"></i>
|
|
35
32
|
<span class="menu-title-text">{{ getTitle(item) }}</span>
|
|
36
33
|
</el-menu-item>
|
|
37
34
|
</template>
|
|
@@ -61,9 +58,6 @@ export default {
|
|
|
61
58
|
getTitle(route) {
|
|
62
59
|
return (route && route.meta && route.meta.title) || route.name || route.path
|
|
63
60
|
},
|
|
64
|
-
getIcon(route) {
|
|
65
|
-
return (route && route.meta && route.meta.icon) || 'el-icon-menu'
|
|
66
|
-
},
|
|
67
61
|
getChildren(route) {
|
|
68
62
|
if (!route || !Array.isArray(route.children)) return []
|
|
69
63
|
return route.children.filter(r => this.isMenuVisible(r))
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="column-settings">
|
|
3
|
+
<el-checkbox-group v-model="selected">
|
|
4
|
+
<el-checkbox v-for="col in columns" :key="col.key" :label="col.key">
|
|
5
|
+
{{ col.label }}
|
|
6
|
+
</el-checkbox>
|
|
7
|
+
</el-checkbox-group>
|
|
8
|
+
</div>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script>
|
|
12
|
+
export default {
|
|
13
|
+
name: 'ColumnSettings',
|
|
14
|
+
props: {
|
|
15
|
+
columns: {
|
|
16
|
+
type: Array,
|
|
17
|
+
default: () => []
|
|
18
|
+
},
|
|
19
|
+
modelValue: {
|
|
20
|
+
type: Array,
|
|
21
|
+
default: () => []
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
emits: ['update:modelValue'],
|
|
25
|
+
data() {
|
|
26
|
+
return {
|
|
27
|
+
selected: [...this.modelValue]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
watch: {
|
|
31
|
+
modelValue(val) {
|
|
32
|
+
this.selected = [...val]
|
|
33
|
+
},
|
|
34
|
+
selected(val) {
|
|
35
|
+
this.$emit('update:modelValue', val)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<style scoped>
|
|
42
|
+
.column-settings .el-checkbox {
|
|
43
|
+
display: block;
|
|
44
|
+
margin: 6px 0;
|
|
45
|
+
}
|
|
46
|
+
</style>
|
package/frontEnd/src/main.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createApp } from 'vue'
|
|
2
2
|
import App from './App.vue'
|
|
3
|
-
|
|
4
|
-
import ElementUI from 'element-ui'
|
|
5
|
-
import 'element-ui/lib/theme-chalk/index.css'
|
|
6
3
|
import router from './router'
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
import ElementPlus from 'element-plus'
|
|
6
|
+
import 'element-plus/dist/index.css'
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
const app = createApp(App)
|
|
9
|
+
app.use(router)
|
|
10
|
+
app.use(ElementPlus)
|
|
11
|
+
app.mount('#app')
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-cascader
|
|
3
|
+
ref="cascader"
|
|
4
|
+
v-model="value"
|
|
5
|
+
:options="options"
|
|
6
|
+
:props="{ checkStrictly: true,emitPath: true }"
|
|
7
|
+
@change="handleChange"
|
|
8
|
+
/>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup>
|
|
12
|
+
import { ref } from 'vue'
|
|
13
|
+
|
|
14
|
+
const value = ref('')
|
|
15
|
+
const cascader = ref()
|
|
16
|
+
|
|
17
|
+
const options = [
|
|
18
|
+
{
|
|
19
|
+
value: 'zhejiang',
|
|
20
|
+
label: '浙江',
|
|
21
|
+
children: [
|
|
22
|
+
{ value: 'hangzhou', label: '杭州' }
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const handleChange = () => {
|
|
28
|
+
const nodes = cascader.value?.getCheckedNodes?.() || []
|
|
29
|
+
const node = nodes[nodes.length - 1]
|
|
30
|
+
const label = node?.label ?? node?.text ?? node?.data?.label
|
|
31
|
+
console.log('label:', label)
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<section class="page table-page">
|
|
3
|
+
<h1 class="title">表格页面</h1>
|
|
4
|
+
<div class="toolbar">
|
|
5
|
+
<el-input v-model="keyword" placeholder="按主题搜索" clearable style="width: 240px" />
|
|
6
|
+
<el-select v-model="type" placeholder="类型" clearable style="width: 160px; margin-left: 8px">
|
|
7
|
+
<el-option label="培训" value="TRAINING" />
|
|
8
|
+
<el-option label="晨夕会" value="MORNING" />
|
|
9
|
+
</el-select>
|
|
10
|
+
<el-button type="primary" @click="onSearch" style="margin-left: 8px">查询</el-button>
|
|
11
|
+
<el-button @click="onReset" style="margin-left: 8px">重置</el-button>
|
|
12
|
+
<el-popover placement="bottom" trigger="click" width="260">
|
|
13
|
+
<template #reference>
|
|
14
|
+
<el-button style="margin-left: 8px">列设置</el-button>
|
|
15
|
+
</template>
|
|
16
|
+
<ColumnSettings v-model="visibleKeys" :columns="columns" />
|
|
17
|
+
</el-popover>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<el-table
|
|
21
|
+
:key="tableKey"
|
|
22
|
+
:data="rows"
|
|
23
|
+
border
|
|
24
|
+
stripe
|
|
25
|
+
size="small"
|
|
26
|
+
style="width: 100%"
|
|
27
|
+
:default-sort="{ prop: 'createTm', order: 'descending' }"
|
|
28
|
+
@sort-change="onSortChange"
|
|
29
|
+
>
|
|
30
|
+
<el-table-column type="index" label="序号" width="60" align="center" />
|
|
31
|
+
<el-table-column
|
|
32
|
+
v-for="col in columns.filter(c => visibleKeys.includes(c.key))"
|
|
33
|
+
:key="col.key"
|
|
34
|
+
:prop="col.prop"
|
|
35
|
+
:label="col.label"
|
|
36
|
+
:width="col.width"
|
|
37
|
+
:min-width="col.minWidth"
|
|
38
|
+
:align="col.align || 'left'"
|
|
39
|
+
:header-align="col.headerAlign || col.align || 'left'"
|
|
40
|
+
:sortable="col.sortable || false"
|
|
41
|
+
:fixed="col.fixed || false"
|
|
42
|
+
>
|
|
43
|
+
<template #default="{ row }">
|
|
44
|
+
<template v-if="col.type === 'type'">
|
|
45
|
+
<el-tag :type="getTypeTag(row.meetTypeCd)" size="small">{{ formatType(row.meetTypeCd) }}</el-tag>
|
|
46
|
+
</template>
|
|
47
|
+
<template v-else-if="col.type === 'date'">
|
|
48
|
+
{{ formatDate(row[col.prop]) }}
|
|
49
|
+
</template>
|
|
50
|
+
<template v-else-if="col.type === 'datetime'">
|
|
51
|
+
{{ formatDateTime(row[col.prop]) }}
|
|
52
|
+
</template>
|
|
53
|
+
<template v-else-if="col.type === 'action'">
|
|
54
|
+
<el-button type="text" size="small" @click="onView(row)">详情</el-button>
|
|
55
|
+
<el-button type="text" size="small" @click="onDelete(row)">删除</el-button>
|
|
56
|
+
</template>
|
|
57
|
+
<template v-else>
|
|
58
|
+
{{ row[col.prop] }}
|
|
59
|
+
</template>
|
|
60
|
+
</template>
|
|
61
|
+
</el-table-column>
|
|
62
|
+
</el-table>
|
|
63
|
+
|
|
64
|
+
<div class="pagination">
|
|
65
|
+
<el-pagination layout="total, prev, pager, next" :current-page="page" :page-size="pageSize" :total="total" @current-change="onPageChange" />
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
</section>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<script>
|
|
73
|
+
import { get } from '../utils/request'
|
|
74
|
+
import ColumnSettings from '../components/ColumnSettings.vue'
|
|
75
|
+
|
|
76
|
+
export default {
|
|
77
|
+
name: 'TablePage',
|
|
78
|
+
data() {
|
|
79
|
+
return {
|
|
80
|
+
columns: [
|
|
81
|
+
{ key: 'organizationName', prop: 'organizationName', label: '所属机构', minWidth: 160 },
|
|
82
|
+
{ key: 'meetSubj', prop: 'meetSubj', label: '会议主题', minWidth: 240 },
|
|
83
|
+
{ key: 'meetNo', prop: 'meetNo', label: '会议编号', minWidth: 180 },
|
|
84
|
+
{ key: 'displayName', prop: 'displayName', label: '创建人', width: 120 },
|
|
85
|
+
{ key: 'meetTypeCd', prop: 'meetTypeCd', label: '类型', width: 120, align: 'center', type: 'type' },
|
|
86
|
+
{ key: 'createTm', prop: 'createTm', label: '创建日期', width: 160, align: 'center', type: 'date', sortable: 'custom' },
|
|
87
|
+
{ key: 'updateTm', prop: 'updateTm', label: '最近编辑时间', width: 190, align: 'center', type: 'datetime', sortable: 'custom' },
|
|
88
|
+
{ key: 'action', prop: '', label: '操作', width: 140, align: 'center', fixed: 'right', type: 'action' }
|
|
89
|
+
],
|
|
90
|
+
visibleKeys: [],
|
|
91
|
+
rows: [],
|
|
92
|
+
total: 0,
|
|
93
|
+
page: 1,
|
|
94
|
+
pageSize: 10,
|
|
95
|
+
sortField: 'createTm',
|
|
96
|
+
sortOrder: 'descending',
|
|
97
|
+
keyword: '',
|
|
98
|
+
type: '',
|
|
99
|
+
tableKey: 0
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
components: {
|
|
103
|
+
ColumnSettings
|
|
104
|
+
},
|
|
105
|
+
created() {
|
|
106
|
+
this.visibleKeys = this.columns.map(c => c.key)
|
|
107
|
+
this.fetch()
|
|
108
|
+
},
|
|
109
|
+
methods: {
|
|
110
|
+
async fetch() {
|
|
111
|
+
const params = {
|
|
112
|
+
page: this.page,
|
|
113
|
+
pageSize: this.pageSize,
|
|
114
|
+
sortField: this.sortField,
|
|
115
|
+
sortOrder: this.sortOrder
|
|
116
|
+
}
|
|
117
|
+
if (this.keyword) params.meetSubj = this.keyword
|
|
118
|
+
if (this.type) params.meetTypeCd = this.type
|
|
119
|
+
const res = await get('/meeting/list', params)
|
|
120
|
+
this.rows = Array.isArray(res.list) ? res.list : []
|
|
121
|
+
this.total = Number.isFinite(res.total) ? res.total : this.rows.length
|
|
122
|
+
},
|
|
123
|
+
onSearch() {
|
|
124
|
+
this.page = 1
|
|
125
|
+
this.fetch()
|
|
126
|
+
},
|
|
127
|
+
onReset() {
|
|
128
|
+
this.keyword = ''
|
|
129
|
+
this.type = ''
|
|
130
|
+
this.page = 1
|
|
131
|
+
this.fetch()
|
|
132
|
+
},
|
|
133
|
+
onPageChange(p) {
|
|
134
|
+
this.page = p
|
|
135
|
+
this.fetch()
|
|
136
|
+
},
|
|
137
|
+
onSortChange({ prop, order }) {
|
|
138
|
+
this.sortField = prop || ''
|
|
139
|
+
this.sortOrder = order || ''
|
|
140
|
+
this.page = 1
|
|
141
|
+
this.fetch()
|
|
142
|
+
},
|
|
143
|
+
// 通过改变 key 强制表格重渲染,确保动态列显示/隐藏立即生效
|
|
144
|
+
bumpTableKey() {
|
|
145
|
+
this.tableKey += 1
|
|
146
|
+
},
|
|
147
|
+
onView(row) {
|
|
148
|
+
const lines = [
|
|
149
|
+
`会议主题:${row.meetSubj || ''}`,
|
|
150
|
+
`内容:${row.plainContent || ''}`,
|
|
151
|
+
`所属机构:${row.organizationName || ''}`,
|
|
152
|
+
`会议类型:${this.formatType(row.meetTypeCd)}`,
|
|
153
|
+
`创建人:${row.displayName || ''}`,
|
|
154
|
+
`创建日期:${this.formatDate(row.createTm)}`,
|
|
155
|
+
`最近编辑时间:${this.formatDateTime(row.updateTm)}`
|
|
156
|
+
]
|
|
157
|
+
this.$alert(lines.join('\n'), '会议详情', { confirmButtonText: '确定' })
|
|
158
|
+
},
|
|
159
|
+
onDelete(row) {
|
|
160
|
+
this.$confirm(`确定删除会议「${row.meetSubj || ''}」吗?`, '提示', {
|
|
161
|
+
type: 'warning',
|
|
162
|
+
confirmButtonText: '确定',
|
|
163
|
+
cancelButtonText: '取消'
|
|
164
|
+
})
|
|
165
|
+
.then(() => {
|
|
166
|
+
this.rows = this.rows.filter(item => item.id !== row.id)
|
|
167
|
+
this.$message({ type: 'success', message: '删除成功' })
|
|
168
|
+
})
|
|
169
|
+
.catch(() => {})
|
|
170
|
+
},
|
|
171
|
+
formatType(code) {
|
|
172
|
+
if (code === 'TRAINING') return '培训'
|
|
173
|
+
if (code === 'MORNING') return '晨夕会'
|
|
174
|
+
return code || ''
|
|
175
|
+
},
|
|
176
|
+
getTypeTag(code) {
|
|
177
|
+
if (code === 'TRAINING') return 'primary'
|
|
178
|
+
if (code === 'MORNING') return 'warning'
|
|
179
|
+
return 'info'
|
|
180
|
+
},
|
|
181
|
+
formatDate(value) {
|
|
182
|
+
if (!value) return ''
|
|
183
|
+
if (value.length === 10) return value
|
|
184
|
+
const d = new Date(value)
|
|
185
|
+
if (Number.isNaN(d.getTime())) return ''
|
|
186
|
+
const yyyy = d.getFullYear()
|
|
187
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
|
188
|
+
const dd = String(d.getDate()).padStart(2, '0')
|
|
189
|
+
return `${yyyy}-${mm}-${dd}`
|
|
190
|
+
},
|
|
191
|
+
formatDateTime(value) {
|
|
192
|
+
if (!value) return ''
|
|
193
|
+
if (value.length >= 16 && value.includes(' ')) return value
|
|
194
|
+
const d = new Date(value)
|
|
195
|
+
if (Number.isNaN(d.getTime())) return ''
|
|
196
|
+
const yyyy = d.getFullYear()
|
|
197
|
+
const mm = String(d.getMonth() + 1).padStart(2, '0')
|
|
198
|
+
const dd = String(d.getDate()).padStart(2, '0')
|
|
199
|
+
const hh = String(d.getHours()).padStart(2, '0')
|
|
200
|
+
const mi = String(d.getMinutes()).padStart(2, '0')
|
|
201
|
+
const ss = String(d.getSeconds()).padStart(2, '0')
|
|
202
|
+
return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}`
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
,
|
|
206
|
+
watch: {
|
|
207
|
+
visibleKeys() {
|
|
208
|
+
this.bumpTableKey()
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
</script>
|
|
213
|
+
|
|
214
|
+
<style scoped>
|
|
215
|
+
.page.table-page {
|
|
216
|
+
padding: 16px;
|
|
217
|
+
}
|
|
218
|
+
.title {
|
|
219
|
+
font-size: 18px;
|
|
220
|
+
margin-bottom: 12px;
|
|
221
|
+
}
|
|
222
|
+
.toolbar {
|
|
223
|
+
margin-bottom: 12px;
|
|
224
|
+
display: flex;
|
|
225
|
+
align-items: center;
|
|
226
|
+
}
|
|
227
|
+
.pagination {
|
|
228
|
+
margin-top: 12px;
|
|
229
|
+
text-align: right;
|
|
230
|
+
}
|
|
231
|
+
</style>
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import Router from 'vue-router'
|
|
3
|
-
|
|
1
|
+
import { createRouter, createWebHashHistory } from 'vue-router'
|
|
4
2
|
import { routes } from './routes'
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export default new Router({
|
|
9
|
-
mode: 'hash',
|
|
4
|
+
const router = createRouter({
|
|
5
|
+
history: createWebHashHistory(),
|
|
10
6
|
routes
|
|
11
7
|
})
|
|
12
8
|
|
|
9
|
+
export default router
|
|
@@ -1,63 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// - 本文件只负责声明路由与菜单元信息,不做权限控制
|
|
4
|
-
// - AppMenu 会根据 meta.showInMenu 渲染左侧菜单
|
|
5
|
-
// - icon 使用 Element UI 内置图标类名
|
|
6
|
-
import LineChartPage from '../pages/LineChartPage.vue'
|
|
7
|
-
import MedalSetting from '../pages/MedalSetting.vue'
|
|
8
|
-
import MeetingListPage from '../pages/MeetingListPage.vue'
|
|
9
|
-
import NameScrollPage from '../pages/NameScrollPage.vue'
|
|
1
|
+
import TablePage from '../pages/TablePage.vue'
|
|
2
|
+
import CascaderPage from '../pages/CascaderPage.vue'
|
|
10
3
|
|
|
11
|
-
// routes 将在 router/index 中被 VueRouter 使用
|
|
12
4
|
export const routes = [
|
|
13
|
-
// 默认路由:根路径重定向到折线图页面
|
|
14
5
|
{
|
|
15
6
|
path: '/',
|
|
16
|
-
redirect: '/
|
|
7
|
+
redirect: '/table'
|
|
17
8
|
},
|
|
18
|
-
// 折线图页面示例
|
|
19
9
|
{
|
|
20
|
-
path: '/
|
|
21
|
-
name: '
|
|
22
|
-
component:
|
|
10
|
+
path: '/table',
|
|
11
|
+
name: 'Table',
|
|
12
|
+
component: TablePage,
|
|
23
13
|
meta: {
|
|
24
|
-
|
|
25
|
-
title: '折线图',
|
|
26
|
-
// 左侧菜单图标
|
|
27
|
-
icon: 'el-icon-data-line',
|
|
28
|
-
// 是否在菜单中展示
|
|
14
|
+
title: '表格页面',
|
|
29
15
|
showInMenu: true
|
|
30
16
|
}
|
|
31
17
|
},
|
|
32
|
-
// 勋章设置页面
|
|
33
18
|
{
|
|
34
|
-
path: '/
|
|
35
|
-
name: '
|
|
36
|
-
component:
|
|
19
|
+
path: '/cascader',
|
|
20
|
+
name: 'Cascader',
|
|
21
|
+
component: CascaderPage,
|
|
37
22
|
meta: {
|
|
38
|
-
title: '
|
|
39
|
-
icon: 'el-icon-medal',
|
|
40
|
-
showInMenu: true
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
// 会议列表页面
|
|
44
|
-
{
|
|
45
|
-
path: '/meeting-list',
|
|
46
|
-
name: 'MeetingList',
|
|
47
|
-
component: MeetingListPage,
|
|
48
|
-
meta: {
|
|
49
|
-
title: '会议列表',
|
|
50
|
-
icon: 'el-icon-date',
|
|
51
|
-
showInMenu: true
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
path: '/name-scroll',
|
|
56
|
-
name: 'NameScroll',
|
|
57
|
-
component: NameScrollPage,
|
|
58
|
-
meta: {
|
|
59
|
-
title: '名字滚动',
|
|
60
|
-
icon: 'el-icon-user',
|
|
23
|
+
title: '级联选择',
|
|
61
24
|
showInMenu: true
|
|
62
25
|
}
|
|
63
26
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineConfig } from 'vite'
|
|
2
|
+
import vue from '@vitejs/plugin-vue'
|
|
3
|
+
import vueDevTools from 'vite-plugin-vue-devtools'
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
plugins: [
|
|
7
|
+
vue(),
|
|
8
|
+
vueDevTools()
|
|
9
|
+
],
|
|
10
|
+
server: {
|
|
11
|
+
port: 5173,
|
|
12
|
+
open: false,
|
|
13
|
+
proxy: {
|
|
14
|
+
'/api': {
|
|
15
|
+
target: 'http://localhost:3000',
|
|
16
|
+
changeOrigin: true,
|
|
17
|
+
rewrite: (path) => path.replace(/^\/api/, '/api')
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
build: {
|
|
22
|
+
outDir: 'dist',
|
|
23
|
+
sourcemap: false
|
|
24
|
+
}
|
|
25
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue2server7",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "nodemon --watch src --ext ts --exec \"ts-node src/app.ts\"",
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
"typecheck": "tsc --noEmit",
|
|
10
10
|
"lint": "eslint .",
|
|
11
11
|
"test": "npm run build && node --test",
|
|
12
|
-
"front-dev": "cd frontEnd && npm run
|
|
12
|
+
"front-dev": "cd frontEnd && npm run dev",
|
|
13
13
|
"front-build": "cd frontEnd && npm run build",
|
|
14
|
+
"front-preview": "cd frontEnd && npm run preview",
|
|
14
15
|
"copy-frontend": "rm -rf dist/public && mkdir -p dist/public && cp -R frontEnd/dist/* dist/public/",
|
|
15
16
|
"build:all": "npm run build && npm run front-build && npm run copy-frontend",
|
|
16
17
|
"发布": "npm publish",
|
package/test/1.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
|
|
3
|
+
// 读取 text 文件
|
|
4
|
+
const content = fs.readFileSync("input.txt", "utf8");
|
|
5
|
+
|
|
6
|
+
// 正则:匹配 注解 + 字段
|
|
7
|
+
const regex =
|
|
8
|
+
/@ApiModelProperty\s*\(\s*value\s*=\s*"([^"]+)"\s*\)\s*[\r\n]+\s*private\s+\w+\s+(\w+)\s*;/g;
|
|
9
|
+
|
|
10
|
+
let match;
|
|
11
|
+
const result = [];
|
|
12
|
+
|
|
13
|
+
while ((match = regex.exec(content)) !== null) {
|
|
14
|
+
const label = match[1]; // 中文
|
|
15
|
+
const field = match[2]; // 字段名
|
|
16
|
+
|
|
17
|
+
result.push({
|
|
18
|
+
field,
|
|
19
|
+
label
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 输出 JSON
|
|
24
|
+
console.log(JSON.stringify(result, null, 2));
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
-
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
7
|
-
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
|
8
|
-
<title><%= htmlWebpackPlugin.options.title %></title>
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
11
|
-
<noscript>
|
|
12
|
-
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
|
13
|
-
</noscript>
|
|
14
|
-
<div id="app"></div>
|
|
15
|
-
<!-- built files will be auto injected -->
|
|
16
|
-
</body>
|
|
17
|
-
</html>
|