完善成绩查询页面接口调用,根据接口数据,重新组合显示数据
This commit is contained in:
parent
a1a57c77f5
commit
9278dcc610
@ -56,3 +56,17 @@ export const drpkkbApi = async (params: any) => {
|
|||||||
export const xsXkListApi = async (params: any) => {
|
export const xsXkListApi = async (params: any) => {
|
||||||
return await get("/mobile/jz/xsxk/list", params);
|
return await get("/mobile/jz/xsxk/list", params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询学生考试场次
|
||||||
|
*/
|
||||||
|
export const xsKsccApi = async (params: any) => {
|
||||||
|
return await get("/mobile/jz/kscc", params);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询学生考试成绩
|
||||||
|
*/
|
||||||
|
export const xsKscjApi = async (params: any) => {
|
||||||
|
return await get("/mobile/jz/kscj", params);
|
||||||
|
};
|
||||||
|
|||||||
@ -17,10 +17,11 @@ export function useLayout(options: LayoutOptions): UseLayoutInterfaceReturn {
|
|||||||
async function requestApi(pageNo: number, pageSize: number) {
|
async function requestApi(pageNo: number, pageSize: number) {
|
||||||
if (isFunction(options.api)) {
|
if (isFunction(options.api)) {
|
||||||
try {
|
try {
|
||||||
const result = await options.api(Object.assign({}, {
|
let params = Object.assign({}, {
|
||||||
rows: pageSize,
|
rows: pageSize,
|
||||||
page: pageNo
|
page: pageNo
|
||||||
}, options.param))
|
}, options.param)
|
||||||
|
const result = await options.api(params)
|
||||||
await nextTick()
|
await nextTick()
|
||||||
if (methods.value) {
|
if (methods.value) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|||||||
@ -3,20 +3,20 @@
|
|||||||
<!-- 顶部蓝色背景 -->
|
<!-- 顶部蓝色背景 -->
|
||||||
<view class="blue-header">
|
<view class="blue-header">
|
||||||
<view class="header-content">
|
<view class="header-content">
|
||||||
<text class="title">2024学年第一学期二年级期中</text>
|
<text class="title">{{ kscc.ksmc }}</text>
|
||||||
<text class="subtitle">教学质量监测成绩报告</text>
|
<text class="subtitle">教学质量监测成绩报告</text>
|
||||||
|
|
||||||
<view class="color-bar"></view>
|
<view class="color-bar"></view>
|
||||||
|
|
||||||
<text class="total-score">全科(满分700分)</text>
|
<text class="total-score">共{{kscjList.length}}科(满分{{ kscjList.length * 100 }}分)</text>
|
||||||
|
|
||||||
<text class="grade">A</text>
|
<text class="grade">{{ curKsdj.dfbs }}</text>
|
||||||
|
|
||||||
<view class="grade-info">
|
<view class="grade-info">
|
||||||
<text class="grade-explanation" @click="showGradeInfo">等级说明</text>
|
<text class="grade-explanation" @click="showGradeInfo">等级说明</text>
|
||||||
<view class="grade-box">
|
<view class="grade-box">
|
||||||
<text class="grade-label">区域等级</text>
|
<text class="grade-label">区域等级</text>
|
||||||
<text class="grade-value">相对较好</text>
|
<text class="grade-value">{{ curKsdj.dsms }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -28,6 +28,7 @@
|
|||||||
<!-- 选项卡 -->
|
<!-- 选项卡 -->
|
||||||
<view class="tabs">
|
<view class="tabs">
|
||||||
<view
|
<view
|
||||||
|
v-if="kscjList.length > 2"
|
||||||
class="tab-item"
|
class="tab-item"
|
||||||
:class="{ active: activeTab === 'diagnosis' }"
|
:class="{ active: activeTab === 'diagnosis' }"
|
||||||
@click="switchTab('diagnosis')"
|
@click="switchTab('diagnosis')"
|
||||||
@ -55,17 +56,16 @@
|
|||||||
<view class="po-ab inset-0 px-15" style="overflow: auto">
|
<view class="po-ab inset-0 px-15" style="overflow: auto">
|
||||||
<view
|
<view
|
||||||
class="subject-item"
|
class="subject-item"
|
||||||
v-for="(subject, index) in subjects"
|
v-for="(kscj, index) in kscjList"
|
||||||
:key="index"
|
:key="index"
|
||||||
>
|
>
|
||||||
<view class="subject-header">
|
<view class="subject-header">
|
||||||
<text class="subject-name"
|
<text class="subject-name">{{ kscj.kmmc }}</text>
|
||||||
>{{ subject.name }}(满分{{ subject.fullScore }})</text
|
<text v-if="kscj.ksdj.id">(分数{{ kscj.ksfs }})</text>
|
||||||
>
|
|
||||||
</view>
|
</view>
|
||||||
<view class="subject-body">
|
<view class="subject-body">
|
||||||
<text class="subject-grade">{{ subject.grade }}</text>
|
<text class="subject-grade">{{ kscj.ksdj.dfbs }}</text>
|
||||||
<text class="detail-btn">详情</text>
|
<text class="detail-btn" :style="{ color: kscj.ksdj.djclr }" v-if="kscj.ksdj.id">{{ kscj.ksdj.dsms }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -73,7 +73,11 @@
|
|||||||
|
|
||||||
<!-- 分数趋势视图 -->
|
<!-- 分数趋势视图 -->
|
||||||
<view class="trend-view" v-if="activeTab === 'trend'">
|
<view class="trend-view" v-if="activeTab === 'trend'">
|
||||||
<!-- 图表占位区域 -->
|
<!-- 选项卡 -->
|
||||||
|
<BasicTabs
|
||||||
|
ref="tabsRef" :list="xqKmmcList" bar-width="60px" scroll-count="4"
|
||||||
|
:current="curKmIndex" @change="switchKm"
|
||||||
|
/>
|
||||||
<view class="radar-placeholder" id="chart-container1">
|
<view class="radar-placeholder" id="chart-container1">
|
||||||
<canvas
|
<canvas
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
@ -152,8 +156,29 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, watch, nextTick } from "vue";
|
import { ref, onMounted, watch, nextTick } from "vue";
|
||||||
import { navigateBack } from "@/utils/uniapp";
|
|
||||||
import uCharts from "@/components/charts/u-charts.js";
|
import uCharts from "@/components/charts/u-charts.js";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { xsKscjApi } from "@/api/base/server";
|
||||||
|
import { useUserStore } from "@/store/modules/user";
|
||||||
|
import { useDataStore } from "@/store/modules/data";
|
||||||
|
const { getCurXs } = useUserStore();
|
||||||
|
const { getData } = useDataStore();
|
||||||
|
dayjs.locale("zh-cn");
|
||||||
|
|
||||||
|
const kmTabsRef = ref<any>(null)
|
||||||
|
|
||||||
|
const fsScale = 100;
|
||||||
|
|
||||||
|
const curXs = ref<any>({})
|
||||||
|
const kscc = ref<any>({})
|
||||||
|
|
||||||
|
const kscjList = ref<any>([])
|
||||||
|
const curKsdj = ref<any>({})
|
||||||
|
|
||||||
|
const xqKmList = ref<any>([])
|
||||||
|
const curKm = ref<any>({})
|
||||||
|
const curKmIndex = ref<number>(0)
|
||||||
|
const xqKmmcList = ref<string[]>([])
|
||||||
|
|
||||||
// 当前选中的选项卡
|
// 当前选中的选项卡
|
||||||
const activeTab = ref("scores");
|
const activeTab = ref("scores");
|
||||||
@ -165,15 +190,26 @@ function switchTab(tab: string) {
|
|||||||
|
|
||||||
// 科目数据
|
// 科目数据
|
||||||
const subjects = ref([
|
const subjects = ref([
|
||||||
{ name: "语文", fullScore: 98, grade: "B" },
|
{ id: "1", kmmc: "语文", fullScore: 98, grade: "B" },
|
||||||
{ name: "数学", fullScore: 96, grade: "A" },
|
{ id: "2", kmmc: "数学", fullScore: 96, grade: "A" },
|
||||||
{ name: "英语", fullScore: 98, grade: "A" },
|
{ id: "3", kmmc: "英语", fullScore: 98, grade: "A" },
|
||||||
{ name: "科学", fullScore: 94, grade: "A" },
|
{ id: "4", kmmc: "科学", fullScore: 94, grade: "A" },
|
||||||
{ name: "音乐", fullScore: 93, grade: "A" },
|
// { id: "5", kmmc: "音乐", fullScore: 93, grade: "A" },
|
||||||
{ name: "美术", fullScore: 93, grade: "A" },
|
// { id: "6", kmmc: "美术", fullScore: 93, grade: "A" },
|
||||||
{ name: "体育", fullScore: 93, grade: "A" },
|
{ id: "7", kmmc: "体育", fullScore: 93, grade: "A" },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
type ColorMapType = {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
const colorMap: ColorMapType = {
|
||||||
|
"A": "#FF6B6B",
|
||||||
|
"B": "#4D96FF",
|
||||||
|
"C": "#6BCB77",
|
||||||
|
"D": "#FFD93D",
|
||||||
|
"E": "#B8B8B8",
|
||||||
|
};
|
||||||
|
|
||||||
// 雷达图数据
|
// 雷达图数据
|
||||||
const radarData = {
|
const radarData = {
|
||||||
categories: ["语文", "数学", "英语", "科学", "音乐", "美术", "体育"],
|
categories: ["语文", "数学", "英语", "科学", "音乐", "美术", "体育"],
|
||||||
@ -181,7 +217,7 @@ const radarData = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 趋势图数据
|
// 趋势图数据
|
||||||
const trendData = {
|
let trendData = {
|
||||||
categories: ["01-04", "02-04", "03-04", "04-04", "05-04"],
|
categories: ["01-04", "02-04", "03-04", "04-04", "05-04"],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
@ -191,6 +227,33 @@ const trendData = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 后端查询到的所有科目列表
|
||||||
|
const srcKmList = ref<any>([]);
|
||||||
|
// 后端查询到的考试等级列表
|
||||||
|
const srcKsdjList = ref<any>([]);
|
||||||
|
// 后端查询到的当前学生本次考试成绩列表
|
||||||
|
const srcKsccKscjList = ref<any>([]);
|
||||||
|
// 后端查询到的当前学生本次学期所有成绩列表
|
||||||
|
const srcXqKscjList = ref<any>([]);
|
||||||
|
|
||||||
|
const switchKm = (index : number) => {
|
||||||
|
curKmIndex.value = index;
|
||||||
|
curKm.value = xqKmList.value[index];
|
||||||
|
trendData = {
|
||||||
|
categories: curKm.value.rqList,
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "成绩趋势",
|
||||||
|
data: curKm.value.fsList,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
if (activeTab.value === "trend") {
|
||||||
|
// 重绘趋势图
|
||||||
|
drawTrendChart();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 绘制雷达图
|
// 绘制雷达图
|
||||||
const drawRadarChart = () => {
|
const drawRadarChart = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
@ -326,7 +389,118 @@ watch(activeTab, (newValue) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Float乘以倍数,然后四舍五入转int
|
||||||
|
const floatToInt = (floatNum: number, scale: number) => {
|
||||||
|
return Math.round(floatNum * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化考试等级列表
|
||||||
|
const initKsdj = () => {
|
||||||
|
srcKsdjList.value.forEach((ksdj: any) => {
|
||||||
|
ksdj.djfsd = floatToInt(ksdj.djfsd, fsScale); // 等级最低分
|
||||||
|
ksdj.djfsg = floatToInt(ksdj.djfsg, fsScale); // 等级最高分
|
||||||
|
ksdj.djclr = colorMap[ksdj.dfbs] || ''; // 等级颜色
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 单科科目成绩构建
|
||||||
|
const buildKmKscj = (km: any, cjList: any) => {
|
||||||
|
let cj = cjList.find((item: any) => item.kmId === km.id);
|
||||||
|
if (cj) {
|
||||||
|
km.ksfs = cj.ksfs; // 记录分数
|
||||||
|
const fs = floatToInt(cj.ksfs, fsScale);
|
||||||
|
// 查询考试等级
|
||||||
|
km.ksdj = srcKsdjList.value.find((item: any) => item.djfsd <= fs && item.djfsg >= fs);
|
||||||
|
} else {
|
||||||
|
km.ksfs = 0.00;
|
||||||
|
km.ksdj = {
|
||||||
|
id: '',
|
||||||
|
dfbs: '无',
|
||||||
|
dsms: '无'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return km;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建当前学期所有科目成绩(对象是按照{ 科目id:{ 日期:成绩 } }的结构拼接)
|
||||||
|
const buildXqKmKscjList = () => {
|
||||||
|
const xqKscjMap = new Map<string, any>();
|
||||||
|
const len = srcXqKscjList.value.length;
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const exam = srcXqKscjList.value[i];
|
||||||
|
exam.ksrq = dayjs(exam.kskstime).format('MM-DD');
|
||||||
|
if (!xqKscjMap.has(exam.kmId)) {
|
||||||
|
xqKscjMap.set(exam.kmId, {});
|
||||||
|
}
|
||||||
|
xqKscjMap.get(exam.kmId)[exam.ksrq] = exam.ksfs;
|
||||||
|
}
|
||||||
|
xqKmList.value = [];
|
||||||
|
// 遍历map
|
||||||
|
const keys = Array.from(xqKscjMap.keys());
|
||||||
|
for (let i = 0; i < keys.length; i++) {
|
||||||
|
const key = keys[i];
|
||||||
|
const value = xqKscjMap.get(key);
|
||||||
|
// 目前value是Object,改成map
|
||||||
|
const dataMap = new Map(Object.entries(value));
|
||||||
|
let km = {
|
||||||
|
id: key,
|
||||||
|
kmmc: srcKmList.value.find((item: any) => item.id === key)?.kmmc,
|
||||||
|
rqList: Array.from(dataMap.keys()).map(String),
|
||||||
|
fsList: Array.from(dataMap.values()).map(Number)
|
||||||
|
};
|
||||||
|
xqKmList.value.push(km);
|
||||||
|
}
|
||||||
|
xqKmmcList.value = xqKmList.value.map((item: any) => item.kmmc);
|
||||||
|
switchKm(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const rebuildData = () => {
|
||||||
|
// 根据考试场次,分解对应的科目
|
||||||
|
let ksccKmmcList = getData.kmmc.split(",");
|
||||||
|
let ksccKmIdList = getData.kmId.split(",");
|
||||||
|
let ksfsList = [];
|
||||||
|
let totalFs = 0.00;
|
||||||
|
kscjList.value = [];
|
||||||
|
for (let i = 0; i < ksccKmIdList.length; i++) {
|
||||||
|
let km = { id: ksccKmIdList[i], kmmc: ksccKmmcList[i] };
|
||||||
|
let kmKscj = buildKmKscj(km, srcKsccKscjList.value);
|
||||||
|
ksfsList.push(kmKscj.ksfs);
|
||||||
|
totalFs += kmKscj.ksfs;
|
||||||
|
kscjList.value.push(kmKscj);
|
||||||
|
}
|
||||||
|
// 雷达图数据
|
||||||
|
radarData.categories = ksccKmmcList;
|
||||||
|
radarData.series = [{ name: "分数", data: ksfsList }];
|
||||||
|
// 当前成绩列表
|
||||||
|
totalFs = floatToInt(totalFs, fsScale) / ksccKmIdList.length;
|
||||||
|
curKsdj.value = srcKsdjList.value.find((item: any) => item.djfsd <= totalFs && item.djfsg >= totalFs);
|
||||||
|
// 构建趋势图所需的成绩列表信息
|
||||||
|
buildXqKmKscjList();
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
curXs.value = getCurXs;
|
||||||
|
kscc.value = getData;
|
||||||
|
xsKscjApi({
|
||||||
|
xsId: getCurXs.id,
|
||||||
|
ksccId: getData.id,
|
||||||
|
njmcId: getData.njmcId
|
||||||
|
}).then(res => {
|
||||||
|
if (res.resultCode == 1) {
|
||||||
|
srcKmList.value = res.result.kmList;
|
||||||
|
srcKsdjList.value = res.result.ksdjList;
|
||||||
|
srcKsccKscjList.value = res.result.ksccKscjList;
|
||||||
|
srcXqKscjList.value = res.result.xqKscjList;
|
||||||
|
// 初始化考试等级
|
||||||
|
initKsdj();
|
||||||
|
// 重构显示数据
|
||||||
|
rebuildData();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
// 接口调用失败
|
||||||
|
console.error("调用查询成绩接口失败:", error);
|
||||||
|
});
|
||||||
// 默认绘制学科成绩视图
|
// 默认绘制学科成绩视图
|
||||||
// 延迟执行确保DOM已经渲染
|
// 延迟执行确保DOM已经渲染
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -601,6 +775,21 @@ function hideGradeInfo() {
|
|||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.km-info {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
.km-mc {
|
||||||
|
flex: 1 0 1px;
|
||||||
|
}
|
||||||
|
.switch-btn {
|
||||||
|
padding: 4px 12px;
|
||||||
|
background-color: rgba(25, 118, 210, 0.8);
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.radar-placeholder {
|
.radar-placeholder {
|
||||||
height: 300px;
|
height: 300px;
|
||||||
@ -721,4 +910,124 @@ function hideGradeInfo() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 学生选择器弹窗样式 */
|
||||||
|
.student-selector {
|
||||||
|
background: linear-gradient(135deg, #ffffff 0%, #f8faff 100%);
|
||||||
|
border-top-left-radius: 20px;
|
||||||
|
border-top-right-radius: 20px;
|
||||||
|
padding-bottom: 30px;
|
||||||
|
|
||||||
|
.selector-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20px;
|
||||||
|
border-bottom: 1px solid #f0f2f5;
|
||||||
|
|
||||||
|
.selector-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-btn {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.9);
|
||||||
|
background-color: #e6e8eb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-list {
|
||||||
|
padding: 0 20px;
|
||||||
|
max-height: 50%;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.student-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 16px 0;
|
||||||
|
border-bottom: 1px solid #f5f7fa;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-active {
|
||||||
|
background: linear-gradient(135deg, rgba(74, 144, 226, 0.08) 0%, rgba(53, 122, 189, 0.05) 100%);
|
||||||
|
padding: 16px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-avatar {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
flex-shrink: 0;
|
||||||
|
box-shadow: 0 2px 8px rgba(74, 144, 226, 0.15);
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
|
||||||
|
.avatar-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-info {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 15px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
.student-name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.student-class {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #606266;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: linear-gradient(135deg, #4A90E2 0%, #357ABD 100%);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 0 2px 8px rgba(74, 144, 226, 0.3);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,724 +1,165 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="grades-page flex flex-col">
|
<view class="ks-application-page">
|
||||||
<!-- 顶部蓝色背景 -->
|
<BasicListLayout @register="register">
|
||||||
<view class="blue-header">
|
<template v-slot="{ data }">
|
||||||
<view class="header-content">
|
<view class="ks-card" @click="viewDetails(data)">
|
||||||
<text class="title">2024学年第一学期二年级期中</text>
|
<view class="card-header">
|
||||||
<text class="subtitle">教学质量监测成绩报告</text>
|
<text class="applicant-name"
|
||||||
|
>{{ data.ksmc }}</text
|
||||||
<view class="color-bar"></view>
|
|
||||||
|
|
||||||
<text class="total-score">全科(满分700分)</text>
|
|
||||||
|
|
||||||
<text class="grade">A</text>
|
|
||||||
|
|
||||||
<view class="grade-info">
|
|
||||||
<text class="grade-explanation" @click="showGradeInfo">等级说明</text>
|
|
||||||
<view class="grade-box">
|
|
||||||
<text class="grade-label">区域等级</text>
|
|
||||||
<text class="grade-value">相对较好</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 白色内容区 -->
|
|
||||||
<view class="flex-1" style="background-color: #f6f6f6; position: relative">
|
|
||||||
<view class="content-area">
|
|
||||||
<!-- 选项卡 -->
|
|
||||||
<view class="tabs">
|
|
||||||
<view
|
|
||||||
class="tab-item"
|
|
||||||
:class="{ active: activeTab === 'diagnosis' }"
|
|
||||||
@click="switchTab('diagnosis')"
|
|
||||||
>
|
|
||||||
<text>学科诊断</text>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="tab-item"
|
|
||||||
:class="{ active: activeTab === 'scores' }"
|
|
||||||
@click="switchTab('scores')"
|
|
||||||
>
|
|
||||||
<text>学科成绩</text>
|
|
||||||
</view>
|
|
||||||
<view
|
|
||||||
class="tab-item"
|
|
||||||
:class="{ active: activeTab === 'trend' }"
|
|
||||||
@click="switchTab('trend')"
|
|
||||||
>
|
|
||||||
<text>分数趋势</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 学科成绩视图 -->
|
|
||||||
<view class="score-view flex-1 po-re" v-if="activeTab === 'scores'">
|
|
||||||
<view class="po-ab inset-0 px-15" style="overflow: auto">
|
|
||||||
<view
|
|
||||||
class="subject-item"
|
|
||||||
v-for="(subject, index) in subjects"
|
|
||||||
:key="index"
|
|
||||||
>
|
>
|
||||||
<view class="subject-header">
|
</view>
|
||||||
<text class="subject-name"
|
<view class="card-body">
|
||||||
>{{ subject.name }}(满分{{ subject.fullScore }})</text
|
<view class="info-row">
|
||||||
>
|
<text class="label">考试科目:</text>
|
||||||
</view>
|
<text class="value">{{ data.kmmc }}</text>
|
||||||
<view class="subject-body">
|
</view>
|
||||||
<text class="subject-grade">{{ subject.grade }}</text>
|
<view class="info-row">
|
||||||
<text class="detail-btn">详情</text>
|
<text class="label">开始时间:</text>
|
||||||
</view>
|
<text class="value">{{ data.kskstime }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-row">
|
||||||
|
<text class="label">结束时间:</text>
|
||||||
|
<text class="value">{{ data.ksjstime }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="card-footer">
|
||||||
|
<text>查看详情</text>
|
||||||
<!-- 分数趋势视图 -->
|
<text class="arrow">
|
||||||
<view class="trend-view" v-if="activeTab === 'trend'">
|
<uni-icons type="arrowright" size="16" color="#ccc"></uni-icons>
|
||||||
<!-- 图表占位区域 -->
|
</text>
|
||||||
<view class="radar-placeholder" id="chart-container1">
|
|
||||||
<canvas
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
canvas-id="trendCanvas"
|
|
||||||
id="trendCanvas"
|
|
||||||
class="charts"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</template>
|
||||||
<!-- 学科诊断视图 -->
|
</BasicListLayout>
|
||||||
<view class="diagnosis-view flex-1 po-re" v-if="activeTab === 'diagnosis'">
|
|
||||||
<view class="po-ab inset-0 p-15" style="overflow: auto">
|
|
||||||
<view class="radar-placeholder" id="chart-container">
|
|
||||||
<canvas
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
canvas-id="radarCanvas"
|
|
||||||
id="radarCanvas"
|
|
||||||
class="charts"
|
|
||||||
/>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 诊断评语 -->
|
|
||||||
<view class="diagnosis-comment">
|
|
||||||
<text class="comment-title">尊敬的家长,您好</text>
|
|
||||||
<text class="comment-text"
|
|
||||||
>向您祝贺,朱信权同学本次考试成绩位于较优秀之列!</text
|
|
||||||
>
|
|
||||||
<text class="comment-text"
|
|
||||||
>这次考试中道德与法治学科表现最优秀,继续保持学科优势!相对来说英语学科表现最弱,不过也有27道题的答题表现超出同层次的平均。</text
|
|
||||||
>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<!-- 等级说明弹窗 -->
|
|
||||||
<u-popup
|
|
||||||
:show="gradeInfoPopupVisible"
|
|
||||||
mode="center"
|
|
||||||
round="10"
|
|
||||||
:closeable="true"
|
|
||||||
@close="hideGradeInfo"
|
|
||||||
>
|
|
||||||
<view class="grade-info-popup">
|
|
||||||
<view class="popup-header">
|
|
||||||
<text class="popup-title">等级说明</text>
|
|
||||||
<u-icon
|
|
||||||
name="close"
|
|
||||||
size="20"
|
|
||||||
color="#999"
|
|
||||||
@click="hideGradeInfo"
|
|
||||||
></u-icon>
|
|
||||||
</view>
|
|
||||||
<view class="popup-content">
|
|
||||||
<view
|
|
||||||
class="grade-item"
|
|
||||||
v-for="(item, index) in gradeInfoList"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<view
|
|
||||||
class="grade-label"
|
|
||||||
:style="{ backgroundColor: item.color }"
|
|
||||||
>{{ item.grade }}</view
|
|
||||||
>
|
|
||||||
<view class="grade-desc">
|
|
||||||
<text class="grade-title">{{ item.desc }}</text>
|
|
||||||
<text class="grade-detail">{{ item.description }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</u-popup>
|
|
||||||
</view>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, watch, nextTick } from "vue";
|
import { ref } from "vue";
|
||||||
import { navigateBack } from "@/utils/uniapp";
|
import { useLayout } from "@/components/BasicListLayout/hooks/useLayout";
|
||||||
import uCharts from "@/components/charts/u-charts.js";
|
import { xsKsccApi } from "@/api/base/server";
|
||||||
|
import { useUserStore } from "@/store/modules/user";
|
||||||
|
import { useDataStore } from "@/store/modules/data";
|
||||||
|
const { getCurXs } = useUserStore();
|
||||||
|
const { setData } = useDataStore();
|
||||||
|
|
||||||
// 当前选中的选项卡
|
let pageParams = ref({
|
||||||
const activeTab = ref("scores");
|
rows: 10,
|
||||||
|
xsId: getCurXs.id
|
||||||
|
})
|
||||||
|
|
||||||
// 切换选项卡
|
// 模拟请假申请数据
|
||||||
function switchTab(tab: string) {
|
const mockLeaveData = [
|
||||||
activeTab.value = tab;
|
{
|
||||||
}
|
id: "ks001",
|
||||||
|
applicantName: "施瑞辰",
|
||||||
|
reason: "家里有事要处理",
|
||||||
|
startTime: "2025-02-17 08:00",
|
||||||
|
endTime: "2025-02-17 18:00",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ks002",
|
||||||
|
applicantName: "李晓明",
|
||||||
|
reason: "身体不适,需要就医",
|
||||||
|
startTime: "2025-02-18 09:00",
|
||||||
|
endTime: "2025-02-18 17:00",
|
||||||
|
},
|
||||||
|
// 可以添加更多模拟数据
|
||||||
|
];
|
||||||
|
|
||||||
// 科目数据
|
// 模拟 API,实际应替换为真实 API 调用
|
||||||
const subjects = ref([
|
const testList = async (param?: any): Promise<{ message: string, resultCode: number, rows: any[] }> => {
|
||||||
{ name: "语文", fullScore: 98, grade: "B" },
|
console.log("Simulating API call for ks list with params:", param);
|
||||||
{ name: "数学", fullScore: 96, grade: "A" },
|
// 这里简单返回所有数据,真实场景需要分页
|
||||||
{ name: "英语", fullScore: 98, grade: "A" },
|
return new Promise((resolve) => {
|
||||||
{ name: "科学", fullScore: 94, grade: "A" },
|
setTimeout(() => {
|
||||||
{ name: "音乐", fullScore: 93, grade: "A" },
|
resolve({ message: "测试", resultCode: 1, rows: mockLeaveData });
|
||||||
{ name: "美术", fullScore: 93, grade: "A" },
|
}, 500);
|
||||||
{ name: "体育", fullScore: 93, grade: "A" },
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 雷达图数据
|
|
||||||
const radarData = {
|
|
||||||
categories: ["语文", "数学", "英语", "科学", "音乐", "美术", "体育"],
|
|
||||||
series: [{ name: "分数", data: [85, 90, 88, 92, 86, 91, 89] }],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 趋势图数据
|
|
||||||
const trendData = {
|
|
||||||
categories: ["01-04", "02-04", "03-04", "04-04", "05-04"],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "成绩趋势",
|
|
||||||
data: [84, 81, 89, 92, 99],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
// 绘制雷达图
|
|
||||||
const drawRadarChart = () => {
|
|
||||||
nextTick(() => {
|
|
||||||
try {
|
|
||||||
// 获取容器信息
|
|
||||||
const query = uni.createSelectorQuery();
|
|
||||||
query
|
|
||||||
.select("#chart-container")
|
|
||||||
.boundingClientRect((data) => {
|
|
||||||
if (!data) {
|
|
||||||
console.error("未找到雷达图容器");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 安全类型判断
|
|
||||||
const rect = data as any;
|
|
||||||
const canvasWidth = rect.width || 300;
|
|
||||||
const canvasHeight = rect.height || 300;
|
|
||||||
|
|
||||||
const ctx = uni.createCanvasContext("radarCanvas");
|
|
||||||
|
|
||||||
// 绘制雷达图配置
|
|
||||||
const options = {
|
|
||||||
type: "radar",
|
|
||||||
context: ctx,
|
|
||||||
width: canvasWidth,
|
|
||||||
height: canvasHeight,
|
|
||||||
categories: radarData.categories,
|
|
||||||
series: radarData.series,
|
|
||||||
animation: true,
|
|
||||||
background: "#FFFFFF",
|
|
||||||
padding: [10, 10, 10, 10],
|
|
||||||
dataLabel: false,
|
|
||||||
legend: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
extra: {
|
|
||||||
radar: {
|
|
||||||
gridType: "radar",
|
|
||||||
gridColor: "#CCCCCC",
|
|
||||||
gridCount: 3,
|
|
||||||
opacity: 0.2,
|
|
||||||
labelShow: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
new uCharts(options);
|
|
||||||
})
|
|
||||||
.exec();
|
|
||||||
} catch (error) {
|
|
||||||
console.error("绘制雷达图出错:", error);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 绘制趋势图
|
const [register, { reload }] = useLayout({
|
||||||
const drawTrendChart = () => {
|
api: xsKsccApi,
|
||||||
nextTick(() => {
|
componentProps: {},
|
||||||
try {
|
param: pageParams.value
|
||||||
// 获取容器信息
|
});
|
||||||
const query = uni.createSelectorQuery();
|
|
||||||
query
|
|
||||||
.select("#chart-container1")
|
|
||||||
.boundingClientRect((data) => {
|
|
||||||
if (!data) {
|
|
||||||
console.error("未找到趋势图容器");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 安全类型判断
|
// 查看详情或新增处理函数
|
||||||
const rect = data as any;
|
const viewDetails = (item: any | null) => {
|
||||||
const canvasWidth = rect.width || 300;
|
setData(item);
|
||||||
const canvasHeight = rect.height || 300;
|
uni.navigateTo({ url: '/pages/base/grades/detail' });
|
||||||
|
|
||||||
const ctx = uni.createCanvasContext("trendCanvas");
|
|
||||||
|
|
||||||
// 绘制折线图配置
|
|
||||||
const options = {
|
|
||||||
type: "line",
|
|
||||||
context: ctx,
|
|
||||||
width: canvasWidth,
|
|
||||||
height: canvasHeight,
|
|
||||||
categories: trendData.categories,
|
|
||||||
series: trendData.series,
|
|
||||||
animation: true,
|
|
||||||
background: "#FFFFFF",
|
|
||||||
padding: [15, 15, 0, 15],
|
|
||||||
dataLabel: true,
|
|
||||||
dataPointShape: true,
|
|
||||||
enableScroll: false,
|
|
||||||
legend: {
|
|
||||||
show: false,
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
disableGrid: true,
|
|
||||||
axisLine: true,
|
|
||||||
axisLineColor: "#CCCCCC",
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
gridType: "dash",
|
|
||||||
dashLength: 2,
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
min: 80,
|
|
||||||
max: 100,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
extra: {
|
|
||||||
line: {
|
|
||||||
type: "straight",
|
|
||||||
width: 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
new uCharts(options);
|
|
||||||
})
|
|
||||||
.exec();
|
|
||||||
} catch (error) {
|
|
||||||
console.error("绘制趋势图出错:", error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 监听选项卡变化,重新渲染对应图表
|
|
||||||
watch(activeTab, (newValue) => {
|
|
||||||
if (newValue === "diagnosis") {
|
|
||||||
setTimeout(drawRadarChart, 50);
|
|
||||||
} else if (newValue === "trend") {
|
|
||||||
setTimeout(drawTrendChart, 50);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 默认绘制学科成绩视图
|
|
||||||
// 延迟执行确保DOM已经渲染
|
|
||||||
setTimeout(() => {
|
|
||||||
if (activeTab.value === "diagnosis") {
|
|
||||||
drawRadarChart();
|
|
||||||
} else if (activeTab.value === "trend") {
|
|
||||||
drawTrendChart();
|
|
||||||
}
|
|
||||||
}, 300);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 等级说明弹窗状态
|
|
||||||
const gradeInfoPopupVisible = ref(false);
|
|
||||||
|
|
||||||
// 等级说明数据
|
|
||||||
const gradeInfoList = ref([
|
|
||||||
{
|
|
||||||
grade: "A+",
|
|
||||||
color: "#FF6B6B",
|
|
||||||
desc: "优异",
|
|
||||||
description: "超过90%同学,处于年级前列",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
grade: "A",
|
|
||||||
color: "#4D96FF",
|
|
||||||
desc: "相对较好",
|
|
||||||
description: "超过80%同学,表现良好",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
grade: "B",
|
|
||||||
color: "#6BCB77",
|
|
||||||
desc: "良好",
|
|
||||||
description: "超过60%同学,达到年级中上水平",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
grade: "C",
|
|
||||||
color: "#FFD93D",
|
|
||||||
desc: "一般",
|
|
||||||
description: "达到年级平均水平",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
grade: "D",
|
|
||||||
color: "#B8B8B8",
|
|
||||||
desc: "待提高",
|
|
||||||
description: "未达到年级平均水平,需要加强",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 显示等级说明弹窗
|
|
||||||
function showGradeInfo() {
|
|
||||||
gradeInfoPopupVisible.value = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 隐藏等级说明弹窗
|
|
||||||
function hideGradeInfo() {
|
|
||||||
gradeInfoPopupVisible.value = false;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.grades-page {
|
.ks-application-page {
|
||||||
background-color: #f8f8f8;
|
|
||||||
height: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 顶部蓝色背景 */
|
.ks-card {
|
||||||
.blue-header {
|
background-color: #ffffff;
|
||||||
background-color: #2672ff;
|
border-radius: 8px;
|
||||||
padding: 15px 15px 50px 15px;
|
margin-bottom: 15px;
|
||||||
position: relative;
|
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);
|
||||||
color: white;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.back-icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.more-icon {
|
|
||||||
position: absolute;
|
|
||||||
top: 15px;
|
|
||||||
right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-content {
|
|
||||||
padding-top: 30px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-bar {
|
|
||||||
width: 180px;
|
|
||||||
height: 15px;
|
|
||||||
background: linear-gradient(
|
|
||||||
to right,
|
|
||||||
#29b6f6,
|
|
||||||
#4caf50,
|
|
||||||
#ff9800,
|
|
||||||
#f57c00,
|
|
||||||
#ffab91,
|
|
||||||
#ffe0b2
|
|
||||||
);
|
|
||||||
border-radius: 15px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.total-score {
|
|
||||||
font-size: 16px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grade {
|
|
||||||
font-size: 50px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grade-info {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.grade-explanation {
|
|
||||||
font-size: 14px;
|
|
||||||
margin-right: 15px;
|
|
||||||
position: relative;
|
|
||||||
padding-bottom: 2px;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 1px;
|
|
||||||
background-color: rgba(255, 255, 255, 0.7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.grade-box {
|
|
||||||
background-color: rgba(255, 255, 255, 0.2);
|
|
||||||
padding: 8px 20px;
|
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.grade-label {
|
|
||||||
font-size: 14px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grade-value {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 内容区域 */
|
|
||||||
.content-area {
|
|
||||||
border-top-left-radius: 20px;
|
|
||||||
border-top-right-radius: 20px;
|
|
||||||
background-color: white;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: absolute;
|
}
|
||||||
z-index: 3;
|
|
||||||
top: -70rpx;
|
|
||||||
left: 30rpx;
|
|
||||||
right: 30rpx;
|
|
||||||
bottom: 30rpx;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
/* 选项卡 */
|
.card-header {
|
||||||
.tabs {
|
padding: 12px 15px;
|
||||||
display: flex;
|
border-bottom: 1px solid #f0f0f0;
|
||||||
border-bottom: 1px solid #ebeef5;
|
.applicant-name {
|
||||||
|
font-size: 16px;
|
||||||
.tab-item {
|
font-weight: bold;
|
||||||
flex: 1;
|
color: #333;
|
||||||
text-align: center;
|
|
||||||
padding: 15px 0;
|
|
||||||
position: relative;
|
|
||||||
color: #606266;
|
|
||||||
font-size: 15px;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: #1976d2;
|
|
||||||
font-weight: 500;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 25%;
|
|
||||||
width: 50%;
|
|
||||||
height: 2px;
|
|
||||||
background-color: #1976d2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 学科成绩视图 */
|
|
||||||
.score-view {
|
|
||||||
padding: 15px;
|
|
||||||
|
|
||||||
.subject-item {
|
|
||||||
padding-top: 30rpx;
|
|
||||||
.subject-header {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
|
|
||||||
.subject-name {
|
|
||||||
font-size: 15px;
|
|
||||||
color: #606266;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.subject-body {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
padding-bottom: 15px;
|
|
||||||
|
|
||||||
.subject-grade {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-btn {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #909399;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 分数趋势视图 */
|
|
||||||
.trend-view {
|
|
||||||
padding: 15px;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.chart-placeholder {
|
|
||||||
height: 300px;
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
border-radius: 8px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.placeholder-text {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.radar-placeholder {
|
|
||||||
height: 300px;
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
border-radius: 8px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.placeholder-text {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 学科诊断视图 */
|
|
||||||
.diagnosis-view {
|
|
||||||
padding: 15px;
|
|
||||||
|
|
||||||
.diagnosis-comment {
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 8px;
|
|
||||||
background-color: #f8f8f8;
|
|
||||||
|
|
||||||
.comment-title {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #303133;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.comment-text {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #606266;
|
|
||||||
line-height: 1.6;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 等级说明弹窗 */
|
.card-body {
|
||||||
.grade-info-popup {
|
padding: 15px;
|
||||||
width: 280px;
|
.info-row {
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 10px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.popup-header {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
margin-bottom: 10px;
|
||||||
align-items: center;
|
&:last-child {
|
||||||
padding: 15px;
|
margin-bottom: 0;
|
||||||
border-bottom: 1px solid #f2f2f2;
|
}
|
||||||
|
.label {
|
||||||
.popup-title {
|
font-size: 14px;
|
||||||
font-size: 16px;
|
color: #666;
|
||||||
font-weight: 500;
|
width: 70px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.value {
|
||||||
|
font-size: 14px;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
flex: 1;
|
||||||
}
|
|
||||||
|
|
||||||
.popup-content {
|
|
||||||
padding: 10px 15px 20px;
|
|
||||||
max-height: 60vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.grade-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
padding: 8px;
|
|
||||||
border-radius: 6px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grade-label {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
color: #fff;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 12px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grade-desc {
|
|
||||||
flex: 1;
|
|
||||||
|
|
||||||
.grade-title {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #333;
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grade-detail {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666;
|
|
||||||
line-height: 1.4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
.card-footer {
|
||||||
|
padding: 12px 15px;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #888;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增按钮样式示例 (可根据 BasicListLayout 的 bottom 插槽调整)
|
||||||
|
.button {
|
||||||
|
padding: 10px 15px;
|
||||||
|
background-color: #447ade;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 10px 15px; // 示例外边距
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -147,7 +147,7 @@ const menuItems = ref([
|
|||||||
{
|
{
|
||||||
title: "成绩查询",
|
title: "成绩查询",
|
||||||
icon: "/static/base/home/file-search-line.png",
|
icon: "/static/base/home/file-search-line.png",
|
||||||
path: "/pages/base/grades/detail",
|
path: "/pages/base/grades/list",
|
||||||
},
|
},
|
||||||
// {
|
// {
|
||||||
// title: "在线请假",
|
// title: "在线请假",
|
||||||
@ -244,7 +244,7 @@ function switchStudent(student: any) {
|
|||||||
|
|
||||||
// 这里可以添加切换学生后的其他操作,如刷新页面数据等
|
// 这里可以添加切换学生后的其他操作,如刷新页面数据等
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: `已切换到${student.name}`,
|
title: `已切换到${student.xm}`,
|
||||||
icon: "none",
|
icon: "none",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user