Commit cca4623f by xiaowenfeng

1、修改了router

parent 11c053cc
<template> <template>
<div id="app-body"> <div id="app">
<Header></Header> <router-view/>
<div class="main-wrap">
<div class="left-menu-wrap">
<LeftNav :company="company"></LeftNav>
</div>
<div class="right-wrap">
<Home :root="company"></Home>
</div>
</div>
</div> </div>
</template> </template>
<script>
import Header from './components/Header'
import LeftNav from './components/LeftNav'
import Home from './views/Home'
export default {
data () {
return {
company: '深圳企大科技有限公司'
}
},
components: {
Header,
LeftNav,
Home
}
}
</script>
<style lang="less"> <style lang="less">
@nav-width: 208px; @nav-width: 208px;
...@@ -67,7 +42,7 @@ cursor: pointer ; ...@@ -67,7 +42,7 @@ cursor: pointer ;
min-width: 1440px;/*no*/ min-width: 1440px;/*no*/
min-height: 900px; /*no*/ min-height: 900px; /*no*/
height: 100%; height: 100%;
#app-body { #app {
width: 100%; width: 100%;
height: 100%; height: 100%;
// overflow-x: scroll; // overflow-x: scroll;
......
<template> <template>
<a-drawer <a-drawer
title="编辑部门" title="添加子部门"
:placement="placement" :placement="placement"
:closable="false" :closable="false"
:visible="visible" :visible="visible"
:wrap-style="{ position: 'absolute' }" :wrap-style="{ position: 'absolute' }"
:wrapClassName="'right-drawer'" :wrapClassName="'right-drawer'"
:get-container="'#rightBody'" :get-container="'#rightBody'"
@close="onClose"
> >
<p class="drawer-form-title">部门信息</p> <a-form>
<div class="department-edit"> <p class="drawer-form-title">部门信息</p>
<a-form> <div class="department-edit">
<a-form-item label="部门名称" v-bind="validateInfos.name"> <a-form-item label="部门名称" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/> <a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/>
</a-form-item> </a-form-item>
<a-form-item label="上级部门"> <a-form-item label="上级部门">
<a-input v-model:value="modelRef.superiorDepartment" allow-clear/> <a-input v-model:value="modelRef.superiorDepartment" allow-clear @click="setSuperiorDepartment"/>
</a-form-item> </a-form-item>
<a-form-item label="简介" class="drawer-text"> <a-form-item label="简介" class="drawer-text">
<a-textarea v-model:value="modelRef.describe" allow-clear/> <a-textarea v-model:value="modelRef.describe" allow-clear/>
</a-form-item> </a-form-item>
</a-form> </div>
</div> </a-form>
<p class="drawer-form-title">部门必修课</p> <div class="bot-btn">
<div class="bot-btn">
<a-space :size="35"> <a-space :size="35">
<a-button type="default" class="qd-right-drawer-btn" @click="onClose"> <a-button type="default" class="qd-right-drawer-btn" @click="onClose">
删除dddd 删除
</a-button> </a-button>
<a-button type="default" class="qd-right-drawer-btn qd-right-drawer-btn-save " @click="onSubmit"> <a-button type="default" class="qd-right-drawer-btn qd-right-drawer-btn-save " @click="onSubmit">
保存 保存
...@@ -36,23 +34,24 @@ ...@@ -36,23 +34,24 @@
取消 取消
</a-button> </a-button>
</a-space> </a-space>
</div> </div>
<DepSelectModal :visible="depSelectModalVisible" @close="onDepSelectModalClose"></DepSelectModal>
</a-drawer> </a-drawer>
</template> </template>
<script> <script>
import { reactive, toRaw } from 'vue' import { reactive, toRaw } from 'vue'
import { useForm } from '@ant-design-vue/use' import { useForm } from '@ant-design-vue/use'
import DepSelectModal from './DepSelectModal'
export default { export default {
props: ['visible'], props: ['visible'],
data () { data () {
return { return {
depSelectModalVisible: false,
placement: 'right' placement: 'right'
} }
}, },
methods: { components: {
onClose () { DepSelectModal
this.$emit('close')
}
}, },
setup () { setup () {
const modelRef = reactive({ const modelRef = reactive({
...@@ -86,6 +85,17 @@ export default { ...@@ -86,6 +85,17 @@ export default {
modelRef, modelRef,
onSubmit onSubmit
} }
},
methods: {
onClose () {
this.$emit('close')
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
},
setSuperiorDepartment () {
this.depSelectModalVisible = true
}
} }
} }
</script> </script>
...@@ -96,7 +106,7 @@ export default { ...@@ -96,7 +106,7 @@ export default {
padding-top: 20px; padding-top: 20px;
.drawer-text{ .drawer-text{
height: 101px !important; height: 101px !important;
padding-top: 1px !important; // padding-top: 1px !important;
} }
} }
</style> </style>
<template>
<a-drawer
title="批量修改年度达标学分值"
:placement="placement"
:closable="false"
:visible="visible"
:wrap-style="{ position: 'absolute' }"
:wrapClassName="'right-drawer'"
:get-container="'#rightBody'"
>
<a-form>
<p class="drawer-form-title">设置学分分值</p>
<div class="department-edit">
<a-form-item label="学分分数" v-bind="validateInfos.complianceScore">
<a-input-number v-model:value="modelRef.complianceScore" :defaultValue="0" :min="0" allow-clear :placeholder="'请设置年度学分达标分数'" @change="handleChange"/>
</a-form-item>
</div>
</a-form>
<div class="bot-btn">
<a-space :size="35">
<a-button type="default" class="qd-right-drawer-btn qd-right-drawer-btn-save " @click="onSubmit">
保存
</a-button>
<a-button type="default" class="qd-right-drawer-btn" @click="onClose">
取消
</a-button>
</a-space>
</div>
<DepSelectModal :visible="depSelectModalVisible" @close="onDepSelectModalClose"></DepSelectModal>
</a-drawer>
</template>
<script>
import { reactive, toRaw } from 'vue'
import { useForm } from '@ant-design-vue/use'
import DepSelectModal from './DepSelectModal'
export default {
props: ['visible'],
data () {
return {
depSelectModalVisible: false,
placement: 'right'
}
},
components: {
DepSelectModal
},
setup () {
const modelRef = reactive({
complianceScore: 0
})
const rulesRef = reactive({
complianceScore: [
{
required: true,
message: '请输入学分',
type: 'number'
}
]
})
const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef)
const onSubmit = e => {
e.preventDefault()
validate()
.then(() => {
console.log(toRaw(modelRef))
})
.catch(err => {
console.log('error', err)
})
}
return {
validateInfos,
resetFields,
modelRef,
onSubmit
}
},
methods: {
onClose () {
this.$emit('close')
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
},
setSuperiorDepartment () {
this.depSelectModalVisible = true
},
handleChange () {
console.log(arguments)
}
}
}
</script>
<style lang="less" scoped>
.department-edit{
height: 276px;
width: 100%;
padding-top: 20px;
.drawer-text{
height: 101px !important;
// padding-top: 1px !important;
}
}
</style>
<template> <template>
<a-modal <a-modal
:get-container="'#rightBody'"
:visible="true"
:maskStyle="{position: 'absolute'}" :maskStyle="{position: 'absolute'}"
:closable="false" :closable="false"
:wrapClassName="'qd-input-modal'" :wrapClassName="'qd-input-modal'"
:confirm-loading="confirmLoading"
:okText="'确定'" :okText="'确定'"
:cancelText="'取消'" :cancelText="'取消'"
:get-container="setParent"
title="选择部门" title="选择部门"
:visible="visible"
@ok="handleOk" @ok="handleOk"
@cancel="handleCancel"
> >
<div class="select-wrap"> <div class="select-wrap">
<div class="content"> <div class="content">
...@@ -19,20 +21,114 @@ ...@@ -19,20 +21,114 @@
allow-clear allow-clear
/> />
<div class="current"> <div class="current">
<div>深圳企大云科技有限公司</div> <div class="top">
<div>></div> <div class="right">
<div>客服部</div> <span>深圳企大云科技有限公司</span>
<span>></span>
<span>客服部</span>
</div>
<a-button type="default">上级部门</a-button>
</div>
<div class="list">
<a-radio-group v-model:value="value" @change="onChange">
<a-radio :style="radioStyle" :value="1">
<ApartmentOutlined/>
<span class="item-name" title="客服一部">客服一部</span>
<a-button >
<span class="iconfont iconjiegou"></span>
<span>下级</span>
</a-button>
</a-radio>
<a-radio :style="radioStyle" :value="2">
<ApartmentOutlined/>
<span class="item-name">客服一部</span>
<a-button >
<span class="iconfont iconjiegou"></span>
<span>下级</span>
</a-button>
</a-radio>
<a-radio :style="radioStyle" :value="3">
<ApartmentOutlined/>
<span class="item-name">客服一部</span>
<a-button >
<span class="iconfont iconjiegou"></span>
<span>下级</span>
</a-button>
</a-radio>
<a-radio :style="radioStyle" :value="4">
<ApartmentOutlined/>
<span class="item-name">客服一部</span>
<a-button >
<span class="iconfont iconjiegou"></span>
<span>下级</span>
</a-button>
</a-radio>
</a-radio-group>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="content"> <div class="content">
<p class="title">已选</p> <p class="title">已选</p>
<div class="choose"></div> <div class="choose">
<div class="has-selectd">
<div class="item-wrap">
<ApartmentOutlined/>
<span class="item-name" title="客服一部">客服一部客服一部客服一部客服一部客服一部客服一部</span>
<a-button><CloseCircleFilled /></a-button>
</div>
</div>
</div>
</div> </div>
</div> </div>
</a-modal> </a-modal>
</template> </template>
<script>
import { ApartmentOutlined, CloseCircleFilled } from '@ant-design/icons-vue'
export default {
props: {
visible: {
type: Boolean,
default: true
}
},
data () {
return {
value: 1,
confirmLoading: false,
radioStyle: {
display: 'block',
height: '30px',
lineHeight: '30px'
}
}
},
components: {
ApartmentOutlined,
CloseCircleFilled
},
methods: {
onChange (e) {
console.log('radio checked', e.target.value)
},
handleOk (e) {
this.confirmLoading = true
setTimeout(() => {
this.$emit('close')
this.confirmLoading = false
}, 2000)
},
handleCancel () {
this.$emit('close')
},
setParent () {
return document.getElementById('rightBody')
}
}
}
</script>
<style lang="less" scoped> <style lang="less" scoped>
@import url('../css/common.less');
.select-wrap { .select-wrap {
width: 100%; width: 100%;
height: 100%; height: 100%;
...@@ -64,6 +160,95 @@ ...@@ -64,6 +160,95 @@
font-size: 16px; font-size: 16px;
} }
} }
.current {
padding: 6px 0 6px 15px;
height: 318px;
.top {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 22px;
line-height: 22px;
.right {
width: 259px;
height: 18px;
line-height: 18px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
text-align: left;
>:first-child {
width: 70px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
>:last-child {
width: 100px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
span {
display: inline-block;
vertical-align: middle;
font-size: 12px;
}
}
.ant-btn {
padding: 0;
width: 59px;
height: 22px;
line-height: 22px;
font-size: 14px;
min-width: 59px; /*no*/
}
}
.list {
text-align: left;
height: 278px;
overflow-y: scroll;
.ant-radio-group {
width: 100%;
.ant-radio-wrapper {
width: 100%;
margin: 0;
position: relative;
}
}
}
}
.list .ant-radio-group .ant-radio-wrapper .item-name, .has-selectd .item-wrap .item-name {
display: inline-block;
width: 160px;
vertical-align: middle;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
.current .list .ant-btn, .has-selectd .item-wrap .ant-btn {
position: absolute;
height: 18px;
line-height: 18px;
font-size: 12px;
right: 4px;
padding: 0;
background: none;
border: none;
top: 50%;
transform: translateY(-50%);
}
.has-selectd {
width: 100%;
height: 100%;
padding: 10px 4px 10px 8px;
text-align: left;
overflow-y: scroll;
.item-wrap {
position: relative;
}
}
} }
} }
} }
......
...@@ -8,50 +8,51 @@ ...@@ -8,50 +8,51 @@
:wrapClassName="'right-drawer'" :wrapClassName="'right-drawer'"
:get-container="'#rightBody'" :get-container="'#rightBody'"
> >
<p class="drawer-form-title">部门信息</p> <a-form>
<div class="department-edit"> <p class="drawer-form-title">部门信息</p>
<a-form> <div class="department-edit">
<a-form-item label="部门名称" v-bind="validateInfos.name"> <a-form-item label="部门名称" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/> <a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/>
</a-form-item> </a-form-item>
<a-form-item label="上级部门"> <a-form-item label="上级部门">
<a-input v-model:value="modelRef.superiorDepartment" allow-clear/> <a-input v-model:value="modelRef.superiorDepartment" allow-clear @click="setSuperiorDepartment"/>
</a-form-item> </a-form-item>
<a-form-item label="简介" class="drawer-text"> <a-form-item label="简介" class="drawer-text">
<a-textarea v-model:value="modelRef.describe" allow-clear/> <a-textarea v-model:value="modelRef.describe" allow-clear/>
</a-form-item> </a-form-item>
</a-form> </div>
</div> <p class="drawer-form-title">部门必修课</p>
<p class="drawer-form-title">部门必修课</p> </a-form>
<div class="bot-btn"> <div class="bot-btn">
<a-space :size="35"> <a-space :size="35">
<a-button type="default" class="qd-right-drawer-btn" @click="onClose"> <a-button type="default" class="qd-right-drawer-btn" @click="onClose">
删除 删除
</a-button> </a-button>
<a-button type="default" class="qd-right-drawer-btn qd-right-drawer-btn-save " @click="onSubmit"> <a-button type="default" class="qd-right-drawer-btn qd-right-drawer-btn-save " @click="onSubmit">
保存 保存
</a-button> </a-button>
<a-button type="default" class="qd-right-drawer-btn" @click="onClose"> <a-button type="default" class="qd-right-drawer-btn" @click="onClose">
取消 取消
</a-button> </a-button>
</a-space> </a-space>
</div> </div>
<DepSelectModal :visible="depSelectModalVisible" @close="onDepSelectModalClose"></DepSelectModal>
</a-drawer> </a-drawer>
</template> </template>
<script> <script>
import DepSelectModal from './DepSelectModal'
import { reactive, toRaw } from 'vue' import { reactive, toRaw } from 'vue'
import { useForm } from '@ant-design-vue/use' import { useForm } from '@ant-design-vue/use'
export default { export default {
props: ['visible'], props: ['visible'],
data () { data () {
return { return {
depSelectModalVisible: false,
placement: 'right' placement: 'right'
} }
}, },
methods: { components: {
onClose () { DepSelectModal
this.$emit('close')
}
}, },
setup () { setup () {
const modelRef = reactive({ const modelRef = reactive({
...@@ -85,6 +86,17 @@ export default { ...@@ -85,6 +86,17 @@ export default {
modelRef, modelRef,
onSubmit onSubmit
} }
},
methods: {
onClose () {
this.$emit('close')
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
},
setSuperiorDepartment () {
this.depSelectModalVisible = true
}
} }
} }
</script> </script>
...@@ -95,7 +107,7 @@ export default { ...@@ -95,7 +107,7 @@ export default {
padding-top: 20px; padding-top: 20px;
.drawer-text{ .drawer-text{
height: 101px !important; height: 101px !important;
padding-top: 1px !important; // padding-top: 1px !important;
} }
} }
</style> </style>
<template>
<div class="import-wrap" v-show="visible">
<div class="import-head">
<a-button type="default" class="back" @click="close"><span class="iconfont iconziyuan"></span><span class="back-text">返回</span></a-button>
<div class="title">批量导入/导出学员</div>
</div>
<div class="content">
<div class="import-export-wrap">
<div class="import-export-top">
<div class="wrap">
<p>1、下载组织架构模板,填写成员信息</p>
<FileExcelOutlined class="fileicon"/>
<p>填写时请勿将顺序打乱,保持原有顺序格式</p>
<a-button type="default">下载模板</a-button>
</div>
<div class="center"></div>
<div class="wrap">
<p>2、上传填好的文件</p>
<FileExcelOutlined class="fileicon"/>
<p>仅支持xls、xslx格式文件</p>
<a-upload
v-model:fileList="fileList"
:multiple="false"
:showUploadList="false"
@change="handleChange"
>
<a-button type="default">上传文件</a-button>
</a-upload>
<p>注意:您当前站点剩余500个可使用账号数,若超过人数限制请先联系<a>企大客服</a>,增加账号数。</p>
</div>
</div>
<div class="import-export-bottom">
<p>·导入会覆盖原有(重复)员工的信息,如需更新已存在的员工,请先导出组织架构,再导出表格进行修改</p>
<p>·子管理员仅能上传和导出有权限范围内的组织架构</p>
<p>·若与企业微信/钉钉有绑定关系的,若与企业微信/钉钉组织架构不一致,请及时修正或停用企业微信新/钉钉的 捆绑同步功能。</p>
</div>
<div class="export">
<FileExcelOutlined />
<p>按部门导出学员</p>
<a-button type="default">导出</a-button>
</div>
</div>
</div>
</div>
</template>
<script>
import { FileExcelOutlined } from '@ant-design/icons-vue'
export default {
props: {
visible: {
require: true,
type: Boolean
}
},
data () {
return {
fileList: []
}
},
components: {
FileExcelOutlined
},
methods: {
handleChange (info) {
console.log(info)
},
close () {
this.$emit('close')
}
}
}
</script>
<style lang="less" scoped>
@import url('../css/iconfont/iconfont.css');
.import-wrap {
width: 100%;
height: 100%;
background: #FFFFFF 100%;
position: absolute;
top: 0;
z-index: 2;
.import-head {
height: 60px;
width: 100%;
background: #F9F9F9 100%;
text-align: center;
position: relative;
.back {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 21px;
}
.ant-btn {
height: 24px;
background-color: rgba(255, 255, 255, 100);
padding: 0;
background: none;
border: none;
}
.back-text {
margin-left: 9px;
}
.title {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: rgba(16, 16, 16, 100);
font-size: 16px;
text-align: left;
font-family: SourceHanSansSC-bold;
font-weight: bold;
}
}
.content {
width: 100%;
height: calc(100% - 60px);
padding-top: 56px;
p {
font-size: 16px;
margin: 0;
}
.import-export-wrap {
margin: auto;
width: 865px;
height: 573px;
line-height: 20px;
border-radius: 4px;
text-align: center;
border: 1px solid rgba(187, 187, 187, 100);
position: relative;
padding: 0 21px;
color: rgba(16, 16, 16, 100);
.ant-btn {
width: 101px;
height: 37px;
border-radius: 90px;
}
.anticon {
font-size: 78px;
color: #000;
}
.import-export-top {
width: 100%;
height: 436px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.wrap {
width: 50%;
height: 100%;
padding: 50px 15px;
.fileicon {
margin: 50px 0 6px 0;
}
.ant-btn {
margin: 18px 0 3px 0;
}
a {
text-decoration: underline;
}
}
.center {
width: 1px;
height: 168px;
background: rgba(187, 187, 187, 100);
}
}
.import-export-bottom {
border-top: 1px solid rgba(187, 187, 187, 100);
width: 100%;
height: 136px;
text-align: left;
padding: 18px 21px;
p {
padding-bottom: 10px;
}
}
.export {
position: absolute;
right: -166px;
top: 0;
width: 151px;
height: 190px;
line-height: 20px;
border-radius: 4px;
text-align: center;
padding: 28px 0 25px 0;
border: 1px solid rgba(187, 187, 187, 100);
p {
margin: 14px 0 18px 0;
}
.anticon {
font-size: 44px;
}
}
}
}
}
</style>
...@@ -41,17 +41,17 @@ export default { ...@@ -41,17 +41,17 @@ export default {
this.$router.isReady().then(() => { this.$router.isReady().then(() => {
const routes = this.$router.options.routes const routes = this.$router.options.routes
const tops = routes[0].tops const tops = routes[0].tops
const leftnav = routes.slice(1, routes.length) const leftnav = routes[0].children
const currentRoute = this.$router.currentRoute.value.matched[0] const currentRoute = this.$route
console.log(leftnav) console.log('leftnav:', leftnav)
console.log(currentRoute)
console.log('tops:', tops) console.log('tops:', tops)
const newTops = tops.map((item) => { console.log('currentRoute:', currentRoute)
tops.map((item) => {
this.rootSubmenuKeys.push(item.id) this.rootSubmenuKeys.push(item.id)
const grop = leftnav.filter(i => { const grop = leftnav.filter(i => {
if (currentRoute && currentRoute.meta && item.id === currentRoute.meta.parent && i.path === currentRoute.path) { if (item.id === currentRoute.meta.parent && currentRoute.path.startsWith(i.path)) {
this.selectedKeys.push(i.path) this.openKeys = [item.id]
this.openKeys.push(item.id) this.selectedKeys = [i.path]
} }
if (i.meta && i.meta.parent) { if (i.meta && i.meta.parent) {
return i.meta.parent === item.id return i.meta.parent === item.id
...@@ -64,10 +64,9 @@ export default { ...@@ -64,10 +64,9 @@ export default {
} }
return item return item
}) })
// console.log('newTops:', newTops) this.menus = tops
// console.log('this.selectedKeys:', this.selectedKeys) console.log(this.menus)
// console.log('this.openKeys:', this.openKeys) console.log(this.openKeys)
this.menus = newTops
}) })
}, },
methods: { methods: {
......
<template> <template>
<div class="nav-list"> <div class="nav-list">
<a-menu v-model:selectedKeys="current" mode="horizontal"> <a-menu v-model:selectedKeys="current" mode="horizontal">
<a-menu-item :key="item.path" v-for="item in $route.matched[0].children"> <router-link :to="{path: item.path}">{{item.name}}</router-link> </a-menu-item> <a-menu-item :key="item.path" v-for="item in $route.matched[1].children"> <router-link :to="{path: item.path}">{{item.name}}</router-link> </a-menu-item>
</a-menu> </a-menu>
</div> </div>
</template> </template>
...@@ -13,6 +13,7 @@ export default { ...@@ -13,6 +13,7 @@ export default {
} }
}, },
mounted () { mounted () {
console.log('rightNav:', this.$route)
this.current.push(this.$route.path) this.current.push(this.$route.path)
} }
} }
......
...@@ -47,9 +47,6 @@ export default { ...@@ -47,9 +47,6 @@ export default {
type: Array type: Array
} }
}, },
mounted () {
this.expandedKeys = this.defaultExpandedKeys
},
data () { data () {
return { return {
expandedKeys: [], expandedKeys: [],
...@@ -84,6 +81,9 @@ export default { ...@@ -84,6 +81,9 @@ export default {
// editable: '1' // editable: '1'
// }) // })
} }
},
mounted () {
this.expandedKeys = this.defaultExpandedKeys
} }
} }
</script> </script>
......
...@@ -5,130 +5,226 @@ ...@@ -5,130 +5,226 @@
@right-drawer-header-height: 111px; @right-drawer-header-height: 111px;
@right-drawer-btns-height: 81px; @right-drawer-btns-height: 81px;
@right-drawer-body-height: calc(100% - @right-drawer-header-height - @right-drawer-btns-height); @right-drawer-body-height: calc(100% - @right-drawer-header-height - @right-drawer-btns-height);
.has-top-nav-page-wrap { .has-top-nav-page-wrap {
width: 100%; width: 100%;
height: 100%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
.tree-menu {
width: 297px;
height: 100%; height: 100%;
display: flex; background: #F2F2F2 100%;
flex-direction: row; }
flex-wrap: nowrap;
justify-content: flex-start; .right-operate {
.tree-menu { width: @right-operate;
width: 297px; height: 100%;
height: 100%; background: #FFFFFF 100%;
background: #F2F2F2 100%; }
}
.right-operate {
width: @right-operate;
height: 100%;
background: #FFFFFF 100%;
}
} }
.flex-justify { .flex-justify {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
text-align: justify; text-align: justify;
} }
::v-deep(.qd-btn) { ::v-deep(.qd-btn) {
width: 93px; width: 93px;
height: 30px; height: 30px;
border-radius: 90px; border-radius: 90px;
font-size: 14px; font-size: 14px;
text-align: center; text-align: center;
font-family: PingFang SC; font-family: PingFang SC;
padding: 0; padding: 0;
} }
::v-deep(.qd-btn-default-w) { ::v-deep(.qd-btn-default-w) {
min-width: 93px;/*no*/ min-width: 93px;
/*no*/
} }
::v-deep(.qd-table) { ::v-deep(.qd-table) {
.ant-table-thead > tr > th { .ant-table-thead>tr>th {
padding-top: 10px; padding-top: 10px;
padding-bottom: 10px; padding-bottom: 10px;
font-weight: bold; font-weight: bold;
}
.ant-table-tbody>tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)>td {
background: @f9-color !important;
}
.ant-table-row {
td {
padding-top: 10px;
padding-bottom: 10px;
}
}
}
.right-body {
::v-deep(.right-drawer) {
.ant-drawer-content-wrapper {
width: 669px !important;
}
.ant-drawer-header {
padding: 54px 23px 21px 23px;
border: none;
height: @right-drawer-header-height;
.ant-drawer-title {
line-height: 36px;
font-size: 24px;
}
}
.ant-drawer-body {
padding: 0 23px;
height: @right-drawer-body-height;
.drawer-form-title {
height: 36px;
line-height: 36px;
font-size: 16px;
padding: 0 9px;
background-color: #f0f0f0;
font-family: SourceHanSansSC-regular;
margin: 0;
}
} }
.ant-table-tbody > tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected) > td {
background: @f9-color !important; .ant-drawer-content-wrapper {
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.12);
border: 1px solid rgba(255, 255, 255, 100);
} }
.ant-table-row {
td { .bot-btn {
padding-top: 10px; position: absolute;
padding-bottom: 10px; bottom: 0;
width: 100%;
height: @right-drawer-btns-height;
border-top: 1px solid #e8e8e8;
padding: 23px 23px 22px 23px;
text-align: center;
left: 0;
background: #fff;
border-radius: 0 0 4px 4px;
.qd-right-drawer-btn {
width: 85px;
height: 36px;
border-radius: 4px;
padding: 0;
}
.qd-right-drawer-btn-save {
background: #000000 100%;
color: #fff;
} }
} }
.ant-form-item {
height: 64px;
padding: 14px 0;
margin: 0;
.ant-form-item-label {
width: 148px;
}
.ant-input-affix-wrapper {
border-radius: 4px;
}
.ant-input-number {
width: 100%;
border-radius: 4px;
}
}
.ant-input-affix-wrapper-textarea-with-clear-btn {
height: 100px;
}
textarea {
resize: none;
}
.ant-form-item-control-wrapper {
width: 458px;
}
} }
.right-body { ::v-deep(.ant-modal-root) {
::v-deep(.right-drawer) { .qd-input-modal {
.ant-drawer-content-wrapper{ position: absolute;
width: 669px !important;
} .ant-modal {
.ant-drawer-header { width: 708px !important;
padding: 54px 23px 21px 23px; border-radius: 5px;
border: none;
height: @right-drawer-header-height; .ant-modal-content {
.ant-drawer-title{ background: none;
line-height: 36px;
font-size: 24px; .ant-modal-header {
} height: 62px;
} border-top-right-radius: 5px;
.ant-drawer-body{ border-top-left-radius: 5px;
padding: 0 23px; background: #F4F4F4 10000%;
height: @right-drawer-body-height;
.drawer-form-title { .ant-modal-title {
height: 36px; font-size: 18px;
line-height: 36px; height: 27px;
font-size: 16px; line-height: 27px;
padding: 0 9px;
background-color: #f0f0f0;
font-family: SourceHanSansSC-regular;
margin: 0;
} }
} }
.ant-drawer-content-wrapper {
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.12); .ant-modal-body {
border: 1px solid rgba(255, 255, 255, 100); background: #FFFFFF 100%;
} height: 450px;
.bot-btn { padding: 0 41px;
position: absolute; }
bottom: 0;
width: 100%; .ant-modal-footer {
height: @right-drawer-btns-height; border: none;
border-top: 1px solid #e8e8e8; height: 67px;
padding: 23px 23px 22px 23px;
text-align: center; text-align: center;
left: 0; background: #FFFFFF 100%;
background: #fff; position: relative;
border-radius: 0 0 4px 4px;
.qd-right-drawer-btn{ .ant-btn {
width: 85px; position: absolute;
height: 36px; padding: 0;
border-radius: 4px; height: 30px;
padding: 0; line-height: 30px;
width: 80px;
border-radius: 4px;
top: 50%;
transform: translateY(-50%);
font-size: 14px;
} }
.qd-right-drawer-btn-save {
background: #000000 100%; div {
>:last-child {
left: 254px;
background: #000;
color: #fff; color: #fff;
border: none;
}
>:first-child {
left: 375px;
}
} }
}
} }
.ant-form-item { }
height: 64px;
padding: 14px 0;
margin: 0;
.ant-form-item-label {
width: 148px;
}
}
.ant-input-affix-wrapper-textarea-with-clear-btn{
height: 100px;
}
textarea {
resize: none;
}
.ant-form-item-control-wrapper {
width: 458px;
}
} }
} }
}
\ No newline at end of file
@font-face {font-family: "iconfont"; @font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1605576180830'); /* IE9 */ src: url('iconfont.eot?t=1606441605337'); /* IE9 */
src: url('iconfont.eot?t=1605576180830#iefix') format('embedded-opentype'), /* IE6-IE8 */ src: url('iconfont.eot?t=1606441605337#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAU8AAsAAAAACewAAATwAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDQAqGXIVuATYCJAMYCw4ABCAFhG0HZBuoCBEVpMGQ/QGyIRvoS1Jju+ulJqUQ385vecMmhuoIjrxz3wGxhRGQAAAAAADB8/3a79znKx8xj3SxpImET8cbHvFolUqliUVCpHsm75De+3e9FExeAW90UilJQWeqqKndOkLY9KH9P4horM3e3qs0FQhdNJtIJpOIVEjZLTRvABm+fwHwv2s7XEu50rDQqOIpmieTUMWi2t/2WALvB5tLTbomKleP/4ShXXzSn5Lj99CfrCxAA3HbNGmAqfoPtPbdX/u1et5Fm74z7WX/mTiizRNDIkomJELaxb3eXKJUCIWQOhaxa+eqBxP4NgSIqcMU2NbhSwM3BvEiAWR1KTUeuD0pTAJXCFEXcadFjoCDYA4FtsC58fvyjyICCquIV07Nk0mg6Yv9pqiCH6MaDbirKwC3+0ADPQAMyG5kaRm1Rj0g4s/zLYNATEChvuq/4F3+m/L/ci6+AQ1iYlIpSLtcw/nH0yBOxFAK9ljQTp1bMULB58UVFQYYIfBlNsLAF02huZircG0RQLwg+2D3EAyCxmL9IiGvLhKO0uI8iQK6QjX+BrOEhCLEAHBygDYp936Mo6ImFzEFzZNrckF0Tm9yw/1LbVIzsj0Vpcm9zVtH2Syxph7MQW+iuAQp6v1LjSnnqYllER0sbR6XqioVmIGFxSgvBpOVhZhllS9NTxXPZYbo8hvpFwJNV73fG9R2uk31/dPL24aXZOcfs7hGzZ8cejPwovGHJd/S4kKsPFoqg5XLiep4sTSpbymWHy3A/kmNB8sTK71p8ScJSkDvtRESMCY9XKgA4nLRn6h0ae64l6uul/68eoj7Ce+w3l+up/oxgYK/G8ApNlIj6PSERlGF+UcYFx2f/FWQRyr+MHUR+on/Qqq/wE1bgF9fTPMzc6YoDBttd3YmSVlZkgK+xiF+JkM0EOOWPA/7yloeWCnhghrfO66oMBuUaYe6pAXcWjU73maPbwYuJJvyXoLaLY2yS5juln6WXniydZ+fcRPu6YaZmE/JyvD/oAkdgq5IQ9Y8Nwkfgm4MMWy8yTdLKfR04+trQ4GAVAIYah3a4xykDytjrDIhNhC3VLWU1a8UjVVNLk9L7J/rViiVZ94lpFGqz3k29+B02ITnjieGksMmBI1X7OBMeEvApeMpoS2ClSIXCUptEj7KaKbg1GKiPsHg6UE2/MQZQ164drih/JHIO+Et+uw1XNJO4IljAt5Jb8EnAiBLy8gIAD1s8iFbO5GOzldvGgegr832xfg3vDkjMQ1u/x8SA8DHlfqjlWmZ7OOAgpv70nNn3GG+XjHt7Ht75UwEcMzggKPputL2wCVXK+Klqkhp5gEIweO+gcJTC5pAC92we8CS0AuOQB/EdONxf0IxBShiI6CLWgKhgHVQ5PEEmgKO6Yb9DJYyfoCjQBDETIvMExPahOTNi2CnOEJ/ADtwJDmrN+bqTzQb34nba8h+UZLtQpWX/tkPjChVXJO2plYlIOEA7/Q+9J5hFp5w0HytOq+KgqKmlA8cFje8CHaKI/QHsANH0g7Xm8DPf6LZ+E4Stv04/qIke3yo8jID/SMUM23bFXLamlqVuPNIOMA7CuilEcMcfdqEg+brAoN5VbDdKGsobz4S1vIRwIv4EqcYUbHiEKe4uN7adFHp948qVscaj1nPqhzuIi2wZIdOF+mGs5+EcjFZNLxZLAA=') format('woff2'), url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAX0AAsAAAAAC0QAAAWlAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDbAqIZIc8ATYCJAMgCxIABCAFhG0HfBvCCVFUb5JkPxJj2wVbuMViK1O5nZgOTVP5Hw//7ff7fWbmyrsP8aYWiaKrk/DIIhESkQQJYiMTKnxpXgJ+39JNSqcJOc+nyyhaU9Vy7e9mc312jvI8TqMUQoJwDOKmCems9Zkah5tRJvpPzMrv5S4Ku7jy036uzrto0zfTXu52fxuqnqiQNCRCuo+JlwSlR0zEq5e9UE/MmycT6MyYap3I759oqJBrBeK+xIY0zCUqLeLQxtQ1OxbxCvS06VlyAfAS/n38FxxDkiqTpzq9u0jo+Fe8+ECCTgCZeRQQtpeOwW5kbCGFeKrNfITiyi0d3ex2mDNkSCupf8Xzzefznt94Yf7itk5HXnS9r8wOQ4o7wpzbP7ykkdUqokaRAxDeVjX8giZCGOWDeAVR8xAvIeo6CDfqBuxkfpvHq4Oo2+ikAq3bYQSZQnEOKH6S0TtBZcgKtatUC/QRtUcsQzNGg94jpAlNsuIjbJvIlNmLdpnmgmEzdy82V1I3b/I3bihIcY2wlqC02hSNpi5vtsp8+CrX3BmC2bCVQEzjwdyozCNvtg0sb54nrgFAWKteD6Fq3TCNRskn64e3jnFEVh+bWXeo9BM3HJfelJ3WuizTVBXNXudOrzDd6iEKZqrbRNNyXJwBJMJMgpgDOuTtvu4wLMXb5eidvF5cZ62y4OesGVZpjkOiqmj3ddU18YpwdZORis3nl1zXwojs9ocGL0/QTuQPKqA2/tqEQQd4cPamWtt68xl/46lC81ypfdE0Yw1OiuvMoWo9QanXmuXPWofjpxJO7HCqRZ4qnwTz2mSmYGZ5OglxcJXaWQICzp5NUF5NqWeCD5i3rm/n1R8n/8hi7yb8d0nQ3bYdeufn7qsL0JXtaCwac2XHAslbmrPl6Lf70OdutBQt67UBLLby92jT0TbZyCiiG9oavzJa+AR2EyuMjMyy3fApvuineIvm6ClrYrcBeNN7F/r8BduJ7fr8eZcNw4ARtrNEI+rsFqCrV9BCtIDiF6Ddhl8J4hZeSVk9BsCiYtgfDigqGuDFxUXw4sXF/UMS5XIMk8sSE2UyU1OZHBAJUt1kB3Ycuzic6znZcJEziECs/uCEFysMxhn4GJrnLhxsLJFKHac8XDlneZI+5Uzfp51dx5uuw7gNCifjNXejDa+eaD3QaqYBui6BH6LcPP8nS1LSYDJyKK4jhWlpUEqIqMN83iTPS0FbXr/egoCALAtIk8470yqX9VVqSkQZxJJMw23DTf2G0KHasbXaCf+SfR6jaey8Qg7bUHpocCCUUbA+VnA9mDymgPVhFYxwiuHZ3X1aCVPI7GaVtKz4SCTuYgs4LChk5MWt1izPlNBK9oArPLk05zRP8wt6fWz6GN3rPIc7D+cIHKKPbR+9u7oQvgSkQ6OE9g46kt3Yd6L5yBQQ+UpSM9N+QFMRt/oS9DDnAiK/p0P/hJUMzp95mMPEfmuJX8eMz+dto4OCLwED2yVf5yhs5nvPMMeUeVAmtWU6NEPY2a2bb0d5Qqcm8X3PHfO3zehJdnNCazKFpDENWWuJW4RbUOnbhlprHzqbrnbvGyc6ovSw4UtAGPENyZA3yEb8cIvwFypT/qE2Eh3onIXJAftWwuHSWoSKhIe3cEleWRidouOo5QNsk4WSDYaaF4h3JRzkH1isuUIB2cYmdY12XV9vuLC2zFkuTocsK7m6ttwh1nlxvVabgIDCumea51XlNHZMQEhBgkU+MSdWKhg3vRqXfv8BWI1MSFoGnPm+AOG5xbOVuSWDexVZsAY8lvbeG2tNqdxgZtC8lGOXlA6Zqiyxqn65HYipue0a5ZWNBU1kuJHz/Ufnj/QC6MhHayNFjhJV1NFEGz31Q8lnExZ7pQ0Seu/i122oo5qS35RFh/W1zlNthtnwKtUy36sU9Zxxcah3b4suXwfpl5bAlg0RAAAA') format('woff2'),
url('iconfont.woff?t=1605576180830') format('woff'), url('iconfont.woff?t=1606441605337') format('woff'),
url('iconfont.ttf?t=1605576180830') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ url('iconfont.ttf?t=1606441605337') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1605576180830#iconfont') format('svg'); /* iOS 4.1- */ url('iconfont.svg?t=1606441605337#iconfont') format('svg'); /* iOS 4.1- */
} }
.iconfont { .iconfont {
...@@ -15,6 +15,14 @@ ...@@ -15,6 +15,14 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.iconziyuan:before {
content: "\e601";
}
.iconjurassic_hat:before {
content: "\e69a";
}
.iconquanquanb:before { .iconquanquanb:before {
content: "\e6d4"; content: "\e6d4";
} }
......
...@@ -20,6 +20,12 @@ Created by iconfont ...@@ -20,6 +20,12 @@ Created by iconfont
/> />
<missing-glyph /> <missing-glyph />
<glyph glyph-name="ziyuan" unicode="&#58881;" d="M588.468659 638.734409H123.316451L371.227243 837.44641a31.947267 31.947267 0 1 1-39.614611 49.837737l-319.472671-255.578137v-11.501016a30.669376 30.669376 0 0 1 0-4.472617v-3.194727a30.669376 30.669376 0 0 1 0-4.472617v-11.501016l319.472671-255.578137a31.947267 31.947267 0 1 1 40.253556 49.837737L123.316451 574.839875h465.152208C792.292223 574.839875 958.418011 431.716119 958.418011 255.367205s-166.125789-319.47267-369.949352-319.472671H95.841801a31.947267 31.947267 0 0 1 0-63.894534h492.626858C830.628943-128 1022.312545 43.876297 1022.312545 255.367205s-191.683602 383.367205-433.843886 383.367204z" horiz-adv-x="1024" />
<glyph glyph-name="jurassic_hat" unicode="&#59034;" d="M529.2 261.4l421.7 251c12.1 7.2 12.1 24.7 0 31.9l-421.7 251c-10.6 6.3-23.8 6.3-34.4 0l-421.7-251c-12.1-7.2-12.2-24.7 0-31.9l421.7-251c10.6-6.3 23.8-6.3 34.4 0zM512 224.39999999999998c-11.8 0-23.4 3.2-33.5 9.2l-265.4 158v-226.4c0-11.2 5.8-21.7 15.3-27.5l267.9-164.9c10.2-6.3 23.1-6.3 33.4 0l267.9 164.9c9.5 5.9 15.3 16.3 15.3 27.5V392.8L545.5 233.60000000000002c-10.1-6-21.7-9.2-33.5-9.2zM925 443.4c-17.7 0-32-14.4-32-32.3V267c0-17.8 14.3-32.3 32-32.3s32 14.4 32 32.3V411.1c0 17.8-14.3 32.3-32 32.3z" horiz-adv-x="1024" />
<glyph glyph-name="quanquanb" unicode="&#59092;" d="M491.880777-74.394105c-237.529835 0-430.759721 193.240119-430.759721 430.759721 0 237.529835 193.229886 430.769954 430.759721 430.769954s430.759721-193.240119 430.759721-430.769954C922.640498 118.846014 729.410612-74.394105 491.880777-74.394105zM491.880777 726.786087c-204.250894 0-370.410238-166.168554-370.410238-370.419448 0-204.240661 166.159344-370.410238 370.410238-370.410238S862.289991 152.124955 862.289991 356.365616C862.289991 560.61651 696.131671 726.786087 491.880777 726.786087zM491.880777 171.279201c-102.056374 0-185.096648 83.030042-185.096648 185.087439s83.040275 185.087439 185.096648 185.087439 185.077206-83.030042 185.077206-185.087439S593.937151 171.279201 491.880777 171.279201zM491.880777 481.102548c-68.777433 0-124.747165-55.959499-124.747165-124.736932s55.968709-124.736932 124.747165-124.736932S616.607476 287.588183 616.607476 356.365616 560.65821 481.102548 491.880777 481.102548z" horiz-adv-x="1024" /> <glyph glyph-name="quanquanb" unicode="&#59092;" d="M491.880777-74.394105c-237.529835 0-430.759721 193.240119-430.759721 430.759721 0 237.529835 193.229886 430.769954 430.759721 430.769954s430.759721-193.240119 430.759721-430.769954C922.640498 118.846014 729.410612-74.394105 491.880777-74.394105zM491.880777 726.786087c-204.250894 0-370.410238-166.168554-370.410238-370.419448 0-204.240661 166.159344-370.410238 370.410238-370.410238S862.289991 152.124955 862.289991 356.365616C862.289991 560.61651 696.131671 726.786087 491.880777 726.786087zM491.880777 171.279201c-102.056374 0-185.096648 83.030042-185.096648 185.087439s83.040275 185.087439 185.096648 185.087439 185.077206-83.030042 185.077206-185.087439S593.937151 171.279201 491.880777 171.279201zM491.880777 481.102548c-68.777433 0-124.747165-55.959499-124.747165-124.736932s55.968709-124.736932 124.747165-124.736932S616.607476 287.588183 616.607476 356.365616 560.65821 481.102548 491.880777 481.102548z" horiz-adv-x="1024" />
......
...@@ -5,21 +5,26 @@ import store from './store' ...@@ -5,21 +5,26 @@ import store from './store'
import http from './service/http' import http from './service/http'
import './libs/flexible' import './libs/flexible'
import { import {
ConfigProvider,
Button, Button,
Popover, Popover,
Menu, Menu,
Breadcrumb, Breadcrumb,
Input, Input,
InputNumber,
Tree, Tree,
Table, Table,
Space, Space,
Drawer, Drawer,
Form, Form,
Modal Modal,
Radio,
Select,
DatePicker,
Upload,
Spin
} from 'ant-design-vue' } from 'ant-design-vue'
// console.log(process.env)
// router.beforeEach((to, from, next) => { // router.beforeEach((to, from, next) => {
// /* 必须调用 `next` */ // /* 必须调用 `next` */
// console.log(to) // console.log(to)
...@@ -27,22 +32,28 @@ import { ...@@ -27,22 +32,28 @@ import {
// next() // next()
// }) // })
// createApp.config.devtools = process.env.NODE_ENV === 'dev'
const app = createApp(App) const app = createApp(App)
app.config.globalProperties.$http = http app.config.globalProperties.$http = http
if (process.env.NODE_ENV === 'dev') { app.use(ConfigProvider)
app.config.devtools = true .use(Button)
} .use(Popover)
app.use(Button) .use(Menu)
app.use(Popover) .use(Breadcrumb)
app.use(Menu) .use(Input)
app.use(Breadcrumb) .use(InputNumber)
app.use(Input) .use(Tree)
app.use(Tree) .use(Table)
app.use(Table) .use(Space)
app.use(Space) .use(Drawer)
app.use(Drawer) .use(Form)
app.use(Form) .use(Modal)
app.use(Modal) .use(Radio)
app.use(store) .use(Select)
app.use(router) .use(DatePicker)
app.mount('#app') .use(Upload)
.use(Spin)
.use(store)
.use(router)
.mount('#app')
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHashHistory } from 'vue-router'
import App from '../App.vue' import Home from '../views/Home.vue'
import ErrPage from '../views/ErrPage.vue' import ErrPage from '../views/ErrPage.vue'
const routes = [ const routes = [
{ {
path: '/', path: '/',
name: 'App', name: 'Home',
component: App, component: Home,
redirect: '/traineeManage', redirect: '/traineeManage',
tops: [ tops: [
{ {
...@@ -39,78 +39,80 @@ const routes = [ ...@@ -39,78 +39,80 @@ const routes = [
id: 'top6', id: 'top6',
items: [] items: []
} }
] ],
},
{
path: '/traineeManage',
name: '学员管理',
component: () => import('../views/origanizationManage/TraineeManage.vue'),
redirect: '/traineeManage/member',
meta: { parent: 'top4' },
children: [ children: [
{ {
path: '/traineeManage/member', path: '/traineeManage',
name: '学员管理', name: '学员管理',
component: () => import('../views/origanizationManage/Member.vue') component: () => import('../views/origanizationManage/TraineeManage.vue'),
redirect: '/traineeManage/member',
meta: { parent: 'top4' },
children: [
{
path: '/traineeManage/member',
name: '学员管理',
component: () => import('../views/origanizationManage/Member.vue')
},
{
path: '/traineeManage/department',
name: '部门管理',
component: () => import('../views/origanizationManage/Department.vue')
}
]
}, },
{ {
path: '/traineeManage/department', path: '/adminManage',
name: '部门管理',
component: () => import('../views/origanizationManage/Department.vue')
}
]
},
{
path: '/adminManage',
name: '管理员',
meta: { parent: 'top4' },
component: () => import('../views/origanizationManage/AdminManage.vue'),
redirect: '/adminManage/admin',
children: [
{
path: '/adminManage/admin',
name: '管理员', name: '管理员',
component: () => import('../views/origanizationManage/Admin.vue') meta: { parent: 'top4' },
component: () => import('../views/origanizationManage/AdminManage.vue'),
redirect: '/adminManage/admin',
children: [
{
path: '/adminManage/admin',
name: '管理员',
component: () => import('../views/origanizationManage/Admin.vue')
}
]
},
{
path: '/instructorManage',
name: '讲师管理',
meta: { parent: 'top4' },
component: () => import('../views/origanizationManage/InstructorManage.vue')
},
{
path: '/curriculumResource',
name: '课程资源',
meta: { parent: 'top2' },
component: () => import('../views/recource/CurriculumResource.vue')
},
{
path: '/learningPlan',
name: '学习计划',
meta: { parent: 'top2' },
component: () => import('../views/recource/LearningPlan.vue')
},
{
path: '/examinationMaterials',
name: '考试资料',
meta: { parent: 'top2' },
component: () => import('../views/recource/ExaminationMaterials.vue')
},
{
path: '/personalAchievement',
name: '个人成就',
meta: { parent: 'top2' },
component: () => import('../views/recource/PersonalAchievement.vue')
},
{
path: '/application',
name: '应用',
meta: { parent: 'top2' },
component: () => import('../views/recource/Application.vue')
} }
] ]
}, },
{ {
path: '/instructorManage',
name: '讲师管理',
meta: { parent: 'top4' },
component: () => import('../views/origanizationManage/InstructorManage.vue')
},
{
path: '/curriculumResource',
name: '课程资源',
meta: { parent: 'top2' },
component: () => import('../views/recource/CurriculumResource.vue')
},
{
path: '/learningPlan',
name: '学习计划',
meta: { parent: 'top2' },
component: () => import('../views/recource/LearningPlan.vue')
},
{
path: '/examinationMaterials',
name: '考试资料',
meta: { parent: 'top2' },
component: () => import('../views/recource/ExaminationMaterials.vue')
},
{
path: '/personalAchievement',
name: '个人成就',
meta: { parent: 'top2' },
component: () => import('../views/recource/PersonalAchievement.vue')
},
{
path: '/application',
name: '应用',
meta: { parent: 'top2' },
component: () => import('../views/recource/Application.vue')
},
{
path: '/404', path: '/404',
name: 'error-404', name: 'error-404',
component: ErrPage component: ErrPage
...@@ -122,7 +124,7 @@ const routes = [ ...@@ -122,7 +124,7 @@ const routes = [
] ]
const router = createRouter({ const router = createRouter({
history: createWebHistory(), history: createWebHashHistory(),
routes routes
}) })
......
const CONTACT_API = { const CONTACT_API = {
// 获取联系人列表 // 获取联系人列表
getContactList: { findMenuList: {
method: 'get', method: 'get',
url: '' url: '/sys/review/menu/list.do?'
} }
} }
export default CONTACT_API export default CONTACT_API
import axios from 'axios' import axios from 'axios'
import qs from 'qs'
import service from './contactApi' import service from './contactApi'
// service 循环遍历输出不同的请求方法 // service 循环遍历输出不同的请求方法
const instance = axios.create({ const instance = axios.create({
baseURL: 'http://localhost:8080/api', baseURL: './',
timeout: 1000 timeout: 1000,
withCredentials: true
}) })
// 包裹请求 // 包裹请求
...@@ -13,12 +15,13 @@ const Http = {} ...@@ -13,12 +15,13 @@ const Http = {}
for (const key in service) { for (const key in service) {
// url 请求相对路径 // url 请求相对路径
// method 请求方法 // method 请求方法
const { method, url } = service[key] let { method, url } = service[key]
// async 作用:实在不想写回调地狱 // async 作用:实在不想写回调地狱
// params 请求参数 get:url; put, post, patch(data); delete: url // params 请求参数 get:url; put, post, patch(data); delete: url
// isFormData 是否是formData // isFormData 是否是formData
// config 请求配置 // config 请求配置
Http[key] = async function (params, isFormData = false, config = {}) { Http[key] = async function (params, isFormData = false, config = {}) {
// 处理后的参数
let newParams = {} let newParams = {}
if (params && isFormData) { if (params && isFormData) {
newParams = new FormData() newParams = new FormData()
...@@ -39,6 +42,7 @@ for (const key in service) { ...@@ -39,6 +42,7 @@ for (const key in service) {
} }
} else if (method === 'delete' || method === 'get') { } else if (method === 'delete' || method === 'get') {
config.params = newParams config.params = newParams
url += qs.stringify(params)
try { try {
response = await instance[method](url, newParams, config) response = await instance[method](url, newParams, config)
} catch (err) { } catch (err) {
......
<template> <template>
<div class="right-body" id="rightBody"> <a-config-provider :locale="root.locale">
<div class="right-main"> <Header></Header>
<div class="breadcrumb"> <div class="main-wrap">
<a-breadcrumb separator=">>"> <div class="left-menu-wrap">
<a-breadcrumb-item>{{root}}</a-breadcrumb-item> <LeftNav :company="root.company"></LeftNav>
<a-breadcrumb-item :href="item.path" v-for="item in list" :key="item.path"> </div>
{{item.name}} <div class="right-wrap">
</a-breadcrumb-item> <div class="right-body" id="rightBody" ref="rightBody">
</a-breadcrumb> <div class="right-main">
</div> <div class="breadcrumb">
<div class="right-main-body"> <a-breadcrumb separator=">>">
<router-view></router-view> <!-- <a-breadcrumb-item>{{root.company}}</a-breadcrumb-item> -->
<a-breadcrumb-item
v-for="item in list"
:href="item.path"
:key="item.path"
>
{{item.name}}
</a-breadcrumb-item>
</a-breadcrumb>
</div>
<div class="right-main-body">
<router-view></router-view>
</div>
</div> </div>
<Footer></Footer>
</div>
</div> </div>
<Footer></Footer> </div>
</div> </a-config-provider>
</template> </template>
<script> <script>
import Header from '../components/Header'
import LeftNav from '../components/LeftNav'
import Footer from '../components/Footer' import Footer from '../components/Footer'
import { getCurrentInstance } from 'vue'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
export default { export default {
props: {
root: {
type: String,
required: true
}
},
data () { data () {
return { return {
list: [] list: [],
root: {
locale: zhCN,
company: '深圳企大科技有限公司'
}
} }
}, },
components: { components: {
Header,
LeftNav,
Footer Footer
}, },
setup (props) {
const { ctx } = getCurrentInstance()
console.log(ctx.$http)
},
mounted () {
console.log(this.$http.findMenuList({
_CONST_USER_ID_: 200009123
}))
this.$router.isReady().then(() => {
this.getBreadcrumb()
})
},
watch: { watch: {
$route (to, from) { $route (to, from) {
// console.log('to:', to)
// console.log('from:', from)
this.getBreadcrumb() this.getBreadcrumb()
} }
}, },
methods: { methods: {
getBreadcrumb () { getBreadcrumb () {
const matched = this.$route.matched this.list = this.$route.matched
// console.log(matched)
this.list = matched
} }
} }
} }
...@@ -65,63 +91,6 @@ export default { ...@@ -65,63 +91,6 @@ export default {
background: #F9F9F9 100%; background: #F9F9F9 100%;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
::v-deep(.ant-modal-root) {
.qd-input-modal{
position: absolute;
.ant-modal {
width: 708px !important;
border-radius: 5px;
.ant-modal-content {
background: none;
.ant-modal-header {
height: 62px;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
background: #F4F4F4 10000%;
.ant-modal-title {
font-size: 18px;
height: 27px;
line-height: 27px;
}
}
.ant-modal-body {
background: #FFFFFF 100%;
height: 450px;
padding: 0 41px;
}
.ant-modal-footer {
border: none;
height: 67px;
text-align: center;
background: #FFFFFF 100%;
position: relative;
.ant-btn {
position: absolute;
padding: 0;
height: 30px;
line-height: 30px;
width: 80px;
border-radius: 4px;
top: 50%;
transform: translateY(-50%);
font-size: 14px;
}
div {
>:last-child {
left: 254px;
background: #000;
color: #fff;
border: none;
}
>:first-child {
left: 375px;
}
}
}
}
}
}
}
.right-main { .right-main {
width: 100%; width: 100%;
height: calc(100% - @footer-height); height: calc(100% - @footer-height);
...@@ -137,6 +106,7 @@ export default { ...@@ -137,6 +106,7 @@ export default {
.right-main-body { .right-main-body {
width: 100%; width: 100%;
height: calc(100% - @right-main-body-height); height: calc(100% - @right-main-body-height);
position: relative;
&>div{ &>div{
height: 100%; height: 100%;
width: 100%; width: 100%;
......
<template> <template>
<div class="has-top-nav-page-wrap"> <div class="has-top-nav-page-wrap">
<ImportAndExport :visible="importAndExportVisible" @close="onImportAndExportClose"></ImportAndExport>
<div class="tree-menu member-tree"> <div class="tree-menu member-tree">
<div class="input-wrap"> <div class="input-wrap">
<a-input <a-input
...@@ -36,38 +37,6 @@ ...@@ -36,38 +37,6 @@
:defaultExpandedKeys="['0-0']" :defaultExpandedKeys="['0-0']"
:treeData="roleTreeData" :treeData="roleTreeData"
></Tree> ></Tree>
<!-- <a-tree
v-show="searchType.current === Object.keys(searchType.types)[0]"
v-model:expandedKeys="expandedKeys"
:treeData="organizationTreeData"
:replaceFields="{
children:'children', title:'name', key:'id'
}"
showIcon
@select="selectOrganization"
>
<template #icon>
<span class="iconfont iconjiegou"></span>
</template>
<template v-slot:title="item">
<span class="qd-tree-title">{{item.name}}</span>
<a-space :size="2" class="oprate-icon">
<a-button type="default" @click.stop="testAdd(item)"><PlusOutlined></PlusOutlined></a-button>
<a-button type="default" @click.stop="test(item)"><CloseOutlined></CloseOutlined></a-button>
</a-space>
<div v-if="addSub === item.id" class="add-sub">
<a-input @click.stop=""></a-input>
<CloseCircleFilled @click.stop=""/>
<CheckCircleFilled @click.stop=""/>
</div>
</template>
<template #custom=item>
<span>{{item.title}}</span>
<a-button type="default" @click.stop="test(item)">删除</a-button>
<a-button type="default" @click.stop="test(item)">添加</a-button>
</template>
</a-tree> -->
</div> </div>
</div> </div>
<div class="right-operate operate-wrap"> <div class="right-operate operate-wrap">
...@@ -75,7 +44,7 @@ ...@@ -75,7 +44,7 @@
<div class="top-wrap flex-justify"> <div class="top-wrap flex-justify">
<span class="top-title">客服部</span> <span class="top-title">客服部</span>
<span class="menber-count">共4人</span> <span class="menber-count">共4人</span>
<a-button type='default' class="qd-btn" @click="edit">编辑</a-button> <a-button type='default' class="qd-btn" @click="editDep">编辑</a-button>
</div> </div>
<div class="current-breadcrumb flex-justify"> <div class="current-breadcrumb flex-justify">
<span>深圳企大科技有限公司</span> <span class="ant-breadcrumb-separator">&gt;</span> <span>客服部</span> <span>深圳企大科技有限公司</span> <span class="ant-breadcrumb-separator">&gt;</span> <span>客服部</span>
...@@ -88,7 +57,7 @@ ...@@ -88,7 +57,7 @@
</div> </div>
<div class="level-list-wrap"> <div class="level-list-wrap">
<div class="level-optation flex-justify"> <div class="level-optation flex-justify">
<a-button type="default" class="qd-btn qd-btn-default-w">添加子部门</a-button> <a-button type="default" class="qd-btn qd-btn-default-w" @click="addDep">添加子部门</a-button>
</div> </div>
<a-table class="qd-table" :showHeader="false" :pagination="false" :data-source="tableData" :columns="columns" :scroll="{y: 84}"> <a-table class="qd-table" :showHeader="false" :pagination="false" :data-source="tableData" :columns="columns" :scroll="{y: 84}">
<template #tags> <template #tags>
...@@ -105,68 +74,45 @@ ...@@ -105,68 +74,45 @@
<div class="level-list-wrap"> <div class="level-list-wrap">
<div class="level-optation flex-justify"> <div class="level-optation flex-justify">
<a-space :size="15"> <a-space :size="15">
<a-button type="default" class="qd-btn">添加学员</a-button> <a-button type="default" class="qd-btn" @click="addMenber">添加学员</a-button>
<a-button type="default" class="qd-btn dif-btn">批量删除/导入/修改</a-button> <a-button type="default" class="qd-btn dif-btn" @click="()=> importAndExportVisible = true">批量删除/导入/修改</a-button>
<a-button type="default" class="qd-btn">调整部门</a-button> <a-button type="default" class="qd-btn" @click="()=> depSelectModalVisible = true">调整部门</a-button>
<a-button type="default" class="qd-btn">批量删除</a-button> <a-button type="default" class="qd-btn">批量删除</a-button>
<a-button type="default" class="qd-btn qd-btn-default-w">年度达标学分</a-button> <a-button type="default" class="qd-btn qd-btn-default-w" @click="() => {componentIndex = 3; drawerVisible = true}">年度达标学分</a-button>
</a-space> </a-space>
</div> </div>
<a-table class="qd-table" :data-source="menberData" :columns="menberColumns" :row-selection="rewSelection"></a-table> <a-table class="qd-table" :data-source="menberData" :columns="menberColumns" :row-selection="rewSelection"></a-table>
</div> </div>
</section> </section>
</div> </div>
<DepSelectModal></DepSelectModal> <component :is="componentArr[componentIndex]" :visible="drawerVisible" @close="onDrawerClose"></component>
<!-- <DepartmentDrawer :visible="visible" @close="onClose"></DepartmentDrawer> --> <DepSelectModal :visible="depSelectModalVisible" @close="onDepSelectModalClose"></DepSelectModal>
<component :is="'DepartmentDrawer'" :visible="visible" @close="onClose"></component>
</div> </div>
</template> </template>
<script> <script>
import { RightOutlined } from '@ant-design/icons-vue' import EditDepDrawer from '../../components/EditDepDrawer'
import DepartmentDrawer from '../../components/DepartmentDrawer' import AddDepDrawer from '../../components/AddDepDrawer'
import TestDrawer from '../../components/TestDrawer' import AddMenberDrawer from '../../components/AddMenberDrawer'
import Tree from '../../components/Tree'
import DepSelectModal from '../../components/DepSelectModal' import DepSelectModal from '../../components/DepSelectModal'
import ComplianceScoreDrawer from '../../components/ComplianceScoreDrawer'
import ImportAndExport from '../../components/ImportAndExport'
import Tree from '../../components/Tree'
import { RightOutlined } from '@ant-design/icons-vue'
import { aTree, listToTree } from '../../libs/testModal' import { aTree, listToTree } from '../../libs/testModal'
console.log(listToTree(aTree)) console.log(listToTree(aTree))
export default { export default {
components: {
RightOutlined,
Tree,
/* eslint-disable */
DepSelectModal,
DepartmentDrawer,
TestDrawer
/* eslint-enable */
},
mounted () {
this.expandedKeys.push(0)
this.departmentList = aTree
},
setup () {
const rewSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
},
onSelect: (record, selected, selectedRows) => {
console.log(record, selected, selectedRows)
},
onSelectAll: (selected, selectedRows, changeRows) => {
console.log(selected, selectedRows, changeRows)
}
}
return {
rewSelection
}
},
data () { data () {
return { return {
searchKey: '', searchKey: '',
showLine: false, showLine: false,
showIcon: true, showIcon: true,
visible: false, drawerVisible: false,
importAndExportVisible: false,
depSelectModalVisible: false,
expandedKeys: [], expandedKeys: [],
departmentList: [], departmentList: [],
componentIndex: [],
componentArr: ['EditDepDrawer', 'AddDepDrawer', 'AddMenberDrawer', 'ComplianceScoreDrawer'],
roleTreeData: [{ roleTreeData: [{
name: '所有', name: '所有',
id: '0-0', id: '0-0',
...@@ -353,21 +299,72 @@ export default { ...@@ -353,21 +299,72 @@ export default {
} }
} }
}, },
computed: {
placeholder () {
const searchType = this.searchType
const keys = Object.keys(searchType.types)
if (searchType.current === keys[0]) {
return '搜索学员'
} else {
return '搜素角色'
}
},
organizationTreeData () {
if (this.departmentList.length <= 1) {
return []
}
return listToTree(this.departmentList)
}
},
components: {
/* eslint-disable */
EditDepDrawer,
AddDepDrawer,
AddMenberDrawer,
ComplianceScoreDrawer,
/* eslint-enable */
ImportAndExport,
DepSelectModal,
Tree,
RightOutlined
},
setup () {
const rewSelection = {
onChange: (selectedRowKeys, selectedRows) => {
console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows)
},
onSelect: (record, selected, selectedRows) => {
console.log(record, selected, selectedRows)
},
onSelectAll: (selected, selectedRows, changeRows) => {
console.log(selected, selectedRows, changeRows)
}
}
return {
rewSelection
}
},
methods: { methods: {
testAdd (e) { editDep () {
console.log(e.dataRef.id) this.componentIndex = 0
console.log(this.expandedKeys) this.drawerVisible = true
this.expandedKeys.push(e.dataRef.id) },
this.addSub = e.dataRef.id addDep () {
this.componentIndex = 1
this.drawerVisible = true
}, },
edit () { addMenber () {
this.visible = true this.componentIndex = 2
this.drawerVisible = true
}, },
onClose () { onDrawerClose () {
this.visible = false this.drawerVisible = false
}, },
test (item) { onImportAndExportClose () {
console.log(item) this.importAndExportVisible = false
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
}, },
onChange (e) { onChange (e) {
this.searchKey = e.target.value this.searchKey = e.target.value
...@@ -388,22 +385,9 @@ export default { ...@@ -388,22 +385,9 @@ export default {
} }
}, },
computed: { mounted () {
placeholder () { this.expandedKeys.push(0)
const searchType = this.searchType this.departmentList = aTree
const keys = Object.keys(searchType.types)
if (searchType.current === keys[0]) {
return '搜索学员'
} else {
return '搜素角色'
}
},
organizationTreeData () {
if (this.departmentList.length <= 1) {
return []
}
return listToTree(this.departmentList)
}
} }
} }
</script> </script>
......
const IS_DEBUG = process.env.NODE_ENV === 'dev' const IS_DEBUG = process.env.NODE_ENV === 'dev'
const px2rem = require('postcss-px2rem') const px2rem = require('postcss-px2rem')
// 配置基本大小 const path = require('path')
// 基准大小 baseSize,按设计稿1920 / 10计算
const postcss = px2rem({ const postcss = px2rem({
// 基准大小 baseSize,按设计稿1920 / 10计算
remUnit: 192 remUnit: 192
}) })
console.log(`当前运行环境为: ${IS_DEBUG ? 'development' : 'production'}`)
module.exports = { module.exports = {
publicPath: './',
assetsDir: 'static',
outputDir: 'admin-new',
lintOnSave: true, lintOnSave: true,
configureWebpack: config => { productionSourceMap: IS_DEBUG,
if (IS_DEBUG) { filenameHashing: true,
config.output.devtoolModuleFilenameTemplate = info => { configureWebpack: {
const resPath = info.resourcePath mode: IS_DEBUG ? 'development' : 'production',
if ((/\.vue$/.test(resPath) && !/type=script/.test(info.identifier)) || /node_modules/.test(resPath)) { devtool: IS_DEBUG ? 'source-map' : false,
return `webpack:///${resPath}?${info.hash}` output: {
} path: path.resolve(__dirname, 'admin-new'),
return `webpack:///${resPath.replace('./src', 'clm-admin-dev/src')}` filename: 'js/[name].[hash:8].js',
} chunkFilename: 'js/[name].[hash:8].js'
} }
}, },
css: { css: {
extract: !IS_DEBUG,
sourceMap: IS_DEBUG, sourceMap: IS_DEBUG,
loaderOptions: { loaderOptions: {
postcss: { postcss: {
plugins: [postcss] plugins: [postcss]
} }
} }
},
devServer: {
proxy: 'http://192.168.1.9:8093'
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment