feat: 老师端
This commit is contained in:
parent
d1765d936c
commit
da364bc97d
4
.env
4
.env
@ -1,5 +1,5 @@
|
||||
#VITE_HOST = http://192.168.0.114:9053
|
||||
#VITE_HOST = http://43.136.52.196:9053
|
||||
VITE_HOST= https://ai.xuexiaole.com
|
||||
VITE_HOST = http://43.136.52.196:9053
|
||||
#VITE_HOST= https://ai.xuexiaole.com
|
||||
VITE_OSS_HOST = https://xxl-1313840333.cos.ap-guangzhou.myqcloud.com
|
||||
VITE_WS_URL = wss://test.qiaoying.vip/wss/websocket
|
||||
@ -55,6 +55,8 @@ export const getPaperReleaseRecordList = (params: {
|
||||
schoolId: string;
|
||||
current: number;
|
||||
size: number;
|
||||
classId?: string;
|
||||
subjectId?: string;
|
||||
}) => {
|
||||
return request({
|
||||
url: '/school/paperReleaseRecord/list',
|
||||
@ -62,3 +64,81 @@ export const getPaperReleaseRecordList = (params: {
|
||||
params,
|
||||
});
|
||||
};
|
||||
|
||||
// 班级列表(按教师)- 接口 org/class/listByTeacher,可选年级筛选
|
||||
export const getClassListByTeacher = (params?: { gradeId?: string; gradeName?: string }) => {
|
||||
return request({
|
||||
url: '/org/class/listByTeacher',
|
||||
method: 'GET',
|
||||
params: params || {},
|
||||
});
|
||||
};
|
||||
|
||||
// 根据班级ID获取学科列表
|
||||
export const getSubjectListByClassId = (classId: string) => {
|
||||
return request({
|
||||
url: '/org/class/listSubjectInfoByClassId',
|
||||
method: 'GET',
|
||||
params: { classId },
|
||||
});
|
||||
};
|
||||
|
||||
// ---------- 班级作业完成情况报表 school/report/classHomework/list ----------
|
||||
export interface ClassHomeworkSubjectStat {
|
||||
subjectId: number;
|
||||
subjectName: string;
|
||||
homeworkCount: number;
|
||||
completedCount: number;
|
||||
uncompletedCount: number;
|
||||
}
|
||||
|
||||
export interface ClassHomeworkStudentItem {
|
||||
userId: number;
|
||||
userName: string;
|
||||
totalCount: number;
|
||||
completedCount: number;
|
||||
uncompletedCount: number;
|
||||
subjectStats: ClassHomeworkSubjectStat[];
|
||||
}
|
||||
|
||||
export interface ClassHomeworkReportData {
|
||||
classId: number;
|
||||
className: string;
|
||||
subjects: { subjectId: number; subjectName: string }[];
|
||||
studentList: ClassHomeworkStudentItem[];
|
||||
}
|
||||
|
||||
/** 班级作业报表:GET 请求,参数以 form 表单风格放在 query(subjectIds 为多个同名参数) */
|
||||
export const getClassHomeworkReport = (params: {
|
||||
classId: string | number;
|
||||
/** 学科ID列表,可多选,不传或空则查全部学科 */
|
||||
subjectIds?: number[];
|
||||
startTime?: string;
|
||||
endTime?: string;
|
||||
}) => {
|
||||
// form 表单编码:空格用 +,特殊字符用 encodeURIComponent 后把 %20 替换为 +
|
||||
const formEncode = (v: string) => encodeURIComponent(v).replace(/%20/g, '+');
|
||||
|
||||
const query: string[] = [];
|
||||
query.push('classId=' + formEncode(String(params.classId)));
|
||||
if (params.subjectIds && params.subjectIds.length > 0) {
|
||||
params.subjectIds.forEach((id) => {
|
||||
query.push('subjectIds=' + formEncode(String(id)));
|
||||
});
|
||||
}
|
||||
if (params.startTime != null && params.startTime !== '' && String(params.startTime).trim() !== '') {
|
||||
// 后端 Date 类型需要带时分秒,picker 只返回 yyyy-MM-dd,补 00:00:00
|
||||
const st = String(params.startTime).trim();
|
||||
query.push('startTime=' + formEncode(st.includes(' ') ? st : st + ' 00:00:00'));
|
||||
}
|
||||
if (params.endTime != null && params.endTime !== '' && String(params.endTime).trim() !== '') {
|
||||
// 结束时间补 23:59:59,保证包含当天
|
||||
const et = String(params.endTime).trim();
|
||||
query.push('endTime=' + formEncode(et.includes(' ') ? et : et + ' 23:59:59'));
|
||||
}
|
||||
const queryString = query.join('&');
|
||||
return request({
|
||||
url: '/school/report/classHomework/list?' + queryString,
|
||||
method: 'GET',
|
||||
});
|
||||
};
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
<template>
|
||||
<view class="select-wrap">
|
||||
<view class="select-btn" @click="showPicker = true">
|
||||
<view class="select-btn" @click="openPopup">
|
||||
<text class="select-text">{{ currentLabel }}</text>
|
||||
<image class="select-arrow" :src="`${OSS_URL}/icon/icon_arrow_down.svg`" mode="aspectFit" />
|
||||
</view>
|
||||
|
||||
<uni-popup ref="popupRef" type="bottom" @change="onPopupChange">
|
||||
<view class="picker-content">
|
||||
<view
|
||||
class="picker-content"
|
||||
:style="{ paddingRight: capsulePaddingRightRpx + 'rpx' }"
|
||||
>
|
||||
<view class="picker-header">
|
||||
<text class="cancel" @click="handleCancel">取消</text>
|
||||
<text class="title">请选择</text>
|
||||
@ -33,10 +36,39 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from 'vue';
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
|
||||
const OSS_URL = 'https://xxl-1313840333.cos.ap-guangzhou.myqcloud.com';
|
||||
|
||||
// 右上角胶囊预留(避免弹层被遮挡)
|
||||
const capsulePaddingRightRpx = ref(0);
|
||||
|
||||
const getCapsulePadding = () => {
|
||||
try {
|
||||
// #ifdef MP-WEIXIN
|
||||
const menuButton = uni.getMenuButtonBoundingClientRect();
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
if (menuButton && systemInfo?.windowWidth) {
|
||||
const pxToRpx = 750 / systemInfo.windowWidth;
|
||||
// 右侧:从胶囊左缘到屏幕右缘 + 间距,避免「确定」等被胶囊遮住
|
||||
const rightPx = systemInfo.windowWidth - menuButton.left;
|
||||
capsulePaddingRightRpx.value = Math.ceil(rightPx * pxToRpx) + 24;
|
||||
} else {
|
||||
capsulePaddingRightRpx.value = 140;
|
||||
}
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
capsulePaddingRightRpx.value = 0;
|
||||
// #endif
|
||||
} catch {
|
||||
capsulePaddingRightRpx.value = 140;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getCapsulePadding();
|
||||
});
|
||||
|
||||
interface SelectOption {
|
||||
label: string;
|
||||
value: string | number;
|
||||
@ -76,6 +108,10 @@ watch(
|
||||
{ immediate: true },
|
||||
);
|
||||
|
||||
const openPopup = () => {
|
||||
showPicker.value = true;
|
||||
};
|
||||
|
||||
watch(showPicker, (val) => {
|
||||
if (val) {
|
||||
popupRef.value?.open();
|
||||
|
||||
@ -115,6 +115,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "homework/filter",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "筛选条件",
|
||||
"disableScroll": true,
|
||||
"pageOrientation": "landscape",
|
||||
"allowsBounceVertical": "NO",
|
||||
"mp-weixin": {
|
||||
"pageOrientation": "landscape"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "homework/index",
|
||||
"style": {
|
||||
|
||||
@ -210,6 +210,13 @@
|
||||
<rich-text :nodes="filterTitle(typeof data.aiAnswer === 'string' ? data.aiAnswer : String(data.aiAnswer))" />
|
||||
</view>
|
||||
</view>
|
||||
<!-- AI点评 -->
|
||||
<view v-if="data?.aiAnalyze != null " class="answer-box">
|
||||
<view class="answer-box-title">AI点评</view>
|
||||
<view class="answer-box-main analyze">
|
||||
<rich-text :nodes="filterTitle(typeof data.aiAnalyze === 'string' ? data.aiAnalyze : String(data.aiAnalyze))" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</scroll-view>
|
||||
|
||||
|
||||
@ -26,7 +26,9 @@
|
||||
<view class="book-box">
|
||||
<view class="book">
|
||||
<template v-if="paperList.length && paperList[activeIdx]">
|
||||
<!-- key 随题目变化,切换题目时强制重新挂载,重新加载题目内容(含公式 SVG 等),避免网络差时图片加载失败不重试 -->
|
||||
<Question
|
||||
:key="`question-${activeIdx}-${paperList[activeIdx]?.id ?? ''}`"
|
||||
:data="paperList[activeIdx]"
|
||||
:idx="activeIdx + 1"
|
||||
:total="paperList.length"
|
||||
|
||||
475
src/pages/teacher/homework/filter.vue
Normal file
475
src/pages/teacher/homework/filter.vue
Normal file
@ -0,0 +1,475 @@
|
||||
<template>
|
||||
<view class="filter-page" :style="safeAreaStyle">
|
||||
<!-- 顶部标题 -->
|
||||
<view class="header" :style="topRightPaddingStyle">
|
||||
<qy-BackBar leftText="筛选条件" />
|
||||
</view>
|
||||
|
||||
<!-- 筛选区域 -->
|
||||
<scroll-view class="filter-body" scroll-y>
|
||||
<!-- 班级选择 -->
|
||||
<view class="filter-section">
|
||||
<view class="section-title">
|
||||
<text class="section-title-text">选择班级</text>
|
||||
<text class="section-required">*必选</text>
|
||||
</view>
|
||||
<view class="option-grid">
|
||||
<view
|
||||
v-for="cls in classList"
|
||||
:key="cls.id"
|
||||
class="option-item"
|
||||
:class="{ active: selectedClassId === cls.id }"
|
||||
@click="selectedClassId = cls.id"
|
||||
>
|
||||
<text class="option-text">{{ cls.name }}</text>
|
||||
<view v-if="selectedClassId === cls.id" class="option-check">✓</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="classList.length === 0" class="empty-hint">
|
||||
<text>{{ classLoading ? '加载中...' : '暂无班级数据' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 学科选择 -->
|
||||
<view class="filter-section">
|
||||
<view class="section-title">
|
||||
<text class="section-title-text">选择学科</text>
|
||||
<text class="section-hint">可多选,不选默认全部</text>
|
||||
</view>
|
||||
<view v-if="!selectedClassId" class="empty-hint">
|
||||
<text>请先选择班级</text>
|
||||
</view>
|
||||
<view v-else-if="subjectLoading" class="empty-hint">
|
||||
<text>加载学科中...</text>
|
||||
</view>
|
||||
<view v-else-if="subjectList.length === 0" class="empty-hint">
|
||||
<text>该班级暂无学科数据</text>
|
||||
</view>
|
||||
<view v-else class="option-grid">
|
||||
<view
|
||||
v-for="sub in subjectList"
|
||||
:key="sub.value"
|
||||
class="option-item"
|
||||
:class="{ active: selectedSubjectIds.includes(sub.value) }"
|
||||
@click="toggleSubject(sub.value)"
|
||||
>
|
||||
<text class="option-text">{{ sub.label }}</text>
|
||||
<view v-if="selectedSubjectIds.includes(sub.value)" class="option-check">✓</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 时间范围 -->
|
||||
<view class="filter-section">
|
||||
<view class="section-title">
|
||||
<text class="section-title-text">时间范围</text>
|
||||
<text class="section-hint">可选</text>
|
||||
</view>
|
||||
<view class="date-row">
|
||||
<picker mode="date" :value="startTime" @change="onStartChange">
|
||||
<view class="date-picker-box" :class="{ filled: !!startTime }">
|
||||
<text class="date-picker-text">{{ startTime || '开始日期' }}</text>
|
||||
</view>
|
||||
</picker>
|
||||
<text class="date-sep">至</text>
|
||||
<picker mode="date" :value="endTime" @change="onEndChange">
|
||||
<view class="date-picker-box" :class="{ filled: !!endTime }">
|
||||
<text class="date-picker-text">{{ endTime || '结束日期' }}</text>
|
||||
</view>
|
||||
</picker>
|
||||
<view v-if="startTime || endTime" class="date-clear" @click="clearDate">
|
||||
<text>清除</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="bottom-bar">
|
||||
<view class="btn-reset" @click="handleReset">
|
||||
<text>重置</text>
|
||||
</view>
|
||||
<view class="btn-confirm" :class="{ disabled: !selectedClassId }" @click="handleConfirm">
|
||||
<text>查询</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted } from 'vue';
|
||||
import { onShow } from '@dcloudio/uni-app';
|
||||
import { getClassListByTeacher, getSubjectListByClassId } from '@/api/teacher';
|
||||
import { teacher } from '@/store/teacher';
|
||||
import { storeToRefs } from 'pinia';
|
||||
const teacherStore = teacher();
|
||||
const { schoolId } = storeToRefs(teacherStore);
|
||||
|
||||
// 胶囊预留 + 安全区域
|
||||
const topPaddingRightRpx = ref(0);
|
||||
const safeAreaLeftRpx = ref(0);
|
||||
const topRightPaddingStyle = computed(() =>
|
||||
topPaddingRightRpx.value > 0 ? { paddingRight: topPaddingRightRpx.value + 'rpx' } : {},
|
||||
);
|
||||
const safeAreaStyle = computed(() => {
|
||||
const style: Record<string, string> = {};
|
||||
if (safeAreaLeftRpx.value > 0) {
|
||||
style.paddingLeft = safeAreaLeftRpx.value + 'rpx';
|
||||
}
|
||||
return style;
|
||||
});
|
||||
function getCapsulePadding() {
|
||||
try {
|
||||
// #ifdef MP-WEIXIN
|
||||
const menuButton = uni.getMenuButtonBoundingClientRect();
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
if (menuButton && systemInfo?.windowWidth) {
|
||||
const pxToRpx = 750 / systemInfo.windowWidth;
|
||||
const rightPx = systemInfo.windowWidth - menuButton.left;
|
||||
topPaddingRightRpx.value = Math.ceil(rightPx * pxToRpx) + 24;
|
||||
} else {
|
||||
topPaddingRightRpx.value = 140;
|
||||
}
|
||||
// 计算左侧安全区域
|
||||
if (systemInfo?.safeArea && systemInfo.safeArea.left > 0) {
|
||||
const pxToRpx = 750 / (systemInfo.windowWidth || systemInfo.screenWidth);
|
||||
safeAreaLeftRpx.value = Math.ceil(systemInfo.safeArea.left * pxToRpx) + 4;
|
||||
}
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
topPaddingRightRpx.value = 0;
|
||||
// #endif
|
||||
} catch {
|
||||
topPaddingRightRpx.value = 140;
|
||||
}
|
||||
}
|
||||
|
||||
// 班级列表
|
||||
const classList = ref<{ id: string; name: string }[]>([]);
|
||||
const classLoading = ref(false);
|
||||
const selectedClassId = ref('');
|
||||
|
||||
// 学科列表(根据选择的班级动态获取)
|
||||
const subjectList = ref<{ value: number; label: string }[]>([]);
|
||||
const subjectLoading = ref(false);
|
||||
const selectedSubjectIds = ref<number[]>([]);
|
||||
|
||||
// 监听班级选择变化,获取对应学科
|
||||
watch(() => selectedClassId.value, async (newClassId) => {
|
||||
// 清空之前的学科选择
|
||||
selectedSubjectIds.value = [];
|
||||
subjectList.value = [];
|
||||
if (!newClassId) return;
|
||||
subjectLoading.value = true;
|
||||
try {
|
||||
const res = await getSubjectListByClassId(newClassId);
|
||||
const data = res?.data ?? res;
|
||||
// 适配接口返回格式
|
||||
if (Array.isArray(data)) {
|
||||
subjectList.value = data.map((item: any) => ({
|
||||
value: item.subjectId ?? item.id ?? item.value,
|
||||
label: item.subjectName ?? item.name ?? item.label ?? '',
|
||||
}));
|
||||
} else {
|
||||
subjectList.value = [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取学科列表失败', e);
|
||||
subjectList.value = [];
|
||||
} finally {
|
||||
subjectLoading.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 时间 —— 默认当天
|
||||
function getTodayStr() {
|
||||
const d = new Date();
|
||||
const y = d.getFullYear();
|
||||
const m = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(d.getDate()).padStart(2, '0');
|
||||
return `${y}-${m}-${day}`;
|
||||
}
|
||||
const today = getTodayStr();
|
||||
const startTime = ref(today);
|
||||
const endTime = ref(today);
|
||||
|
||||
function toggleSubject(value: number) {
|
||||
const idx = selectedSubjectIds.value.indexOf(value);
|
||||
if (idx >= 0) {
|
||||
selectedSubjectIds.value = selectedSubjectIds.value.filter((v) => v !== value);
|
||||
} else {
|
||||
selectedSubjectIds.value = [...selectedSubjectIds.value, value];
|
||||
}
|
||||
}
|
||||
|
||||
function onStartChange(e: any) {
|
||||
startTime.value = e.detail?.value || '';
|
||||
}
|
||||
function onEndChange(e: any) {
|
||||
endTime.value = e.detail?.value || '';
|
||||
}
|
||||
function clearDate() {
|
||||
startTime.value = '';
|
||||
endTime.value = '';
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
selectedClassId.value = '';
|
||||
selectedSubjectIds.value = [];
|
||||
startTime.value = '';
|
||||
endTime.value = '';
|
||||
}
|
||||
|
||||
function handleConfirm() {
|
||||
if (!selectedClassId.value) {
|
||||
uni.showToast({ title: '请先选择班级', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
// 找到班级名称
|
||||
const cls = classList.value.find((c) => c.id === selectedClassId.value);
|
||||
const className = cls?.name || '';
|
||||
// 拼接参数跳转到作业记录页
|
||||
const params: string[] = [];
|
||||
params.push('classId=' + encodeURIComponent(selectedClassId.value));
|
||||
params.push('className=' + encodeURIComponent(className));
|
||||
if (selectedSubjectIds.value.length > 0) {
|
||||
params.push('subjectIds=' + encodeURIComponent(selectedSubjectIds.value.join(',')));
|
||||
}
|
||||
if (startTime.value) {
|
||||
params.push('startTime=' + encodeURIComponent(startTime.value));
|
||||
}
|
||||
if (endTime.value) {
|
||||
params.push('endTime=' + encodeURIComponent(endTime.value));
|
||||
}
|
||||
const url = '/pages/teacher/homework/index?' + params.join('&');
|
||||
uni.navigateTo({ url });
|
||||
}
|
||||
|
||||
const fetchClassList = async () => {
|
||||
if (!schoolId.value) return;
|
||||
classLoading.value = true;
|
||||
try {
|
||||
const res = await getClassListByTeacher();
|
||||
const data = res?.data ?? res;
|
||||
classList.value = Array.isArray(data) ? data : data?.list ?? data?.rows ?? [];
|
||||
} catch (e) {
|
||||
console.error('获取班级列表失败', e);
|
||||
classList.value = [];
|
||||
} finally {
|
||||
classLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getCapsulePadding();
|
||||
if (schoolId.value) fetchClassList();
|
||||
});
|
||||
|
||||
onShow(async () => {
|
||||
if (!schoolId.value) {
|
||||
try {
|
||||
await teacherStore.getLoginUser();
|
||||
} catch (err) {
|
||||
console.error('刷新老师信息失败', err);
|
||||
}
|
||||
}
|
||||
if (schoolId.value && classList.value.length === 0) {
|
||||
fetchClassList();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.filter-page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-image: url('https://xxl-1313840333.cos.ap-guangzhou.myqcloud.com/urm/main_bg.svg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
padding-left: 16rpx;
|
||||
padding-right: 16rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 4rpx 12rpx 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
// 筛选区域
|
||||
.filter-body {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
padding: 4rpx 12rpx 6rpx;
|
||||
}
|
||||
|
||||
.filter-section {
|
||||
background: linear-gradient(180deg, #fff 0%, #f8f6ff 100%);
|
||||
border-radius: 8rpx;
|
||||
padding: 6rpx 10rpx;
|
||||
margin-bottom: 6rpx;
|
||||
box-shadow: 0 1rpx 6rpx rgba(143, 157, 247, 0.1);
|
||||
border: 1rpx solid rgba(196, 181, 255, 0.2);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 5rpx;
|
||||
gap: 4rpx;
|
||||
}
|
||||
.section-title-text {
|
||||
font-family: $font-special;
|
||||
font-size: 15rpx;
|
||||
font-weight: 600;
|
||||
color: $font-color;
|
||||
}
|
||||
.section-required {
|
||||
font-size: 11rpx;
|
||||
color: #e05040;
|
||||
}
|
||||
.section-hint {
|
||||
font-size: 11rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
// 选项网格
|
||||
.option-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 5rpx;
|
||||
}
|
||||
.option-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 3rpx;
|
||||
padding: 4rpx 8rpx;
|
||||
background: rgba(196, 181, 255, 0.1);
|
||||
border: 1rpx solid rgba(196, 181, 255, 0.25);
|
||||
border-radius: 6rpx;
|
||||
transition: all 0.2s;
|
||||
|
||||
.option-text {
|
||||
font-family: $font-special;
|
||||
font-size: 13rpx;
|
||||
color: #666;
|
||||
}
|
||||
.option-check {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #8f9df7 0%, #92fc90 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 10rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: linear-gradient(135deg, rgba(143, 157, 247, 0.15) 0%, rgba(202, 181, 255, 0.15) 100%);
|
||||
border-color: #8f9df7;
|
||||
|
||||
.option-text {
|
||||
color: #8f9df7;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
padding: 8rpx 0;
|
||||
text {
|
||||
font-size: 12rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
// 日期行
|
||||
.date-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6rpx;
|
||||
}
|
||||
.date-picker-box {
|
||||
padding: 4rpx 10rpx;
|
||||
background: rgba(196, 181, 255, 0.1);
|
||||
border: 1rpx solid rgba(196, 181, 255, 0.25);
|
||||
border-radius: 6rpx;
|
||||
min-width: 90rpx;
|
||||
text-align: center;
|
||||
|
||||
.date-picker-text {
|
||||
font-size: 12rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&.filled {
|
||||
border-color: #8f9df7;
|
||||
.date-picker-text {
|
||||
color: #8f9df7;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
.date-sep {
|
||||
font-size: 12rpx;
|
||||
color: #999;
|
||||
}
|
||||
.date-clear {
|
||||
padding: 2rpx 6rpx;
|
||||
text {
|
||||
font-size: 12rpx;
|
||||
color: #e05040;
|
||||
}
|
||||
}
|
||||
|
||||
// 底部按钮
|
||||
.bottom-bar {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
gap: 10rpx;
|
||||
padding: 0 12rpx;
|
||||
padding-bottom: calc(6rpx + env(safe-area-inset-bottom));
|
||||
}
|
||||
.btn-reset {
|
||||
flex: 1;
|
||||
padding: 7rpx 0;
|
||||
border-radius: 8rpx;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border: 1rpx solid rgba(196, 181, 255, 0.3);
|
||||
text-align: center;
|
||||
|
||||
text {
|
||||
font-family: $font-special;
|
||||
font-size: 13rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
.btn-confirm {
|
||||
flex: 2;
|
||||
padding: 7rpx 0;
|
||||
border-radius: 8rpx;
|
||||
background: linear-gradient(269deg, #adadff 2%, #cab5ff 52%, #8f9df7 100%);
|
||||
box-shadow: 0 2rpx 8rpx rgba(143, 157, 247, 0.3);
|
||||
text-align: center;
|
||||
|
||||
text {
|
||||
font-family: $font-special;
|
||||
font-size: 13rpx;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&:active:not(.disabled) {
|
||||
opacity: 0.85;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@ -38,7 +38,7 @@
|
||||
<!-- 右侧功能入口 -->
|
||||
<view class="right-section">
|
||||
<view class="content">
|
||||
<view class="entry-card" @click="handleNavigate('/pages/teacher/homework/index')">
|
||||
<view class="entry-card" @click="handleNavigate('/pages/teacher/homework/filter')">
|
||||
<view class="card-icon homework-icon">
|
||||
<image :src="`${OSS_URL}/icon/homeWork_hisJob.svg`" mode="aspectFit" />
|
||||
</view>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
export * from './tool';
|
||||
export * from './map';
|
||||
export * from './getStatic';
|
||||
export * from './subject';
|
||||
36
src/utils/subject.ts
Normal file
36
src/utils/subject.ts
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* 学科选项:与 admin playground store/basic-data/subject 保持一致(教材选择弹框学科数据来源)
|
||||
*/
|
||||
export interface SubjectOption {
|
||||
value: number;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const subjects: SubjectOption[] = [
|
||||
{ value: 2, label: '语文' },
|
||||
{ value: 3, label: '数学' },
|
||||
{ value: 4, label: '英语' },
|
||||
{ value: 5, label: '科学' },
|
||||
{ value: 6, label: '物理' },
|
||||
{ value: 7, label: '化学' },
|
||||
{ value: 8, label: '历史' },
|
||||
{ value: 9, label: '道德与法治' },
|
||||
{ value: 10, label: '地理' },
|
||||
{ value: 11, label: '生物' },
|
||||
{ value: 12, label: '政治' },
|
||||
{ value: 13, label: '信息' },
|
||||
{ value: 14, label: '通用' },
|
||||
{ value: 15, label: '日语' },
|
||||
];
|
||||
|
||||
/** 学科下拉选项(用于筛选等),与 admin 教材选择弹框学科数据一致 */
|
||||
export function getSubjectOptions(): SubjectOption[] {
|
||||
return subjects;
|
||||
}
|
||||
|
||||
/** 学科 value 转 label */
|
||||
export function getSubjectLabel(value: number | string): string {
|
||||
const v = Number(value);
|
||||
const item = subjects.find((s) => s.value === v);
|
||||
return item?.label ?? '';
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user