调整工作量

This commit is contained in:
ywyonui 2025-08-20 19:31:02 +08:00
parent 526cdc1075
commit 301bab459a
4 changed files with 273 additions and 34 deletions

19
src/api/base/gzlApi.ts Normal file
View File

@ -0,0 +1,19 @@
// 食堂巡查相关API接口
import { get, post } from "@/utils/request";
// 获取工作量
export const gzlFindPageApi = async (params: any) => {
return await get("/api/gzl/findPage", params);
};
// 获取当前学期和周次
export const gzlGetDqXqAndZcApi = async () => {
return await get("/api/gzl/getDqXqAndZc");
};
/**
*
*/
export const dqPkApi = async () => {
return await get("/mobile/jz/pkkb/dqpk");
};

View File

@ -222,11 +222,6 @@ export const resourcesAddNumByTypeApi = async (params: any) => {
return await post("/api/resources/addNumByType", params); return await post("/api/resources/addNumByType", params);
}; };
// 获取工作量
export const gzlFindPageApi = async (params: any) => {
return await get("/api/gzl/findPage", params);
};
// 获取校平均工作量 // 获取校平均工作量
export const getJsPjGzlApi = async () => { export const getJsPjGzlApi = async () => {
return await get("/api/comConfig/getJsPjGzl"); return await get("/api/comConfig/getJsPjGzl");

View File

@ -1,6 +1,10 @@
<template> <template>
<BasicLayout :show-nav-bar="true" :nav-bar-props="{ title: '工作量统计' }"> <BasicLayout :show-nav-bar="true" :nav-bar-props="{ title: '工作量统计' }">
<view class="grade-analysis-page"> <view class="grade-analysis-page">
<view class="week-selector" @click="openWeekPicker">
<text>{{ curZc?.mc || '选择周次' }}</text>
<uni-icons type="right" size="16" color="#fff"></uni-icons>
</view>
<uni-section title="排课工作量" type="line" titleFontSize="16px" padding> <uni-section title="排课工作量" type="line" titleFontSize="16px" padding>
<view v-if="pkList.length"> <view v-if="pkList.length">
<view class="section-sub-card r-md" v-for="(pk, index) in pkList" :key="index"> <view class="section-sub-card r-md" v-for="(pk, index) in pkList" :key="index">
@ -21,7 +25,7 @@
</view> </view>
<view class="stat-item"> <view class="stat-item">
<text class="label">周工作量</text> <text class="label">周工作量</text>
<text class="value">{{ (pk.xs || 1.0) * (pk.ks || 0.0) }}</text> <text class="value">{{ formatNumber((pk.xs || 1.0) * (pk.ks || 0.0)) }}</text>
</view> </view>
</view> </view>
</view> </view>
@ -43,7 +47,7 @@
<view class="table-body"> <view class="table-body">
<view class="table-row" v-for="(zw, index) in zwList" :key="index"> <view class="table-row" v-for="(zw, index) in zwList" :key="index">
<view class="td">{{ zw.zwMc }}</view> <view class="td">{{ zw.zwMc }}</view>
<view class="td flex-80">{{ zw.ks }}</view> <view class="td flex-80">{{ formatNumber(zw.ks) }}</view>
</view> </view>
</view> </view>
</view> </view>
@ -66,7 +70,7 @@
<view class="table-row" v-for="(zdy, index) in zdyList" :key="index"> <view class="table-row" v-for="(zdy, index) in zdyList" :key="index">
<view class="td">{{ zdy.xmMc }}</view> <view class="td">{{ zdy.xmMc }}</view>
<view class="td">{{ zdy.lxMc }}</view> <view class="td">{{ zdy.lxMc }}</view>
<view class="td">{{ zdy.ks }}</view> <view class="td">{{ formatNumber(zdy.ks) }}</view>
</view> </view>
</view> </view>
</view> </view>
@ -100,21 +104,42 @@
<text>无工作量</text> <text>无工作量</text>
</view> </view>
</uni-section> --> </uni-section> -->
<!-- 周选择弹窗 -->
<uni-popup ref="weekPopup" type="bottom" @change="popupChange">
<view class="week-picker-popup">
<view class="popup-header">
<text class="title">选择周</text>
</view>
<view class="week-list">
<scroll-view scroll-y style="max-height: 60vh" :scroll-top="targetScrollTop">
<view v-for="(zc, index) in zcList" :key="index" :class="[
'week-item',
{ active: zc.djz === curZc.djz },
]" @click="selectWeek(zc)">
<text>{{ zc.mc }}</text>
<text v-if="zc.dnDjz === dnDjz" class="current-tag">当前周</text>
</view>
</scroll-view>
</view>
</view>
</uni-popup>
</view> </view>
<template #bottom> <template #bottom>
<view class="bottom-container"> <view class="bottom-container">
<view class="stats-grid"> <view class="stats-grid">
<view class="stat-item"> <view class="stat-item">
<text class="label">总工作量</text> <text class="label">总工作量</text>
<text class="value primary">{{ gzl.zks }}</text> <text class="value primary">{{ formatNumber(gzl.zks) }}</text>
</view> </view>
<view class="stat-item"> <view class="stat-item">
<text class="label">校平均工作量</text> <text class="label">校平均工作量</text>
<text class="value success">{{ gzl.pjks }}</text> <text class="value success">{{ formatNumber(gzl.pjks) }}</text>
</view> </view>
<view class="stat-item"> <view class="stat-item">
<text class="label">工作量比例</text> <text class="label">工作量比例</text>
<text class="value">{{ gzl.bl }}%</text> <text class="value">{{ formatNumber(gzl.bl) }}%</text>
</view> </view>
</view> </view>
</view> </view>
@ -123,44 +148,158 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { gzlFindPageApi, getJsPjGzlApi } from "@/api/base/server"; import { ref, onMounted, nextTick } from "vue";
import { gzlFindPageApi } from "@/api/base/gzlApi";
import BasicLayout from "@/components/BasicLayout/Layout.vue"; import BasicLayout from "@/components/BasicLayout/Layout.vue";
import { useUserStore } from "@/store/modules/user"; import { useUserStore } from "@/store/modules/user";
import { useCommonStore } from "@/store/modules/common";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import weekOfYear from "dayjs/plugin/weekOfYear";
import isoWeek from "dayjs/plugin/isoWeek";
dayjs.locale("zh-cn");
dayjs.extend(weekOfYear);
dayjs.extend(isoWeek);
const { getJs } = useUserStore(); const { getJs } = useUserStore();
const { getDqPkZcList, getDqXqAndZc } = useCommonStore();
//
const dnDjz = ref(dayjs().isoWeek());
//
const curZc = ref<any>({});
//
const zcList = ref<any>([]);
//
const showWeekPicker = ref(false);
const weekPopup = ref<any>(null);
const targetScrollTop = ref(0);
const gzl = ref<any>({}); const gzl = ref<any>({});
const pkList = ref<any[]>([ const pkList = ref<any[]>([]);
{ id: 1, kmMc: "语文", xs: 1.0, ks: 5.0 }, const zwList = ref<any[]>([]);
{ id: 2, kmMc: "数学", xs: 1.0, ks: 4.0 }, const bzrList = ref<any[]>([]);
{ id: 3, kmMc: "英语", xs: 1.0, ks: 3.0 }, const zdyList = ref<any[]>([]);
]);
const zwList = ref<any[]>([
{ id: 1, zwMc: "书记", ks: 5.0 },
{ id: 2, zwMc: "校长", ks: 4.0 },
]);
const bzrList = ref<any[]>([
{ id: 1, njmc: "一年级", bjmc: "1班", zb: 0.33, ks: 2.0 },
{ id: 2, njmc: "二年级", bjmc: "1班", zb: 0.5, ks: 3.0 },
{ id: 3, njmc: "二年级", bjmc: "2班", zb: 1.0, ks: 6.0 },
]);
const zdyList = ref<any[]>([ //
{ id: 1, xmMc: "书记", ks: 5.0 }, const loadGzlData = async () => {
{ id: 2, xmMc: "校长", ks: 4.0 }, try {
]); console.log(curZc.value);
const res = await gzlFindPageApi({
onMounted(async () => { jsId: getJs.id,
{ zc: curZc.value.djz //
const res = await gzlFindPageApi({ jsId: getJs.id }); });
if (!res.rows || !res.rows.length) { if (!res.rows || !res.rows.length) {
gzl.value = {};
pkList.value = [];
zwList.value = [];
bzrList.value = [];
zdyList.value = [];
return; return;
} }
gzl.value = res.rows[0] || {}; gzl.value = res.rows[0] || {};
pkList.value = gzl.value.gzlPkList || []; pkList.value = gzl.value.gzlPkList || [];
zwList.value = gzl.value.gzlZwList || []; zwList.value = gzl.value.gzlZwList || [];
bzrList.value = gzl.value.gzlBzrList || []; bzrList.value = gzl.value.gzlBzrList || [];
zdyList.value = gzl.value.gzlZdyList || []; zdyList.value = gzl.value.gzlZdyList || [];
} catch (error) {
console.error("加载工作量数据失败:", error);
}
};
// 20
const formatNumber = (value: number | string | undefined | null): string => {
if (value === undefined || value === null || value === '') {
return '0';
}
const num = parseFloat(value.toString());
if (isNaN(num)) {
return '0';
}
// 2
const formatted = num.toFixed(2);
// 0
return formatted.replace(/\.?0+$/, '');
};
//
const openWeekPicker = async () => {
showWeekPicker.value = true;
//
await nextTick();
if (weekPopup.value) {
weekPopup.value.open("bottom");
} else {
console.error("Week popup ref is not available.");
}
};
//
const closeWeekPicker = () => {
if (weekPopup.value) {
weekPopup.value.close();
}
};
//
const popupChange = (e: { show: boolean }) => {
if (!e.show) {
showWeekPicker.value = false;
}
};
//
const selectWeek = async (zc: any) => {
if (curZc.value && zc && zc.djz === curZc.value.djz) {
//
closeWeekPicker();
return;
}
//
curZc.value = zc;
//
closeWeekPicker();
//
await loadGzlData();
};
onMounted(async () => {
try {
//
const res = await getDqXqAndZc();
const zcListData = await getDqPkZcList();
//
zcList.value = zcListData || [];
//
let currentZc = zcListData?.find((item: any) => item.zc === res.zc);
if (!currentZc && zcListData && zcListData.length > 0) {
currentZc = zcListData[0];
}
//
curZc.value = currentZc || { mc: '选择周次', djz: 0, zc: 0 };
//
await loadGzlData();
} catch (error) {
console.error("初始化失败:", error);
// undefined
curZc.value = { mc: '选择周次', djz: 0, zc: 0 };
zcList.value = [];
} }
}); });
</script> </script>
@ -171,6 +310,18 @@ onMounted(async () => {
padding-bottom: 20rpx; padding-bottom: 20rpx;
} }
.week-selector {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 15px;
background-color: #4477ee;
color: #ffffff;
font-size: 15px;
margin: 20rpx;
border-radius: 8px;
}
// --- Section Styling --- // --- Section Styling ---
.uni-section { .uni-section {
background-color: #fff; background-color: #fff;
@ -316,4 +467,54 @@ onMounted(async () => {
padding: 15px; padding: 15px;
margin-top: 8px; margin-top: 8px;
} }
/* 周选择弹窗样式 */
.week-picker-popup {
background-color: #fff;
border-radius: 16px 16px 0 0;
padding-bottom: 20px;
.popup-header {
display: flex;
justify-content: center;
align-items: center;
padding: 15px;
border-bottom: 1px solid #f0f0f0;
position: relative;
.title {
font-size: 16px;
font-weight: 500;
color: #333;
}
}
.week-list {
padding: 10px 0;
.week-item {
height: 53.5px; //
display: flex;
justify-content: space-between;
align-items: center; //
padding: 0 15px; // padding padding
border-bottom: 1px solid #f5f5f5;
box-sizing: border-box;
&.active {
background-color: #f0f7ff;
color: #4477ee;
}
.current-tag {
font-size: 12px;
color: #fff;
background-color: #4477ee;
padding: 2px 6px;
border-radius: 10px;
white-space: nowrap; //
}
}
}
}
</style> </style>

View File

@ -6,6 +6,7 @@ import {
zwGetListByLxApi, zwGetListByLxApi,
} from "@/api/base/common"; } from "@/api/base/common";
import { jsdJsdkbApi, jsdKsccApi } from "@/api/base/server"; import { jsdJsdkbApi, jsdKsccApi } from "@/api/base/server";
import { dqPkApi, gzlGetDqXqAndZcApi } from "@/api/base/gzlApi";
import { defineStore } from "pinia"; import { defineStore } from "pinia";
interface CommonState { interface CommonState {
@ -79,6 +80,29 @@ export const useCommonStore = defineStore({
this.data.kscc[params.bjId] = await jsdKsccApi(params); this.data.kscc[params.bjId] = await jsdKsccApi(params);
} }
return Promise.resolve(this.data.kscc[params.bjId]); return Promise.resolve(this.data.kscc[params.bjId]);
},
async getDqPk(): Promise<any> {
if (!this.data.dqpk) {
const res = await dqPkApi();
if (res && res.resultCode === 1) {
this.data.dqpk = res.result;
}
}
return Promise.resolve(this.data.dqpk);
},
async getDqPkZcList(): Promise<any> {
const dqpk = await this.getDqPk();
const ret = dqpk.zcList || [];
return Promise.resolve(ret);
},
async getDqXqAndZc(): Promise<any> {
if (!this.data.dqXqAndZc) {
const res = await gzlGetDqXqAndZcApi();
if (res && res.resultCode === 1) {
this.data.dqXqAndZc = res.result;
}
}
return Promise.resolve(this.data.dqXqAndZc);
}, },
// 清除班级考试场次缓存 // 清除班级考试场次缓存
clearKsccCache(bjId?: string) { clearKsccCache(bjId?: string) {