zsysview 0.0.5 → 0.0.7
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/README.md +3 -1
- package/assets/default_avatar.png +0 -0
- package/assets/login_bg.jpg +0 -0
- package/components/export/export_dialog.vue +150 -0
- package/components/export/export_progress.vue +62 -0
- package/components/list/zsyslist.vue +2 -2
- package/components/list/zsyslist_header.vue +1 -1
- package/components/zsys_delbutton.vue +60 -0
- package/core/app.ts +13 -2
- package/core/common/common.ts +29 -0
- package/core/common/zsys_eventBus.ts +45 -0
- package/core/common/zsys_time.ts +26 -0
- package/core/httpapi/http_api_return_data.ts +43 -0
- package/core/httpapi/http_api_v1.ts +149 -0
- package/core/httpapi/http_axios.ts +54 -0
- package/core/router copy.ts +148 -0
- package/core/router.ts +95 -0
- package/core/user_token.ts +17 -0
- package/css/common.css +16 -0
- package/package.json +6 -2
- package/view/app.vue +0 -1
- package/view/backup/backup.vue +308 -0
- package/view/building.vue +22 -0
- package/view/department/department.vue +111 -0
- package/view/department/department_edit_dialog.vue +267 -0
- package/view/desktop/desktop.vue +11 -0
- package/view/log/log.vue +60 -0
- package/view/log/log_setting.vue +41 -0
- package/view/login.vue +5 -5
- package/view/main/breadcrumb.vue +41 -0
- package/view/main/main.vue +60 -0
- package/view/main/userHeader.vue +72 -0
- package/view/main/userMenu.vue +132 -0
- package/view/main/userMenuItem.vue +49 -0
- package/view/position/position.vue +58 -0
- package/view/position/position_edit_dialog.vue +203 -0
- package/view/role/role.vue +72 -0
- package/view/role/role_edit_dialog.vue +271 -0
- package/view/self/change_password.vue +97 -0
- package/view/self/self.vue +62 -0
- package/view/user/change_user_password_dialog.vue +155 -0
- package/view/user/user.vue +110 -0
- package/view/user/user_edit_dialog.vue +283 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 白色 -->
|
|
3
|
+
<div style="padding-left: 20px; padding-right: 20px; ">
|
|
4
|
+
<div
|
|
5
|
+
style="height:60px; margin-right: 10px; float: left; display: flex; align-items: center; justify-content: center;">
|
|
6
|
+
<el-image style="height: 40px; " />
|
|
7
|
+
<!-- :src="logoUrl" -->
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div style="float: left; line-height: 60px;">岗位行为识别系统</div>
|
|
11
|
+
<!-- 右上角 -->
|
|
12
|
+
<el-dropdown trigger="click" class="user_operate">
|
|
13
|
+
<span class="el-dropdown-link">
|
|
14
|
+
{{ user.uname }}
|
|
15
|
+
<el-icon class="el-icon--right">
|
|
16
|
+
<arrow-down />
|
|
17
|
+
</el-icon>
|
|
18
|
+
</span>
|
|
19
|
+
<template #dropdown>
|
|
20
|
+
<el-dropdown-menu>
|
|
21
|
+
<el-dropdown-item @click="changepassword">修改密码</el-dropdown-item>
|
|
22
|
+
<el-dropdown-item @click="loginout">退出</el-dropdown-item>
|
|
23
|
+
</el-dropdown-menu>
|
|
24
|
+
</template>
|
|
25
|
+
</el-dropdown>
|
|
26
|
+
<!-- 右上角 -->
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
</template>
|
|
32
|
+
|
|
33
|
+
<script setup lang="ts">
|
|
34
|
+
import { useTokenStore } from '../../core/user_token' //'../../core/user_token';
|
|
35
|
+
import { useRouter } from 'vue-router';
|
|
36
|
+
import { ArrowDown } from '@element-plus/icons-vue'
|
|
37
|
+
// import logoUrl from '../../assets/logo_40.png';
|
|
38
|
+
import { HttpApiV1 as http } from '../../core/httpapi/http_api_v1';
|
|
39
|
+
import { reactive } from 'vue';
|
|
40
|
+
const r = useRouter()
|
|
41
|
+
|
|
42
|
+
const user = reactive({
|
|
43
|
+
uname: '',
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
http.Post(http.url_usercenter, {}).then((res) => {
|
|
47
|
+
if (res.IsSuccess) {
|
|
48
|
+
let d = res.data as { uname: string }
|
|
49
|
+
user.uname = d.uname
|
|
50
|
+
}
|
|
51
|
+
}).catch((err) => {
|
|
52
|
+
console.log('er1111r');
|
|
53
|
+
console.log(err);
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const loginout = () => {
|
|
57
|
+
useTokenStore().saveToken('')
|
|
58
|
+
r.push('/login')
|
|
59
|
+
}
|
|
60
|
+
const changepassword = () => {
|
|
61
|
+
r.push('/password')
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
</script>
|
|
65
|
+
|
|
66
|
+
<style scoped>
|
|
67
|
+
.user_operate {
|
|
68
|
+
float: right;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
line-height: 60px;
|
|
71
|
+
}
|
|
72
|
+
</style>
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-aside width="200px" style="position: fixed;top:60px;left: 0px; bottom: 0px;">
|
|
3
|
+
<el-scrollbar style=" background-color: #252423;"><!-- border-right:1px solid #dcdfe6; -->
|
|
4
|
+
<el-menu default-active="2" router style="margin-bottom: 20px;" background-color="#252423" text-color="#fff" active-text-color="#409EFF">
|
|
5
|
+
<usermenuitem v-for="v in menus" :key="v.url" v-bind:item="v" />
|
|
6
|
+
</el-menu>
|
|
7
|
+
</el-scrollbar>
|
|
8
|
+
</el-aside>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import { onMounted, type DefineComponent, reactive ,markRaw} from 'vue';
|
|
13
|
+
import { HttpApiV1 as http } from '../../core/httpapi/http_api_v1';
|
|
14
|
+
import usermenuitem from './userMenuItem.vue'
|
|
15
|
+
import { CommonHelper } from '../../core/common/common';
|
|
16
|
+
import {
|
|
17
|
+
Document, Reading, Setting, Avatar, Location, VideoCamera,
|
|
18
|
+
OfficeBuilding, User, House, SetUp, Collection, Bell, Odometer,CopyDocument
|
|
19
|
+
} from '@element-plus/icons-vue'
|
|
20
|
+
const menus = reactive(
|
|
21
|
+
[
|
|
22
|
+
{ name: '首页', iconname:'House', icon: markRaw(House), url: '/desktop', show: true },
|
|
23
|
+
{ name: '个人中心', icon: markRaw(User), url: '/self', show: true },
|
|
24
|
+
{ name: '数据看板', icon: markRaw(Odometer), url: '/chart', show: false },
|
|
25
|
+
{ name: '事件管理', icon: markRaw(Collection), url: '/eventgroup/event', show: false },
|
|
26
|
+
// {
|
|
27
|
+
// name: '事件管理', icon: markRaw(Collection), url: '/111', show: false,
|
|
28
|
+
// children: [
|
|
29
|
+
// { name: '数据看板', icon: markRaw(Odometer), url: '/user', show: false },
|
|
30
|
+
// { name: '事件', icon: markRaw(Collection), url: '/eventgroup/event', show: false },
|
|
31
|
+
// ]
|
|
32
|
+
// },
|
|
33
|
+
{ name: '行为分析引擎', icon: markRaw(SetUp), url: '/engine', show: false },
|
|
34
|
+
{ name: '设备管理', icon: markRaw(VideoCamera), url: '/equipment', show: false },
|
|
35
|
+
{ name: '区域管理', icon: markRaw(Location), url: '/area', show: false },
|
|
36
|
+
{ name: '报表与统计', icon: markRaw(Document), url: '/building?1', show: false },
|
|
37
|
+
{ name: '报警与通知', icon: markRaw(Bell), url: '/building?2', show: false },
|
|
38
|
+
{
|
|
39
|
+
name: '系统管理', icon: markRaw(Setting), url: '/zsys', show: false,
|
|
40
|
+
children: [
|
|
41
|
+
{ name: '用户管理', icon: markRaw(User), url: '/user', show: false },
|
|
42
|
+
{ name: '组织架构', icon: markRaw(OfficeBuilding), url: '/department', show: false },
|
|
43
|
+
{ name: '职务', icon: markRaw(Avatar), url: '/position', show: false },
|
|
44
|
+
{ name: '角色权限', icon: markRaw(Avatar), url: '/role', show: false },
|
|
45
|
+
{ name: '日志', icon: markRaw(Reading), url: '/log', show: false },
|
|
46
|
+
{ name: '备份', icon: markRaw(CopyDocument), url: '/backup', show: false },
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
])
|
|
50
|
+
|
|
51
|
+
interface MenuItem {
|
|
52
|
+
name: string
|
|
53
|
+
icon?: DefineComponent<{}, {}, any>;
|
|
54
|
+
url: string
|
|
55
|
+
children?: MenuItem[]
|
|
56
|
+
show: boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function findMenuByName(menuList: MenuItem[], name: string): any | undefined {
|
|
60
|
+
for (const menu of menuList) {
|
|
61
|
+
if (menu.name === name) {
|
|
62
|
+
return menu;
|
|
63
|
+
}
|
|
64
|
+
if (menu.children && menu.children.length > 0) {
|
|
65
|
+
const found = findMenuByName(menu.children, name);
|
|
66
|
+
if (found) {
|
|
67
|
+
return found;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const showIfHas = (name: string, needpermission: string, ps: string[]) => {
|
|
75
|
+
let groups = needpermission.split('|')
|
|
76
|
+
let show = false
|
|
77
|
+
for (const g of groups) {
|
|
78
|
+
let need = g.split(',')
|
|
79
|
+
if (CommonHelper.StringArrayHasStringArray(ps, need)) {
|
|
80
|
+
show = true
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (show) {
|
|
85
|
+
let menuItem = findMenuByName(menus, name);
|
|
86
|
+
menuItem.show = show
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const menuview = (ps: string[]) => {
|
|
91
|
+
showIfHas('事件管理', 'gwxw.event', ps)
|
|
92
|
+
showIfHas('数据看板', 'gwxw.event', ps)
|
|
93
|
+
// showIfHas('事件', 'gwxw.event', ps)
|
|
94
|
+
showIfHas('行为分析引擎', 'gwxw.engine', ps)
|
|
95
|
+
showIfHas('设备管理', 'gwxw.equipment', ps)
|
|
96
|
+
showIfHas('区域管理', 'gwxw.area', ps)
|
|
97
|
+
showIfHas('报表与统计', 'gwxw.total', ps)
|
|
98
|
+
showIfHas('报警与通知', 'gwxw.notice', ps)
|
|
99
|
+
|
|
100
|
+
showIfHas('系统管理', 'zsys.user|zsys.department|zsys.position|zsys.role|zsys.log|zsys.backup', ps)
|
|
101
|
+
showIfHas('用户管理', 'zsys.user', ps)
|
|
102
|
+
showIfHas('组织架构', 'zsys.department', ps)
|
|
103
|
+
showIfHas('职务', 'zsys.position', ps)
|
|
104
|
+
showIfHas('角色权限', 'zsys.role', ps)
|
|
105
|
+
showIfHas('日志', 'zsys.log', ps)
|
|
106
|
+
showIfHas('备份', 'zsys.backup', ps)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const getUerPermission = async () => {
|
|
110
|
+
try {
|
|
111
|
+
let res = await http.Post(http.url_user_permission, {})
|
|
112
|
+
if (res.IsSuccess) {
|
|
113
|
+
let ps = res.data as string[]
|
|
114
|
+
menuview(ps)
|
|
115
|
+
}
|
|
116
|
+
} catch (e) {
|
|
117
|
+
console.log(e);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
onMounted(() => {
|
|
124
|
+
getUerPermission()
|
|
125
|
+
})
|
|
126
|
+
</script>
|
|
127
|
+
|
|
128
|
+
<style scoped>
|
|
129
|
+
.el-menu--vertical {
|
|
130
|
+
border-right: none !important;
|
|
131
|
+
}
|
|
132
|
+
</style>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<!-- 无子级 -->
|
|
3
|
+
<el-menu-item v-if="!data.item.children && data.item.show" :index="data.item.url">
|
|
4
|
+
<el-icon>
|
|
5
|
+
<!-- <component :is="component"></component> -->
|
|
6
|
+
<component :is="data.item.icon"></component>
|
|
7
|
+
</el-icon>
|
|
8
|
+
<span>{{data.item.name}}</span>
|
|
9
|
+
</el-menu-item>
|
|
10
|
+
<!-- 有子级 -->
|
|
11
|
+
<el-sub-menu :index="data.item.url" v-else-if="data.item.show">
|
|
12
|
+
<template #title>
|
|
13
|
+
<el-icon><component :is="markRaw(data.item.icon as object)"/></el-icon>
|
|
14
|
+
<span>{{data.item.name}}</span>
|
|
15
|
+
</template>
|
|
16
|
+
<usermenuitem v-for="v in data.item.children" :key="v.url" v-bind:item="v"/>
|
|
17
|
+
<!-- <el-menu-item index="1222211" route="/22222">
|
|
18
|
+
<el-icon><component :is="data.item.icon"></component></el-icon>
|
|
19
|
+
<span>222222</span>
|
|
20
|
+
</el-menu-item> -->
|
|
21
|
+
</el-sub-menu>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import { type DefineComponent ,markRaw } from 'vue';
|
|
26
|
+
import usermenuitem from './userMenuItem.vue'
|
|
27
|
+
|
|
28
|
+
interface d{
|
|
29
|
+
item:MenuItem
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface MenuItem {
|
|
33
|
+
name: string
|
|
34
|
+
icon?:DefineComponent<{}, {}, any>;
|
|
35
|
+
// iconname:string
|
|
36
|
+
url:string
|
|
37
|
+
children?: MenuItem[]
|
|
38
|
+
show:boolean
|
|
39
|
+
}
|
|
40
|
+
const data=defineProps<d>()
|
|
41
|
+
|
|
42
|
+
// console.log(data.item);
|
|
43
|
+
// const component = resolveComponent(data.item.iconname)
|
|
44
|
+
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<style scoped>
|
|
48
|
+
|
|
49
|
+
</style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<breadcrumb />
|
|
3
|
+
<div style="padding: 0px 20px;">
|
|
4
|
+
<el-tabs v-model="activeName" @tab-click="handleClick">
|
|
5
|
+
<el-tab-pane label="全部职务" name="first">
|
|
6
|
+
<zsyslist :config="listconfig" module="position">
|
|
7
|
+
<template #headermain>
|
|
8
|
+
<el-button class="main_btn" type="primary"
|
|
9
|
+
@click="view.edit_id = 0n; view.edit_dialog_show = true">新建</el-button>
|
|
10
|
+
</template>
|
|
11
|
+
<template #content>
|
|
12
|
+
<!-- <el-table-column prop="position_id" label="职务ID" width="180" /> -->
|
|
13
|
+
<el-table-column prop="position_title" label="职务名称" width="140" />
|
|
14
|
+
<el-table-column prop="position_notes" label="备注" min-width="180" />
|
|
15
|
+
<el-table-column label="操作" width="100">
|
|
16
|
+
<template #default="{ row }">
|
|
17
|
+
<el-space>
|
|
18
|
+
<el-link type="primary"
|
|
19
|
+
@click="view.edit_id = BigInt(row.position_id); view.edit_dialog_show = true;">修改</el-link>
|
|
20
|
+
<zsys_delbutton :id="BigInt(row.position_id)" :api_url="HttpApiV1.url_position_del" />
|
|
21
|
+
</el-space>
|
|
22
|
+
</template>
|
|
23
|
+
</el-table-column>
|
|
24
|
+
</template>
|
|
25
|
+
</zsyslist>
|
|
26
|
+
</el-tab-pane>
|
|
27
|
+
</el-tabs>
|
|
28
|
+
</div>
|
|
29
|
+
<position_edit_dialog :id="view.edit_id" v-model="view.edit_dialog_show" />
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<script setup lang="ts">
|
|
33
|
+
import { ref, reactive } from 'vue'
|
|
34
|
+
import type { TabsPaneContext } from 'element-plus'
|
|
35
|
+
import breadcrumb from '../main/breadcrumb.vue';
|
|
36
|
+
import zsyslist, { type ListConfig } from '../../components/list/zsyslist.vue';
|
|
37
|
+
import { HttpApiV1 } from '../../core/httpapi/http_api_v1';
|
|
38
|
+
import position_edit_dialog from './position_edit_dialog.vue';
|
|
39
|
+
import zsys_delbutton from '../../components/zsys_delbutton.vue';
|
|
40
|
+
const activeName = ref('first')
|
|
41
|
+
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
42
|
+
console.log(tab, event)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const view = reactive({
|
|
46
|
+
edit_id: 0n,
|
|
47
|
+
edit_dialog_show: false,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
//============列表控件===========================
|
|
51
|
+
const listconfig: ListConfig = reactive({
|
|
52
|
+
ApiUrl: HttpApiV1.url_position_list,
|
|
53
|
+
QuickConditionsGroups: []
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
</script>
|
|
57
|
+
|
|
58
|
+
<style scoped></style>
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
<!-- ReusableDialog.vue -->
|
|
2
|
+
<template>
|
|
3
|
+
<el-dialog v-model="visible" title="职务" :align-center="true" :before-close="handleBeforeClose" @open="open"
|
|
4
|
+
width="550" :draggable="true" :overflow="true" @opened="focus" destroy-on-close>
|
|
5
|
+
<!-- 默认插槽放主要内容 -->
|
|
6
|
+
<el-form @submit.prevent ref="ruleFormRef" :model="form" :rules="rules"
|
|
7
|
+
style="padding-left: 10px;padding-right: 10px;" label-width="auto" v-loading="view.loading"
|
|
8
|
+
:disabled="view.saving">
|
|
9
|
+
<el-form-item label="职务名称" prop="position_title">
|
|
10
|
+
<el-input ref="inputRef" v-model="form.position_title" />
|
|
11
|
+
</el-form-item>
|
|
12
|
+
<el-form-item label="备注" prop="position_notes">
|
|
13
|
+
<el-input v-model="form.position_notes" type="textarea" :rows="4" />
|
|
14
|
+
</el-form-item>
|
|
15
|
+
</el-form>
|
|
16
|
+
|
|
17
|
+
<!-- 底部按钮区插槽 -->
|
|
18
|
+
<template #footer>
|
|
19
|
+
<div style="display: flex;justify-content: right;">
|
|
20
|
+
<el-tooltip v-if="form.position_id==0n" content="保存成功后不关闭窗口">
|
|
21
|
+
<el-checkbox v-model="view.donotClose" label="连续录入" style="margin-right: 10px;" />
|
|
22
|
+
</el-tooltip>
|
|
23
|
+
|
|
24
|
+
<el-tooltip content="快捷键 Alt+S" :show-after="800">
|
|
25
|
+
<el-button type="primary" @click="submitForm(ruleFormRef)" :disabled="view.loading"
|
|
26
|
+
:loading="view.saving">保存(<el-text tag="ins" style="color: white;">S</el-text>)</el-button>
|
|
27
|
+
</el-tooltip>
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<el-button @click="close">取消</el-button>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
</template>
|
|
34
|
+
</el-dialog>
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script setup lang="ts">
|
|
38
|
+
import { ref, watch, reactive, type PropType } from 'vue';
|
|
39
|
+
import { HttpApiV1 as http } from '../../core/httpapi/http_api_v1';
|
|
40
|
+
import { ZSYSMessage } from '../../components/message';
|
|
41
|
+
import type { FormInstance, FormRules, ElInput } from 'element-plus'
|
|
42
|
+
import { useMagicKeys, whenever } from '@vueuse/core'
|
|
43
|
+
import type { HttpApiReturnData } from '../../core/httpapi/http_api_return_data';
|
|
44
|
+
import { zsysEventBus } from '../../core/common/zsys_eventBus';
|
|
45
|
+
const eventBus=zsysEventBus()
|
|
46
|
+
|
|
47
|
+
const inputRef = ref<InstanceType<typeof ElInput> | null>(null)
|
|
48
|
+
const props = defineProps({
|
|
49
|
+
modelValue: { type: Boolean, required: true }, // 控制显示隐藏
|
|
50
|
+
id: { type: BigInt as unknown as PropType<bigint>, required: true }
|
|
51
|
+
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const emit = defineEmits<{
|
|
55
|
+
(e: 'update:modelValue', value: boolean): void;
|
|
56
|
+
// (e: 'confirm'): void;
|
|
57
|
+
// (e: 'close'): void;
|
|
58
|
+
}>();
|
|
59
|
+
|
|
60
|
+
const visible = ref(false);
|
|
61
|
+
|
|
62
|
+
// 同步外部 v-model 变化
|
|
63
|
+
watch(
|
|
64
|
+
() => props.modelValue,
|
|
65
|
+
(val) => {
|
|
66
|
+
visible.value = val;
|
|
67
|
+
},
|
|
68
|
+
{ immediate: true }
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
// 内部状态变化通知外部
|
|
72
|
+
watch(visible, (val) => {
|
|
73
|
+
emit('update:modelValue', val);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const open=()=>{
|
|
77
|
+
view.isnew=(props.id==0n?true:false)
|
|
78
|
+
getData()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const close = () => {
|
|
82
|
+
visible.value = false;
|
|
83
|
+
// emit('close');
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const handleBeforeClose = (done: () => void) => {
|
|
87
|
+
ruleFormRef.value?.clearValidate();
|
|
88
|
+
// 可以在这里添加关闭前的拦截逻辑
|
|
89
|
+
done();
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const view = reactive({
|
|
93
|
+
loading: true,
|
|
94
|
+
saving: false,
|
|
95
|
+
donotClose: false,
|
|
96
|
+
isnew:true
|
|
97
|
+
})
|
|
98
|
+
//^^^^^^^^^^^^^^^上方为对话框功能^^^^^^^^^^^^^^^
|
|
99
|
+
|
|
100
|
+
//===============下方为数据部分===============
|
|
101
|
+
|
|
102
|
+
//=================表单
|
|
103
|
+
const ruleFormRef = ref<FormInstance>()
|
|
104
|
+
const form = ref({
|
|
105
|
+
position_id: props.id as bigint,
|
|
106
|
+
position_title: '',
|
|
107
|
+
position_notes: '',
|
|
108
|
+
})
|
|
109
|
+
const rules = reactive<FormRules<typeof form>>({
|
|
110
|
+
position_title: [
|
|
111
|
+
{ required: true, message: '请输入职务名称', trigger: 'blur' },
|
|
112
|
+
],
|
|
113
|
+
})
|
|
114
|
+
//=================
|
|
115
|
+
|
|
116
|
+
//获取修改数据
|
|
117
|
+
const getData = async () => {
|
|
118
|
+
view.loading = true
|
|
119
|
+
form.value.position_id = props.id
|
|
120
|
+
if (props.id != 0n) {
|
|
121
|
+
view.donotClose=false
|
|
122
|
+
try {
|
|
123
|
+
let res = await http.Post(http.url_position_detail, { id: props.id })
|
|
124
|
+
if (res.IsSuccess) {
|
|
125
|
+
let data = res.data as {
|
|
126
|
+
position_id: bigint
|
|
127
|
+
position_title: string
|
|
128
|
+
position_notes: string
|
|
129
|
+
}
|
|
130
|
+
form.value = data
|
|
131
|
+
}
|
|
132
|
+
} catch (e) {
|
|
133
|
+
console.log(e);
|
|
134
|
+
} finally {
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
form.value.position_title = ''
|
|
139
|
+
form.value.position_notes = ''
|
|
140
|
+
}
|
|
141
|
+
view.loading = false
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//保存
|
|
145
|
+
const saveData = async (): Promise<HttpApiReturnData> => {
|
|
146
|
+
return await http.Post(http.url_position_save, {
|
|
147
|
+
position_id: form.value.position_id,
|
|
148
|
+
position_title: form.value.position_title,
|
|
149
|
+
position_notes: form.value.position_notes
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
//验证表单处理界面并保存
|
|
154
|
+
const submitForm = (formEl: FormInstance | undefined) => {
|
|
155
|
+
if (!formEl) return
|
|
156
|
+
formEl.validate(async (valid) => {
|
|
157
|
+
if (valid) {
|
|
158
|
+
view.saving = true
|
|
159
|
+
try {
|
|
160
|
+
let res = await saveData()
|
|
161
|
+
if (res.IsSuccess) {
|
|
162
|
+
// emit('confirm');
|
|
163
|
+
if (view.donotClose) {
|
|
164
|
+
setTimeout(() => { focus() }, 200);
|
|
165
|
+
} else {
|
|
166
|
+
close();
|
|
167
|
+
}
|
|
168
|
+
ZSYSMessage.ShowSuccess("保存成功")
|
|
169
|
+
eventBus.emit('aud',{module:'position',id:form.value.position_id})
|
|
170
|
+
} else {
|
|
171
|
+
ZSYSMessage.ShowError(res.message)
|
|
172
|
+
}
|
|
173
|
+
} catch (e) {
|
|
174
|
+
|
|
175
|
+
} finally {
|
|
176
|
+
// emit('confirm');
|
|
177
|
+
// close();
|
|
178
|
+
view.saving = false
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const focus = () => {
|
|
186
|
+
inputRef.value?.focus()
|
|
187
|
+
inputRef.value?.select()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
//==========快捷键
|
|
191
|
+
const keys = useMagicKeys()
|
|
192
|
+
|
|
193
|
+
whenever(keys.alt_s, () => {
|
|
194
|
+
if (visible.value) {
|
|
195
|
+
console.log('Alt+S提交')
|
|
196
|
+
submitForm(ruleFormRef.value)
|
|
197
|
+
}
|
|
198
|
+
// 在这里执行你的业务逻辑
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
</script>
|
|
202
|
+
|
|
203
|
+
<style scoped></style>
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<breadcrumb />
|
|
3
|
+
<div style="padding: 0px 20px;">
|
|
4
|
+
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
|
|
5
|
+
<el-tab-pane label="角色列表" name="first">
|
|
6
|
+
<zsyslist :config="listconfig" module="role">
|
|
7
|
+
<template #headermain>
|
|
8
|
+
<el-button class="main_btn" type="primary" @click="newdata">新建</el-button>
|
|
9
|
+
</template>
|
|
10
|
+
<template #content>
|
|
11
|
+
<!-- <el-table-column prop="role_id" label="ID" width="180" /> -->
|
|
12
|
+
<el-table-column prop="role_name" label="角色名称" width="180" />
|
|
13
|
+
<el-table-column prop="event_state" label="状态" width="80">
|
|
14
|
+
<template #default="{ row }">
|
|
15
|
+
<el-tag type="info" v-if="row.role_enable == 0" :disable-transitions="true" size="small">禁用</el-tag>
|
|
16
|
+
<el-tag type="success" v-if="row.role_enable == 1" :disable-transitions="true" size="small">启用</el-tag>
|
|
17
|
+
</template>
|
|
18
|
+
</el-table-column>
|
|
19
|
+
<el-table-column prop="role_notes" label="备注" min-width="180" />
|
|
20
|
+
<el-table-column label="操作" width="130">
|
|
21
|
+
<template #default="{ row }">
|
|
22
|
+
<el-space>
|
|
23
|
+
<el-link type="primary"
|
|
24
|
+
@click="view.edit_id = BigInt(row.role_id); view.edit_dialog_show = true;">查看和编辑</el-link>
|
|
25
|
+
<zsys_delbutton :id="BigInt(row.role_id)" :api_url="HttpApiV1.url_sysrole_del" />
|
|
26
|
+
</el-space>
|
|
27
|
+
</template>
|
|
28
|
+
</el-table-column>
|
|
29
|
+
</template>
|
|
30
|
+
</zsyslist>
|
|
31
|
+
</el-tab-pane>
|
|
32
|
+
</el-tabs>
|
|
33
|
+
</div>
|
|
34
|
+
<role_edit_dialog :id="view.edit_id" v-model="view.edit_dialog_show" />
|
|
35
|
+
</template>
|
|
36
|
+
|
|
37
|
+
<script setup lang="ts">
|
|
38
|
+
import { ref, reactive } from 'vue'
|
|
39
|
+
import type { TabsPaneContext } from 'element-plus'
|
|
40
|
+
import breadcrumb from '../main/breadcrumb.vue';
|
|
41
|
+
import zsyslist, { type ListConfig } from '../../components/list/zsyslist.vue';
|
|
42
|
+
import { HttpApiV1 } from '../../core/httpapi/http_api_v1';
|
|
43
|
+
import zsys_delbutton from '../../components/zsys_delbutton.vue';
|
|
44
|
+
import role_edit_dialog from './role_edit_dialog.vue';
|
|
45
|
+
const activeName = ref('first')
|
|
46
|
+
const handleClick = (tab: TabsPaneContext, event: Event) => {
|
|
47
|
+
console.log(tab, event)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const view = reactive({
|
|
51
|
+
edit_id: BigInt(0),
|
|
52
|
+
edit_dialog_show: false
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const newdata = () => {
|
|
56
|
+
view.edit_id = BigInt(0)
|
|
57
|
+
console.log(view);
|
|
58
|
+
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
view.edit_dialog_show = true
|
|
61
|
+
}, 100)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//============列表控件===========================
|
|
65
|
+
const listconfig: ListConfig = reactive({
|
|
66
|
+
ApiUrl: HttpApiV1.url_sysrole_list,
|
|
67
|
+
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<style scoped></style>
|