feat: 报表管理开发

This commit is contained in:
15200171637
2023-02-07 09:05:32 +08:00
parent 234574059e
commit d5a93142a7
13 changed files with 1613 additions and 21223 deletions

2
.env
View File

@@ -4,7 +4,7 @@ VUE_APP_BASE=/manage
VUE_APP_BASE_API=/manageApi
#文件路径
VUE_APP_FILE_PATH=/upload/
# 代理url 本地调试,不可以用在其他地方
# 代理url 本地调试,不可以用在其他地方(厂商内部地址,开发代理直接用测试环境)
VUE_APP_PROXY_URL=http://111.231.196.214/manageApi
# 登录url
VUE_APP_LOGIN_URL=https://u-pre.boe.com/web

21211
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -18,6 +18,7 @@
"axios": "^1.1.3",
"core-js": "^3.8.3",
"dayjs": "^1.11.6",
"echarts":"^5.4.1",
"element-plus": "^2.2.17",
"element-resize-detector": "^1.2.4",
"html2canvas": "^1.4.1",

BIN
src/assets/svg/export.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 B

View File

@@ -0,0 +1 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 13.66"><defs><style>.cls-1{fill:#387df7;}</style></defs><title>daochu备份</title><g id="报表管理-组织学习数据"><g id="组织学习数据-概览备份"><g id="编组-9"><g id="daochu备份"><path id="形状" class="cls-1" d="M12.62,7.61a.52.52,0,0,1,.52.51V12a1.84,1.84,0,0,1-1.84,1.83H1.83A1.83,1.83,0,0,1,0,12V2.52A1.83,1.83,0,0,1,1.83.69H7.09a.52.52,0,0,1,0,1H1.83A.79.79,0,0,0,1,2.52V12a.79.79,0,0,0,.79.79H11.3a.8.8,0,0,0,.8-.79V8.12a.51.51,0,0,1,.52-.51Zm1.2-4.37a.51.51,0,0,1,0,.78L10.91,6.93a.52.52,0,1,1-.73-.73l2-2c-4.51.3-6.3,2.26-6.3,6.7a.52.52,0,0,1-.26.45.53.53,0,0,1-.52,0,.52.52,0,0,1-.26-.45c0-5.07,2.24-7.44,7.42-7.74L10.18,1.06A.49.49,0,0,1,10,.56a.5.5,0,0,1,.37-.37.52.52,0,0,1,.5.14l2.91,2.91Z" transform="translate(0 -0.17)"/></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 872 B

View File

@@ -430,6 +430,55 @@ export default {
},
];
}
if (n.indexOf("/operational") !== -1 || n.indexOf("/OperationaL") !== -1) {
state.list = [
{
name: "报表中心",
},
{
name:'营运数据概览'
}
];
}
if (n.indexOf("/learningpathmap") !== -1 || n.indexOf("/LearningPathMap") !== -1) {
state.list = [
{
name: "报表中心",
},
{
name:'板块详细数据'
},
{
name:'学习路径图'
}
];
}
if (n.indexOf("/overvoew") !== -1 || n.indexOf("/OvervoeW") !== -1) {
state.list = [
{
name: "报表中心",
},
{
name:'组织学习数据'
},
{
name:'概览'
}
];
}
if (n.indexOf("/employeelearning") !== -1 || n.indexOf("/EmployeelearninG") !== -1) {
state.list = [
{
name: "报表中心",
},
{
name:'组织学习数据'
},
{
name:'员工学习数据'
}
];
}
}
);

View File

