Files
fe-manage/src/components/drawers/ProjectScore.vue
2023-03-16 18:30:31 +08:00

1033 lines
31 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!--发布公告-->
<template>
<div class="split"></div>
<div class="contentscore">
<a-tabs v-model:activeKey="activeKeyScore" @change="tabsChange">
<a-tab-pane key="1" tab="学员获取">
<div class="group">
<div class="groupleft">
<div class="groupname" style="width: 42px">姓名</div>
<a-input
class="ant-input"
v-model:value="searchNameValue"
placeholder="请输入姓名"
/>
</div>
<div class="groupright" style="margin-left: 16px;">
<div class="btn1" @click="searchStu">
<img src="../../assets/images/courseManage/search0.png" />
<span class="btn1text">搜索</span>
</div>
<div class="btn2" @click="resetStud">
<img src="../../assets/images/courseManage/reset0.png" />
<span class="btn2text">重置</span>
</div>
</div>
</div>
<div class="tableBox" style="margin: 20px 32px 30px 32px">
<a-table
style="border: 1px solid #f2f6fe"
:columns="tablecolumnStu"
:data-source="tabledataStu"
:loading="tableDataTotal === -1 ? true : false"
expandRowByClick="true"
@expand="expandTable"
:pagination="false"
/>
<div class="pa">
<a-pagination
v-if="tableDataTotal > 10"
:showSizeChanger="false"
showQuickJumper="true"
hideOnSinglePage="true"
:pageSize="pageSize"
:current="currentPage"
:total="tableDataTotal"
class="pagination"
@change="changePagination"
/>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="2" tab="榜单" force-render>
<div class="scorelist">
<div class="grouprightscore">
<div class="sbutton" @click="typeChange(0)">
<img
v-if="stuValue === 1"
src="../../assets/images/taskpage/stu0.png"
/>
<img v-else src="../../assets/images/taskpage/stu.png" />
<div :class="stuValue === 1? '' : 'btn1'">学员积分榜</div>
</div>
<div class="sbutton" @click="typeChange(1)">
<img
v-if="stuValue === 1"
src="../../assets/images/taskpage/group.png"
/>
<img v-else src="../../assets/images/taskpage/group0.png" />
<div :class="stuValue === 1 ? 'btn1' : ''">小组积分榜</div>
</div>
</div>
<div class="group" style="justify-content: center">
<div class="groupleft">
<div class="groupname">姓名</div>
<a-input
class="ant-input"
style="width: 152px;"
v-model:value="searchRankName"
placeholder="请输入姓名"
/>
</div>
<div class="groupright">
<div class="btn1" style="margin-left: 16px" @click="searchRank">
<img src="../../assets/images/courseManage/search0.png" />
<span class="btn1text">搜索</span>
</div>
<div class="btn2" @click="rankReset">
<img src="../../assets/images/courseManage/reset0.png" />
<span class="btn2text">重置</span>
</div>
</div>
</div>
<div class="radiobutton">
<a-radio-group
v-model:value="todayvalue"
button-style="solid"
@change="changeday"
>
<a-radio-button class="today" value="1">今天</a-radio-button>
<a-radio-button class="today" value="2">七天</a-radio-button>
<a-radio-button class="today" value="3">近一个月</a-radio-button>
</a-radio-group>
</div>
<div class="listdiv">
<div class="slist">
<a-list :data-source="stuValue === 1 ? datascoreg : datascore" :loading="scoreRankLoading">
<template #renderItem="{ item }">
<div class="item">
<div v-if="!isSearchRank">
<div v-if="item.index == 1" class="itemleft">
<div class="itemimage">
<img src="../../assets/images/taskpage/gold.png" />
</div>
<div class="itemid">{{ item.index }}</div>
</div>
<div v-else-if="item.index == 2" class="itemleft">
<div class="itemimage">
<img src="../../assets/images/taskpage/siler.png" />
</div>
<div class="itemid">{{ item.index }}</div>
</div>
<div v-else-if="item.index == 3" class="itemleft">
<div class="itemimage">
<img src="../../assets/images/taskpage/copper.png" />
</div>
<div class="itemid">{{ item.index }}</div>
</div>
<div v-else class="itemleft">
<div class="elseid">{{ item.index }}</div>
</div>
</div>
<div class="itemcenter">{{ item.name }}</div>
<div class="itemright">{{ item.pointsCountStr }}</div>
</div>
</template>
</a-list>
</div>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="3" tab="获取规则">
<div class="projectscore">
<div class="pjc_body">
<div class="groupright">
<div class="spandiv"><span class="spantext">规则</span></div>
<div v-if="edit" class="btns">
<div v-if="checkPer(permissions)" class="btn1" @click="edit = false">
<img src="../../assets/images/projectadd/edit1.png" />
<span class="btn1text">编辑</span>
</div>
</div>
<div v-else class="btns">
<div class="btn1" @click="editRule">
<span class="btn1text">保存</span>
</div>
</div>
</div>
<div v-if="edit" class="pjcb_content">
<div class="content content2">
<span>每完成一项任务则可获得 </span
><span class="scoretext">{{ score1 }} </span><span>积分,除此以外:</span>
</div>
<!--
<div class="content">
<span>作业完成作业成绩不低于 </span
><span class="scoretext">{{ done2 }}</span
><span>分获得</span> <span class="scoretext">{{ done3 }}</span
><span>积分</span>
</div>-->
<div class="content">
<span>作业最早完成任意一项目作业的前</span
><span class="scoretext">{{ four3 }}</span
><span>名学员且成绩不低于</span>
<span class="scoretext">{{ four4 }}</span
><span>分获得</span> <span class="scoretext">{{ four5 }}</span
><span>积分</span>
</div>
<div class="content">
<span>在线最早完成任意一门课程的</span><span class="scoretext">{{ four1 }}</span
><span>名学员获得</span>
<span class="scoretext">{{ four2 }}</span
><span style="margin-right: 50px">积分</span>
</div>
<div class="content">
<span>考试完成任意一场考试且成绩高于</span
><span class="scoretext">{{ five1 }}</span
><span>分获得</span> <span class="scoretext">{{ five2 }}</span
><span>积分</span>
</div>
<div class="content">
<span>面授直播活动完成任意一面授课直播活动且考勤正常学员获得 </span
><span class="scoretext">{{ six1 }}</span
><span>积分</span>
</div>
<div class="content">
<span>成为小组长获得</span
><span class="scoretext">{{ seven1 }}</span
><span style="margin-right: 50px">积分同一项目只加一次</span>
</div> <div class="content">
<span>优秀学员可获得</span>
<span class="scoretext">{{ seven2 }}</span
><span>积分同一项目只加一次</span>
</div>
</div>
<div v-else class="pjcb_content">
<div class="content content2">
<span>每完成一项任务则可获得 </span
><span
><a-input
v-model:value="score1"
:bordered="false"
@change="getScore"
/> </span
><span>积分除此以外</span>
</div>
<div class="content">
<span>作业最早完成任意一项作业的</span
><a-input v-model:value="four3" :bordered="false" /><span
>名学员且成绩不低于</span
>
<a-input v-model:value="four4" :bordered="false" /><span
>分获得</span
>
<a-input v-model:value="four5" :bordered="false" /><span
>积分</span
>
</div>
<div class="content">
<span>在线最早完成任意一门课程的</span
><a-input v-model:value="four1" :bordered="false" /><span
>名学完在线课程获得</span
>
<a-input v-model:value="four2" :bordered="false" /><span
style="margin-right: 50px"
>积分</span
>
</div>
<div class="content">
<span>考试完成任意一场考试且成绩高于</span
><a-input v-model:value="five1" :bordered="false" /><span
>分获得</span
>
<a-input v-model:value="five2" :bordered="false" /><span
>积分</span
>
</div>
<div class="content">
<span>面授直播活动完成任意一面授课直播活动且考勤正常学员获得 </span
><a-input v-model:value="six1" :bordered="false" /><span
>积分</span
>
</div>
<div class="content">
<span>成为小组长获得</span
><a-input v-model:value="seven1" :bordered="false" /><span
style="margin-right: 50px"
>积分同一项目只加一次</span
> </div> <div class="content">
<span>优秀学员可获得</span>
<a-input v-model:value="seven2" :bordered="false" /><span
>积分同一项目只加一次</span
>
</div>
</div>
</div>
</div></a-tab-pane
>
</a-tabs>
</div>
<stu-score-detail
v-model:Svisible="Svisible"
v-model:studentId="checkStuId"
v-model:projectId="proId"
/>
</template>
<script>
import StuScoreDetail from "../../components/drawers/StuScoreDetail";
import { reactive, toRefs, onMounted } from "vue";
import * as api from "../../api/index1";
// import { message } from "ant-design-vue";
import { scoreRule } from "../../api/indexTaskadd"; //获取项目积分规则
import { setScoreRule } from "../../api/indexTaskadd"; //设置项目积分规则
import { getProjStu } from "../../api/indexProjStu";
import { message } from "ant-design-vue";
import {checkPer} from "@/utils/utils";
export default {
name: "ProjectScore",
components: {
StuScoreDetail,
},
props: {
permissions:{
type:String,
default: ''
},
projectId: {
type: Number,
default: null,
},
},
setup(props) {
const state = reactive({
tabledataStu: [
// {
// key: 1,
// name: "小李",
// bum: "产研部",
// gangw: "产品经理",
// group: "好好学习",
// diploma: "0",
// operation: "查看",
// },
],
tablecolumnStu: [
{
title: "姓名",
dataIndex: "name",
key: "name",
width: 30,
align: "left",
className: "h",
},
{
title: "部门",
dataIndex: "bum",
key: "bum",
width: 40,
align: "center",
className: "h",
},
{
title: "岗位",
dataIndex: "gangw",
key: "gangw",
width: 40,
align: "center",
className: "h",
},
{
title: "所属小组",
dataIndex: "group",
key: "group",
width: 40,
align: "center",
className: "h",
},
{
title: "已获得积分",
dataIndex: "diploma",
key: "diploma",
width: 40,
align: "center",
className: "h",
},
{
title: "操作",
dataIndex: "operation",
key: "operation",
width: 60,
align: "center",
className: "operation",
customRender: (value) => {
return (
<div
style="color:#387df7;cursor:pointer"
onClick={() => {
state.Svisible = true;
console.log(value.record.key);
state.checkStuId = value.record.key;
}}
>
查看
</div>
);
},
},
],
datascore: [
],
datascoreg: [
],
scoreRankLoading:true,
valueName: "", //排行榜输入姓名
valueDate: "", //排行榜输入日期
noticeChecked: true,
noticeContent: "请输入要发布的公告",
activeKeyScore: "1",
stuName: "请输入姓名",
todayvalue: "1",
stuValue: 0,
Svisible: false,
score1: null,
done2: null,
done3: null,
four1: null,
four2: null,
four3: null,
four4: null,
four5: null,
five1: null,
five2: null,
six1: null,
seven1: null,
seven2: null,
edit: true,
searchRankName: "", //榜单搜索名称
pageSize: 10,
currentPage: 1,
tableDataTotal: null,
searchNameValue: null, //学员获取的姓名
checkStuId: null,
proId: null,
startTime: (new Date(new Date(new Date().toLocaleDateString()).getTime())).getTime().toString(),
scoresum: 0,
isSearchRank: false
});
const getTableData = () => {
let datas = state.tabledataStu;
datas.map((value) => {
{
//单层项目
value.operation = (
<div class="operation">
<div
class="jc"
onClick={() => {
state.Svisible = true;
}}
>
查看
</div>
</div>
);
}
});
state.tabledataStu = datas;
};
getTableData();
const tabsChange = (e) => {
if (e == 2) {
// console.log('获取项目积分-榜单')
scoreRank();
} else if (e == 3) {
getScoreRule();
}
rankReset();
state.todayvalue = "1";
state.stuValue = 0;
};
//重置
const rankReset = () => {
state.searchRankName = "";
scoreRank();
};
// start -------榜单---------------榜单------------榜单------------------榜单---------
//学员积分还是小组积分
const typeChange = (num) => {
console.log(num)
state.stuValue = Number(num);
scoreRank();
};
//选择时间
const changeday = (e) => {
state.todayvalue = e.target.value;
console.log('切换时间显示-今天-七天-近一个月', e.target.value)
if(e.target.value==1){
state.startTime = (new Date(new Date(new Date().toLocaleDateString()).getTime())).getTime().toString()
}else if(e.target.value==2){
state.startTime = ((new Date(new Date(new Date().toLocaleDateString()).getTime())).getTime() - 7*24*60*60*1000).toString()
}else{
state.startTime = ((new Date(new Date(new Date().toLocaleDateString()).getTime())).getTime() - 31*24*60*60*1000).toString()
}
scoreRank();
};
//搜索
const searchRank = () => {
scoreRank();
};
//项目积分榜单
const scoreRank = (period, type) => {
state.scoreRankLoading = true;
state.datascore = [];
state.datascoreg = [];
console.log("projectId----->", props.projectId,period, type);
console.log('我是查询榜单传递的数据',{
projectId: props.projectId, // 项目id
name: state.searchRankName, // 名字,没有则传空字符串
startTime:state.startTime, // 数据查询的起始时间 10位时间戳
size: 5, // 前多少名
type: Number(state.stuValue), // 查询类型 0 学员积分榜 1 小组积分榜
})
let obj = {
projectId: props.projectId, // 项目id
name: state.searchRankName, // 名字,没有则传空字符串
startTime: state.startTime, // 数据查询的起始时间 10位时间戳
size: 5, // 前多少名
type: Number(state.stuValue), // 查询类型 0 学员积分榜 1 小组积分榜
};
api
.scoreRank(obj)
.then((res) => {
console.log("获取项目积分-榜单", res);
if(res.data.code==200){
state.datascore = res.data.data;
state.datascoreg = res.data.data;
state.scoreRankLoading = false;
if(state.searchRankName==""){
state.isSearchRank = false;
}else{
state.isSearchRank = true;
}
}else{
state.datascore = [];
state.datascoreg = [];
state.scoreRankLoading = false;
}
})
.catch((err) => {
console.log("获取项目积分-榜单失败", err);
message.destroy();
message.error('榜单获取失败');
state.datascore = [];
state.datascoreg = [];
state.scoreRankLoading = false;
});
};
// end -----榜单----------------榜单----------------------榜单-----------榜单----------
//设置积分规则
const editRule = () => {
console.log(props.projectId);
let obj = {
projectId: Number(props.projectId),
datas:[
{
"type": 1,
"pointsCount": Number(state.score1),
"typeDesc": "完成【必修/选修】获得%p积分",
"typeDescConfig": ""
},
{
"type": 2,
"pointsCount": Number(state.done3),
"typeDesc": "完成作业成绩不低于%d分获得%p积分",
"typeDescConfig": state.done2
},
{
"type": 3,
"pointsCount": Number(state.four2),
"typeDesc": "前%d名学完在线课程获得%p积分",
"typeDescConfig": state.four1
},
{
"type": 4,
"pointsCount": Number(state.four5),
"typeDesc": "前%d名提交作业且成绩不低于%d分获得%p积分",
"typeDescConfig": state.four3 + ';' + state.four4
},
{
"type": 5,
"pointsCount": Number(state.five2),
"typeDesc": "考试成绩高于%d分获得%p积分",
"typeDescConfig": state.five1
},
{
"type": 6,
"pointsCount": Number(state.six1),
"typeDesc": "考勤正常学员获得%p积分",
"typeDescConfig": ""
},
{
"type": 7,
"pointsCount": Number(state.seven1),
"typeDesc": "成为小组长获得%p积分",
"typeDescConfig": ""
},
{
"type": 8,
"pointsCount": Number(state.seven2),
"typeDesc": "优秀学员可获得%p积分",
"typeDescConfig": ""
}
]
};
console.log('我是修改积分规则传递得参数', obj);
setScoreRule(obj)
.then((res) => {
console.log(res.data, "修改成功");
message.destroy();
getScoreRule();
return message.success("修改积分规则成功");
})
.catch((err) => {
console.log(err.data);
message.destroy();
return message.warning("修改积分规则失败");
});
// scoreRule({
// projectId: props.projectId,
// });
state.edit = true;
};
const getStu = (obj) => {
state.proId = props.projectId;
let objn = obj || {
deptIds: [],
groupId: "",
groupName: "",
name: "",
pageNo: state.currentPage,
pageSize: 10,
projectId: props.projectId,
topFlag: "",
};
getProjStu(objn).then((res) => {
console.log("dedaole", res.data.data.rows);
let result = res.data.data.rows;
state.tableDataTotal = res.data.data.total;
setStuData(result);
});
};
const setStuData = (tabledata) => {
let data = tabledata;
let array = [];
data.map((item) => {
let obj = {
key: item.studentId,
name: item.name,
bum: item.userInfoBo.deptName,
gangw: item.userInfoBo.jobName,
group: item.groupName,
diploma: item.allPointsCount,
// operation: "查看",
};
array.push(obj);
});
state.tabledataStu = array;
};
const changePagination = (current) => {
state.currentPage = current;
getStu();
};
const searchStu = () => {
let obj = {
deptIds: [],
groupId: "",
groupName: "",
name: state.searchNameValue,
pageNo: state.currentPage,
pageSize: 10,
projectId: props.projectId,
topFlag: "",
};
getStu(obj);
};
const resetStud = () => {
state.searchNameValue = null;
getStu();
};
const getScoreRule = () => {
scoreRule({
projectId: props.projectId,
})
.then((res) => {
console.log("获取了项目积分规则", res.data.data);
let result = res.data.data;
//Write operation failed: computed value is readonly 总积分
state.scoresum = Number(result[0].pointsCount) + Number(result[1].pointsCount) + Number(result[2].pointsCount) + Number(result[3].pointsCount) + Number(result[4].pointsCount) + Number(result[5].pointsCount) + Number(result[6].pointsCount) + Number(result[7].pointsCount)
state.score1 = result[0].pointsCount;
state.done2 = result[1].typeDescConfig;
state.done3 = result[1].pointsCount;
state.four1 = result[2].typeDescConfig;
state.four2 = result[2].pointsCount;
state.four3 = result[3].typeDescConfig.slice(0,result[3].typeDescConfig.indexOf(';'));
state.four4 = result[3].typeDescConfig.slice(result[3].typeDescConfig.indexOf(';')+1);
state.four5 = result[3].pointsCount;
state.five1 = result[4].typeDescConfig;
state.five2 = result[4].pointsCount;
state.six1 = result[5].pointsCount;
state.seven1 = result[6].pointsCount;
state.seven2 = result[7].pointsCount;
})
.catch((err) => {
console.log("获取项目积分规则失败了", err);
});
};
onMounted(() => {
getStu();
});
return {
...toRefs(state),
typeChange,
changeday,
searchRank,
rankReset,
tabsChange,
scoreRank,
editRule,
getStu,
setStuData,
changePagination,
searchStu,
resetStud,
getScoreRule,
checkPer
};
},
// computed: {
// // 计算属性的 getter
// scoresum: function () {
// return (
// Number(this.score1) +
// Number(this.done3) +
// Number(this.four2) +
// Number(this.four5) +
// Number(this.five2) +
// Number(this.six1) +
// Number(this.seven1) +
// Number(this.seven2)
// );
// },
// },
};
</script>
<style lang="scss">
.contentscore {
margin-top: 20px;
margin-bottom: 100px;
.ant-tabs-nav-wrap {
border-bottom: 1px solid #ededed;
}
.ant-tabs-tab-btn {
font-size: 18px;
font-weight: 700;
}
.ant-input {
border-radius: 8px;
width: 264px;
height: 40px;
}
.group {
display: flex;
.groupleft {
display: flex;
align-items: center;
margin-left: 32px;
.groupname {
height: 22px;
width: 42px;
color: #000000;
font-size: 14px;
}
}
.groupright {
display: flex;
.btn1 {
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16px;
border: 1px solid #4ea6ff;
border-radius: 8px;
background: #4ea6ff;
cursor: pointer;
.btn1text {
color: #ffffff;
margin-left: 5px;
font-size: 14px;
}
}
.btn2 {
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 32px;
border: 1px solid #4ea6ff;
border-radius: 8px;
cursor: pointer;
background: #4ea6ff;
.btn2text {
color: #fff;
margin-left: 5px;
font-size: 14px;
}
}
}
}
.tableBox {
.ant-table-selection-column {
padding: 0px !important;
// padding-left: 45px !important;
}
.ant-table-thead > tr > th {
background-color: rgba(239, 244, 252, 1) !important;
color: rgba(0, 0, 0, 0.85);
}
.ant-table-cell {
color: rgba(0, 0, 0, 0.65);
}
.ant-table-selection-column {
padding: 0 !important;
}
th.h {
background-color: #eff4fc !important;
}
.ant-table-tbody
> tr:hover:not(.ant-table-expanded-row):not(.ant-table-row-selected)
> td {
background: #f6f9fd;
}
.ant-table-tbody > tr > td {
border-bottom: 1px solid rgba(240, 244, 254, 1);
padding: 16px 16px;
.operation {
color: rgba(56, 125, 247, 1);
cursor: pointer;
}
}
.pa {
margin-top: 15px;
// height: 20px;
// background-color: red;
display: flex;
justify-content: center;
// bottom: 20px;
}
}
.scorelist {
padding-bottom: 100px;
padding-top: 50px;
.grouprightscore {
display: flex;
justify-content: center;
margin-bottom: 30px;
text-align: center;
.sbutton {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: 90px;
margin-right: 90px;
}
.btn1 {
color: #4ea6ff;
}
}
.radiobutton {
margin-top: 23px;
margin-bottom: 23px;
justify-content: center;
display: flex;
text-align: center;
.today {
width: 120px;
height: 32px;
}
}
.listdiv {
display: flex;
justify-content: space-evenly;
text-align: center;
.slist {
width: 736px;
background-color: #f5f8fc;
padding-left: 28px;
padding-right: 28px;
padding-bottom: 20px;
padding-top: 16px;
font-size: 18px;
.item {
display: flex;
justify-content: space-evenly;
text-align: center;
border-bottom: none;
height: 56px;
align-items: center;
background-color: white;
border-radius: 21px;
margin-top: 10px;
.itemleft {
justify-content: center;
display: flex;
align-items: center;
width: 150px;
.itemid {
font-size: 40px;
font-family: math;
font-style: italic;
font-weight: 700;
color: #4ea6ff;
margin-left: 5px;
}
.elseid {
font-size: 26px;
font-family: math;
font-weight: 500;
margin-left: 40px;
}
}
.itemcenter {
width: 300px;
}
.itemright {
width: 150px;
}
}
}
}
}
.projectscore {
.pjc_body {
margin-left: 34px;
margin-right: 34px;
.spandiv {
position: relative;
/* height: 100%; */
width: 40px;
.spantext {
position: absolute;
left: 0;
bottom: 0px;
}
}
.groupright {
display: flex;
justify-content: space-between;
.btn1 {
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16px;
border: 1px solid #4ea6ff;
border-radius: 8px;
background: #4ea6ff;
cursor: pointer;
.btn1text {
color: #ffffff;
margin-left: 5px;
font-size: 14px;
}
}
.btn2 {
width: 100px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 32px;
border: 1px solid #4ea6ff;
border-radius: 8px;
cursor: pointer;
background: #ffffff;
.btn2text {
color: #4ea6ff;
margin-left: 5px;
font-size: 14px;
}
}
}
.pjcb_content {
border: 1px solid #4ea6ff;
padding: 20px;
margin-top: 10px;
.ant-input {
width: 46px;
font-size: 16px;
color: #4ea6ff;
}
.scoretext {
color: #4ea6ff;
font-size: 16px;
margin-left: 3px;
margin-right: 4px;
}
.pjcb_content :last-child {
margin-bottom: 0px;
}
.content {
align-items: center;
height: 50px;
display: flex;
}
margin-bottom: 130px;
}
}
}
}
</style>