Commit 90b3d43bb2d77ac0db222147bbbc68147abef4c1
1 parent
6d135206
角色管理 登录 菜单
Showing
19 changed files
with
930 additions
and
110 deletions
src/api/login/index.ts deleted
100644 → 0
| 1 | -import request from '../request' | |
| 2 | -import { AxiosRequestConfig } from 'axios'; | |
| 3 | - | |
| 4 | -export const login = async ( params: any, data: any ) => { | |
| 5 | - // let res: any = await request.post( '/login', data, {userName: '123', password: 'cmnt123'} ) | |
| 6 | - let res: any = await request({ | |
| 7 | - url: '/login', | |
| 8 | - method: 'post', | |
| 9 | - data: { | |
| 10 | - userName: '123', | |
| 11 | - password: 'cmnt123' | |
| 12 | - } | |
| 13 | - }) | |
| 14 | - // let res: any = await request( {url: '/neighborhood/getList', params:{propertyId: 1, type: 1}, method: 'post' }) | |
| 15 | - return res | |
| 16 | -} | |
| 17 | 0 | \ No newline at end of file |
src/api/user/login/index.ts
| 1 | 1 | import request from '../../request' |
| 2 | -import { AxiosRequestConfig } from 'axios'; | |
| 3 | 2 | |
| 4 | -export const login = async ( params: any, data: any ) => { | |
| 5 | - // let res: any = await request.post( '/login', data, {userName: '123', password: 'cmnt123'} ) | |
| 3 | +/** | |
| 4 | + * @description 登录 | |
| 5 | + * @function login | |
| 6 | + */ | |
| 7 | +export const login = async ( data: any ) => { | |
| 6 | 8 | let res: any = await request({ |
| 7 | 9 | url: '/login', |
| 8 | 10 | method: 'post', |
| 9 | - data: { | |
| 10 | - userName: '123', | |
| 11 | - password: 'cmnt123' | |
| 12 | - } | |
| 11 | + data: data | |
| 12 | + }) | |
| 13 | + return res | |
| 14 | +} | |
| 15 | + | |
| 16 | +/** | |
| 17 | + * @description 权限菜单 | |
| 18 | + * @function menuData | |
| 19 | + */ | |
| 20 | +export const menuData = async () => { | |
| 21 | + let res: any = await request({ | |
| 22 | + url: '/permission/list', | |
| 23 | + method: 'get', | |
| 13 | 24 | }) |
| 14 | - // let res: any = await request( {url: '/neighborhood/getList', params:{propertyId: 1, type: 1}, method: 'post' }) | |
| 15 | 25 | return res |
| 16 | 26 | } |
| 17 | 27 | \ No newline at end of file | ... | ... |
src/api/user/role/index.ts
| 1 | 1 | import request from '../../request' |
| 2 | -import {formDataWrapper} from '@/utils/tool' | |
| 2 | +import {formDataWrapper, deleteEmptyParam} from '@/utils/tool' | |
| 3 | 3 | |
| 4 | 4 | /** |
| 5 | 5 | * @description 角色列表 |
| ... | ... | @@ -9,7 +9,64 @@ export const roleList = async ( params: any ) => { |
| 9 | 9 | let res: any = await request({ |
| 10 | 10 | url: '/role/list', |
| 11 | 11 | method: 'get', |
| 12 | + params: deleteEmptyParam(params) | |
| 13 | + }) | |
| 14 | + return res | |
| 15 | +} | |
| 16 | + | |
| 17 | +/** | |
| 18 | + * @description 角色权限 | |
| 19 | + * @function rolePermission | |
| 20 | + */ | |
| 21 | + export const rolePermission = async ( params: any ) => { | |
| 22 | + let res: any = await request({ | |
| 23 | + url: '/role/user/permission', | |
| 24 | + method: 'get', | |
| 25 | + params: params | |
| 26 | + }) | |
| 27 | + return res | |
| 28 | +} | |
| 29 | + | |
| 30 | +/** | |
| 31 | + * @description 角色用户列表 | |
| 32 | + * @function roleUser | |
| 33 | + */ | |
| 34 | + export const roleUser = async ( params: any ) => { | |
| 35 | + let res: any = await request({ | |
| 36 | + url: '/role/user', | |
| 37 | + method: 'put', | |
| 12 | 38 | params: params |
| 13 | 39 | }) |
| 14 | 40 | return res |
| 41 | +} | |
| 42 | + | |
| 43 | +/** | |
| 44 | + * @description 角色添加修改 | |
| 45 | + * @function roleSave | |
| 46 | + */ | |
| 47 | + export const roleSave = async ( params: any ) => { | |
| 48 | + let res: any = await request({ | |
| 49 | + url: '/role/save', | |
| 50 | + method: 'put', | |
| 51 | + data: params | |
| 52 | + }) | |
| 53 | + return res | |
| 54 | +} | |
| 55 | + | |
| 56 | +/** | |
| 57 | + * @description 修改角色状态 | |
| 58 | + * @function roleStatus | |
| 59 | + */ | |
| 60 | + export const roleStatus = async (data: any) => { | |
| 61 | + let res: any = await request.put( '/role/status', formDataWrapper(data) ) | |
| 62 | + return res | |
| 63 | +} | |
| 64 | + | |
| 65 | +/** | |
| 66 | + * @description 角色关联权限 | |
| 67 | + * @function rolePermissionSave | |
| 68 | + */ | |
| 69 | + export const rolePermissionSave = async (data: any) => { | |
| 70 | + let res: any = await request.post( '/role/permission', data ) | |
| 71 | + return res | |
| 15 | 72 | } |
| 16 | 73 | \ No newline at end of file | ... | ... |
src/layout/menu.vue
| ... | ... | @@ -18,10 +18,15 @@ import { |
| 18 | 18 | let styleData = computed(() => { |
| 19 | 19 | return styles; |
| 20 | 20 | }); |
| 21 | +let menuData = computed(() => { | |
| 22 | + let res = store.family.menuStore().menuList; | |
| 23 | + return res; | |
| 24 | +}); | |
| 21 | 25 | </script> |
| 22 | 26 | |
| 23 | 27 | <template> |
| 24 | 28 | <el-scrollbar wrap-class="scrollbar-wrapper"> |
| 29 | + <!-- {{menuData}} --> | |
| 25 | 30 | <el-menu |
| 26 | 31 | default-active="2" |
| 27 | 32 | :background-color="styleData.menuBg" |
| ... | ... | @@ -32,41 +37,58 @@ let styleData = computed(() => { |
| 32 | 37 | :collapse-transition="false" |
| 33 | 38 | :collapse="store.family.appStore().isCollapse" |
| 34 | 39 | > |
| 35 | - <el-sub-menu index="1"> | |
| 40 | + <el-sub-menu | |
| 41 | + :index="index + ''" | |
| 42 | + v-for="(item, index) in menuData" | |
| 43 | + :key="index" | |
| 44 | + > | |
| 45 | + <template #title> | |
| 46 | + <el-icon><location /></el-icon> | |
| 47 | + <span>{{ item.name }}假菜单</span> | |
| 48 | + </template> | |
| 49 | + <el-menu-item-group v-for="(ele, i) in item.menuList" :key="i"> | |
| 50 | + <el-menu-item :index="ele.path ? ele.path : '/'">{{ | |
| 51 | + ele.name | |
| 52 | + }}</el-menu-item> | |
| 53 | + </el-menu-item-group> | |
| 54 | + </el-sub-menu> | |
| 55 | + | |
| 56 | + <el-sub-menu index="11"> | |
| 36 | 57 | <template #title> |
| 37 | 58 | <el-icon><location /></el-icon> |
| 38 | - <span>物业管理</span> | |
| 59 | + <span>物业管理真菜单可点</span> | |
| 39 | 60 | </template> |
| 40 | 61 | <el-menu-item-group> |
| 41 | 62 | <el-menu-item index="/property">物业列表</el-menu-item> |
| 42 | 63 | </el-menu-item-group> |
| 43 | 64 | </el-sub-menu> |
| 44 | - <el-sub-menu index="2"> | |
| 65 | + <el-sub-menu index="12"> | |
| 45 | 66 | <template #title> |
| 46 | 67 | <el-icon><location /></el-icon> |
| 47 | - <span>小区管理</span> | |
| 68 | + <span>小区管理真菜单可点</span> | |
| 48 | 69 | </template> |
| 49 | 70 | <el-menu-item-group> |
| 50 | 71 | <el-menu-item index="/">小区管理</el-menu-item> |
| 51 | 72 | </el-menu-item-group> |
| 52 | 73 | </el-sub-menu> |
| 53 | - <el-sub-menu index="3"> | |
| 74 | + <el-sub-menu index="13"> | |
| 54 | 75 | <template #title> |
| 55 | 76 | <el-icon><location /></el-icon> |
| 56 | - <span>用户管理</span> | |
| 77 | + <span>用户管理真菜单可点</span> | |
| 57 | 78 | </template> |
| 58 | 79 | <el-menu-item-group> |
| 59 | 80 | <el-menu-item index="/user">用户列表</el-menu-item> |
| 60 | 81 | </el-menu-item-group> |
| 61 | 82 | </el-sub-menu> |
| 62 | - <!-- <el-menu-item index="3" disabled> | |
| 63 | - <el-icon><document /></el-icon> | |
| 64 | - <template #title>Navigator Three</template> | |
| 65 | - </el-menu-item> --> | |
| 66 | - <el-menu-item index="4"> | |
| 67 | - <el-icon><setting /></el-icon> | |
| 68 | - <template #title>Navigator Four</template> | |
| 69 | - </el-menu-item> | |
| 83 | + <el-sub-menu index="14"> | |
| 84 | + <template #title> | |
| 85 | + <el-icon><location /></el-icon> | |
| 86 | + <span>角色管理真菜单可点</span> | |
| 87 | + </template> | |
| 88 | + <el-menu-item-group> | |
| 89 | + <el-menu-item index="/role">角色列表</el-menu-item> | |
| 90 | + </el-menu-item-group> | |
| 91 | + </el-sub-menu> | |
| 70 | 92 | </el-menu> |
| 71 | 93 | </el-scrollbar> |
| 72 | 94 | </template> | ... | ... |
src/pinia/modules/app.ts
| 1 | -const id = 'app' | |
| 1 | +const id: string = 'app' | |
| 2 | 2 | const state = () => ({ |
| 3 | - isCollapse: false, | |
| 4 | - }) | |
| 5 | - const getters = { | |
| 6 | - getCollapseStatus () { | |
| 7 | - return this.isCollapse | |
| 8 | - } | |
| 9 | - } | |
| 10 | - const actions = { | |
| 11 | - toggleCollapse() { | |
| 12 | - this.isCollapse = !this.isCollapse | |
| 13 | - }, | |
| 3 | + isCollapse: false, | |
| 4 | +}) | |
| 5 | +const getters = { | |
| 6 | + getCollapseStatus () { | |
| 7 | + return this.isCollapse | |
| 14 | 8 | } |
| 9 | +} | |
| 10 | +const actions = { | |
| 11 | + toggleCollapse() { | |
| 12 | + this.isCollapse = !this.isCollapse | |
| 13 | + }, | |
| 14 | +} | |
| 15 | 15 | |
| 16 | 16 | export default { |
| 17 | 17 | namespace: true, | ... | ... |
src/pinia/modules/login.ts
| 1 | -const id = 'login' | |
| 2 | -const state = () => ({ | |
| 1 | +interface LoginUser { | |
| 2 | + token: string, | |
| 3 | + organizationId: number, | |
| 4 | + id: number, | |
| 5 | + userName: string | |
| 6 | +} | |
| 7 | +const id: string = 'login' | |
| 8 | +const state: Function = () => ({ | |
| 3 | 9 | token: '', |
| 10 | + organizationId: null, | |
| 11 | + id: null, | |
| 12 | + userName: '' | |
| 4 | 13 | }) |
| 5 | 14 | const getters = { |
| 6 | - // getCollapseStatus () { | |
| 7 | - // return this.isCollapse | |
| 8 | - // } | |
| 9 | 15 | getToken() { |
| 10 | 16 | return this.token |
| 17 | + }, | |
| 18 | + getOid() { | |
| 19 | + return this.organizationId | |
| 20 | + }, | |
| 21 | + getId() { | |
| 22 | + return this.id | |
| 23 | + }, | |
| 24 | + getUserName() { | |
| 25 | + return this.userName | |
| 11 | 26 | } |
| 12 | 27 | } |
| 13 | 28 | const actions = { |
| 14 | - setToken(tokenStr: string) { | |
| 15 | - this.token = tokenStr | |
| 29 | + setUserInfo(obj: LoginUser) { | |
| 30 | + this.token = obj.token | |
| 31 | + this.organizationId = obj.organizationId | |
| 32 | + this.id = obj.id | |
| 33 | + this.userName = obj.userName | |
| 16 | 34 | } |
| 17 | 35 | } |
| 18 | 36 | ... | ... |
src/pinia/modules/menu.ts
| 1 | -const id = 'menu' | |
| 2 | -const state = () => ({ | |
| 3 | - data1: '10086', | |
| 4 | - desc: 'test', | |
| 5 | - }) | |
| 6 | - const getters = { | |
| 7 | - doubleCount() { | |
| 8 | - return this.desc | |
| 9 | - }, | |
| 10 | - doubleCountPlusOne() { | |
| 11 | - return this.data1 | |
| 12 | - } | |
| 1 | +interface MenuItem { | |
| 2 | + menuList: MenuItem[], | |
| 3 | + id: number, | |
| 4 | + name: string, | |
| 5 | + priority: number, | |
| 6 | + url: string | null, | |
| 7 | + selected: boolean, | |
| 8 | + parentId: number | null, | |
| 9 | + keyword: string | null, | |
| 10 | + status: number | |
| 11 | +} | |
| 12 | +const id: string = 'menu' | |
| 13 | +const state: Function = () => ({ | |
| 14 | + menuList: [] | |
| 15 | +}) | |
| 16 | +const getters = { | |
| 17 | + getMenuList() { | |
| 18 | + return this.menuList | |
| 13 | 19 | } |
| 14 | - const actions = { | |
| 15 | - reset() { | |
| 16 | - this.data1 = '10010' | |
| 17 | - }, | |
| 18 | - grown() { | |
| 19 | - this.desc = 'test test' | |
| 20 | - } | |
| 20 | +} | |
| 21 | +const actions = { | |
| 22 | + setMenuList (data: MenuItem[]) { | |
| 23 | + this.menuList = data | |
| 21 | 24 | } |
| 25 | +} | |
| 22 | 26 | |
| 23 | 27 | export default { |
| 24 | 28 | namespace: true, | ... | ... |
src/router/index.ts
| 1 | 1 | import { createRouter, createWebHashHistory } from 'vue-router' |
| 2 | +import Role from "./modules/role" | |
| 2 | 3 | import User from "./modules/user" |
| 3 | 4 | import Resident from "./modules/resident" |
| 4 | 5 | import Property from "./modules/property" |
| ... | ... | @@ -36,6 +37,7 @@ const routes: Array<any> = [ |
| 36 | 37 | }] |
| 37 | 38 | // component: () => import(/* webpackChunkName: "About" */ '@/views/tengxi/about.vue') |
| 38 | 39 | }, |
| 40 | + Role, | |
| 39 | 41 | User, |
| 40 | 42 | Resident, |
| 41 | 43 | Property, |
| ... | ... | @@ -46,16 +48,16 @@ const routes: Array<any> = [ |
| 46 | 48 | name: 'Login', |
| 47 | 49 | component: () => import(/* webpackChunkName: "About" */ '@/views/user/login.vue') |
| 48 | 50 | }, |
| 49 | - // { | |
| 50 | - // path: '/404', | |
| 51 | - // name: 'Error', | |
| 52 | - // component: () => import(/* webpackChunkName: "Error" */ '@/views/error/404.vue'), | |
| 53 | - // hidden: true | |
| 54 | - // }, | |
| 55 | - // { | |
| 56 | - // path: '/:pathMatch(.*)*', | |
| 57 | - // redirect: '/404' | |
| 58 | - // }, | |
| 51 | + { | |
| 52 | + path: '/404', | |
| 53 | + name: 'Error', | |
| 54 | + component: () => import(/* webpackChunkName: "Error" */ '@/views/error/404.vue'), | |
| 55 | + hidden: true | |
| 56 | + }, | |
| 57 | + { | |
| 58 | + path: '/:pathMatch(.*)*', | |
| 59 | + redirect: '/404' | |
| 60 | + }, | |
| 59 | 61 | |
| 60 | 62 | ] |
| 61 | 63 | ... | ... |
src/router/modules/role.ts
0 → 100644
| 1 | +import Layout from '@/layout/enter.vue' | |
| 2 | +const role = { | |
| 3 | + path: '/', | |
| 4 | + component: Layout, | |
| 5 | + name: 'Role', | |
| 6 | + children: [{ | |
| 7 | + path: 'role', | |
| 8 | + name: 'roleList', | |
| 9 | + component: () => import('@/views/role/index.vue'), | |
| 10 | + meta: { title: '角色管理' } | |
| 11 | + }, { | |
| 12 | + path: '/role/user', | |
| 13 | + name: 'roleUser', | |
| 14 | + component: () => import('@/views/role/user.vue'), | |
| 15 | + meta: { title: '角色用户' } | |
| 16 | + }, { | |
| 17 | + path: '/role/edit', | |
| 18 | + name: 'roleEdit', | |
| 19 | + component: () => import('@/views/role/edit.vue'), | |
| 20 | + meta: { title: '角色编辑' } | |
| 21 | + }, { | |
| 22 | + path: '/role/permission', | |
| 23 | + name: 'rolePermission', | |
| 24 | + component: () => import('@/views/role/permission.vue'), | |
| 25 | + meta: { title: '角色权限' } | |
| 26 | + }] | |
| 27 | +} | |
| 28 | + | |
| 29 | +export default role | ... | ... |
src/router/modules/user.ts
| ... | ... | @@ -5,19 +5,19 @@ const user = { |
| 5 | 5 | name: 'User', |
| 6 | 6 | children: [{ |
| 7 | 7 | path: 'user', |
| 8 | - name: 'user', | |
| 8 | + name: 'userList', | |
| 9 | 9 | component: () => import('@/views/user/index.vue'), |
| 10 | 10 | meta: { title: '用户管理' } |
| 11 | 11 | }, { |
| 12 | 12 | path: '/user/role', |
| 13 | - name: 'role', | |
| 13 | + name: 'userRole', | |
| 14 | 14 | component: () => import('@/views/user/role.vue'), |
| 15 | 15 | meta: { title: '用户角色' } |
| 16 | 16 | }, { |
| 17 | 17 | path: '/user/edit', |
| 18 | - name: 'edition', | |
| 18 | + name: 'userEdit', | |
| 19 | 19 | component: () => import('@/views/user/edit.vue'), |
| 20 | - meta: { title: '用户角色' } | |
| 20 | + meta: { title: '用户编辑' } | |
| 21 | 21 | }] |
| 22 | 22 | } |
| 23 | 23 | ... | ... |
src/utils/progress.ts
| ... | ... | @@ -5,6 +5,7 @@ import router from '@/router/index' |
| 5 | 5 | NProgress.configure({ showSpinner: false }) |
| 6 | 6 | |
| 7 | 7 | router.beforeEach((to: any, from: any, next: any) => { |
| 8 | + // if (to.matched.length == 0) { router.push(to.path); } | |
| 8 | 9 | NProgress.start() |
| 9 | 10 | const hasToken = true |
| 10 | 11 | const whiteList = ['/login'] |
| ... | ... | @@ -18,12 +19,12 @@ router.beforeEach((to: any, from: any, next: any) => { |
| 18 | 19 | // next({ path: '/about' }) |
| 19 | 20 | next() |
| 20 | 21 | NProgress.done() |
| 21 | - } else { | |
| 22 | + } else { | |
| 22 | 23 | next() |
| 23 | 24 | NProgress.done() |
| 24 | 25 | } |
| 25 | 26 | } else { |
| 26 | - console.log('hasno t') | |
| 27 | + console.log('hasnot') | |
| 27 | 28 | if (whiteList.indexOf(to.path) !== -1) { |
| 28 | 29 | next() |
| 29 | 30 | } else { | ... | ... |
src/utils/tool.ts
| ... | ... | @@ -166,4 +166,18 @@ export function formDataWrapper (data: any) { |
| 166 | 166 | fd.append(i, data[i]) |
| 167 | 167 | } |
| 168 | 168 | return fd |
| 169 | +} | |
| 170 | + | |
| 171 | +/** | |
| 172 | + * 请求参数删除为null的 | |
| 173 | + * @param {object}} data | |
| 174 | + * @returns {FormData} fd | |
| 175 | + */ | |
| 176 | + export function deleteEmptyParam (params: any) { | |
| 177 | + for (const i in params) { | |
| 178 | + if (!(params[i] + '').trim()) { | |
| 179 | + delete params[i] | |
| 180 | + } | |
| 181 | + } | |
| 182 | + return params | |
| 169 | 183 | } |
| 170 | 184 | \ No newline at end of file | ... | ... |
src/views/dashboard/index.vue
| 1 | 1 | <script setup lang="ts"> |
| 2 | 2 | import {ref} from 'vue' |
| 3 | 3 | import {propertyList } from '@/api/tengxi' |
| 4 | +import router from '@/router' | |
| 4 | 5 | const title = ref(import.meta.env.VITE_APP_TITLE).value |
| 5 | 6 | propertyList().then(res => { |
| 6 | 7 | console.log(res) |
| 7 | 8 | }).catch(error => { |
| 8 | 9 | console.log(error) |
| 9 | 10 | }) |
| 11 | +console.log(router.getRoutes()) | |
| 10 | 12 | </script> |
| 11 | 13 | |
| 12 | 14 | <template> | ... | ... |
src/views/role/edit.vue
0 → 100644
| 1 | +<script setup lang="ts"> | |
| 2 | +import { reactive, ref, getCurrentInstance, onMounted } from "vue"; | |
| 3 | +import { roleSave } from "@/api/user/role"; | |
| 4 | +import { useRoute } from "vue-router"; | |
| 5 | +import type { ElForm } from "element-plus"; | |
| 6 | +const { | |
| 7 | + appContext: { | |
| 8 | + config: { globalProperties }, | |
| 9 | + }, | |
| 10 | +} = getCurrentInstance(); | |
| 11 | +let form = reactive({ | |
| 12 | + data: { | |
| 13 | + roleName: "", | |
| 14 | + code: "", | |
| 15 | + roleDesc: "", | |
| 16 | + }, | |
| 17 | + dataType: "", | |
| 18 | +}); | |
| 19 | +const ruleFormRef = ref<InstanceType<typeof ElForm>>(); | |
| 20 | +// 表单验证规则 | |
| 21 | +const rules = reactive({ | |
| 22 | + roleName: [ | |
| 23 | + { | |
| 24 | + required: true, | |
| 25 | + message: "请填写角色名称", | |
| 26 | + trigger: "blur", | |
| 27 | + }, | |
| 28 | + ], | |
| 29 | + code: [ | |
| 30 | + { | |
| 31 | + required: true, | |
| 32 | + message: "请填写角色代码", | |
| 33 | + trigger: "blur", | |
| 34 | + }, | |
| 35 | + ], | |
| 36 | +}); | |
| 37 | +// 表单重置 | |
| 38 | +const resetForm = (formEl: InstanceType<typeof ElForm> | undefined) => { | |
| 39 | + if (!formEl) return; | |
| 40 | + formEl.resetFields(); | |
| 41 | +}; | |
| 42 | +// 表单提交 | |
| 43 | +const submitForm = (formEl: InstanceType<typeof ElForm> | undefined) => { | |
| 44 | + if (!formEl) return; | |
| 45 | + formEl.validate((valid) => { | |
| 46 | + if (valid) { | |
| 47 | + roleSave(form.data) | |
| 48 | + .then((res) => { | |
| 49 | + if (res) { | |
| 50 | + globalProperties.$message.success("操作成功"); | |
| 51 | + history.go(-1); | |
| 52 | + } | |
| 53 | + }) | |
| 54 | + .catch((error) => { | |
| 55 | + console.log(error); | |
| 56 | + }); | |
| 57 | + } else { | |
| 58 | + globalProperties.$message.error("请检查表单格式"); | |
| 59 | + return false; | |
| 60 | + } | |
| 61 | + }); | |
| 62 | +}; | |
| 63 | +onMounted(() => { | |
| 64 | + form.data = useRoute().query; | |
| 65 | + if (JSON.stringify(form.data) === "{}") { | |
| 66 | + form.dataType = "add"; | |
| 67 | + } else { | |
| 68 | + form.dataType = "edit"; | |
| 69 | + } | |
| 70 | +}); | |
| 71 | +</script> | |
| 72 | + | |
| 73 | +<template> | |
| 74 | + <div class="page-container"> | |
| 75 | + <el-card class="form_card" style="max-width: 1303px"> | |
| 76 | + <h1 v-show="form.dataType === 'add'">新增角色</h1> | |
| 77 | + <h1 v-show="form.dataType === 'edit'">编辑角色</h1> | |
| 78 | + <el-form | |
| 79 | + :inline="true" | |
| 80 | + :model="form.data" | |
| 81 | + :rules="rules" | |
| 82 | + ref="ruleFormRef" | |
| 83 | + label-width="120px" | |
| 84 | + style="display: flex; flex-wrap: wrap; width: 100%" | |
| 85 | + > | |
| 86 | + <el-form-item label="角色名称" prop="roleName" style="width: 100%"> | |
| 87 | + <el-input | |
| 88 | + v-model.trim="form.data.roleName" | |
| 89 | + placeholder="请填写角色名称" | |
| 90 | + maxlength="15" | |
| 91 | + /> | |
| 92 | + </el-form-item> | |
| 93 | + <el-form-item label="角色描述" prop="roleDesc" style="width: 100%"> | |
| 94 | + <el-input | |
| 95 | + v-model.trim="form.data.roleDesc" | |
| 96 | + placeholder="请填写角色描述" | |
| 97 | + maxlength="15" | |
| 98 | + /> | |
| 99 | + </el-form-item> | |
| 100 | + <el-form-item label="角色代码" prop="code" style="width: 100%"> | |
| 101 | + <el-input | |
| 102 | + v-model.trim="form.data.code" | |
| 103 | + placeholder="请填写角色代码" | |
| 104 | + maxlength="15" | |
| 105 | + /> | |
| 106 | + </el-form-item> | |
| 107 | + <el-form-item style="width: 100%"> | |
| 108 | + <el-button type="primary" @click="submitForm(ruleFormRef)" | |
| 109 | + >提交</el-button | |
| 110 | + > | |
| 111 | + <el-button | |
| 112 | + type="info" | |
| 113 | + @click="resetForm(ruleFormRef)" | |
| 114 | + v-show="form.dataType === 'add'" | |
| 115 | + >取消</el-button | |
| 116 | + > | |
| 117 | + </el-form-item> | |
| 118 | + </el-form> | |
| 119 | + </el-card> | |
| 120 | + </div> | |
| 121 | +</template> | ... | ... |
src/views/role/index.vue
0 → 100644
| 1 | +<script setup lang="ts"> | |
| 2 | +import { reactive, ref, onMounted, getCurrentInstance } from "vue"; | |
| 3 | +import { roleList, roleStatus } from "@/api/user/role"; | |
| 4 | +import { parseTime } from "@/utils/tool"; | |
| 5 | +import Pagination from "@/components/Pagination/index.vue"; | |
| 6 | +const { | |
| 7 | + appContext: { | |
| 8 | + config: { globalProperties }, | |
| 9 | + }, | |
| 10 | +} = getCurrentInstance(); | |
| 11 | +interface Form { | |
| 12 | + page: number; | |
| 13 | + pageSize: number; | |
| 14 | + roleName: string; | |
| 15 | +} | |
| 16 | +interface Params { | |
| 17 | + total: number; | |
| 18 | + query: Form; | |
| 19 | +} | |
| 20 | +interface Data { | |
| 21 | + loading: boolean; | |
| 22 | + list: List[] | null; | |
| 23 | + params: Params; | |
| 24 | +} | |
| 25 | +interface List { | |
| 26 | + roleName: string, | |
| 27 | + code: string, | |
| 28 | + roleDesc: string, | |
| 29 | + status: number, | |
| 30 | + createTime: string, | |
| 31 | + updateTime: string, | |
| 32 | + creator: string, | |
| 33 | + creatorId: number, | |
| 34 | + updator: string, | |
| 35 | + updatorId: number, | |
| 36 | + type: number, | |
| 37 | + oId: number | |
| 38 | +} | |
| 39 | +let data: Data = reactive({ | |
| 40 | + list: [], | |
| 41 | + loading: false, | |
| 42 | + params: { | |
| 43 | + total: 0, | |
| 44 | + query: { | |
| 45 | + page: 1, | |
| 46 | + pageSize: 10, | |
| 47 | + roleName: "", | |
| 48 | + }, | |
| 49 | + }, | |
| 50 | +}); | |
| 51 | +// 列表 | |
| 52 | +const getList = async () => { | |
| 53 | + data.loading = true; | |
| 54 | + try { | |
| 55 | + const res = await roleList(data.params.query); | |
| 56 | + data.list = res.data.data.list; | |
| 57 | + data.params.total = res.data.data.total; | |
| 58 | + } catch (e) { | |
| 59 | + console.log(e); | |
| 60 | + } finally { | |
| 61 | + data.loading = false; | |
| 62 | + } | |
| 63 | +}; | |
| 64 | +// 分页 | |
| 65 | +const handlePageChange = (page, size) => { | |
| 66 | + data.params.query.page = page; | |
| 67 | + data.params.query.pageSize = size; | |
| 68 | + getList(); | |
| 69 | +}; | |
| 70 | +// 查询 | |
| 71 | +const handleSearch = () => { | |
| 72 | + getList(); | |
| 73 | +}; | |
| 74 | +// 状态 | |
| 75 | +const handleStatus = async (obj) => { | |
| 76 | + try { | |
| 77 | + const res = await roleStatus({ | |
| 78 | + roleId: obj.id, | |
| 79 | + status: obj.status? 0: 1 | |
| 80 | + }); | |
| 81 | + if(res?.data) { | |
| 82 | + globalProperties.$message.success("操作成功"); | |
| 83 | + getList() | |
| 84 | + } else { | |
| 85 | + globalProperties.$message.error("操作失败"); | |
| 86 | + } | |
| 87 | + } catch (e) { | |
| 88 | + console.log(e); | |
| 89 | + } | |
| 90 | +}; | |
| 91 | +// 状态值 | |
| 92 | +enum statusEnum { | |
| 93 | + "禁用" = 0, | |
| 94 | + "启用", | |
| 95 | +} | |
| 96 | +onMounted(() => { | |
| 97 | + getList(); | |
| 98 | +}); | |
| 99 | +</script> | |
| 100 | + | |
| 101 | +<template> | |
| 102 | + <div class="page-container"> | |
| 103 | + <h1>角色列表</h1> | |
| 104 | + <el-row style="padding-bottom: 20px"> | |
| 105 | + <el-form :inline="true" label-width="70px"> | |
| 106 | + <el-form-item label="角色名"> | |
| 107 | + <el-input | |
| 108 | + v-model.trim="data.params.query.roleName" | |
| 109 | + placeholder="请填写角色名" | |
| 110 | + maxlength="15" | |
| 111 | + @change="handleSearch" | |
| 112 | + /> | |
| 113 | + </el-form-item> | |
| 114 | + <el-form-item> | |
| 115 | + <el-button type="primary" @click="handleSearch">查询</el-button> | |
| 116 | + <el-button type="primary"> | |
| 117 | + <router-link to="/role/edit">添加角色</router-link> | |
| 118 | + </el-button> | |
| 119 | + </el-form-item> | |
| 120 | + </el-form> | |
| 121 | + </el-row> | |
| 122 | + <el-table | |
| 123 | + :data="data.list" | |
| 124 | + style="width: 100%" | |
| 125 | + border | |
| 126 | + v-loading="data.loading" | |
| 127 | + align="center" | |
| 128 | + element-loading-text="拼命加载中" | |
| 129 | + > | |
| 130 | + <el-table-column prop="id" label="ID" align="center"> </el-table-column> | |
| 131 | + <el-table-column prop="roleName" label="角色名称" align="center"> | |
| 132 | + </el-table-column> | |
| 133 | + <el-table-column prop="createTime" label="注册时间" align="center"> | |
| 134 | + <template #default="scope"> | |
| 135 | + {{ parseTime(new Date(scope.row.createTime).getTime()) }} | |
| 136 | + </template> | |
| 137 | + </el-table-column> | |
| 138 | + <el-table-column prop="status" label="状态" align="center"> | |
| 139 | + <template #default="scope"> | |
| 140 | + {{ statusEnum[scope.row.status] }} | |
| 141 | + </template> | |
| 142 | + </el-table-column> | |
| 143 | + <el-table-column label="操作" align="center"> | |
| 144 | + <template #default="scope"> | |
| 145 | + <el-button type="text" | |
| 146 | + ><router-link :to="{ path: '/role/edit', query: scope.row }" | |
| 147 | + >编辑</router-link | |
| 148 | + ></el-button | |
| 149 | + > | |
| 150 | + <el-button type="text" @click="handleStatus(scope.row)">{{ | |
| 151 | + scope.row.status ? "禁用" : "启用" | |
| 152 | + }}</el-button> | |
| 153 | + <el-button type="text" | |
| 154 | + ><router-link :to="{ path: '/role/user', query: {id: scope.row.id} }" | |
| 155 | + >用户</router-link | |
| 156 | + ></el-button | |
| 157 | + > | |
| 158 | + <el-button type="text" | |
| 159 | + ><router-link :to="{ path: '/role/permission', query: {roleId: scope.row.id, roleName: scope.row.roleName} }" | |
| 160 | + >权限</router-link | |
| 161 | + ></el-button | |
| 162 | + > | |
| 163 | + </template> | |
| 164 | + </el-table-column> | |
| 165 | + </el-table> | |
| 166 | + <Pagination | |
| 167 | + :total="data.params.total" | |
| 168 | + :currentPage="data.params.query.page" | |
| 169 | + :pageSize="data.params.query.pageSize" | |
| 170 | + @pageChange="handlePageChange" | |
| 171 | + ></Pagination> | |
| 172 | + </div> | |
| 173 | +</template> | ... | ... |
src/views/role/permission.vue
0 → 100644
| 1 | +<script setup lang="ts"> | |
| 2 | +import { reactive, ref, getCurrentInstance, onMounted } from "vue"; | |
| 3 | +import { rolePermissionSave, rolePermission } from "@/api/user/role"; | |
| 4 | +import { useRoute } from "vue-router"; | |
| 5 | +import type Node from 'element-plus/es/components/tree/src/model/node' | |
| 6 | +import type { ElForm } from "element-plus"; | |
| 7 | +import type { ElTree } from 'element-plus' | |
| 8 | +const { | |
| 9 | + appContext: { | |
| 10 | + config: { globalProperties }, | |
| 11 | + }, | |
| 12 | +} = getCurrentInstance(); | |
| 13 | +let form = reactive({ | |
| 14 | + data: { | |
| 15 | + roleId: useRoute().query.roleId, | |
| 16 | + permissionIds: [], | |
| 17 | + }, | |
| 18 | + permissions: [], | |
| 19 | + defaultPermissions: [], | |
| 20 | + collections: [] | |
| 21 | +}); | |
| 22 | +const ruleFormRef = ref<InstanceType<typeof ElForm>>(); | |
| 23 | +const addTreeTest = ref<InstanceType<typeof ElTree>>() | |
| 24 | +// 表单重置 | |
| 25 | +const resetForm = (formEl: InstanceType<typeof ElForm> | undefined) => { | |
| 26 | + if (!formEl) return; | |
| 27 | + form.defaultPermissions = [] | |
| 28 | + addTreeTest.value!.setCheckedNodes([]) | |
| 29 | + formEl.resetFields(); | |
| 30 | +}; | |
| 31 | +// 表单提交 | |
| 32 | +const submitForm = (formEl: InstanceType<typeof ElForm> | undefined) => { | |
| 33 | + if (!formEl) return; | |
| 34 | + formEl.validate((valid) => { | |
| 35 | + if (valid) { | |
| 36 | + rolePermissionSave(form.data) | |
| 37 | + .then((res) => { | |
| 38 | + if (res) { | |
| 39 | + globalProperties.$message.success("操作成功"); | |
| 40 | + history.go(-1); | |
| 41 | + } | |
| 42 | + }) | |
| 43 | + .catch((error) => { | |
| 44 | + console.log(error); | |
| 45 | + }); | |
| 46 | + } else { | |
| 47 | + globalProperties.$message.error("请检查表单格式"); | |
| 48 | + return false; | |
| 49 | + } | |
| 50 | + }); | |
| 51 | +}; | |
| 52 | +// 获取角色权限 | |
| 53 | +const getPermissions = async (roleId = useRoute().query.roleId) => { | |
| 54 | + try { | |
| 55 | + let res = await rolePermission({ roleId: roleId }); | |
| 56 | + form.permissions = res.data.data; | |
| 57 | + form.defaultPermissions = getCheckedPermissions(res.data.data) | |
| 58 | + } catch (e) { | |
| 59 | + console.log(e); | |
| 60 | + } | |
| 61 | +}; | |
| 62 | +interface Tree { | |
| 63 | + label: string | |
| 64 | + children?: Tree[] | |
| 65 | +} | |
| 66 | +const defaultProps: Tree = { | |
| 67 | + children: "menuList", | |
| 68 | + label: "name", | |
| 69 | +}; | |
| 70 | +const getCheckedPermissions = (menuArray: Tree[]) => { | |
| 71 | + if (menuArray) { | |
| 72 | + menuArray.map((item: Tree) => { | |
| 73 | + if (item.menuList) { | |
| 74 | + getCheckedPermissions(item.menuList); | |
| 75 | + } | |
| 76 | + if (item.selected) { | |
| 77 | + form.collections.push(item.id); | |
| 78 | + } | |
| 79 | + }); | |
| 80 | + } | |
| 81 | + return form.collections; | |
| 82 | +}; | |
| 83 | +const getCheckedRoles = (node: Node, data: Node[]) => { | |
| 84 | + form.data.permissionIds = [...data.checkedKeys, ...data.halfCheckedKeys]; | |
| 85 | +}; | |
| 86 | +onMounted(() => { | |
| 87 | + getPermissions(); | |
| 88 | +}); | |
| 89 | +</script> | |
| 90 | + | |
| 91 | +<template> | |
| 92 | + <div class="page-container"> | |
| 93 | + <el-card class="form_card" style="max-width: 1303px"> | |
| 94 | + <h1 v-show="form.dataType === 'edit'">角色权限</h1> | |
| 95 | + <el-form | |
| 96 | + :inline="true" | |
| 97 | + :model="form.data" | |
| 98 | + ref="ruleFormRef" | |
| 99 | + label-width="120px" | |
| 100 | + style="display: flex; flex-wrap: wrap; width: 100%" | |
| 101 | + > | |
| 102 | + <el-form-item label="角色名称" prop="roleName" style="width: 100%"> | |
| 103 | + <el-input | |
| 104 | + v-model.trim="useRoute().query.roleName" | |
| 105 | + placeholder="请填写角色名称" | |
| 106 | + maxlength="15" | |
| 107 | + disabled | |
| 108 | + /> | |
| 109 | + </el-form-item> | |
| 110 | + <el-form-item label="角色ID" prop="roleDesc" style="width: 100%"> | |
| 111 | + <el-input | |
| 112 | + v-model.trim="useRoute().query.roleId" | |
| 113 | + placeholder="请填写角色ID" | |
| 114 | + maxlength="15" | |
| 115 | + disabled | |
| 116 | + /> | |
| 117 | + </el-form-item> | |
| 118 | + <el-form-item label="角色权限" prop="permissionIds" style="width: 100%"> | |
| 119 | + <el-tree | |
| 120 | + :data="form.permissions" | |
| 121 | + :props="defaultProps" | |
| 122 | + :default-checked-keys="form.defaultPermissions" | |
| 123 | + node-key="id" | |
| 124 | + ref="addTreeTest" | |
| 125 | + show-checkbox | |
| 126 | + @check="getCheckedRoles" | |
| 127 | + /> | |
| 128 | + </el-form-item> | |
| 129 | + <el-form-item style="width: 100%"> | |
| 130 | + <el-button type="primary" @click="submitForm(ruleFormRef)" | |
| 131 | + >提交</el-button | |
| 132 | + > | |
| 133 | + <el-button | |
| 134 | + type="info" | |
| 135 | + @click="resetForm(ruleFormRef)" | |
| 136 | + >置空</el-button | |
| 137 | + > | |
| 138 | + </el-form-item> | |
| 139 | + </el-form> | |
| 140 | + </el-card> | |
| 141 | + </div> | |
| 142 | +</template> | ... | ... |
src/views/role/user.vue
0 → 100644
| 1 | +<script setup lang="ts"> | |
| 2 | +import { reactive, onMounted } from "vue"; | |
| 3 | +import { useRoute } from 'vue-router'; | |
| 4 | +import { roleUser } from "@/api/user/role"; | |
| 5 | +import Pagination from "@/components/Pagination/index.vue"; | |
| 6 | +interface Form { | |
| 7 | + page: number; | |
| 8 | + pageSize: number; | |
| 9 | + roleId: string | number; | |
| 10 | +} | |
| 11 | +interface Params { | |
| 12 | + total: number; | |
| 13 | + query: Form; | |
| 14 | +} | |
| 15 | +interface Data { | |
| 16 | + loading: boolean; | |
| 17 | + list: any[] | null; | |
| 18 | + params: Params; | |
| 19 | +} | |
| 20 | +let data: Data = reactive({ | |
| 21 | + list: [], | |
| 22 | + loading: false, | |
| 23 | + params: { | |
| 24 | + total: 0, | |
| 25 | + query: { | |
| 26 | + page: 1, | |
| 27 | + pageSize: 10, | |
| 28 | + roleId: '', | |
| 29 | + }, | |
| 30 | + }, | |
| 31 | +}); | |
| 32 | +// 状态值 | |
| 33 | +enum statusEnum { | |
| 34 | + "禁用" = 0, | |
| 35 | + "启用", | |
| 36 | +} | |
| 37 | +// 列表 | |
| 38 | +const getList = async () => { | |
| 39 | + data.loading = true; | |
| 40 | + try { | |
| 41 | + const res = await roleUser(data.params.query); | |
| 42 | + data.list = res.data.data.list; | |
| 43 | + data.params.total = res.data.data.total; | |
| 44 | + } catch (e) { | |
| 45 | + console.log(e); | |
| 46 | + } finally { | |
| 47 | + data.loading = false; | |
| 48 | + } | |
| 49 | +}; | |
| 50 | +// 分页 | |
| 51 | +const handlePageChange = (page, size) => { | |
| 52 | + data.params.query.page = page; | |
| 53 | + data.params.query.pageSize = size; | |
| 54 | + getList(); | |
| 55 | +}; | |
| 56 | +onMounted(() => { | |
| 57 | + data.params.query.roleId = useRoute().query.id; | |
| 58 | + getList(); | |
| 59 | +}); | |
| 60 | +</script> | |
| 61 | + | |
| 62 | +<template> | |
| 63 | + <div class="page-container"> | |
| 64 | + <h1>角色用户</h1> | |
| 65 | + <el-table | |
| 66 | + :data="data.list" | |
| 67 | + style="width: 100%" | |
| 68 | + border | |
| 69 | + v-loading="data.loading" | |
| 70 | + align="center" | |
| 71 | + element-loading-text="拼命加载中" | |
| 72 | + > | |
| 73 | + <el-table-column prop="id" label="ID" align="center"> </el-table-column> | |
| 74 | + <el-table-column prop="userName" label="用户名称" align="center"> | |
| 75 | + </el-table-column> | |
| 76 | + <el-table-column prop="cellphone" label="手机号码" align="center"> | |
| 77 | + </el-table-column> | |
| 78 | + <el-table-column prop="status" label="状态" align="center"> | |
| 79 | + <template #default="scope"> | |
| 80 | + {{ statusEnum[scope.row.status] }} | |
| 81 | + </template> | |
| 82 | + </el-table-column> | |
| 83 | + </el-table> | |
| 84 | + <Pagination | |
| 85 | + :total="data.params.total" | |
| 86 | + :currentPage="data.params.query.page" | |
| 87 | + :pageSize="data.params.query.pageSize" | |
| 88 | + @pageChange="handlePageChange" | |
| 89 | + ></Pagination> | |
| 90 | + </div> | |
| 91 | +</template> | ... | ... |
src/views/user/index.vue
| ... | ... | @@ -12,7 +12,7 @@ interface Form { |
| 12 | 12 | page: number; |
| 13 | 13 | pageSize: number; |
| 14 | 14 | userName?: string; |
| 15 | - cellPhone?: string; | |
| 15 | + cellphone?: string; | |
| 16 | 16 | } |
| 17 | 17 | interface Params { |
| 18 | 18 | total: number; |
| ... | ... | @@ -32,7 +32,7 @@ let data = reactive({ |
| 32 | 32 | page: 1, |
| 33 | 33 | pageSize: 10, |
| 34 | 34 | userName: "", |
| 35 | - cellPhone: "", | |
| 35 | + cellphone: "", | |
| 36 | 36 | }, |
| 37 | 37 | }, |
| 38 | 38 | }); |
| ... | ... | @@ -108,7 +108,7 @@ onMounted(() => { |
| 108 | 108 | </el-form-item> |
| 109 | 109 | <el-form-item label="用户名"> |
| 110 | 110 | <el-input |
| 111 | - v-model.trim="data.params.query.cellPhone" | |
| 111 | + v-model.trim="data.params.query.cellphone" | |
| 112 | 112 | placeholder="请填写用户手机号" |
| 113 | 113 | maxlength="15" |
| 114 | 114 | @change="handleSearch" |
| ... | ... | @@ -159,7 +159,7 @@ onMounted(() => { |
| 159 | 159 | >初始密码</el-button |
| 160 | 160 | > |
| 161 | 161 | <el-button type="text" |
| 162 | - ><router-link :to="{ path: '/user/role', query: scope.row }" | |
| 162 | + ><router-link :to="{ path: '/user/role', query: {id: scope.row.id}}" | |
| 163 | 163 | >角色</router-link |
| 164 | 164 | ></el-button |
| 165 | 165 | > | ... | ... |
src/views/user/login.vue
| 1 | 1 | <script setup lang="ts"> |
| 2 | -import { login } from "@/api/user/login"; | |
| 3 | -import * as all from "vue-router"; | |
| 2 | +import { login, menuData } from "@/api/user/login"; | |
| 4 | 3 | import * as store from "@/pinia/index"; |
| 5 | -login().then((res) => { | |
| 6 | - console.log(res); | |
| 7 | - console.log(store.family.loginStore().token); | |
| 8 | - if (res) { | |
| 9 | - store.family.loginStore().setToken(res.data.data.token); | |
| 10 | - } | |
| 4 | +import router from "@/router/index"; | |
| 5 | +import { reactive, ref, getCurrentInstance } from "vue"; | |
| 6 | +import type { ElForm } from "element-plus"; | |
| 7 | +import { UserFilled, Lock } from "@element-plus/icons-vue"; | |
| 8 | +const { | |
| 9 | + appContext: { | |
| 10 | + config: { globalProperties }, | |
| 11 | + }, | |
| 12 | +} = getCurrentInstance(); | |
| 13 | +interface Login { | |
| 14 | + userName: string; | |
| 15 | + password: string; | |
| 16 | +} | |
| 17 | +// 登录表单数据 | |
| 18 | +const loginForm: Login = reactive({ | |
| 19 | + userName: "123", | |
| 20 | + password: "cmnt123", | |
| 11 | 21 | }); |
| 22 | +// 登录框上面标题 | |
| 23 | +const title = ref(import.meta.env.VITE_APP_TITLE).value; | |
| 24 | +const ruleFormRef = ref<InstanceType<typeof ElForm>>(); | |
| 25 | +// 表单提交 | |
| 26 | +const submitForm = (formEl: InstanceType<typeof ElForm> | undefined) => { | |
| 27 | + if (!formEl) return; | |
| 28 | + formEl.validate((valid) => { | |
| 29 | + if (valid) { | |
| 30 | + login(loginForm).then((res) => { | |
| 31 | + if (res?.data) { | |
| 32 | + globalProperties.$message.success("登录成功"); | |
| 33 | + store.family.loginStore().setUserInfo(res.data.data); | |
| 34 | + getMenu().then((res) => { | |
| 35 | + setTimeout(() => { | |
| 36 | + router.push({ path: "/" }); | |
| 37 | + }, 1000); | |
| 38 | + }); | |
| 39 | + } | |
| 40 | + }); | |
| 41 | + } else { | |
| 42 | + console.log("error"); | |
| 43 | + } | |
| 44 | + }); | |
| 45 | +}; | |
| 46 | +// 获取权限菜单 | |
| 47 | +const getMenu = async () => { | |
| 48 | + try { | |
| 49 | + let res = await menuData(); | |
| 50 | + store.family.menuStore().setMenuList(res.data.data); | |
| 51 | + } catch (e) { | |
| 52 | + console.log(e); | |
| 53 | + } | |
| 54 | +}; | |
| 12 | 55 | </script> |
| 13 | 56 | |
| 14 | 57 | <template> |
| 15 | - <p>Login</p> | |
| 16 | - <router-link :to="{ path: '/' }" | |
| 17 | - >回首页</router-link | |
| 18 | - > | |
| 58 | + <div class="login-container"> | |
| 59 | + <el-form | |
| 60 | + :inline="true" | |
| 61 | + :model="loginForm" | |
| 62 | + ref="ruleFormRef" | |
| 63 | + auto-complete="on" | |
| 64 | + label-position="left" | |
| 65 | + label-width="120px" | |
| 66 | + class="login-form" | |
| 67 | + > | |
| 68 | + <div class="title-container"> | |
| 69 | + <h3 class="title">{{ title }}</h3> | |
| 70 | + </div> | |
| 71 | + | |
| 72 | + <el-row> | |
| 73 | + <el-form-item prop="userName" style="width: 100%"> | |
| 74 | + <el-input | |
| 75 | + v-model.trim="loginForm.userName" | |
| 76 | + placeholder="请填写用户名" | |
| 77 | + maxlength="15" | |
| 78 | + :validate-event="false" | |
| 79 | + tabindex="1" | |
| 80 | + type="text" | |
| 81 | + auto-complete="off" | |
| 82 | + clearable | |
| 83 | + :prefix-icon="UserFilled" | |
| 84 | + /> | |
| 85 | + </el-form-item> | |
| 86 | + </el-row> | |
| 87 | + <el-form-item prop="password" style="width: 100%"> | |
| 88 | + <el-input | |
| 89 | + v-model.trim="loginForm.password" | |
| 90 | + placeholder="请填写密码" | |
| 91 | + :validate-event="false" | |
| 92 | + maxlength="15" | |
| 93 | + tabindex="2" | |
| 94 | + :show-password="true" | |
| 95 | + clearable | |
| 96 | + type="password" | |
| 97 | + auto-complete="off" | |
| 98 | + :prefix-icon="Lock" | |
| 99 | + @keyup.enter.native="submitForm(ruleFormRef)" | |
| 100 | + > | |
| 101 | + </el-input> | |
| 102 | + </el-form-item> | |
| 103 | + <el-form-item style="width: 100%"> | |
| 104 | + <el-button | |
| 105 | + type="primary" | |
| 106 | + @click="submitForm(ruleFormRef)" | |
| 107 | + style="width: 100%" | |
| 108 | + >登录</el-button | |
| 109 | + > | |
| 110 | + </el-form-item> | |
| 111 | + </el-form> | |
| 112 | + </div> | |
| 19 | 113 | </template> |
| 20 | 114 | |
| 21 | -<style lang="scss" scoped></style> | |
| 115 | +<style lang="scss"> | |
| 116 | +$bg: #283443; | |
| 117 | +$dark_gray: #889aa4; | |
| 118 | +$light_gray: #fff; | |
| 119 | +$cursor: #fff; | |
| 120 | +@supports (-webkit-mask: none) and (not (cater-color: $cursor)) { | |
| 121 | + .login-container .el-input input { | |
| 122 | + color: $cursor; | |
| 123 | + } | |
| 124 | +} | |
| 125 | +.login { | |
| 126 | + &-container { | |
| 127 | + min-height: 100%; | |
| 128 | + text-align: center; | |
| 129 | + background-color: $bg; | |
| 130 | + .el-input { | |
| 131 | + input { | |
| 132 | + background: transparent; | |
| 133 | + border: 0px; | |
| 134 | + -webkit-appearance: none; | |
| 135 | + border-radius: 0px; | |
| 136 | + color: $light_gray; | |
| 137 | + height: 47px; | |
| 138 | + caret-color: $cursor; | |
| 139 | + &:-webkit-autofill { | |
| 140 | + box-shadow: 0 0 0px 1000px $bg inset !important; | |
| 141 | + -webkit-text-fill-color: $cursor !important; | |
| 142 | + } | |
| 143 | + } | |
| 144 | + } | |
| 145 | + .el-form-item { | |
| 146 | + border: 1px solid rgba(255, 255, 255, 0.1); | |
| 147 | + background: rgba(0, 0, 0, 0.1); | |
| 148 | + border-radius: 5px; | |
| 149 | + color: #454545; | |
| 150 | + } | |
| 151 | + } | |
| 152 | + &-form { | |
| 153 | + position: relative; | |
| 154 | + width: 520px; | |
| 155 | + max-width: 100%; | |
| 156 | + padding: 160px 35px 0; | |
| 157 | + margin: 0 auto; | |
| 158 | + overflow: hidden; | |
| 159 | + } | |
| 160 | +} | |
| 161 | +.title-container { | |
| 162 | + position: relative; | |
| 163 | + .title { | |
| 164 | + font-size: 26px; | |
| 165 | + color: $light_gray; | |
| 166 | + margin: 0px auto 40px auto; | |
| 167 | + text-align: center; | |
| 168 | + font-weight: bold; | |
| 169 | + } | |
| 170 | +} | |
| 171 | +</style> | ... | ... |