xy 2 years ago
parent 57e0e61036
commit f4897c4ea2

@ -1,5 +1,5 @@
<template>
<div>
<div style="position: sticky;top: 0;z-index: 1002;">
<header class="navbar">
<div class="container">
<!-- <button v-show="$store.state.app.device === 'mobile'" :aria-expanded="isShowMenuMobile" class="navbar-toggler" @click="isShowMenuMobile = !isShowMenuMobile">-->
@ -18,9 +18,9 @@
<svg-icon icon-class="modules" class-name="modules__toggler" @click="isShowMenuMobile = !isShowMenuMobile" />
<el-menu
id="navbar-menu"
:text-color="variables.menuText"
:background-color="variables.menuBg"
:active-text-color="variables.menuActiveText"
text-color="hsla(0,0%,100%,.7)"
background-color="var(--theme-color)"
active-text-color="#fff"
:default-active="activeMenu"
mode="horizontal"
>
@ -99,9 +99,9 @@
<el-menu
unique-opened
style="width: 100%;padding: 0 6px;"
:text-color="variables.menuText"
:background-color="variables.menuBg"
:active-text-color="variables.menuActiveText"
text-color="hsla(0,0%,100%,.7)"
background-color="transparent"
active-text-color="#fff"
:default-active="activeMenu"
@select="isShowMenuMobile = false"
>
@ -184,6 +184,7 @@ export default {
this.isIframeSidebarOpened = Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true
} else {
this.$store.commit('app/TOGGLE_SIDEBAR')
this.isIframeSidebarOpened = this.$store.getters.sidebar.opened
}
},
handleFullscreen() {

@ -20,7 +20,7 @@ export default {
if (icon.includes('el-icon')) {
vnodes.push(<i class={[icon, 'sub-el-icon']} />)
} else {
vnodes.push(<svg-icon icon-class={icon} class="sub-el-icon" />)
vnodes.push(<svg-icon icon-class={icon} class='sub-el-icon' />)
}
}
@ -35,9 +35,9 @@ export default {
<style scoped>
.sub-el-icon {
color: currentColor;
font-size: 16px;
width: 16px;
height: 16px;
font-size: 15px;
width: 15px;
height: 15px;
margin-right: 5px;
}
</style>

@ -1,5 +1,5 @@
<template>
<div :class="{'has-logo':showLogo}">
<div :class="{'has-logo':false}">
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
@ -7,7 +7,7 @@
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
active-text-color="var(--theme-color)"
:collapse-transition="false"
mode="vertical"
>
@ -20,7 +20,7 @@
<script>
import { mapGetters } from 'vuex'
import SidebarItem from './SidebarItem'
import variables from '@/styles/sidebar-variables.scss'
import variables from '@/styles/variables.scss'
export default {
components: { SidebarItem },
@ -55,3 +55,9 @@ export default {
}
}
</script>
<style lang="scss" scoped>
@import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";
@import '~@/styles/sidebar.scss';
</style>

@ -3,7 +3,6 @@
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<navbar />
<div class="main-container">
<div :class="{'fixed-header':fixedHeader}" />
<app-main />
</div>
</div>
@ -50,7 +49,6 @@ export default {
<style lang="scss" scoped>
@import "~@/styles/mixin.scss";
@import "~@/styles/variables.scss";
.app-wrapper {
@include clearfix;
@ -72,15 +70,6 @@ export default {
z-index: 999;
}
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - #{$sideBarWidth});
transition: width 0.28s;
}
.hideSidebar .fixed-header {
width: calc(100% - 54px)
}

@ -27,7 +27,7 @@ if (process.env.NODE_ENV === 'production') {
const { mockXHR } = require('../mock')
mockXHR()
}
//moment
// moment
import moment from 'moment'
Vue.prototype.$moment = moment
// set ElementUI lang to EN
@ -46,6 +46,9 @@ Vue.use(VxeColumn)
Vue.use(VxeColgroup)
Vue.use(VxeModal)
Vue.use(VxeToolbar)
import domZIndex from 'dom-zindex'
domZIndex.setCurrent(2000)
// treeselect
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import Treeselect from '@riophae/vue-treeselect'
@ -66,7 +69,9 @@ Vue.component('CardContainer', CardContainer)
// exec: true,
// });
Vue.config.productionTip = false
Vue.config.errorHandler = (err, vm, info) => {
console.error(info, err)
}
new Vue({
el: '#app',
router,

@ -42,9 +42,9 @@ const mutations = {
const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
const { username, password, pretend_user } = userInfo
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
login({ username: username.trim(), password: password, pretend_user }).then(response => {
console.log(response)
const { access_token, expires_in } = response
commit('SET_TOKEN', access_token)
@ -63,7 +63,7 @@ const actions = {
const { name, avatar, id, role, department } = response
commit('SET_DEPARTMENT',department)
commit('SET_DEPARTMENT', department)
commit('SET_NAME', name)
commit('SET_AVATAR', avatar)
commit('SET_ADMIN_ID', id)

@ -3,6 +3,7 @@
@import './transition.scss';
@import './element-ui.scss';
body {
height: 100%;
-moz-osx-font-smoothing: grayscale;
@ -25,8 +26,8 @@ html {
}
*,
*:before,
*:after {
*::before,
*::after {
box-sizing: inherit;
}

@ -151,13 +151,12 @@
}
}
@import "variables.scss";
#navbar-menu {
.sidebar-item {
display: inline-block;
.el-menu-item:hover ,.el-submenu__title:hover {
color: $menuActiveText !important;
color: #fff !important;
background-color: transparent !important;
}
}

@ -1,27 +0,0 @@
// sidebar
$menuText:#606266;
$menuActiveText:#303133;
$subMenuActiveText:#338de3; //https://github.com/ElemeFE/element/issues/12951
$menuBg:#ffffff;
$menuHover:#e0f2ff;
$menuActiveBg:#dcf3ff;
$subMenuBg:#ffffff;
$subMenuHover:#edf6ff;
$submenuActiveBg:#dcf3ff;
$sideBarWidth: 210px;
// the :export directive is the magic sauce for webpack
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
:export {
menuText: $menuText;
menuActiveText: $menuActiveText;
subMenuActiveText: $subMenuActiveText;
menuBg: $menuBg;
menuHover: $menuHover;
subMenuBg: $subMenuBg;
subMenuHover: $subMenuHover;
sideBarWidth: $sideBarWidth;
}

@ -1,17 +1,14 @@
// sidebar
:root {
--theme-color: #5898f2;
}
$menuText: hsla(0,0%,100%,.7);
$subMenuText: #333;
$menuActiveText: #fff;
$subMenuActiveText:#f4f4f5;
$menuText:#606266;
$menuActiveText:#303133;
$subMenuActiveText:#338de3;
$menuBg: transparent;
$menuHover: transparent;
$menuBg:#ffffff;
$menuHover:#e0f2ff;
$menuActiveBg:#dcf3ff;
$subMenuBg: #fff;
$subMenuHover: #001528;
$subMenuBg:#ffffff;
$subMenuHover:#edf6ff;
$submenuActiveBg:#dcf3ff;
$sideBarWidth: 210px;
$navBarHeight: 200px;

@ -5,9 +5,16 @@
<!-- linesColor="#ffffff" :linesWidth="1" :lineLinked="true" :lineOpacity="0.4" :linesDistance="150" :moveSpeed="3"-->
<!-- :hoverEffect="true" hoverMode="grab" :clickEffect="true" clickMode="push"> </vue-particles>-->
<!-- <img class="title-img" src="~@/assets/login/title.png" alt="">-->
<el-form size="small" ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
label-position="left">
<!-- <img class="title-img" src="~@/assets/login/title.png" alt="">-->
<el-form
ref="loginForm"
size="small"
:model="loginForm"
:rules="loginRules"
class="login-form"
auto-complete="on"
label-position="left"
>
<div class="title-container">
<h3 class="title">欢迎登录</h3>
@ -16,44 +23,63 @@
<el-form-item prop="username">
<div class="form-item">
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<el-input ref="username" v-model="loginForm.username" placeholder="请输入登录名" name="username" type="text"
tabindex="1" auto-complete="on" />
<svg-icon icon-class="user" />
</span>
<input v-model="loginForm.pretend_user" style="display: none;" />
<el-input
ref="username"
v-model="loginForm.username"
placeholder="请输入登录名"
name="username"
type="text"
tabindex="1"
auto-complete="on"
/>
</div>
</el-form-item>
<el-form-item prop="password">
<div class="form-item">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType"
placeholder="请输入密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" />
<svg-icon icon-class="password" />
</span>
<el-input
:key="passwordType"
ref="password"
v-model="loginForm.password"
:type="passwordType"
placeholder="请输入密码"
name="password"
tabindex="2"
auto-complete="on"
@keyup.enter.native="handleLogin"
/>
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
</span>
</div>
</el-form-item>
<!-- <el-form-item prop="code">-->
<!-- <div class="form-item">-->
<!-- <span class="svg-container">-->
<!-- <svg-icon icon-class="message" />-->
<!-- </span>-->
<!-- <el-input ref="username" v-model="loginForm.code" placeholder="请输入验证码" name="username" type="text"-->
<!-- tabindex="1" auto-complete="on" />-->
<!-- <el-button class="msg-btn" :loading="msgLoading" type="primary" size="small" :disabled="isVer" @click="sendSms">{{ isVer ? (''+verTime+'') : '' }}</el-button>-->
<!-- </div>-->
<!-- </el-form-item>-->
<el-button :loading="loading" type="primary" class="login-btn"
@click.native.prevent="handleLogin">登录</el-button>
<!-- <el-form-item prop="code">-->
<!-- <div class="form-item">-->
<!-- <span class="svg-container">-->
<!-- <svg-icon icon-class="message" />-->
<!-- </span>-->
<!-- <el-input ref="username" v-model="loginForm.code" placeholder="请输入验证码" name="username" type="text"-->
<!-- tabindex="1" auto-complete="on" />-->
<!-- <el-button class="msg-btn" :loading="msgLoading" type="primary" size="small" :disabled="isVer" @click="sendSms">{{ isVer ? (''+verTime+'') : '' }}</el-button>-->
<!-- </div>-->
<!-- </el-form-item>-->
<el-button
:loading="loading"
type="primary"
class="login-btn"
@click.native.prevent="handleLogin"
>登录</el-button>
</el-form>
<footer class="copyright">
版权所有{{ copyright }}
</footer>
@ -61,10 +87,6 @@
</template>
<script>
import {
validUsername
} from '@/utils/validate'
import { login, getInfo } from "@/api/me";
const defaultSettings = require('../../../src/settings.js')
export default {
name: 'Login',
@ -77,23 +99,24 @@ export default {
}
}
return {
title: "",
title: '',
loginForm: {
username: '',
password: '',
//code: ''
pretend_user: ''
// code: ''
},
loginRules: {
username: [{
required: true,
trigger: 'blur',
message: "请输入用户名"
message: '请输入用户名'
}],
password: [{
required: true,
trigger: 'blur',
validator: validatePassword
}],
}]
// code: [
// {
// required: true,
@ -117,8 +140,8 @@ export default {
verTime: 60,
isVer: false,
temp: {
mobile: "",
token: ""
mobile: '',
token: ''
}
}
},
@ -131,35 +154,35 @@ export default {
}
},
created() {
this.title = defaultSettings.title;
this.copyright = defaultSettings.copyright;
this.title = defaultSettings.title
this.copyright = defaultSettings.copyright
},
methods: {
async sendSms () {
if (this.isVer) return;
async sendSms() {
if (this.isVer) return
if (this.loginForm.username) {
this.msgLoading = true;
this.msgLoading = true
try {
await sendSms({
username: this.loginForm.username
})
this.isVer = true;
this.verTime = 60;
this.isVer = true
this.verTime = 60
this.$message({
message: '验证码已发送',
type:'success'
type: 'success'
})
let timer = setInterval(() => {
this.verTime--;
const timer = setInterval(() => {
this.verTime--
if (this.verTime <= 0) {
this.isVer = false;
clearInterval(timer);
this.isVer = false
clearInterval(timer)
}
}, 1000);
this.msgLoading = false;
}, 1000)
this.msgLoading = false
} catch (e) {
this.msgLoading = false;
this.msgLoading = false
}
} else {
this.$message({
@ -179,14 +202,12 @@ export default {
this.$refs.password.focus()
})
},
//
//
async handleLogin() {
this.$refs.loginForm.validate(async(valid) => {
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({
path: this.redirect || '/'
})

@ -1,6 +1,7 @@
<template>
<el-card id="todo-card" class="box-card" shadow="hover">
<div slot="header" class="clearfix">
<el-button @click="test">aa</el-button>
<SvgIcon style="color: var(--theme-color);width: 22px;height: 22px;" icon-class="notice" />
<span
style="padding-left: 15px"
@ -25,7 +26,7 @@
:show-header="false"
:height="tableHeight"
:loading="loading"
:data="/^\/system/.test(this.$route.path) ? example : list"
:data="list"
>
<el-table-column type="index" width="46" align="center" />
<el-table-column
@ -41,7 +42,7 @@
/>
<el-table-column label="操作" header-align="center" min-width="122" fixed="right">
<template #default="{ row }">
<el-button size="mini" style="padding: 5px 10px;" @click="show(row)"></el-button>
<el-button size="mini" style="padding: 5px 10px;" @click="read(row)"></el-button>
<el-button size="mini" type="primary" style="padding: 5px 10px;" @click="handle(row)"></el-button>
</template>
</el-table-column>
@ -51,6 +52,7 @@
<vxe-modal
v-model="isShowModal"
:z-index="zIndex"
transfer
show-zoom
:fullscreen="$store.getters.device === 'mobile'"
@ -65,6 +67,7 @@
</template>
<script>
import { PopupManager } from 'element-ui/lib/utils/popup'
import SvgIcon from '@/components/SvgIcon/index.vue'
import ElementResize from 'element-resize-detector'
import axios from 'axios'
@ -85,22 +88,9 @@ export default {
},
data() {
return {
zIndex: PopupManager.nextZIndex(),
isShowModal: false,
modalUrl: '/',
example: [
{
type: 1,
content: '示例1',
created_at: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
read_count: true
},
{
type: 2,
content: '示例2',
created_at: this.$moment().format('YYYY-MM-DD HH:mm:ss'),
read_count: false
}
],
select: {
page: 1,
page_size: 10
@ -121,15 +111,31 @@ export default {
},
{
title: '内容',
key: 'content',
key: 'data',
align: 'left',
'show-overflow-tooltip': true,
minWidth: 200
minWidth: 200,
formatter: (row, column, cellValue) => {
try {
const data = JSON.parse(cellValue)
return data.title
} catch (err) {
console.error(err)
return ''
}
}
}
]
}
},
computed: {},
watch: {
isShowModal(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
},
created() {
this.getNotices()
},
@ -137,21 +143,20 @@ export default {
this.init()
},
methods: {
test() {
console.log(this.list.abc.ddd)
},
async getNotices() {
if (/^\/system/.test(this.$route.path)) return
try {
this.loading = true
const res = await axios.get(`${process.env.VUE_APP_BASE_API}/api/ht/notice/index`, {
const res = await axios.get(`${process.env.VUE_APP_BASE_API}/api/notification/todo`, {
headers: {
'Authorization': `Bearer ${getToken()}`
},
params: this.select
})
if (res.status === 200) {
this.list = res.data.data?.data?.map(i => ({
...i,
module: 'ht'
}))
this.list = res.data.data?.data
}
this.loading = false
} catch (err) {
@ -174,17 +179,40 @@ export default {
})
},
show(row) {
if (row.module === 'ht') {
this.modalUrl = `/${row.module}?auth_token=${window.encodeURIComponent(getToken())}&module_name=${row.module}&to=${window.encodeURIComponent('/contract/contractList?keyword=' + (/\[(.*?)]/.exec(row.title) ? /\[(.*?)]/.exec(row.title)[1] : ''))}`
async read(row) {
try {
this.loading = true
const res = await axios.get(`${process.env.VUE_APP_BASE_API}/api/notification/read`, {
headers: {
'Authorization': `Bearer ${getToken()}`
},
params: {
id: row.id
}
})
if (res.status === 200) {
await this.getNotices()
}
this.loading = false
} catch (err) {
console.error(err)
this.loading = false
}
this.isShowModal = true
},
handle(row) {
if (row.module === 'ht') {
this.modalUrl = `/${row.module}?auth_token=${window.encodeURIComponent(getToken())}&module_name=${row.module}&to=${window.encodeURIComponent('/contract/contractList?keyword=' + (/\[(.*?)]/.exec(row.title) ? /\[(.*?)]/.exec(row.title)[1] : ''))}`
try {
const data = JSON.parse(row.data)
if (data.from === 'ht') {
this.modalUrl = `/${data.from}?auth_token=${window.encodeURIComponent(getToken())}&module_name=${data.from}&to=${window.encodeURIComponent('/contract/contractList?keyword=' + (/\[(.*?)]/.exec(data.title) ? /\[(.*?)]/.exec(data.title)[1] : ''))}`
} else if (data.from === 'oa') {
this.modalUrl = `/${data.from}?auth_token=${window.encodeURIComponent(getToken())}&module_name=${data.from}&to=${window.encodeURIComponent(`/flow/create?flow_id=${data.other?.flow_id}`)}`
}
console.log(this.modalUrl)
this.isShowModal = true
} catch (err) {
this.$message.warning('未找到流程')
console.error(err)
}
this.isShowModal = true
}
}
}

@ -26,7 +26,7 @@
<el-form-item label="分管领导" prop="manager_id">
<user-picker width="100%" v-model="form.manager_id"></user-picker>
</el-form-item>
<el-form-item label="主要领导" prop="leader_id">
<el-form-item label="主要负责人" prop="leader_id">
<user-picker width="100%" v-model="form.leader_id"></user-picker>
</el-form-item>
<el-form-item label="排序" prop="sortnumber">

@ -26,6 +26,14 @@
<el-form-item label="手机号" prop="mobile">
<el-input v-model="form.mobile" clearable />
</el-form-item>
<el-form-item label="部门" prop="department_id">
<el-select v-model="form.department_id" clearable>
<el-option v-for="item in departments" :key="item.id" :value="item.id" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="职位" prop="position">
<el-input v-model="form.position" clearable />
</el-form-item>
<el-form-item label="排序" prop="sortnumber">
<el-input-number v-model="form.sortnumber" controls-position="right" :precision="0" />
</el-form-item>
@ -46,6 +54,10 @@ export default {
type: Boolean,
default: false,
required: true
},
departments: {
type: Array,
default: () => []
}
},
data() {
@ -57,6 +69,8 @@ export default {
password: '',
attendance_closed: 0,
mobile: '',
department_id: '',
position: '',
sortnumber: 0
},
rules: {

@ -27,7 +27,7 @@
<vxe-table
ref="menuTable"
style="margin-top: 10px;"
max-height="600"
:max-height="400"
keep-source
:row-config="{ useKey: 'id', isHover: true }"
:column-config="{ resizable: true }"
@ -136,12 +136,19 @@
<p class="total" type="primary"> {{ roleTotal }} 条数据</p>
</el-tab-pane>
<el-tab-pane label="用户授权" name="permission">
<vxe-toolbar>
<template #buttons>
<el-input v-model="userSelect.keyword" size="small" style="margin-right: 10px;max-width: 200px;" placehodler="请输入关键词"></el-input>
<el-button icon="el-icon-search" type="primary" plain size="small" @click="userSelect.page = 1,getUsers()">搜索</el-button>
</template>
</vxe-toolbar>
<vxe-table
ref="table"
stripe
style="margin-top: 10px;"
:loading="loading"
keep-source
:max-height="400"
show-overflow
:column-config="{ resizable: true }"
:edit-config="{ trigger: 'manual', mode: 'row', showStatus: true, isHover: true, autoClear: false }"
@ -165,6 +172,23 @@
</vxe-column>
</vxe-table>
<el-pagination
style="margin-top: 10px;"
:current-page="userSelect.page"
:page-sizes="[20, 30, 40, 50]"
:page-size="userSelect.rows"
layout="total, sizes, prev, pager, next, jumper"
:total="userTotal"
@size-change="e => {
userSelect.rows = e;
userSelect.page = 1;
getUsers();
}"
@current-change="e => {
userSelect.page = e;
getUsers();
}"
/>
</el-tab-pane>
</el-tabs>
</div>
@ -251,6 +275,12 @@ export default {
},
isShowBindPermissions: false,
total: 0,
userSelect: {
page: 1,
rows: 10,
keyword: ''
},
users: [],
userTotal: 0,
isShowBindRoles: false
@ -447,7 +477,8 @@ export default {
this.loading = true
try {
const res = await grant({
module_id: this.moduleId
module_id: this.moduleId,
...this.userSelect
})
console.log(res)
this.users = res.rows

@ -1,20 +1,22 @@
<template>
<div>
<vxe-modal :value="isShow"
show-footer
title="角色"
:z-index="zIndex"
show-confirm-button
:width="600"
:height="400"
esc-closable
@input="e => $emit('update:isShow',e)">
<vxe-modal
:value="isShow"
show-footer
title="角色"
:z-index="zIndex"
show-confirm-button
:width="600"
:height="400"
esc-closable
@input="e => $emit('update:isShow',e)"
>
<el-form ref="elForm" :model="form" :rules="rules" label-position="top" label-width="100">
<el-form-item label="角色" prop="name" required>
<el-input v-model="form.name" clearable></el-input>
<el-input v-model="form.name" clearable />
</el-form-item>
<el-form-item label="排序" prop="sortnumber">
<el-input-number controls-position="right" :precision="0" v-model="form.sortnumber"></el-input-number>
<el-input-number v-model="form.sortnumber" controls-position="right" :precision="0" />
</el-form-item>
</el-form>
@ -27,10 +29,10 @@
<script>
import { PopupManager } from 'element-ui/lib/utils/popup'
import { roleSave } from "@/api/module"
import { roleSave } from '@/api/module'
export default {
props: {
moduleId: [String,Number],
moduleId: [String, Number],
isShow: {
type: Boolean,
default: false,
@ -42,43 +44,43 @@ export default {
zIndex: PopupManager.nextZIndex(),
loading: false,
form: {
name: "",
name: '',
sortnumber: 0
},
rules: {
name: [
{ required: true, message: "请输入角色" }
{ required: true, message: '请输入角色' }
]
}
}
},
computed: {},
watch: {
isShow(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
},
methods: {
submit () {
this.$refs["elForm"].validate(async valid => {
submit() {
this.$refs['elForm'].validate(async valid => {
if (valid) {
this.loading = true
try {
this.form.module_id = this.moduleId;
this.form.module_id = this.moduleId
await roleSave(this.form)
this.$message.success("新增成功")
this.$message.success('新增成功')
this.$emit('refresh')
this.$emit('update:isShow',false)
this.$emit('update:isShow', false)
this.loading = false
this.$refs["elForm"].resetFields()
this.$refs['elForm'].resetFields()
} catch (err) {
this.loading = false
}
}
})
}
},
computed: {},
watch: {
isShow(newVal) {
if (newVal) {
this.zIndex = PopupManager.nextZIndex()
}
}
}
}
</script>

@ -8,9 +8,9 @@
</template>
</vxe-toolbar>
<vxe-table
ref="table"
stripe
style="margin-top: 10px;"
ref="table"
:loading="loading"
keep-source
show-overflow
@ -18,20 +18,21 @@
:edit-rules="validRules"
:edit-config="{ trigger: 'manual', mode: 'row', showStatus: true, isHover: true, autoClear: false }"
:align="allAlign"
:data="tableData">
<vxe-column type="seq" width="58" align="center"></vxe-column>
<vxe-column field="name" width="160" title="部门名称" :edit-render="{ name: 'input', attrs: { type: 'text'} }"></vxe-column>
:data="tableData"
>
<vxe-column type="seq" width="58" align="center" />
<vxe-column field="name" width="160" title="部门名称" :edit-render="{ name: 'input', attrs: { type: 'text'} }" />
<vxe-column field="manager.name" width="180" title="分管领导" :edit-render="{}">
<template #edit="{ row }">
<UserPicker size="small" v-model="row.manager_id"></UserPicker>
<UserPicker v-model="row.manager_id" size="small" />
</template>
</vxe-column>
<vxe-column field="leader.name" width="180" title="主要领导" :edit-render="{}">
<vxe-column field="leader.name" width="180" title="主要负责人" :edit-render="{}">
<template #edit="{ row }">
<UserPicker size="small" v-model="row.leader_id"></UserPicker>
<UserPicker v-model="row.leader_id" size="small" />
</template>
</vxe-column>
<vxe-column field="sortnumber" width="80" title="排序" align="center" :edit-render="{ name: 'input', attrs: { type: 'number' } }"></vxe-column>
<vxe-column field="sortnumber" width="80" title="排序" align="center" :edit-render="{ name: 'input', attrs: { type: 'number' } }" />
<vxe-column field="operate" title="操作" min-width="220">
<template #default="{ row }">
<template v-if="isActiveStatus(row)">
@ -49,15 +50,15 @@
<p class="total" type="primary"> {{ total }} 条数据</p>
</card-container>
<AddDepartment ref="AddDepartment" :list="tableData" :is-show.sync="isShowAdd" @refresh="getList"></AddDepartment>
<AddDepartment ref="AddDepartment" :list="tableData" :is-show.sync="isShowAdd" @refresh="getList" />
</div>
</template>
<script>
import UserPicker from '@/components/UserPicker/index.vue'
import AddDepartment from './components/AddDepartment.vue'
import { deepCopy } from "@/utils"
import { index, save, destroy } from "@/api/department"
import { deepCopy } from '@/utils'
import { index, save, destroy } from '@/api/department'
export default {
components: {
AddDepartment,
@ -85,14 +86,26 @@ export default {
}
}
},
computed: {
isActiveStatus() {
return function(row) {
if (this.$refs['table']) {
return this.$refs['table'].isEditByRow(row)
}
}
}
},
created() {
this.getList()
},
methods: {
editRowEvent (row) {
editRowEvent(row) {
if (this.$refs['table']) {
this.$refs['table'].setEditRow(row)
}
},
cancelRowEvent (row) {
cancelRowEvent(row) {
if (this.$refs['table']) {
this.$refs['table'].clearEdit().then(() => {
//
@ -101,74 +114,62 @@ export default {
}
},
async getList () {
this.loading = true;
async getList() {
this.loading = true
try {
const res = await index()
this.tableData = res;
this.total = res.length;
this.loading = false;
this.tableData = res
this.total = res.length
this.loading = false
} catch (err) {
console.error(err)
this.loading = false;
this.loading = false
}
},
async saveRowEvent (row) {
async saveRowEvent(row) {
try {
await this.$confirm("确认保存?","提示",{
confirmButtonText: "确认",
cancelButtonText: "取消"
await this.$confirm('确认保存?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消'
})
await this.$refs['table'].clearEdit()
let form = deepCopy(this.form)
for (let key in form) {
const form = deepCopy(this.form)
for (const key in form) {
form[key] = row[key]
}
if (!form.password) {
delete form.password
}
this.loading = true;
this.loading = true
await save(form)
await this.getList();
this.loading = false;
await this.getList()
this.loading = false
} catch (err) {
this.loading = false;
this.loading = false
}
},
async destroyRowEvent (row) {
async destroyRowEvent(row) {
try {
await this.$confirm("确认删除?","提示",{
confirmButtonText: "确认",
cancelButtonText: "取消"
await this.$confirm('确认删除?', '提示', {
confirmButtonText: '确认',
cancelButtonText: '取消'
})
this.loading = true;
this.loading = true
if (row.id) {
await destroy({
id: row.id
})
await this.getList();
await this.getList()
} else {
console.log(row)
this.tableData.splice(this.tableData.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY),1)
this.tableData.splice(this.tableData.findIndex(i => i._X_ROW_KEY === row._X_ROW_KEY), 1)
}
this.loading = false;
this.loading = false
} catch (err) {
this.loading = false;
}
},
},
computed: {
isActiveStatus () {
return function (row) {
if (this.$refs['table']) {
return this.$refs['table'].isEditByRow(row)
}
this.loading = false
}
}
},
created() {
this.getList()
}
}
</script>

@ -3,8 +3,9 @@
<card-container>
<vxe-toolbar>
<template #buttons>
<el-input v-model="select.keyword" style="max-width: 200px;margin-right: 10px;" size="small" placeholder="请输入关键词" />
<el-button icon="el-icon-plus" type="primary" size="small" @click="isShowAdd = true">新增</el-button>
<el-button icon="el-icon-search" type="primary" plain size="small" @click="getList"></el-button>
<el-button icon="el-icon-search" type="primary" plain size="small" @click="select.page = 1,getList()">搜索</el-button>
</template>
</vxe-toolbar>
<vxe-table
@ -28,6 +29,14 @@
<span>***</span>
</template>
</vxe-column>
<vxe-column field="department.name" width="160" align="center" title="部门" :edit-render="{}">
<template #edit="{ row }">
<el-select v-model="row.department_id" size="small">
<el-option v-for="item in departments" :value="item.id" :label="item.name"></el-option>
</el-select>
</template>
</vxe-column>
<vxe-column field="position" width="140" title="职位" align="center" :edit-render="{ name: 'input', attrs: { type: 'text'} }" />
<vxe-column field="attendance_closed" width="130" align="center" title="是否关闭打卡" :edit-render="{ name: 'select', options: [{ value: 1, label: '' },{ value: 0, label: '' }] }" />
<vxe-column field="mobile" width="140" align="center" title="手机号" :edit-render="{ name: 'input', attrs: { type: 'text' } }" />
<vxe-column field="roles" title="角色" min-width="200" show-overflow="tooltip">
@ -72,7 +81,7 @@
/>
</card-container>
<AddUser :is-show.sync="isShowAdd" @refresh="getList" />
<AddUser :is-show.sync="isShowAdd" :departments="departments" @refresh="getList" />
<BindRoles ref="BindRoles" :is-show.sync="isShowBind" @refresh="getList" />
</div>
</template>
@ -82,6 +91,7 @@ import BindRoles from './components/BindRoles.vue'
import AddUser from './components/AddUser.vue'
import { deepCopy } from '@/utils'
import { index, save, destroy } from '@/api/user'
import { index as departmentIndex } from '@/api/department'
export default {
components: {
AddUser,
@ -126,7 +136,7 @@ export default {
{
validator: ({ cellValue }) => {
return new Promise((resolve, reject) => {
if (/^1[3456789]\d{9}$/.test(cellValue)) {
if (!cellValue || /^1[3456789]\d{9}$/.test(cellValue)) {
resolve()
} else {
reject(new Error('手机号格式错误!'))
@ -141,8 +151,11 @@ export default {
name: '',
username: '',
password: '',
department_id: '',
position: '',
sortnumber: 0
}
},
departments: []
}
},
computed: {
@ -155,6 +168,7 @@ export default {
}
},
created() {
this.getDepartments()
this.getList()
},
methods: {
@ -233,6 +247,15 @@ export default {
} catch (err) {
this.loading = false
}
},
async getDepartments() {
try {
this.departments = await departmentIndex({
is_tree: 0
})
} catch (err) {
console.error(err)
}
}
}
}

Loading…
Cancel
Save