Compare commits

...

4 Commits
main ... dev

Author SHA1 Message Date
86183 553c498d51 修改了后端请求地址 2023-11-09 21:11:47 +08:00
86183 3b5293a5ed 修改了Axios请求实例配置 2023-11-09 21:11:31 +08:00
86183 5651b91131 修改了部分UI 2023-11-09 21:11:15 +08:00
86183 aad4061a66 修复了一些Bug 2023-11-09 21:10:52 +08:00
4 changed files with 746 additions and 227 deletions

View File

@ -1,5 +1,5 @@
NODE_ENV=development NODE_ENV=development
VUE_APP_API_BASE_URL=http://localhost:8888/jeecg-boot VUE_APP_API_BASE_URL=http://localhost:8080/jeecg-boot
VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas VUE_APP_CAS_BASE_URL=http://cas.example.org:8443/cas
VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview VUE_APP_ONLINE_BASE_URL=http://fileview.jeecg.com/onlinePreview

View File

@ -2,11 +2,11 @@
<div class="user-wrapper" :class="theme"> <div class="user-wrapper" :class="theme">
<!-- update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航 --> <!-- update_begin author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
<!-- update-begin author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 --> <!-- update-begin author:sunjianlei date:20191@20 for: 解决全局样式冲突的问题 -->
<span class="action" @click="showClick"> <!-- <span class="action" @click="showClick">
<a-icon type="search"></a-icon> <a-icon type="search"></a-icon>
</span> </span> -->
<!-- update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件在手机端呈现出弹出框 --> <!-- update-begin author:sunjianlei date:20200219 for: 菜单搜索改为动态组件在手机端呈现出弹出框 -->
<component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false"> <!-- <component :is="searchMenuComp" v-show="searchMenuVisible || isMobile()" class="borders" :visible="searchMenuVisible" title="搜索菜单" :footer="null" @cancel="searchMenuVisible=false">
<a-select <a-select
class="search-input" class="search-input"
showSearch showSearch
@ -22,18 +22,18 @@
> >
<a-select-option v-for="(site,index) in searchMenuOptions" :key="index" :value="site.id">{{site.meta.title}}</a-select-option> <a-select-option v-for="(site,index) in searchMenuOptions" :key="index" :value="site.id">{{site.meta.title}}</a-select-option>
</a-select> </a-select>
</component> </component> -->
<!-- update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件在手机端呈现出弹出框 --> <!-- update-end author:sunjianlei date:20200219 for: 菜单搜索改为动态组件在手机端呈现出弹出框 -->
<!-- update-end author:sunjianlei date:20191220 for: 解决全局样式冲突的问题 --> <!-- update-end author:sunjianlei date:20191220 for: 解决全局样式冲突的问题 -->
<!-- update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航 --> <!-- update_end author:zhaoxin date:20191129 for: 做头部菜单栏导航 -->
<span class="action"> <!-- <span class="action">
<a class="logout_title" target="_blank" href="http://doc.jeecg.com"> <a class="logout_title" target="_blank" href="http://doc.jeecg.com">
<a-icon type="question-circle-o"></a-icon> <a-icon type="question-circle-o"></a-icon>
</a> </a>
</span> </span>
<header-notice class="action"/> <header-notice class="action"/> -->
<a-dropdown> <!-- <a-dropdown> -->
<span class="action action-full ant-dropdown-link user-dropdown-menu"> <!-- <span class="action action-full ant-dropdown-link user-dropdown-menu">
<a-avatar class="avatar" size="small" :src="getAvatar()"/> <a-avatar class="avatar" size="small" :src="getAvatar()"/>
<span v-if="isDesktop()">欢迎您{{ nickname() }}</span> <span v-if="isDesktop()">欢迎您{{ nickname() }}</span>
</span> </span>
@ -65,7 +65,7 @@
<a-menu-item key="6" @click="clearCache"> <a-menu-item key="6" @click="clearCache">
<a-icon type="sync"/> <a-icon type="sync"/>
<span>清理缓存</span> <span>清理缓存</span>
</a-menu-item> </a-menu-item> -->
<!-- <a-menu-item key="2" disabled> <!-- <a-menu-item key="2" disabled>
<a-icon type="setting"/> <a-icon type="setting"/>
<span>测试</span> <span>测试</span>
@ -77,32 +77,32 @@
<span>退出登录</span> <span>退出登录</span>
</a> </a>
</a-menu-item>--> </a-menu-item>-->
</a-menu> <!-- </a-menu>
</a-dropdown> </a-dropdown> -->
<span class="action"> <span class="action">
<a class="logout_title" href="javascript:;" @click="handleLogout"> <a class="logout_title" href="javascript:;" @click="handleLogout">
<a-icon type="logout"/> <a-icon type="logout"/>
<span v-if="isDesktop()">&nbsp;退出登录</span> <span v-if="isDesktop()">&nbsp;退出登录</span>
</a> </a>
</span> </span>
<user-password ref="userPassword"></user-password> <!-- <user-password ref="userPassword"></user-password>
<depart-select ref="departSelect" :closable="true" title="部门切换"></depart-select> <depart-select ref="departSelect" :closable="true" title="部门切换"></depart-select>
<setting-drawer ref="settingDrawer" :closable="true" title="系统设置"></setting-drawer> <setting-drawer ref="settingDrawer" :closable="true" title="系统设置"></setting-drawer> -->
</div> </div>
</template> </template>
<script> <script>
import HeaderNotice from './HeaderNotice' import HeaderNotice from './HeaderNotice'
import UserPassword from './UserPassword' import UserPassword from './UserPassword'
import SettingDrawer from "@/components/setting/SettingDrawer"; import SettingDrawer from "@/components/setting/SettingDrawer";
import DepartSelect from './DepartSelect' import DepartSelect from './DepartSelect'
import { mapActions, mapGetters,mapState } from 'vuex' import { mapActions, mapGetters,mapState } from 'vuex'
import { mixinDevice } from '@/utils/mixin.js' import { mixinDevice } from '@/utils/mixin.js'
import { getFileAccessHttpUrl,getAction } from "@/api/manage" import { getFileAccessHttpUrl,getAction } from "@/api/manage"
import Vue from 'vue' import Vue from 'vue'
import { UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types" import { UI_CACHE_DB_DICT_DATA } from "@/store/mutation-types"
export default { export default {
name: "UserMenu", name: "UserMenu",
mixins: [mixinDevice], mixins: [mixinDevice],
data(){ data(){
@ -256,13 +256,13 @@
} }
/*update_end author:liushaoqian date:20200507 for: 刷新缓存*/ /*update_end author:liushaoqian date:20200507 for: 刷新缓存*/
} }
} }
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
/* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/ /* update_begin author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
/* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */ /* update-begin author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
.user-wrapper .search-input { .user-wrapper .search-input {
width: 180px; width: 180px;
color: inherit; color: inherit;
@ -274,14 +274,14 @@
color: inherit; color: inherit;
} }
} }
} }
/* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */ /* update-end author:sunjianlei date:20191220 for: 解决全局样式冲突问题 */
/* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/ /* update_end author:zhaoxin date:20191129 for: 让搜索框颜色能随主题颜色变换*/
</style> </style>
<style scoped> <style scoped>
.logout_title { .logout_title {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
} }
</style> </style>