@@ -287,6 +287,59 @@
</div>
<router-link to="/download">下载中心</router-link>
</a-menu-item>
<a-sub-menu key="sub17">
<template #icon>
<div class="imgBox">
<img
style="width: 18px; height: 15px"
src="../assets/images/navleft/course.png"
/>
</div>
</template>
<template #title>报表中心</template>
<a-menu-item key="sub17-1">
<span
:class="{
circleActive: selectedKeys[0] === 'sub17-1' ? true : false,
circle: selectedKeys[0] === 'sub17-1' ? false : true,
}"
></span>
<router-link to="/operational">营运数据概览</router-link>
</a-menu-item>
<a-sub-menu key="sub17-2" class="treeMenu">
<template #title>版块详细数据</template>
<a-menu-item key="sub17-2-1">
<span
:class="{
circleActive: selectedKeys[0] === 'sub17-2-1' ? true : false,
circle: selectedKeys[0] === 'sub17--2-1' ? false : true,
}"
></span>
<router-link to="/learningpathmap">学习路径图</router-link>
</a-menu-item>
</a-sub-menu>
<a-sub-menu key="sub17-3" class="treeMenu">
<template #title>组织学习数据</template>
<a-menu-item key="sub17-3-1">
<span
:class="{
circleActive: selectedKeys[0] === 'sub17-3-1' ? true : false,
circle: selectedKeys[0] === 'sub17-3-1' ? false : true,
}"
></span>
<router-link to="/overvoew">概览</router-link>
</a-menu-item>
<a-menu-item key="sub17-3-2">
<span
:class="{
circleActive: selectedKeys[0] === 'sub17-3-2' ? true : false,
circle: selectedKeys[0] === 'sub17-3-2' ? false : true,
}"
></span>
<router-link to="/employeelearning">员工学习数据</router-link>
</a-menu-item>
</a-sub-menu>
</a-sub-menu>
</a-menu>
</div>
<div
@@ -387,6 +440,7 @@ export default {
"sub13",
"sub14",
"sub15",
"sub17",
],
openKeys: localStorage.getItem("openKeys")
? JSON.parse(localStorage.getItem("openKeys"))
@@ -554,6 +608,30 @@ export default {
selectedKeys: "sub15",
pagename: "下载中心",
},
{
href: "/operational",
openKeys: "sub17",
selectedKeys: "sub17-1",
pagename: "营运数据概览",
},
{
href: "/learningpathmap",
openKeys: "sub17",
selectedKeys: "sub17-2-1",
pagename: "学习路径图",
},
{
href: "/overvoew",
openKeys: "sub17",
selectedKeys: "sub17-3-1",
pagename: "概览",
},
{
href: "/employeelearning",
openKeys: "sub17",
selectedKeys: "sub17-3-2",
pagename: "员工学习数据",
},
],
});
@@ -632,9 +710,12 @@ export default {
break;
} else {
if (i === openpages.length - 1) {
console.log("lujingjingliu", n.toLowerCase());
console.log("dsdsdsdsd", state.keysList);
let pagename = state.keysList.filter((a) => {
return a.href === n.toLowerCase();
});
console.log("可怜见立刻离开", pagename);
if (pagename && pagename.length !== 0) {
let obj = {
pagename: pagename[0].pagename,
@@ -686,6 +767,14 @@ export default {
box-shadow: 0px 1px 35px 0px rgba(118, 136, 166, 0.21);
// margin-top: -50px;
flex-shrink: 0;
.treeMenu {
.ant-menu-title-content {
box-sizing: border-box;
padding-left: 52px !important;
overflow: hidden;
text-overflow: ellipsis;
}
}
.packup {
width: 19px;
height: 15px;
@@ -714,7 +803,7 @@ export default {
.ant-menu-title-content {
padding: 0px !important;
// padding-left: 27px !important;
font-size: 16px;
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 36px;
@@ -723,7 +812,7 @@ export default {
}
.ant-menu-item a,
.ant-menu-item a:hover {
font-size: 16px;
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 36px;
@@ -738,7 +827,7 @@ export default {
//修改左侧padding
.ant-menu-item,
.ant-menu-submenu-title {
padding-left: 27px !important;
padding-left: 9px !important;
height: 49px !important;
line-height: 49px !important;
margin: 0px !important;
@@ -782,8 +871,8 @@ export default {
height: 10px;
border-radius: 5px;
border: 2px solid rgba(255, 255, 255, 1);
margin-left: 24px;
margin-right: 18px;
margin-left: 18px;
margin-right: 14px;
display: inline-block;
}
.circleActive {
@@ -791,8 +880,8 @@ export default {
height: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, 1);
margin-left: 24px;
margin-right: 18px;
margin-left: 18px;
margin-right: 14px;
display: inline-block;
}
}

View File

@@ -53,7 +53,7 @@ export default {
const state = reactive({
openList: store.state.openpages,
});
console.log('state111111',state)
const closePage = (value) => {
console.log("点击关闭页面", value, state.openList);

View File

@@ -0,0 +1,443 @@
<template>
<!-- 员工学习数据页面 -->
<div class="employeelearning">
<!-- 以下为顶部搜索框 -->
<div class="filter">
<div class="select addTimeBox">
<div class="addTime">创建时间</div>
<a-range-picker
style="width: 100%"
format="YYYY-MM-DD"
separator="至"
:placeholder="[' 开始时间', ' 结束时间']"
/>
</div>
<div class="select">
<a-select
style="width: 100%"
placeholder="请选择状态"
allowClear
></a-select>
</div>
<div class="select">
<a-input
style="width: 100%; height: 40px; border-radius: 8px"
placeholder="请输入工号/姓名"
allowClear
showSearch
>
</a-input>
</div>
<div class="select">
<a-input
style="width: 100%; height: 40px; border-radius: 8px"
placeholder="请输入Band"
allowClear
showSearch
>
</a-input>
</div>
<div style="display: flex; margin-bottom: 20px">
<div class="btnn btn1">
<div class="search"></div>
<div class="btnText">搜索</div>
</div>
<div class="btn btn2">
<div class="search"></div>
<div class="btnText">重置</div>
</div>
</div>
</div>
<!-- 以下为导出按钮 -->
<div class="btns">
<div class="btn btn3">
<div><img src="../../assets/svg/export.png" alt="" /></div>
<div class="btnText">导出</div>
</div>
</div>
<!-- 以下为table表格 -->
<div class="tableBox">
<a-table
:columns="columns"
:data-source="tableData"
:loading="tableLoading"
:scroll="{ x: 700 }"
:pagination="false"
>
</a-table>
<div class="tableBox">
<div class="pa">
<a-pagination
v-if="tableDataTotal > 10"
:showSizeChanger="false"
showQuickJumper="true"
hideOnSinglePage="true"
:pageSize="pageSize"
v-model:current="pageNo"
:total="tableDataTotal"
class="pagination"
@change="changePagination"
/>
</div>
</div>
</div>
</div>
</template>
<script>
import { ref, toRefs, reactive } from "vue";
export default {
name: "EmployeelearninG",
setup() {
const state = reactive({
tableLoading: false, // table加载图标
tableDataTotal: 12, // 数据总条数
pageSize: 10, // 每页条数
pageNo: 1, //当前页码
});
// 表格数据
let tableData = ref([
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
{ name: "0000255", manager: "565656" },
]);
// cloumns 表头
const columns = ref([
{
title: "工号",
dataIndex: "name",
key: "name",
width: 120,
ellipsis: true,
align: "center",
},
{
title: "姓名",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "组织信息",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "岗位",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "Band",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "授课次数",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "授课时长(分钟)",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "案例数",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "学习项目",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "学习路径",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "学习课程",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "累计学习时长(分钟)",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "操作",
dataIndex: "operation",
key: "operation",
width: 150,
align: "center",
fixed: "right",
customRender: () => {
return <a>导出详细信息</a>;
},
},
]);
//table 分页事件
const changePagination = (page) => {
state.pageNo = page;
};
return {
...toRefs(state),
tableData,
columns,
changePagination,
};
},
};
</script>
<style lang="scss">
.employeelearning {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.filter {
margin-left: 38px;
margin-right: 20px;
margin-top: 30px;
display: flex;
flex-wrap: wrap;
.select {
margin-right: 20px;
margin-bottom: 20px;
width: calc((100% - 76px - 360px) / 4);
}
.addTimeBox {
width: calc((100% - 76px - 360px) / 4 + 120px) !important;
position: relative;
display: flex;
align-items: center;
.addTime {
position: absolute;
z-index: 10;
margin-left: 10px;
color: rgba(0, 0, 0, 0.4);
}
.ant-picker {
padding-left: 85px;
}
.ant-picker-range .ant-picker-active-bar {
margin-left: 85px;
}
}
.btn {
padding: 0px 26px 0px 26px;
height: 38px;
background: rgba(64, 158, 255, 0);
border-radius: 8px;
border: 1px solid rgba(64, 158, 255, 1);
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: rgba(64, 158, 255, 1);
line-height: 36px;
margin-left: 5px;
}
}
.btnn {
padding: 0px 26px 0px 26px;
height: 38px;
background: #4ea6ff;
border-radius: 8px;
border: 1px solid rgba(64, 158, 255, 1);
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 36px;
margin-left: 5px;
}
}
.btn1 {
.search {
width: 15px;
height: 17px;
background-image: url("../../assets/images/courseManage/search0.png");
}
}
.btn2 {
.search {
width: 16px;
height: 18px;
background-image: url("../../assets/images/courseManage/reset1.png");
}
}
.btn1:hover {
background: rgba(64, 158, 255, 0.76);
.search {
background-image: url("../../assets/images/courseManage/search0.png");
}
.btnText {
color: #ffffff;
}
}
.btn1:active {
background: #0982ff;
}
.btn2:hover {
background: rgba(64, 158, 255, 0.1);
}
.btn2:active {
background: rgba(64, 158, 255, 0.2);
}
}
.tableBox {
margin: 20px 38px 30px;
.ant-table-thead > tr > th {
background-color: #eff4fc;
}
}
.btns {
display: flex;
margin-left: 38px;
// flex-wrap: wrap;
.btn {
padding: 0px 26px 0px 26px;
height: 38px;
background: white;
border-radius: 8px;
border: 1px solid rgba(64, 158, 255, 1);
display: flex;
align-items: center;
cursor: pointer;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
line-height: 36px;
margin-left: 5px;
}
}
.btn3 {
margin-right: 0px;
.search {
width: 17px;
height: 18px;
background-image: url("../../assets/images/courseManage/add0.png");
}
}
.btn3:hover {
// background: rgba(64, 158, 255, 0.76);
background: rgba(64, 158, 255, 0.2);
}
// .btn3:active {
// background: #0982ff;
// }
}
.tableBox {
padding-bottom: 20px;
.pa {
// position: absolute;
// bottom: 20px;
// left: 0;
width: 100%;
// height: 20px;
// background-color: red;
display: flex;
justify-content: center;
// margin-bottom: 10px;
// position: absolute;
// bottom: -40px;
}
}
}
</style>

View File

@@ -0,0 +1,24 @@
<template>
<!-- 学习路径图! -->
<div class="learningpathmap">
<div class="box">
学习路径图页面!
</div>
</div>
</template>
<script>
export default {
name: "LearningPathMap",
};
</script>
<style lang="scss">
.learningpathmap {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
</style>

View File

@@ -0,0 +1,455 @@
<template>
<!-- 营运数据概览页面! -->
<div class="operational">
<div class="echartsOne">
<div class="title">
<div class="left">用户活动趋势</div>
<div class="right">
<img src="../../assets/svg/export.png" alt="" />
<span>导出活动详情</span>
</div>
</div>
<div class="search">
<div class="left">
<div class="leftItem">
<a-select
style="width: 100%"
placeholder="请选择模块"
allowClear
></a-select>
</div>
<div class="leftItem">
<a-select
style="width: 100%"
placeholder="请选择日期格式"
allowClear
></a-select>
</div>
<div class="leftItem">
<a-range-picker
style="width: 100%"
format="YYYY-MM-DD"
separator="至"
:placeholder="[' 开始时间', ' 结束时间']"
/>
</div>
<div class="leftItem">
<a-select
style="width: 100%"
placeholder="请选择入口"
allowClear
></a-select>
</div>
</div>
</div>
<div class="echarts" ref="surfaceRef"></div>
<div class="msg">
<div class="item">
<div class="start" />
<div class="radio" />
<div class="end" />
<div class="text">停留时长</div>
</div>
<div class="item1">
<div class="start" />
<div class="radio" />
<div class="end" />
<div class="text">访问人数</div>
</div>
<div class="item2">
<div class="start" />
<div class="radio" />
<div class="end" />
<div class="text">访问次数</div>
</div>
</div>
</div>
<div class="echartsTwo">
<div class="title">
<div class="left">学习情况</div>
<div class="right">
<img src="../../assets/svg/export.png" alt="" />
<span>导出活动详情</span>
</div>
</div>
<div class="search">
<div class="left">
<div class="leftItem">
<a-select
style="width: 100%"
placeholder="请选择模块"
allowClear
></a-select>
</div>
<div class="leftItem">
<a-select
style="width: 100%"
placeholder="请选择日期格式"
allowClear
></a-select>
</div>
<div class="leftItem">
<a-range-picker
style="width: 100%"
format="YYYY-MM-DD"
separator="至"
:placeholder="[' 开始时间', ' 结束时间']"
/>
</div>
</div>
</div>
<div class="echarts" ref="surface1Ref"></div>
<div class="msg">
<div class="item">
<div class="start" />
<div class="radio" />
<div class="end" />
<div class="text">总学习人数</div>
</div>
<div class="item1">
<div class="start" />
<div class="radio" />
<div class="end" />
<div class="text">人均学习时长</div>
</div>
<div class="item2">
<div class="start" />
<div class="radio" />
<div class="end" />
<div class="text">总学习时长</div>
</div>
</div>
</div>
<div class="echartsThree">
<div class="left"></div>
<div class="right"></div>
</div>
</div>
</template>
<script>
import * as echarts from "echarts";
import { onMounted, ref } from "vue";
export default {
name: "OperationaL",
setup() {
const surfaceRef = ref(null);
const surface1Ref = ref(null);
const option = ref({
tooltip: {
trigger: "axis",
},
grid: {
top: "6%",
left: "0%",
right: "0%",
bottom: "2%",
containLabel: true,
},
xAxis: {
type: "category",
boundaryGap: false,
data: [],
},
yAxis: [
{
type: "value",
axisLine: {
show: true,
},
},
{
type: "value",
splitLine: {
show: false,
},
},
],
series: [
{
name: "访问人数",
type: "line",
data: [],
},
{
name: "访问次数",
type: "line",
data: [],
},
{
name: "停留时长",
type: "line",
data: [],
yAxisIndex: 1,
},
],
});
// 图表1 数据源
const echartOneData = ref([
{
time: "1月",
person: 20,
num: 220,
long: 150,
},
{
time: "2月",
person: 32,
num: 182,
long: 232,
},
{
time: "3月",
person: 40,
num: 191,
long: 201,
},
{
time: "4月",
person: 1,
num: 234,
long: 154,
},
{
time: "5月",
person: 90,
num: 290,
long: 190,
},
{
time: "6月",
person: 30,
num: 330,
long: 330,
},
{
time: "7月",
person: 10,
num: 310,
long: 410,
},
]);
// const calMax = (arr) => {
// const max = Math.max.apply(null, arr);
// const maxint = Math.ceil(max / 5);
// const maxval = maxint * 5 + 50;
// return maxval;
// };
// const calMin = (arr) => {
// const min = Math.min.apply(null, arr);
// const minint = Math.floor(min / 1);
// const minval = minint / 1;
// return minval;
// };
// 处理图表数据的方法
const changeData = () => {
const timeList = [];
const personList = [];
const numList = [];
const longList = [];
echartOneData.value?.forEach((item) => {
timeList.push(item.time);
personList.push(item.person);
numList.push(item.num);
longList.push(item.long);
});
// 处理x轴显示信息
option.value.xAxis.data = timeList;
// 处理左侧Y轴显示信息
// const maxDataRight = calMax(personList);
// const minDataRight = calMin(personList);
// const maxDataLeft = calMax([...numList, longList]);
// const minDataLeft = calMin([...numList, longList]);
// option.value.yAxis[0].min = minDataLeft;
// option.value.yAxis[0].max = maxDataLeft;
// option.value.yAxis[0].splitNumber = 10;
// option.value.yAxis[0].interval = Math.floor(
// (maxDataLeft - minDataLeft) / 10
// );
// option.value.yAxis[1].min = minDataRight;
// option.value.yAxis[1].max = maxDataRight;
// option.value.yAxis[1].splitNumber = 10;
// option.value.yAxis[1].interval = Math.floor(
// (maxDataRight - minDataRight) / 10
// );
// 右侧坐标轴数据
option.value.series[0].data = personList;
//左侧坐标轴数据
option.value.series[1].data = numList;
option.value.series[2].data = longList;
};
// 生成echarts的方法
const createEcharts = () => {
changeData();
const myChart = echarts.init(surfaceRef.value);
option.value && myChart.setOption(option.value);
const myChart1 = echarts.init(surface1Ref.value);
option.value && myChart1.setOption(option.value);
};
// 挂载完成
onMounted(() => {
createEcharts();
});
return {
surfaceRef,
surface1Ref,
echartOneData,
};
},
};
</script>
<style lang="scss">
.operational {
width: 100%;
height: 100%;
// display: flex;
// flex-direction: column;
// box-sizing: border-box;
overflow-x: hidden;
overflow-y: auto;
padding: 0 38px;
.echartsOne,
.echartsTwo {
width: 100%;
height: 600px;
border: 1px solid rgba(232, 236, 239, 1);
margin-top: 20px;
padding: 15px;
border-radius: 4px;
.search {
margin-top: 20px;
width: 100%;
height: 40px;
.left {
display: flex;
.leftItem {
margin-right: 10px;
}
}
}
.title {
display: flex;
justify-content: space-between;
margin-top: 10px;
.left {
font-size: 18px;
color: black;
font-weight: 600;
}
.right {
padding: 0 15px;
background: white;
height: 32px;
line-height: 34px;
border-radius: 4px;
color: #387df7;
border: 1px solid #387df7;
cursor: pointer;
img {
margin-top: -3px;
margin-right: 5px;
}
}
.right:hover {
background: rgba(64, 158, 255, 0.2);
}
}
.echarts {
height: 400px;
width: 100%;
}
.msg {
margin-left: calc(50% - 135px);
width: 330px;
display: flex;
margin-top: 20px;
.item {
display: flex;
align-items: center;
margin-right: 15px;
.start,
.end {
width: 5px;
height: 2px;
background: #387df7;
// margin-top: 4px;
}
.radio {
width: 10px;
height: 10px;
border-radius: 50%;
border: 2px solid #387df7;
}
.text {
margin-left: 3px;
}
}
.item1 {
margin-right: 15px;
display: flex;
align-items: center;
.start,
.end {
width: 5px;
height: 2px;
background: #00cecb;
// margin-top: 4px;
}
.radio {
width: 10px;
height: 10px;
border-radius: 50%;
border: 2px solid #00cecb;
}
.text {
margin-left: 3px;
}
}
.item2 {
display: flex;
align-items: center;
.start,
.end {
width: 5px;
height: 2px;
background: #ffa71a;
// margin-top: 4px;
}
.radio {
width: 10px;
height: 10px;
border-radius: 50%;
border: 2px solid #ffa71a;
}
.text {
margin-left: 3px;
}
}
}
}
.echartsThree {
width: 100%;
height: 400px;
margin-top: 20px;
margin-bottom: 30px;
display: flex;
.left {
width: calc(50% - 5px);
height: 100%;
background: red;
border: 1px solid rgba(232, 236, 239, 1);
border-radius: 4px;
}
.right {
margin-left: 10px;
width: calc(50% - 5px);
height: 100%;
background: chartreuse;
border: 1px solid rgba(232, 236, 239, 1);
border-radius: 4px;
}
}
}
</style>

View File

@@ -0,0 +1,539 @@
<template>
<!-- 概览! -->
<div class="overvoew">
<!-- 以下为顶部搜索框 -->
<div class="filter">
<div class="select addTimeBox">
<div class="addTime">创建时间</div>
<a-range-picker
style="width: 100%"
format="YYYY-MM-DD"
separator="至"
:placeholder="[' 开始时间', ' 结束时间']"
/>
</div>
<div class="select">
<a-select
style="width: 100%"
placeholder="请选择组织"
allowClear
></a-select>
</div>
<div class="select">
<a-input
style="width: 100%; height: 40px; border-radius: 8px"
placeholder="请输入名称"
allowClear
showSearch
>
</a-input>
</div>
<div class="select">
<a-input
style="width: 100%; height: 40px; border-radius: 8px"
placeholder="请输入创建者"
allowClear
showSearch
>
</a-input>
</div>
<div style="display: flex; margin-bottom: 20px">
<div class="btnn btn1">
<div class="search"></div>
<div class="btnText">搜索</div>
</div>
<div class="btn btn2">
<div class="search"></div>
<div class="btnText">重置</div>
</div>
</div>
</div>
<!-- 以下为导出按钮 -->
<div class="tabBtn">
<div class="tab">
<div
v-for="(item, index) in tabData"
:key="index"
:class="currentTab === index ? 'tabActive' : 'tabItem'"
@click="tabClick(index)"
>
{{ item.text }} ({{ item.num }})
</div>
</div>
<div class="btns">
<div class="btn btn3">
<div>
<img src="../../assets/svg/export.png" alt="" />
</div>
<div class="btnText">导出</div>
</div>
</div>
</div>
<!-- 以下为table表格 -->
<div class="tableBox">
<a-table
:columns="columns"
:data-source="tableData"
:loading="tableLoading"
:scroll="{ x: 700 }"
:pagination="false"
@expand="expandTable"
>
</a-table>
<div class="tableBox">
<div class="pa">
<a-pagination
v-if="tableDataTotal > 10"
:showSizeChanger="false"
showQuickJumper="true"
hideOnSinglePage="true"
:pageSize="pageSize"
v-model:current="pageNo"
:total="tableDataTotal"
class="pagination"
@change="changePagination"
/>
</div>
</div>
</div>
</div>
</template>
<script>
import { ref, toRefs, reactive } from "vue";
export default {
name: "OvervoeW",
setup() {
const state = reactive({
tableLoading: false, // table加载图标
tableDataTotal: 12, // 数据总条数
pageSize: 10, // 每页条数
pageNo: 1, //当前页码
currentTab: 1,
});
// 表格数据
let tableData = ref([
{
key: 1,
name: "John Brown sr.",
age: 60,
address: "New York No. 1 Lake Park",
children: [
{
key: 11,
name: "John Brown",
age: 42,
address: "New York No. 2 Lake Park",
},
{
key: 12,
name: "John Brown jr.",
age: 30,
address: "New York No. 3 Lake Park",
children: [
{
key: 121,
name: "Jimmy Brown",
age: 16,
address: "New York No. 3 Lake Park",
},
],
},
{
key: 13,
name: "Jim Green sr.",
age: 72,
address: "London No. 1 Lake Park",
children: [
{
key: 131,
name: "Jim Green",
age: 42,
address: "London No. 2 Lake Park",
children: [
{
key: 1311,
name: "Jim Green jr.",
age: 25,
address: "London No. 3 Lake Park",
},
{
key: 1312,
name: "Jimmy Green sr.",
age: 18,
address: "London No. 4 Lake Park",
},
],
},
],
},
],
},
{
key: 2,
name: "Joe Black",
age: 32,
address: "Sidney No. 1 Lake Park",
},
]);
// cloumns 表头
const columns = ref([
{
title: "名称",
dataIndex: "name",
key: "name",
width: 120,
ellipsis: true,
align: "left",
fixed: "left",
},
{
title: "归属组织",
dataIndex: "age",
ellipsis: true,
key: "age",
width: 120,
align: "center",
fixed: "left",
},
{
title: "分类",
dataIndex: "address",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
fixed: "left",
},
{
title: "阶段总数",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "任务总数",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "学习人数",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "完成人数",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "项目时间",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "发布时间",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "状态",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
{
title: "创建人",
dataIndex: "manager",
ellipsis: true,
key: "manager",
width: 120,
align: "center",
},
]);
const tabData = ref([
{ text: "项目", num: "2" },
{ text: "学习路径图", num: "6" },
{ text: "授课", num: "8" },
{ text: "课程", num: "11" },
{ text: "考试", num: "10" },
{ text: "案例", num: "10" },
]);
const tabClick = (index) => {
state.currentTab = index;
};
//table 分页事件
const changePagination = (page) => {
state.pageNo = page;
};
// columns展开事件
const expandTable = (e, a) => {
console.log("e", e, a);
};
return {
...toRefs(state),
tableData,
columns,
tabData,
tabClick,
changePagination,
expandTable,
};
},
};
</script>
<style lang="scss">
.overvoew {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.filter {
margin-left: 38px;
margin-right: 20px;
margin-top: 30px;
display: flex;
flex-wrap: wrap;
.select {
margin-right: 20px;
margin-bottom: 20px;
width: calc((100% - 76px - 360px) / 4);
}
.addTimeBox {
width: calc((100% - 76px - 360px) / 4 + 120px) !important;
position: relative;
display: flex;
align-items: center;
.addTime {
position: absolute;
z-index: 10;
margin-left: 10px;
color: rgba(0, 0, 0, 0.4);
}
.ant-picker {
padding-left: 85px;
}
.ant-picker-range .ant-picker-active-bar {
margin-left: 85px;
}
}
.btn {
padding: 0px 26px 0px 26px;
height: 38px;
background: rgba(64, 158, 255, 0);
border-radius: 8px;
border: 1px solid rgba(64, 158, 255, 1);
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: rgba(64, 158, 255, 1);
line-height: 36px;
margin-left: 5px;
}
}
.btnn {
padding: 0px 26px 0px 26px;
height: 38px;
background: #4ea6ff;
border-radius: 8px;
border: 1px solid rgba(64, 158, 255, 1);
display: flex;
align-items: center;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
cursor: pointer;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: #ffffff;
line-height: 36px;
margin-left: 5px;
}
}
.btn1 {
.search {
width: 15px;
height: 17px;
background-image: url("../../assets/images/courseManage/search0.png");
}
}
.btn2 {
margin-right: 0px !important;
.search {
width: 16px;
height: 18px;
background-image: url("../../assets/images/courseManage/reset1.png");
}
}
.btn1:hover {
background: rgba(64, 158, 255, 0.76);
.search {
background-image: url("../../assets/images/courseManage/search0.png");
}
.btnText {
color: #ffffff;
}
}
.btn1:active {
background: #0982ff;
}
.btn2:hover {
background: rgba(64, 158, 255, 0.1);
}
.btn2:active {
background: rgba(64, 158, 255, 0.2);
}
}
.tabBtn {
width: 100%;
height: 40px;
display: flex;
justify-content: space-between;
.tab {
margin-left: 38px;
display: flex;
background: #ebeaea;
height: 40px;
line-height: 40px;
border-radius: 8px;
.tabItem {
box-sizing: border-box;
padding: 0 18px;
cursor: pointer;
}
.tabActive {
box-sizing: border-box;
padding: 0 18px;
background: #387df7;
color: white;
border-radius: 8px;
cursor: pointer;
}
}
.btns {
display: flex;
margin-right: 38px;
// flex-wrap: wrap;
.btn {
padding: 0px 26px 0px 26px;
height: 38px;
background: white;
border-radius: 8px;
border: 1px solid rgba(64, 158, 255, 1);
display: flex;
align-items: center;
cursor: pointer;
justify-content: center;
margin-right: 14px;
flex-shrink: 0;
.search {
background-size: 100%;
}
.btnText {
font-size: 14px;
font-weight: 400;
color: #4ea6ff;
line-height: 36px;
margin-left: 5px;
}
}
.btn3 {
margin-right: 0px;
.search {
width: 17px;
height: 18px;
background-image: url("../../assets/images/courseManage/add0.png");
}
}
.btn3:hover {
// background: rgba(64, 158, 255, 0.76);
background: rgba(64, 158, 255, 0.2);
}
// .btn3:active {
// background: #0982ff;
// }
}
}
.tableBox {
margin: 20px 38px 30px;
.ant-table-thead > tr > th {
background-color: #eff4fc;
}
}
.tableBox {
padding-bottom: 20px;
.pa {
// position: absolute;
// bottom: 20px;
// left: 0;
width: 100%;
// height: 20px;
// background-color: red;
display: flex;
justify-content: center;
// margin-bottom: 10px;
// position: absolute;
// bottom: -40px;
}
}
}
</style>

View File

@@ -7,7 +7,7 @@
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
const {defineConfig} = require("@vue/cli-service");
console.log('1111111111111111111111111111111111',process.env.VUE_APP_PROXY_URL)
module.exports = defineConfig({
publicPath: process.env.VUE_APP_BASE,
outputDir: process.env.VUE_APP_OUTPUT_DIR,
@@ -15,10 +15,10 @@ module.exports = defineConfig({
port: 8080,
proxy: {
"/manageApi": {
target: process.env.VUE_APP_PROXY_URL,
target: process.env.VUE_APP_BOE_API_URL,
changeOrigin: true, //表示是否改变原域名
pathRewrite: {
"^/manageApi": "",
// "^/manageApi": "",
},
}, "/userbasic": {
target: process.env.VUE_APP_BOE_API_URL,