Commit cca4623f by xiaowenfeng

1、修改了router

parent 11c053cc
<template>
<div id="app-body">
<Header></Header>
<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 id="app">
<router-view/>
</div>
</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">
@nav-width: 208px;
......@@ -67,7 +42,7 @@ cursor: pointer ;
min-width: 1440px;/*no*/
min-height: 900px; /*no*/
height: 100%;
#app-body {
#app {
width: 100%;
height: 100%;
// overflow-x: scroll;
......
<template>
<a-drawer
title="编辑部门"
title="添加子部门"
:placement="placement"
:closable="false"
:visible="visible"
:wrap-style="{ position: 'absolute' }"
:wrapClassName="'right-drawer'"
:get-container="'#rightBody'"
@close="onClose"
>
<p class="drawer-form-title">部门信息</p>
<div class="department-edit">
<a-form>
<a-form-item label="部门名称" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/>
</a-form-item>
<a-form-item label="上级部门">
<a-input v-model:value="modelRef.superiorDepartment" allow-clear/>
</a-form-item>
<a-form-item label="简介" class="drawer-text">
<a-textarea v-model:value="modelRef.describe" allow-clear/>
</a-form-item>
</a-form>
</div>
<p class="drawer-form-title">部门必修课</p>
<div class="bot-btn">
<a-form>
<p class="drawer-form-title">部门信息</p>
<div class="department-edit">
<a-form-item label="部门名称" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/>
</a-form-item>
<a-form-item label="上级部门">
<a-input v-model:value="modelRef.superiorDepartment" allow-clear @click="setSuperiorDepartment"/>
</a-form-item>
<a-form-item label="简介" class="drawer-text">
<a-textarea v-model:value="modelRef.describe" allow-clear/>
</a-form-item>
</div>
</a-form>
<div class="bot-btn">
<a-space :size="35">
<a-button type="default" class="qd-right-drawer-btn" @click="onClose">
删除dddd
删除
</a-button>
<a-button type="default" class="qd-right-drawer-btn qd-right-drawer-btn-save " @click="onSubmit">
保存
......@@ -36,23 +34,24 @@
取消
</a-button>
</a-space>
</div>
</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'
}
},
methods: {
onClose () {
this.$emit('close')
}
components: {
DepSelectModal
},
setup () {
const modelRef = reactive({
......@@ -86,6 +85,17 @@ export default {
modelRef,
onSubmit
}
},
methods: {
onClose () {
this.$emit('close')
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
},
setSuperiorDepartment () {
this.depSelectModalVisible = true
}
}
}
</script>
......@@ -96,7 +106,7 @@ export default {
padding-top: 20px;
.drawer-text{
height: 101px !important;
padding-top: 1px !important;
// padding-top: 1px !important;
}
}
</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.name">
<a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入10个汉字 (20字符)'"/>
</a-form-item>
<a-form-item label="登陆账号" v-bind="validateInfos.loginAccount">
<a-input v-model:value="modelRef.loginAccount" allow-clear :placeholder="'成员唯一标识,设定后不支持修改'"/>
</a-form-item>
<a-form-item label="手机号" v-bind="validateInfos.phoneNumber">
<a-input v-model:value="modelRef.phoneNumber" allow-clear :placeholder="'请输入手机号'">
<template #addonBefore>
<a-select v-model:value="phoneprefix" style="width: 90px">
<a-select-option value="+86">
+86
</a-select-option>
</a-select>
</template>
</a-input>
</a-form-item>
<a-form-item label="部门" v-bind="validateInfos.superiorDepartment" @click="setSuperiorDepartment">
<a-input v-model:value="modelRef.superiorDepartment" allow-clear :placeholder="'请选择部门'"/>
</a-form-item>
<a-form-item label="岗位" v-bind="validateInfos.post">
<a-input v-model:value="modelRef.post" allow-clear :placeholder="''"/>
</a-form-item>
<a-form-item label="身份证号" v-bind="validateInfos.IDNumber">
<a-input v-model:value="modelRef.IDNumber" allow-clear :placeholder="''"/>
</a-form-item>
<a-form-item label="邮箱" v-bind="validateInfos.email">
<a-input v-model:value="modelRef.email" allow-clear :placeholder="''"/>
</a-form-item>
<a-form-item label="学历" v-bind="validateInfos.education">
<a-select :placeholder="'请选择学员学历'" @change="handleChange">
<a-select-option v-for="(item, key, index) in education" :key="index" :value="key">
{{item}}
</a-select-option>
</a-select>
</a-form-item>
<a-form-item label="角色" v-bind="validateInfos.role">
<a-input v-model:value="modelRef.role" allow-clear :placeholder="'请选择学员角色'"/>
</a-form-item>
</div>
<p class="drawer-form-title">高级设置</p>
<div class="advanced-setting">
<a-form-item label="账号使用期限" v-bind="validateInfos.serviceLife">
<a-radio-group v-model:value="value1" button-style="solid">
<a-radio-button value="1">
7天
</a-radio-button>
<a-radio-button value="2">
1个月
</a-radio-button>
<a-radio-button value="3">
3个月
</a-radio-button>
<a-radio-button value="4">
6个月
</a-radio-button>
</a-radio-group>
<a-date-picker show-time placeholder="请选择时间" @change="onChange" @ok="onOk"/>
</a-form-item>
<a-form-item label="初始密码" v-bind="validateInfos.initialPassword">
<a-input v-model:value="modelRef.initialPassword" allow-clear :disabled="true"/>
</a-form-item>
<a-form-item label="权限身份" v-bind="validateInfos.identity">
<a-radio-group v-model:value="value2" button-style="solid" class="bot-radio">
<a-popover content="可登录学员端,学习开放课程以及自选选修课程等任务。" placement="bottom" :get-popup-container="getPopupContainer">
<a-radio-button value="1">
普通学员
</a-radio-button>
</a-popover>
<a-popover content="可登录管理员端对课程、课件内容进行编辑,上传并增加培训任务和派发培训任务" placement="bottom" :get-popup-container="getPopupContainer">
<a-radio-button value="2">
讲师
</a-radio-button>
</a-popover>
<a-popover content="可登录学员端,可进行成员管理、任务派发、课程审核、资源管理、数据报表下载、平台设置等操作" placement="bottom" :get-popup-container="getPopupContainer">
<a-radio-button value="3">
管理员
</a-radio-button>
</a-popover>
<a-popover content="拥有管理员所有权限,并可添加/删除管理员" placement="bottom" :get-popup-container="getPopupContainer">
<a-radio-button value="4">
超级管理员
</a-radio-button>
</a-popover>
</a-radio-group>
</a-form-item>
</div>
</a-form>
<div class="bot-btn">
<a-space :size="35">
<a-button type="default" class="qd-right-drawer-btn" @click="onClose">
删除
</a-button>
<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, toRefs, 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 phoneprefix = '+86'
const education = {
// 0: '请选择学员学历',
1: '小学及以下',
3: '初中',
4: '高中/中专/技校',
5: '大学专科',
6: '大学本科',
7: '硕士研究生及以上',
8: '其他'
}
const test = reactive({
value1: 1,
value2: '',
phoneprefix: '+86'
})
const modelRef = reactive({
name: '',
loginAccount: '',
phoneNumber: '',
superiorDepartment: '',
post: '',
IDNumber: '',
email: '',
education: 0,
role: '',
serviceLife: '',
initialPassword: '12345',
identity: ''
})
const rulesRef = reactive({
name: [{ required: true, message: 'false' }],
loginAccount: [{ required: true, message: false }],
phoneNumber: [{ required: true, message: false }],
superiorDepartment: [{ required: true, message: false }],
serviceLife: [{ required: true, message: 'false' }],
initialPassword: [{ required: true, message: false }],
identity: [{ required: true, message: 'false' }]
})
const { resetFields, validate, validateInfos } = useForm(modelRef, rulesRef)
const onSubmit = e => {
e.preventDefault()
validate()
.then(() => {
console.log(toRaw(modelRef))
})
.catch(err => {
console.log('error', err)
})
}
const handleChange = (value) => {
console.log(`selected ${value}`)
modelRef.education = value
console.log(modelRef)
}
const getPopupContainer = (trigger) => {
return trigger.parentElement.parentElement.parentElement
}
return {
// phoneprefix,
// value1,
...toRefs(test),
education,
validateInfos,
resetFields,
modelRef,
onSubmit,
handleChange,
getPopupContainer
}
},
methods: {
onClose () {
this.$emit('close')
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
},
setSuperiorDepartment () {
this.depSelectModalVisible = true
},
onChange (value, dateString) {
console.log('Selected Time: ', value)
console.log('Formatted Selected Time: ', dateString)
},
onOk (value) {
console.log('onOk: ', value)
}
}
}
</script>
<style lang="less" scoped>
@department-edit-height: 433px;
@drawer-form-title-height: 36px;
.drawer-form-title {
height: @drawer-form-title-height;
}
.department-edit{
height: @department-edit-height;
width: 100%;
padding: 9px 0;
overflow-y: scroll;
::v-deep(.ant-form-item ){
height: 53px !important;
padding: 5px 0 !important;
.ant-form-item-control-wrapper {
width: 449px;
.ant-form-explain {
font-size: 12px;
}
}
.ant-input-wrapper {
.ant-input-group-addon {
border-radius: 4px;
border: none;
}
}
.ant-select-selector {
border-radius: 4px;
}
}
.drawer-text{
height: 101px !important;
// padding-top: 1px !important;
}
}
.advanced-setting {
height: calc(100% - @department-edit-height - 2 * @drawer-form-title-height);
overflow-y: scroll;
padding: 9px 0;
::v-deep(.ant-form-item) {
height: 53px !important;
padding: 5px 0 !important;
.ant-form-item-control-wrapper {
width: 449px;
.ant-form-explain {
font-size: 12px;
}
.ant-radio-button-wrapper {
width: 58px;
margin-right: 5px;
border-radius: 4px;
padding: 0;
text-align: center;
}
.bot-radio {
.ant-radio-button-wrapper {
padding: 0 15px;
width: auto;
}
}
}
.ant-calendar-picker {
min-width: 60px !important;
}
}
}
.bot-btn {
.qd-right-drawer-btn-save {
width: 114px !important;
min-width: 100px; /*no*/
border: none;
}
}
</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>
<a-modal
:get-container="'#rightBody'"
:visible="true"
:maskStyle="{position: 'absolute'}"
:closable="false"
:wrapClassName="'qd-input-modal'"
:confirm-loading="confirmLoading"
:okText="'确定'"
:cancelText="'取消'"
:get-container="setParent"
title="选择部门"
:visible="visible"
@ok="handleOk"
@cancel="handleCancel"
>
<div class="select-wrap">
<div class="content">
......@@ -19,20 +21,114 @@
allow-clear
/>
<div class="current">
<div>深圳企大云科技有限公司</div>
<div>></div>
<div>客服部</div>
<div class="top">
<div class="right">
<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 class="content">
<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>
</a-modal>
</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>
@import url('../css/common.less');
.select-wrap {
width: 100%;
height: 100%;
......@@ -64,6 +160,95 @@
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 @@
:wrapClassName="'right-drawer'"
:get-container="'#rightBody'"
>
<p class="drawer-form-title">部门信息</p>
<div class="department-edit">
<a-form>
<a-form-item label="部门名称" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/>
</a-form-item>
<a-form-item label="上级部门">
<a-input v-model:value="modelRef.superiorDepartment" allow-clear/>
</a-form-item>
<a-form-item label="简介" class="drawer-text">
<a-textarea v-model:value="modelRef.describe" allow-clear/>
</a-form-item>
</a-form>
</div>
<p class="drawer-form-title">部门必修课</p>
<div class="bot-btn">
<a-space :size="35">
<a-button type="default" class="qd-right-drawer-btn" @click="onClose">
删除
</a-button>
<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>
<a-form>
<p class="drawer-form-title">部门信息</p>
<div class="department-edit">
<a-form-item label="部门名称" v-bind="validateInfos.name">
<a-input v-model:value="modelRef.name" allow-clear :placeholder="'最多允许输入30个汉子 (60字符)'"/>
</a-form-item>
<a-form-item label="上级部门">
<a-input v-model:value="modelRef.superiorDepartment" allow-clear @click="setSuperiorDepartment"/>
</a-form-item>
<a-form-item label="简介" class="drawer-text">
<a-textarea v-model:value="modelRef.describe" allow-clear/>
</a-form-item>
</div>
<p class="drawer-form-title">部门必修课</p>
</a-form>
<div class="bot-btn">
<a-space :size="35">
<a-button type="default" class="qd-right-drawer-btn" @click="onClose">
删除
</a-button>
<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 DepSelectModal from './DepSelectModal'
import { reactive, toRaw } from 'vue'
import { useForm } from '@ant-design-vue/use'
export default {
props: ['visible'],
data () {
return {
depSelectModalVisible: false,
placement: 'right'
}
},
methods: {
onClose () {
this.$emit('close')
}
components: {
DepSelectModal
},
setup () {
const modelRef = reactive({
......@@ -85,6 +86,17 @@ export default {
modelRef,
onSubmit
}
},
methods: {
onClose () {
this.$emit('close')
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
},
setSuperiorDepartment () {
this.depSelectModalVisible = true
}
}
}
</script>
......@@ -95,7 +107,7 @@ export default {
padding-top: 20px;
.drawer-text{
height: 101px !important;
padding-top: 1px !important;
// padding-top: 1px !important;
}
}
</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 {
this.$router.isReady().then(() => {
const routes = this.$router.options.routes
const tops = routes[0].tops
const leftnav = routes.slice(1, routes.length)
const currentRoute = this.$router.currentRoute.value.matched[0]
console.log(leftnav)
console.log(currentRoute)
const leftnav = routes[0].children
const currentRoute = this.$route
console.log('leftnav:', leftnav)
console.log('tops:', tops)
const newTops = tops.map((item) => {
console.log('currentRoute:', currentRoute)
tops.map((item) => {
this.rootSubmenuKeys.push(item.id)
const grop = leftnav.filter(i => {
if (currentRoute && currentRoute.meta && item.id === currentRoute.meta.parent && i.path === currentRoute.path) {
this.selectedKeys.push(i.path)
this.openKeys.push(item.id)
if (item.id === currentRoute.meta.parent && currentRoute.path.startsWith(i.path)) {
this.openKeys = [item.id]
this.selectedKeys = [i.path]
}
if (i.meta && i.meta.parent) {
return i.meta.parent === item.id
......@@ -64,10 +64,9 @@ export default {
}
return item
})
// console.log('newTops:', newTops)
// console.log('this.selectedKeys:', this.selectedKeys)
// console.log('this.openKeys:', this.openKeys)
this.menus = newTops
this.menus = tops
console.log(this.menus)
console.log(this.openKeys)
})
},
methods: {
......
<template>
<div class="nav-list">
<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>
</div>
</template>
......@@ -13,6 +13,7 @@ export default {
}
},
mounted () {
console.log('rightNav:', this.$route)
this.current.push(this.$route.path)
}
}
......
......@@ -47,9 +47,6 @@ export default {
type: Array
}
},
mounted () {
this.expandedKeys = this.defaultExpandedKeys
},
data () {
return {
expandedKeys: [],
......@@ -84,6 +81,9 @@ export default {
// editable: '1'
// })
}
},
mounted () {
this.expandedKeys = this.defaultExpandedKeys
}
}
</script>
......
......@@ -5,130 +5,226 @@
@right-drawer-header-height: 111px;
@right-drawer-btns-height: 81px;
@right-drawer-body-height: calc(100% - @right-drawer-header-height - @right-drawer-btns-height);
.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%;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
.tree-menu {
width: 297px;
height: 100%;
background: #F2F2F2 100%;
}
.right-operate {
width: @right-operate;
height: 100%;
background: #FFFFFF 100%;
}
background: #F2F2F2 100%;
}
.right-operate {
width: @right-operate;
height: 100%;
background: #FFFFFF 100%;
}
}
.flex-justify {
display: flex;
align-items: center;
justify-content: flex-start;
text-align: justify;
display: flex;
align-items: center;
justify-content: flex-start;
text-align: justify;
}
::v-deep(.qd-btn) {
width: 93px;
height: 30px;
border-radius: 90px;
font-size: 14px;
text-align: center;
font-family: PingFang SC;
padding: 0;
width: 93px;
height: 30px;
border-radius: 90px;
font-size: 14px;
text-align: center;
font-family: PingFang SC;
padding: 0;
}
::v-deep(.qd-btn-default-w) {
min-width: 93px;/*no*/
min-width: 93px;
/*no*/
}
::v-deep(.qd-table) {
.ant-table-thead > tr > th {
padding-top: 10px;
padding-bottom: 10px;
font-weight: bold;
.ant-table-thead>tr>th {
padding-top: 10px;
padding-bottom: 10px;
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 {
padding-top: 10px;
padding-bottom: 10px;
.bot-btn {
position: absolute;
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(.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;
::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-drawer-content-wrapper {
box-shadow: 0px 0px 3px 0px rgba(0, 0, 0, 0.12);
border: 1px solid rgba(255, 255, 255, 100);
}
.bot-btn {
position: absolute;
bottom: 0;
width: 100%;
height: @right-drawer-btns-height;
border-top: 1px solid #e8e8e8;
padding: 23px 23px 22px 23px;
}
.ant-modal-body {
background: #FFFFFF 100%;
height: 450px;
padding: 0 41px;
}
.ant-modal-footer {
border: none;
height: 67px;
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;
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;
}
.qd-right-drawer-btn-save {
background: #000000 100%;
div {
>:last-child {
left: 254px;
background: #000;
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";
src: url('iconfont.eot?t=1605576180830'); /* IE9 */
src: url('iconfont.eot?t=1605576180830#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('iconfont.woff?t=1605576180830') format('woff'),
url('iconfont.ttf?t=1605576180830') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1605576180830#iconfont') format('svg'); /* iOS 4.1- */
src: url('iconfont.eot?t=1606441605337'); /* IE9 */
src: url('iconfont.eot?t=1606441605337#iefix') format('embedded-opentype'), /* IE6-IE8 */
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=1606441605337') format('woff'),
url('iconfont.ttf?t=1606441605337') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1606441605337#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
......@@ -15,6 +15,14 @@
-moz-osx-font-smoothing: grayscale;
}
.iconziyuan:before {
content: "\e601";
}
.iconjurassic_hat:before {
content: "\e69a";
}
.iconquanquanb:before {
content: "\e6d4";
}
......
......@@ -20,6 +20,12 @@ Created by iconfont
/>
<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" />
......
......@@ -5,21 +5,26 @@ import store from './store'
import http from './service/http'
import './libs/flexible'
import {
ConfigProvider,
Button,
Popover,
Menu,
Breadcrumb,
Input,
InputNumber,
Tree,
Table,
Space,
Drawer,
Form,
Modal
Modal,
Radio,
Select,
DatePicker,
Upload,
Spin
} from 'ant-design-vue'
// console.log(process.env)
// router.beforeEach((to, from, next) => {
// /* 必须调用 `next` */
// console.log(to)
......@@ -27,22 +32,28 @@ import {
// next()
// })
// createApp.config.devtools = process.env.NODE_ENV === 'dev'
const app = createApp(App)
app.config.globalProperties.$http = http
if (process.env.NODE_ENV === 'dev') {
app.config.devtools = true
}
app.use(Button)
app.use(Popover)
app.use(Menu)
app.use(Breadcrumb)
app.use(Input)
app.use(Tree)
app.use(Table)
app.use(Space)
app.use(Drawer)
app.use(Form)
app.use(Modal)
app.use(store)
app.use(router)
app.mount('#app')
app.use(ConfigProvider)
.use(Button)
.use(Popover)
.use(Menu)
.use(Breadcrumb)
.use(Input)
.use(InputNumber)
.use(Tree)
.use(Table)
.use(Space)
.use(Drawer)
.use(Form)
.use(Modal)
.use(Radio)
.use(Select)
.use(DatePicker)
.use(Upload)
.use(Spin)
.use(store)
.use(router)
.mount('#app')
import { createRouter, createWebHistory } from 'vue-router'
import App from '../App.vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
import ErrPage from '../views/ErrPage.vue'
const routes = [
{
path: '/',
name: 'App',
component: App,
name: 'Home',
component: Home,
redirect: '/traineeManage',
tops: [
{
......@@ -39,78 +39,80 @@ const routes = [
id: 'top6',
items: []
}
]
},
{
path: '/traineeManage',
name: '学员管理',
component: () => import('../views/origanizationManage/TraineeManage.vue'),
redirect: '/traineeManage/member',
meta: { parent: 'top4' },
],
children: [
{
path: '/traineeManage/member',
path: '/traineeManage',
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',
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',
path: '/adminManage',
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',
name: 'error-404',
component: ErrPage
......@@ -122,7 +124,7 @@ const routes = [
]
const router = createRouter({
history: createWebHistory(),
history: createWebHashHistory(),
routes
})
......
const CONTACT_API = {
// 获取联系人列表
getContactList: {
findMenuList: {
method: 'get',
url: ''
url: '/sys/review/menu/list.do?'
}
}
export default CONTACT_API
import axios from 'axios'
import qs from 'qs'
import service from './contactApi'
// service 循环遍历输出不同的请求方法
const instance = axios.create({
baseURL: 'http://localhost:8080/api',
timeout: 1000
baseURL: './',
timeout: 1000,
withCredentials: true
})
// 包裹请求
......@@ -13,12 +15,13 @@ const Http = {}
for (const key in service) {
// url 请求相对路径
// method 请求方法
const { method, url } = service[key]
let { method, url } = service[key]
// async 作用:实在不想写回调地狱
// params 请求参数 get:url; put, post, patch(data); delete: url
// isFormData 是否是formData
// config 请求配置
Http[key] = async function (params, isFormData = false, config = {}) {
// 处理后的参数
let newParams = {}
if (params && isFormData) {
newParams = new FormData()
......@@ -39,6 +42,7 @@ for (const key in service) {
}
} else if (method === 'delete' || method === 'get') {
config.params = newParams
url += qs.stringify(params)
try {
response = await instance[method](url, newParams, config)
} catch (err) {
......
<template>
<div class="right-body" id="rightBody">
<div class="right-main">
<div class="breadcrumb">
<a-breadcrumb separator=">>">
<a-breadcrumb-item>{{root}}</a-breadcrumb-item>
<a-breadcrumb-item :href="item.path" v-for="item in list" :key="item.path">
{{item.name}}
</a-breadcrumb-item>
</a-breadcrumb>
</div>
<div class="right-main-body">
<router-view></router-view>
<a-config-provider :locale="root.locale">
<Header></Header>
<div class="main-wrap">
<div class="left-menu-wrap">
<LeftNav :company="root.company"></LeftNav>
</div>
<div class="right-wrap">
<div class="right-body" id="rightBody" ref="rightBody">
<div class="right-main">
<div class="breadcrumb">
<a-breadcrumb separator=">>">
<!-- <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>
<Footer></Footer>
</div>
</div>
<Footer></Footer>
</div>
</div>
</a-config-provider>
</template>
<script>
import Header from '../components/Header'
import LeftNav from '../components/LeftNav'
import Footer from '../components/Footer'
import { getCurrentInstance } from 'vue'
import zhCN from 'ant-design-vue/es/locale/zh_CN'
export default {
props: {
root: {
type: String,
required: true
}
},
data () {
return {
list: []
list: [],
root: {
locale: zhCN,
company: '深圳企大科技有限公司'
}
}
},
components: {
Header,
LeftNav,
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: {
$route (to, from) {
// console.log('to:', to)
// console.log('from:', from)
this.getBreadcrumb()
}
},
methods: {
getBreadcrumb () {
const matched = this.$route.matched
// console.log(matched)
this.list = matched
this.list = this.$route.matched
}
}
}
......@@ -65,63 +91,6 @@ export default {
background: #F9F9F9 100%;
position: relative;
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 {
width: 100%;
height: calc(100% - @footer-height);
......@@ -137,6 +106,7 @@ export default {
.right-main-body {
width: 100%;
height: calc(100% - @right-main-body-height);
position: relative;
&>div{
height: 100%;
width: 100%;
......
<template>
<div class="has-top-nav-page-wrap">
<ImportAndExport :visible="importAndExportVisible" @close="onImportAndExportClose"></ImportAndExport>
<div class="tree-menu member-tree">
<div class="input-wrap">
<a-input
......@@ -36,38 +37,6 @@
:defaultExpandedKeys="['0-0']"
:treeData="roleTreeData"
></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 class="right-operate operate-wrap">
......@@ -75,7 +44,7 @@
<div class="top-wrap flex-justify">
<span class="top-title">客服部</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 class="current-breadcrumb flex-justify">
<span>深圳企大科技有限公司</span> <span class="ant-breadcrumb-separator">&gt;</span> <span>客服部</span>
......@@ -88,7 +57,7 @@
</div>
<div class="level-list-wrap">
<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>
<a-table class="qd-table" :showHeader="false" :pagination="false" :data-source="tableData" :columns="columns" :scroll="{y: 84}">
<template #tags>
......@@ -105,68 +74,45 @@
<div class="level-list-wrap">
<div class="level-optation flex-justify">
<a-space :size="15">
<a-button type="default" class="qd-btn">添加学员</a-button>
<a-button type="default" class="qd-btn dif-btn">批量删除/导入/修改</a-button>
<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" @click="()=> importAndExportVisible = true">批量删除/导入/修改</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 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>
</div>
<a-table class="qd-table" :data-source="menberData" :columns="menberColumns" :row-selection="rewSelection"></a-table>
</div>
</section>
</div>
<DepSelectModal></DepSelectModal>
<!-- <DepartmentDrawer :visible="visible" @close="onClose"></DepartmentDrawer> -->
<component :is="'DepartmentDrawer'" :visible="visible" @close="onClose"></component>
<component :is="componentArr[componentIndex]" :visible="drawerVisible" @close="onDrawerClose"></component>
<DepSelectModal :visible="depSelectModalVisible" @close="onDepSelectModalClose"></DepSelectModal>
</div>
</template>
<script>
import { RightOutlined } from '@ant-design/icons-vue'
import DepartmentDrawer from '../../components/DepartmentDrawer'
import TestDrawer from '../../components/TestDrawer'
import Tree from '../../components/Tree'
import EditDepDrawer from '../../components/EditDepDrawer'
import AddDepDrawer from '../../components/AddDepDrawer'
import AddMenberDrawer from '../../components/AddMenberDrawer'
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'
console.log(listToTree(aTree))
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 () {
return {
searchKey: '',
showLine: false,
showIcon: true,
visible: false,
drawerVisible: false,
importAndExportVisible: false,
depSelectModalVisible: false,
expandedKeys: [],
departmentList: [],
componentIndex: [],
componentArr: ['EditDepDrawer', 'AddDepDrawer', 'AddMenberDrawer', 'ComplianceScoreDrawer'],
roleTreeData: [{
name: '所有',
id: '0-0',
......@@ -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: {
testAdd (e) {
console.log(e.dataRef.id)
console.log(this.expandedKeys)
this.expandedKeys.push(e.dataRef.id)
this.addSub = e.dataRef.id
editDep () {
this.componentIndex = 0
this.drawerVisible = true
},
addDep () {
this.componentIndex = 1
this.drawerVisible = true
},
edit () {
this.visible = true
addMenber () {
this.componentIndex = 2
this.drawerVisible = true
},
onClose () {
this.visible = false
onDrawerClose () {
this.drawerVisible = false
},
test (item) {
console.log(item)
onImportAndExportClose () {
this.importAndExportVisible = false
},
onDepSelectModalClose () {
this.depSelectModalVisible = false
},
onChange (e) {
this.searchKey = e.target.value
......@@ -388,22 +385,9 @@ 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)
}
mounted () {
this.expandedKeys.push(0)
this.departmentList = aTree
}
}
</script>
......
const IS_DEBUG = process.env.NODE_ENV === 'dev'
const px2rem = require('postcss-px2rem')
// 配置基本大小
const path = require('path')
// 基准大小 baseSize,按设计稿1920 / 10计算
const postcss = px2rem({
// 基准大小 baseSize,按设计稿1920 / 10计算
remUnit: 192
})
console.log(`当前运行环境为: ${IS_DEBUG ? 'development' : 'production'}`)
module.exports = {
publicPath: './',
assetsDir: 'static',
outputDir: 'admin-new',
lintOnSave: true,
configureWebpack: config => {
if (IS_DEBUG) {
config.output.devtoolModuleFilenameTemplate = info => {
const resPath = info.resourcePath
if ((/\.vue$/.test(resPath) && !/type=script/.test(info.identifier)) || /node_modules/.test(resPath)) {
return `webpack:///${resPath}?${info.hash}`
}
return `webpack:///${resPath.replace('./src', 'clm-admin-dev/src')}`
}
productionSourceMap: IS_DEBUG,
filenameHashing: true,
configureWebpack: {
mode: IS_DEBUG ? 'development' : 'production',
devtool: IS_DEBUG ? 'source-map' : false,
output: {
path: path.resolve(__dirname, 'admin-new'),
filename: 'js/[name].[hash:8].js',
chunkFilename: 'js/[name].[hash:8].js'
}
},
css: {
extract: !IS_DEBUG,
sourceMap: IS_DEBUG,
loaderOptions: {
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