View File

@ -16,8 +16,9 @@ let apiBaseUrl = window._CONFIG['domianURL'] || "/jeecg-boot";
// 创建 axios 实例 // 创建 axios 实例
const service = axios.create({ const service = axios.create({
//baseURL: '/jeecg-boot', //baseURL: '/jeecg-boot',
baseURL: apiBaseUrl, // api base_url // baseURL: apiBaseUrl, // api base_url
timeout: 9000 // 请求超时时间 baseURL: 'http://localhost:8080/jeecg-boot',
timeout: 15000 // 请求超时时间
}) })
const err = (error) => { const err = (error) => {
@ -144,7 +145,16 @@ service.interceptors.request.use(config => {
// response interceptor // response interceptor
service.interceptors.response.use((response) => { service.interceptors.response.use((response) => {
return response.data return response.data
}, err) }, error=> {
if(error.code==='ECONNABORTED' && error.message.indexOf('timeout')!==-1){
Vue.prototype.$Jnotification.error({message: '系统提示', description: '网络超时'})
}
else{
Vue.prototype.$Jnotification.error({message: '系统提示', description: '未知错误'})
}
return Promise.reject(error)
}
)
const installer = { const installer = {
vm: {}, vm: {},

View File

@ -0,0 +1,509 @@
<template>
<a-card :bordered="false">
<!-- 查询区域 -->
<div>
<a-button type="primary" @click="visible = true">打开筛选项</a-button>
</div>
<a-drawer placement="right" :visible="visible" width="90%" :closable="false">
<template slot="title">
<span>CET查询筛选项</span>
</template>
<a-descriptions bordered>
<a-descriptions-item label="学院" :span="3">
<div class="collegeDesc">
<a-checkbox :indeterminate="college.liberalData.indeterminate" :checked="college.liberalData.checkAll"
@change="liberalCheckAllOptions($event)">
{{ college.liberalData.label }}
</a-checkbox>
<!-- <hr class="objectHr"> -->
<a-checkbox-group v-model="college.liberalData.liberalCheckList"
:options="college.liberalData.liberalOptions" />
<hr class="objectHr">
<a-checkbox :indeterminate="college.scienceData.indeterminate" :checked="college.scienceData.checkAll"
@change="scienceCheckAllOptions($event)">
{{ college.scienceData.label }}
</a-checkbox>
<!-- <hr class="objectHr"> -->
<a-checkbox-group v-model="college.scienceData.scienceCheckList"
:options="college.scienceData.scienceOpitons" />
<hr class="objectHr">
<a-checkbox :indeterminate="college.artsData.indeterminate" :checked="college.artsData.checkAll"
@change="artsCheckAllOptions($event)">
{{ college.artsData.label }}
</a-checkbox>
<!-- <hr class="objectHr"> -->
<br>
<a-checkbox-group v-model="college.artsData.artsCheckList" :options="college.artsData.artsOptions" />
</div>
</a-descriptions-item>
<a-descriptions-item label="批次" :span="3">
<a-checkbox-group v-model="batch.checkedList" :options="batch.plainOptions" />
</a-descriptions-item>
<a-descriptions-item label="级别" :span="3">
<a-radio-group v-model="selectedLevel" size="large">
<a-radio-button v-for="option in levelOptions" :key="option.value" :value="option.value">
{{ option.label }}
</a-radio-button>
</a-radio-group>
</a-descriptions-item>
<a-descriptions-item label="培养层次" :span="3">
<a-radio-group v-model="selectedCultivationLevel" size="large">
<a-radio-button v-for="option in cultivationLevelOptions" :key="option.value" :value="option.value"
:disabled="(option.value === '研究生' && (selectedExamGrade === '大一' || selectedExamGrade === '大二' || selectedExamGrade === '大三' || selectedExamGrade === '大四')) || ((option.value === '本科') && selectedExamGrade === '研究生')">
{{ option.label }}
</a-radio-button>
</a-radio-group>
</a-descriptions-item>
<a-descriptions-item label="考试时年级" :span="3">
<a-radio-group v-model="selectedExamGrade" size="large">
<a-radio-button v-for="option in examGradeOptions" :key="option.value" :value="option.value"
:disabled="(option.value === '研究生' && selectedCultivationLevel === '本科') || ((option.value === '大一' || option.value === '大二' || option.value === '大三' || option.value === '大四') && selectedCultivationLevel === '研究生')">
{{ option.label }}
</a-radio-button>
</a-radio-group>
</a-descriptions-item>
</a-descriptions>
<div class="buttons">
<a-button type="primary" style="margin-right: 5px;" @click="visible = false" icon="close">取消</a-button>
<a-button type="primary" @click="seachClick" icon="search">查询</a-button>
</div>
</a-drawer>
<a-descriptions bordered style="margin-top:10px;">
<a-descriptions-item label="总人数">
{{ totalEntries }}
</a-descriptions-item>
<a-descriptions-item label="总通过数">
{{ totalPassCount }}
</a-descriptions-item>
<a-descriptions-item label="总通过率">
{{ totalPassRate }}
</a-descriptions-item>
</a-descriptions>
<div v-if="isSeach">
正在加载中 <a-spin />
</div>
<div v-if="colleges.length > 0 && loading === false">
<div class="title">各学院通过率变化</div>
<a-tabs v-model:activeKey="activeKey" type="card" @change="darwLine">
<a-tab-pane v-for="(college, index) in colleges" :key="index" :tab="college">
</a-tab-pane>
</a-tabs>
</div>
<div class="LineChart">
<div id="LineChart"></div>
</div>
<a-table :dataSource="dataSource" :columns="columns" bordered style="margin-top:10px;" :loading="loading"
v-if="colleges.length > 0">
<template slot="passRate" slot-scope="text">
{{ text }}%
</template>
</a-table>
</a-card>
</template>
<script>
import { getAction, postAction } from '@/api/manage'
import '@/assets/less/TableExpand.less'
import * as echarts from 'echarts';
export default {
name: 'CetEnglishList',
data() {
return {
indeterminate: false,
isSeach: false,
activeKey: 0,
loading: false,
//
totalEntries: 0,
//
totalPassCount: 0,
//
totalPassRate: 0,
visible: false,
description: '四六级英语管理页面',
//
dataSource: [],
columns: [
{
title: '学院',
dataIndex: 'college',
key: 'college',
},
{
title: '批次',
dataIndex: 'batch',
key: 'batch',
},
{
title: '报名数',
dataIndex: 'entries',
key: 'entries',
},
{
title: '通过率',
dataIndex: 'passRate',
key: 'passRate',
scopedSlots: { customRender: 'passRate' },
},
],
url: {
list: "/superlilu/cetEnglish/list",
//url
getPassRate: "/superlilu/cetEnglish/passRate",
},
seachData: {
college: [],
batch: [],
level: "",
cultivationlevel: "",
examgrade: ""
},
//
drawData: [],
//
college: {
checkedList: [],
liberalData:
{
label: '文科',
indeterminate: false,
liberalCheckList: [],
checkAll: false,
liberalOptions: [
{ label: '东语学院', value: '东语学院' },
{ label: '法学院', value: '法学院' },
{ label: '管理学院', value: '管理学院' },
{ label: '教师教育学院', value: '教师教育学院' },
{ label: '教育科学学院', value: '教育科学学院' },
{ label: '经济学院', value: '经济学院' },
{ label: '历史文化学院', value: '历史文化学院' },
{ label: '马克思主义学院', value: '马克思主义学院' },
{ label: '西语学院', value: '西语学院' },
{ label: '公共英语教研部', value: '公共英语教研部' },
{ label: '国际教育学院', value: '国际教育学院' },
{ label: '斯拉夫语学院', value: '斯拉夫语学院' },
{ label: '文学院', value: '文学院' },
],
},
artsData: {
label: '艺体',
indeterminate: false,
artsCheckList: [],
checkAll: false,
artsOptions: [
{ label: '传媒学院', value: '传媒学院' },
{ label: '国际美术学院', value: '国际美术学院' },
{ label: '音乐学院', value: '音乐学院' },
{ label: '美术学院', value: '美术学院' },
{ label: '体育科学学院', value: '体育科学学院' },
],
},
scienceData: {
label: '理科',
indeterminate: false,
scienceCheckList: [],
checkAll: false,
scienceOpitons: [
{ label: '物理与电子工程学院', value: '物理与电子工程学院' },
{ label: '生命科学与技术学院', value: '生命科学与技术学院' },
{ label: '数学科学学院', value: '数学科学学院' },
{ label: '计算机科学与信息工程学院', value: '计算机科学与信息工程学院' },
{ label: '化学化工学院', value: '化学化工学院' },
{ label: '地理科学学院', value: '地理科学学院' },
{ label: '光电带隙材料教育部重点实验室', value: '光电带隙材料教育部重点实验室' },
],
},
},
//
batch: {
checkedList: [],
plainOptions: [
{ label: '2021-06-01', value: '2021-06-01' },
{ label: '2021-12-01', value: '2021-12-01' },
{ label: '2022-09-01', value: '2022-09-01' },
{ label: '2023-03-01', value: '2023-03-01' },
{ label: '2023-06-01', value: '2023-06-01' },
]
},
//
levelOptions: [
{ label: '全部', value: '' },
{ label: '英语四级', value: '英语四级' },
{ label: '英语六级', value: '英语六级' }
],
selectedLevel: '',
//
cultivationLevelOptions: [
{ label: '全部', value: '' },
{ label: '研究生', value: '研究生' },
{ label: '本科', value: '本科' },
// { label: '', value: '' }
],
selectedCultivationLevel: '',
//
examGradeOptions: [
{ label: '全部', value: '' },
{ label: '大一', value: '大一' },
{ label: '大二', value: '大二' },
{ label: '大三', value: '大三' },
{ label: '大四', value: '大四' },
{ label: '研究生', value: '研究生' },
{ label: '其他', value: '其他' }
],
selectedExamGrade: '',
colleges: [],
dates: [],
LineChartData: []
}
},
computed: {
getPassRate: function () {
return `${window._CONFIG['domianURL']}/${this.url.getPassRate}`
}
},
// mounted() {
// const cancelButton = document.querySelector('.cancelButton');
// const width = cancelButton.getBoundingClientRect().width;
// cancelButton.style.marginRight = `${width}px`;
// },
methods: {
//tab线
darwLine() {
let college = this.colleges[this.activeKey];
let dates = this.dates;
let drawData = this.LineChartData[this.activeKey];
this.drawLine(college, dates, drawData);
},
// getDraw
drawLine(colleges, dates, drawData) {
//LineChart
let LineChart = echarts.getInstanceByDom(document.getElementById('LineChart'));
if (LineChart != null && LineChart != undefined) {
LineChart.dispose();
}
LineChart = echarts.init(document.getElementById('LineChart'));
let option = {
title: {
text: ''
},
tooltip: {
trigger: 'axis'
},
legend: {
data: colleges
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
show: false
},
xAxis: {
type: 'category',
boundaryGap: false,
data: dates
},
yAxis: {
type: 'value'
},
series: drawData
};
LineChart.setOption(option);
},
//
getDraw() {
//
this.colleges = []
this.dates = []
this.LineChartData = []
//线
let LineChart = echarts.getInstanceByDom(document.getElementById('LineChart'));
if (LineChart != null && LineChart != undefined) {
LineChart.dispose();
}
postAction(this.getPassRate, this.seachData).then(res => {
let data = res.result;
//batch
data.resultList.sort((a, b) => {
return a.batch > b.batch ? 1 : -1;
});
this.loading = false;
//
this.dataSource = Object.assign([], data.resultList);
//
this.totalEntries = data.totalEntries;
this.totalPassCount = data.totalPass;
this.totalPassRate = parseFloat(this.totalPassCount / this.totalEntries * 100).toFixed(2) + "%";
//
data.resultList.forEach(item => {
//
let collegeIndex = this.colleges.indexOf(item.college);
if (collegeIndex === -1) {
this.colleges.push(item.college);
}
let dateIndex = this.dates.indexOf(item.batch);
if (dateIndex === -1) {
this.dates.push(item.batch);
}
});
//线
this.getDrawData(data);
this.isSeach = false
},
).catch(error => {
this.isSeach = false
})
},
//线
getDrawData(data) {
data.resultList.forEach(item => {
//
let collegeIndex = this.colleges.indexOf(item.college);
//
let dateIndex = this.dates.indexOf(item.batch);
if (!this.LineChartData[collegeIndex]) {
this.LineChartData[collegeIndex] = {
name: item.college,
type: 'line',
data: [],
label: {
show: true,
position: 'top'
}
};
}
this.LineChartData[collegeIndex].data[dateIndex] = parseFloat(item.passRate.toFixed(2));
});
this.activeKey = 0
this.darwLine();
},
//
seachClick() {
this.loading = true;
this.isSeach = true;
this.seachData.level = this.selectedLevel;
this.seachData.cultivationlevel = this.selectedCultivationLevel;
this.seachData.examgrade = this.selectedExamGrade;
this.college.checkedList = this.college.liberalData.liberalCheckList.concat(this.college.scienceData.scienceCheckList, this.college.artsData.artsCheckList)
this.seachData.college = this.college.checkedList;
this.seachData.batch = this.batch.checkedList;
//
this.getDraw()
this.visible = false;
// this.searchQuery()
},
liberalCheckAllOptions(e) {//
//
let newArr = []
if (e.target.checked) {
newArr = this.college.liberalData.liberalOptions.map(item => {
return item.value
})
}
this.college.liberalData.liberalCheckList = e.target.checked ? newArr : []
this.college.liberalData.indeterminate = false
this.college.liberalData.checkAll = e.target.checked
},
scienceCheckAllOptions(e) {//
//
let newArr = []
if (e.target.checked) {
newArr = this.college.scienceData.scienceOpitons.map(item => {
return item.value
})
}
this.college.scienceData.scienceCheckList = e.target.checked ? newArr : []
this.college.scienceData.indeterminate = false
this.college.scienceData.checkAll = e.target.checked
},
artsCheckAllOptions(e) {//
//
let newArr = []
if (e.target.checked) {
newArr = this.college.artsData.artsOptions.map(item => {
return item.value
})
}
this.college.artsData.artsCheckList = e.target.checked ? newArr : []
this.college.artsData.indeterminate = false
this.college.artsData.checkAll = e.target.checked
},
},
}
</script>
<style scoped>
@import '~@assets/less/common.less';
.title {
font-size: 24px;
font-weight: bold;
margin: 10px 0;
}
.LineChart {
width: 100%;
height: 400px;
padding: 10px;
}
.buttons {
float: right;
margin-top: 10px;
padding-bottom: 10px;
}
#LineChart {
width: 100%;
height: 100%;
}
.collegeDesc {
display: block;
width: 100%;
}
.objectHr{
border: none;
border-top: 1px dashed #ece8e8;
}
/* #main {
width: 100%;
height: 100%;
} */
/* 第二步 */
</style>