调整课程巡查

This commit is contained in:
ywyonui 2025-07-30 20:23:38 +08:00
parent f32e8f5a5f
commit f8c27fd710
9 changed files with 1368 additions and 871 deletions

View File

@ -104,11 +104,6 @@ export const jsdXkXsListApi = async (params: any) => {
return await get("/mobile/js/xkxs/list", params);
};
// 获取班级学生考试成绩
export const jsdBjKscjApi = async (params: any) => {
return await get("/mobile/js/kscj/bj", params);
};
// 获取班级学生考试成绩(按科目)
export const jsdBjKscjKmApi = async (params: any) => {
return await get("/mobile/js/kscj/bjKm", params);

29
src/api/base/xkscApi.ts Normal file
View File

@ -0,0 +1,29 @@
import { get, post } from "@/utils/request";
/**
*
*/
export const xkscFindPageApi = async (params: any) => {
return await get("/api/xksc/findPage", params);
};
/**
* /
*/
export const xkscSaveApi = async (params: any) => {
return await post("/api/xksc/save", params);
};
/**
* id查询巡查记录
*/
export const xkscFindByIdApi = async (params: any) => {
return await get("/api/xksc/findById", params);
};
/**
*
*/
export const xkscLogicDeleteApi = async (params: any) => {
return await post("/api/xksc/logicDelete", params);
};

View File

@ -1,6 +1,11 @@
import { get, post } from "@/utils/request";
import { get } from "@/utils/request";
//字典接口
//配置参数接口
export const dmBeforeMinuteApi = async () => {
return await get("/api/comConfig/getDmBeforeMinute");
};
};
//配置参数接口
export const xcBeforeMinuteApi = async () => {
return await get("/api/comConfig/getXcBeforeMinute");
};

View File

@ -228,14 +228,14 @@
}
},
{
"path": "pages/view/routine/kefuxuncha/KeFuXunCha",
"path": "pages/view/routine/kefuxuncha/xcXkList",
"style": {
"navigationBarTitleText": "课服巡查",
"enablePullDownRefresh": false
}
},
{
"path": "pages/view/routine/kefuxuncha/KeFuXunChaDetail",
"path": "pages/view/routine/kefuxuncha/xcXkkcDetail",
"style": {
"navigationBarTitleText": "课服巡查详情",
"enablePullDownRefresh": false

View File

@ -94,7 +94,6 @@ import { useCommonStore } from "@/store/modules/common";
import { useUserStore } from "@/store/modules/user";
import { imagUrl } from "@/utils";
import { hideLoading, showLoading } from "@/utils/uniapp";
import { set } from "lodash";
import { reactive, ref } from "vue";
const { logout, getUser, getJs, setJs } = useUserStore();
const { getZwListByLx } = useCommonStore();
@ -108,11 +107,10 @@ const qtZwLabel = ref<any>("");
//
const jsWork = ref<any>({
jf: 88,
ks: 40
jf: 88,
ks: 40,
});
interface GridItem {
id: number | string;
icon: string; // ()
@ -214,7 +212,7 @@ const sections = reactive<Section[]>([
icon: "pass-pending-fill",
text: "课服巡查",
show: true,
path: "/pages/view/routine/kefuxuncha/KeFuXunCha",
path: "/pages/view/routine/kefuxuncha/xcXkList",
},
{
id: "r7",
@ -340,9 +338,9 @@ const handleGridItemClick = async (item: GridItem) => {
const res = await jsdfindJsByPhoneApi({
phone: getJs.lxdh,
});
if (res.result.headPic && res.result.headPic.length) {
res.result.headPic = imagUrl(res.result.headPic);
}
if (res.result.headPic && res.result.headPic.length) {
res.result.headPic = imagUrl(res.result.headPic);
}
setJs(res.result);
hideLoading();
}
@ -365,22 +363,25 @@ onMounted(async () => {
if (getJs.qtzw && typeof getJs.qtzw == "string") {
qtZw = getJs.qtzw.split(",");
}
if (dzZw && dzZw.length){
const res = await getZwListByLx({ zwlx: '党政职务' });
dzZwLabel.value = dzZw.map((zwId: string) => {
const zw = res.result.find((zw: any) => zwId == zw.id);
return zw ? zw.zwmc : '';
}).join(', ');
};
if (qtZw && qtZw.length){
const res = await getZwListByLx({ zwlx: '其他职务' });
qtZwLabel.value = qtZw.map((zwId: string) => {
const zw = res.result.find((zw: any) => zwId == zw.id);
return zw ? zw.zwmc : '';
}).join(', ');
};
})
if (dzZw && dzZw.length) {
const res = await getZwListByLx({ zwlx: "党政职务" });
dzZwLabel.value = dzZw
.map((zwId: string) => {
const zw = res.result.find((zw: any) => zwId == zw.id);
return zw ? zw.zwmc : "";
})
.join(", ");
}
if (qtZw && qtZw.length) {
const res = await getZwListByLx({ zwlx: "其他职务" });
qtZwLabel.value = qtZw
.map((zwId: string) => {
const zw = res.result.find((zw: any) => zwId == zw.id);
return zw ? zw.zwmc : "";
})
.join(", ");
}
});
</script>
<style scoped lang="scss">

View File

@ -1,433 +0,0 @@
<template>
<view class="page-container">
<!-- 1. 顶部 Banner -->
<!-- <view class="header-banner mx-15 mt-15 r-md" style="box-sizing: border-box">
<view class="banner-text">
<text class="banner-title">上课巡查</text>
<text class="banner-subtitle">泸州市实验小学城西学校</text>
</view>
<view class="banner-image-placeholder"></view>
</view> -->
<!-- 2. 我的应用 -->
<!-- <view class="section my-apps mt-15 px-15">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">我的应用</text>
</view>
<uni-card :is-shadow="false" is-full margin="0">
<view class="app-grid">
<view class="app-item" @click="goToRecord">
<view class="app-icon-wrapper record-icon">
</view>
<text class="app-text">巡查记录</text>
</view>
<view class="app-item" @click="goToSummary">
<view class="app-icon-wrapper summary-icon">
</view>
<text class="app-text">巡查汇总</text>
</view>
</view>
</uni-card>
</view> -->
<!-- 3. 巡检情况 -->
<view class="section inspection-status flex-1 flex-col mt-15">
<view class="px-15">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">巡检情况</text>
</view>
<uni-segmented-control
:current="currentTab"
:values="tabs"
style-type="text"
active-color="#447ade"
@clickItem="onTabClick"
/>
</view>
<view class="inspection-list po-re">
<view class="po-ab inset-0">
<BasicListLayout :key="listKey" @register="register">
<template v-slot="{ data: item }">
<uni-card :key="item.id" :is-shadow="true" margin="10px 0">
<view class="inspection-item">
<view class="item-top-row">
<view class="item-image-placeholder"></view>
<view class="item-content">
<text class="item-title">{{ item.title }}</text>
<text class="item-detail">开课老师 {{ item.teacher }}</text>
<text class="item-detail">上课地点 {{ item.location }}</text>
</view>
<view class="item-action" @click="goToDetail(item)">
<text class="action-text">检查</text>
</view>
</view>
<view class="item-stats">
<view class="stat-item">
<text class="stat-value">{{ item.expected }}</text>
<text class="stat-label">应到</text>
</view>
<view class="stat-item">
<text class="stat-value">{{ item.actual }}</text>
<text class="stat-label">实到</text>
</view>
<view class="stat-item">
<text class="stat-value leave">{{ item.leave }}</text>
<text class="stat-label">请假</text>
</view>
<view class="stat-item">
<text class="stat-value absent">{{ item.absent }}</text>
<text class="stat-label">缺勤</text>
</view>
</view>
</view>
</uni-card>
</template>
</BasicListLayout>
</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
import {ref} from "vue";
import {useLayout} from "@/components/BasicListLayout/hooks/useLayout";
interface InspectionItem {
id: number;
title: string;
teacher: string;
location: string;
expected: number;
actual: number;
leave: number;
absent: number;
imageUrl?: string; // URL
}
const currentTab = ref(0); // 0: , 1:
const tabs = ["待巡查", "已巡查"];
const listKey = ref(0);
//
const pendingMockItems: InspectionItem[] = [
{
id: 1,
title: "机器人创客",
teacher: "叶老师",
location: "教学楼3楼",
expected: 18,
actual: 18,
leave: 0,
absent: 0,
imageUrl: "placeholder1.png",
},
{
id: 2,
title: "篮球",
teacher: "叶老师",
location: "教学楼3楼",
expected: 18,
actual: 18,
leave: 0,
absent: 0,
imageUrl: "placeholder2.png",
},
{
id: 3,
title: "足球",
teacher: "叶老师",
location: "教学楼3楼",
expected: 18,
actual: 18,
leave: 0,
absent: 0,
imageUrl: "placeholder3.png",
},
];
const testList = async (param: any): Promise<Requests<any>> => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({message: "测试", resultCode: 1, rows: pendingMockItems});
}, 1000);
});
};
const [register, {reload, setParam}] = useLayout({
api: testList,
componentProps: {
fixed: false,
},
});
const onTabClick = (e: { currentIndex: number }) => {
if (currentTab.value !== e.currentIndex) {
currentTab.value = e.currentIndex;
console.log(`切换到: ${tabs[currentTab.value]}`);
// reload
reload({pageNo: 1, param: {status: currentTab.value}} as any);
// 使 as any reload
// useLayout
}
};
const goToDetail = (item: InspectionItem) => {
console.log("检查:", item.title);
uni.navigateTo({
url: `/pages/view/routine/kefuxuncha/KeFuXunChaDetail?id=${item.id}`,
});
};
const goToRecord = () => {
console.log("跳转到巡查记录");
uni.showToast({title: "功能暂未开放", icon: "none"});
};
const goToSummary = () => {
console.log("跳转到巡查汇总");
uni.showToast({title: "功能暂未开放", icon: "none"});
};
</script>
<style scoped lang="scss">
.page-container {
background-color: #f4f5f7;
min-height: 100%;
display: flex;
flex-direction: column;
}
/* 1. 顶部 Banner */
.header-banner {
background-color: #447ade; //
color: #ffffff;
padding: 20px 15px;
display: flex;
justify-content: space-between;
align-items: center;
height: 120px; // 稿
box-sizing: border-box;
.banner-text {
display: flex;
flex-direction: column;
}
.banner-title {
font-size: 20px;
font-weight: bold;
margin-bottom: 5px;
}
.banner-subtitle {
font-size: 14px;
opacity: 0.9;
}
.banner-image-placeholder {
width: 100px; //
height: 70px; //
background-color: rgba(255, 255, 255, 0.2); //
border-radius: 8px;
}
}
/* 通用 Section 样式 */
.section {
}
.section-title-bar {
display: flex;
align-items: center;
margin-bottom: 10px;
.decorator {
width: 4px;
height: 16px;
background-color: #447ade;
margin-right: 8px;
border-radius: 2px;
}
.title-text {
font-size: 16px;
font-weight: bold;
color: #333;
}
}
/* 2. 我的应用 */
.my-apps {
.app-grid {
display: flex;
justify-content: space-around; /* 均匀分布 */
}
.app-item {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
}
.app-icon-wrapper {
width: 50px;
height: 50px;
border-radius: 50%;
margin-bottom: 8px;
display: flex;
justify-content: center;
align-items: center;
// 使 image
&.record-icon {
background-color: #447ade; //
}
&.summary-icon {
background-color: #ff9800; //
}
}
.app-text {
font-size: 13px;
color: #666;
}
}
/* uni-card 默认样式调整 */
::v-deep .uni-card {
border-radius: 8px !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06) !important; //
}
// BasicListLayout uni-card
::v-deep .inspection-list .uni-card {
margin: 0 0 10px 0 !important; // card margin
}
::v-deep .uni-card .uni-card__content {
padding: 0 !important; // uni-card padding
}
::v-deep .my-apps .uni-card .uni-card__content {
padding: 15px 0 !important; //
}
// BasicListLayout uni-card content padding
::v-deep .inspection-list .uni-card .uni-card__content {
padding: 15px !important; //
}
/* 3. 巡检情况 */
.inspection-status {
::v-deep .uni-segmented-control__text {
font-size: 15px !important;
}
::v-deep .segmented-control {
margin-bottom: 10px; // tab
background-color: #ffffff; //
border-radius: 8px; //
}
}
.inspection-list {
flex: 1;
//
}
.inspection-item {
display: flex;
flex-direction: column;
}
.item-top-row {
display: flex;
align-items: flex-start;
width: 100%;
margin-bottom: 10px;
}
.item-image-placeholder {
width: 80px;
height: 80px;
background-color: #eee; //
border-radius: 8px;
margin-right: 15px;
flex-shrink: 0; //
}
.item-content {
flex: 1;
display: flex;
flex-direction: column;
}
.item-title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 6px;
}
.item-detail {
font-size: 13px;
color: #666;
line-height: 1.6;
}
.item-stats {
display: flex;
justify-content: space-around;
width: 100%;
padding: 5px 0;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
}
.stat-value {
font-size: 18px;
font-weight: bold;
color: #333;
&.leave {
color: #ff9800; //
}
&.absent {
color: #f44336; //
}
}
.stat-label {
font-size: 12px;
color: #999;
margin-top: 2px;
}
.item-action {
margin-left: auto;
padding-left: 10px;
align-self: flex-start;
padding-top: 5px;
.action-text {
font-size: 14px;
color: #f44336; //
font-weight: bold;
cursor: pointer;
}
}
.empty-state {
text-align: center;
color: #999;
padding: 30px 0;
}
</style>

View File

@ -1,404 +0,0 @@
<template>
<view class="detail-page-container">
<scroll-view scroll-y class="main-content">
<!-- 1. 顶部课程信息 (复用列表样式) -->
<uni-card v-if="detailData" :is-shadow="true" margin="15px">
<view class="inspection-item">
<view class="item-top-row">
<view class="item-image-placeholder"></view> <!-- 图片占位 -->
<view class="item-content">
<text class="item-title">{{ detailData.title }}</text>
<text class="item-detail">开课老师 {{ detailData.teacher }}</text>
<text class="item-detail">上课地点 {{ detailData.location }}</text>
</view>
<!-- 详情页不再需要检查按钮 -->
<!-- <view class="item-action">
<text class="action-text">检查</text>
</view> -->
</view>
<view class="item-stats">
<view class="stat-item">
<text class="stat-value">{{ detailData.expected }}</text>
<text class="stat-label">应到</text>
</view>
<view class="stat-item">
<text class="stat-value">{{ detailData.actual }}</text>
<text class="stat-label">实到</text>
</view>
<view class="stat-item">
<text class="stat-value leave">{{ detailData.leave }}</text>
<text class="stat-label">请假</text>
</view>
<view class="stat-item">
<text class="stat-value absent">{{ detailData.absent }}</text>
<text class="stat-label">缺勤</text>
</view>
</view>
</view>
</uni-card>
<!-- 2. 教学计划 -->
<view class="section teaching-plan" v-if="detailData?.teachingPlan">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">教学计划</text>
</view>
<uni-card :is-shadow="true" margin="0 15px">
<view class="plan-content">
<text v-for="(plan, index) in detailData.teachingPlan" :key="index" class="plan-text">{{ plan }}</text>
</view>
</uni-card>
</view>
<!-- 3. 巡查项目 -->
<view class="section inspection-check-items">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">巡查项目</text>
</view>
<uni-card :is-shadow="true" margin="0 15px">
<checkbox-group class="check-list">
<label v-for="item in checkItems" :key="item.id" class="check-item">
<view class="item-info">
<text class="item-text">{{ item.id }}{{ item.text }}</text>
<text class="item-deduction">{{ item.deduction }}</text>
</view>
<checkbox :value="String(item.id)" :checked="item.checked" @click="item.checked = !item.checked" color="#447ade" style="transform:scale(0.8)"/>
</label>
</checkbox-group>
</uni-card>
</view>
<!-- 4. 拍照上传 -->
<view class="section photo-upload">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">拍照上传</text>
</view>
<uni-card :is-shadow="true" margin="0 15px">
<view class="upload-area">
<!-- 这里放置 uni-file-picker 或其他上传组件 -->
<uni-file-picker
v-model="uploadedFiles"
fileMediatype="image"
mode="grid"
:limit="3"
@success="handleUploadSuccess"
/>
</view>
</uni-card>
</view>
</scroll-view>
<!-- 底部提交按钮 -->
<view class="footer-submit">
<button class="submit-button" @click="handleSubmit">提交</button>
</view>
</view>
</template>
<script lang="ts" setup>
import { onLoad } from '@dcloudio/uni-app';
import { ref } from 'vue';
interface InspectionDetail {
id: number;
title: string;
teacher: string;
location: string;
expected: number;
actual: number;
leave: number;
absent: number;
imageUrl?: string; // URL
teachingPlan: string[];
}
interface InspectionCheckItem {
id: number;
text: string;
deduction: number; //
checked: boolean;
}
const inspectionId = ref<string | null>(null);
const detailData = ref<InspectionDetail | null>(null); //
const checkItems = ref<InspectionCheckItem[]>([ //
{ id: 1, text: '未按时上课', deduction: 1, checked: false },
{ id: 2, text: '上课迟到', deduction: 2, checked: false },
{ id: 3, text: '上课内容与教学计划不一致', deduction: 1, checked: false },
]);
const uploadedFiles = ref([]); //
//
const fetchDetailData = (id: string) => {
console.log('模拟请求详情数据ID:', id);
// API 使
detailData.value = {
id: parseInt(id),
title: '机器人创客',
teacher: '叶老师',
location: '教学楼3楼',
expected: 18,
actual: 18,
leave: 0,
absent: 0,
teachingPlan: [
'第一阶段:了解机器人的组成,知道每个零件的名称及用途,认识机器人的结构。',
'第二阶段:在老师的引导下,分组搭建机器人,注意引导幼儿理解机器人的数据线连接和遥控器方向的关系。',
'第三阶段:学会操控机器人的移动方向,并练习把魔方根据要求推到指定位置。',
'第四阶段:组织幼儿参加创客机器人比赛。',
]
};
};
onLoad((options) => {
if (options?.id) {
inspectionId.value = options.id;
console.log('接收到的巡查 ID:', inspectionId.value);
// inspectionId.value null
if (inspectionId.value) {
fetchDetailData(inspectionId.value);
}
} else {
console.error('未接收到巡查 ID');
//
uni.showToast({ title: '加载失败,缺少参数', icon: 'error' });
//
// setTimeout(() => uni.navigateBack(), 1500);
}
});
// 使
const handleUploadSuccess = (res: any) => {
console.log('上传成功:', res);
// uploadedFiles v-model
};
const handleSubmit = () => {
console.log('提交巡查记录');
const selectedCheckItems = checkItems.value.filter(item => item.checked);
console.log('选中的巡查项目:', selectedCheckItems);
console.log('上传的文件:', uploadedFiles.value);
// API
uni.showLoading({ title: '提交中...' });
setTimeout(() => { //
uni.hideLoading();
uni.showToast({ title: '提交成功', icon: 'success' });
//
// uni.navigateBack();
}, 1000);
};
</script>
<style scoped lang="scss">
.detail-page-container {
display: flex;
flex-direction: column;
height: 100vh;
background-color: #f4f5f7;
}
.main-content {
flex: 1;
overflow-y: auto;
padding-bottom: 80px; /* 为底部按钮留出空间 */
}
/* 复用列表页样式并微调 */
.inspection-item {
display: flex;
flex-direction: column;
}
.item-top-row {
display: flex;
align-items: flex-start;
width: 100%;
margin-bottom: 10px;
}
.item-image-placeholder {
width: 60px; /* 详情页图片稍小 */
height: 60px;
background-color: #eee;
border-radius: 8px;
margin-right: 15px;
flex-shrink: 0;
}
.item-content {
flex: 1;
display: flex;
flex-direction: column;
}
.item-title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 6px;
}
.item-detail {
font-size: 13px;
color: #666;
line-height: 1.6;
}
.item-stats {
display: flex;
justify-content: space-around;
width: 100%;
padding: 5px 0;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
}
.stat-value {
font-size: 18px;
font-weight: bold;
color: #333;
&.leave {
color: #ff9800;
}
&.absent {
color: #f44336;
}
}
.stat-label {
font-size: 12px;
color: #999;
margin-top: 2px;
}
/* Section 标题栏 */
.section {
margin-top: 15px;
}
.section-title-bar {
display: flex;
align-items: center;
margin-bottom: 10px;
padding: 0 15px; /* 标题栏左右加内边距 */
.decorator {
width: 4px;
height: 16px;
background-color: #447ade;
margin-right: 8px;
border-radius: 2px;
}
.title-text {
font-size: 16px;
font-weight: bold;
color: #333;
}
}
/* uni-card 样式调整 */
::v-deep .uni-card {
border-radius: 8px !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06) !important;
}
::v-deep .uni-card .uni-card__content {
padding: 15px !important; //
}
/* 教学计划 */
.teaching-plan {
.plan-content {
display: flex;
flex-direction: column;
}
.plan-text {
font-size: 14px;
color: #555;
line-height: 1.8;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}
}
}
/* 巡查项目 */
.inspection-check-items {
.check-list {
// display: flex; //
// flex-direction: column;
}
.check-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0; //
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
}
.item-info {
display: flex;
flex-direction: column;
}
.item-text {
font-size: 14px;
color: #333;
margin-bottom: 4px;
}
.item-deduction {
font-size: 12px;
color: #999;
}
}
/* 拍照上传 */
.photo-upload {
.upload-area {
//
// padding: 10px;
}
::v-deep .uni-file-picker__container {
justify-content: flex-start; //
}
::v-deep .file-picker__box {
margin: 0 10px 10px 0; //
}
// .upload-placeholder {
// width: 80px;
// height: 80px;
// background-color: #f8f8f8;
// border: 1px dashed #ddd;
// border-radius: 8px;
// display: flex;
// justify-content: center;
// align-items: center;
// }
}
/* 底部提交按钮 */
.footer-submit {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #ffffff;
padding: 10px 15px;
padding-bottom: calc(10px + constant(safe-area-inset-bottom)); /* 适配 iPhone X 等底部安全区域 */
padding-bottom: calc(10px + env(safe-area-inset-bottom));
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.05);
z-index: 10;
.submit-button {
background-color: #447ade;
color: #ffffff;
border-radius: 20px;
font-size: 16px;
height: 40px;
line-height: 40px;
&:active {
background-color: #3963bb;
}
}
}
</style>

View File

@ -0,0 +1,447 @@
<template>
<view class="interest-course">
<!-- 选课信息头部 - 固定部分 -->
<view class="selection-header">
<view class="header-content">
<view class="title-section" @click="clickShowXkSelector">
<view class="title">
<text v-if="xkData && xkData.xkmc">{{ xkData.xkmc }}</text>
<text v-else>巡查选课</text>
</view>
<view class="switch-btn" v-if="xkList.length > 1">切换</view>
</view>
</view>
</view>
<!-- 可滚动的内容区域 -->
<view class="scrollable-content">
<!-- 课程网格列表 -->
<view class="course-list" v-if="xkkcList && xkkcList.length > 0">
<view
v-for="(xkkc, index) in xkkcList"
:key="xkkc.id || index"
class="course-item"
>
<view class="course-name">{{ xkkc.kcmc }}</view>
<view class="course-info-item">
<view class="info-label">上课周期类型</view>
<view class="info-data">{{ xkkc.skzqlx }}</view>
</view>
<view class="course-info-item">
<view class="info-label">上课周期</view>
<view class="info-data">{{ xkkc.skzqmc }}</view>
</view>
<view class="course-info-item">
<view class="info-label">上课开始时间</view>
<view class="info-data">{{ xkkc.skkstime }}</view>
</view>
<view class="course-info-item">
<view class="info-label">上课结束时间</view>
<view class="info-data">{{ xkkc.skjstime }}</view>
</view>
<view class="course-info-item">
<view class="info-label">开课地点</view>
<view class="info-data">{{ xkkc.kcdd }}</view>
</view>
<view class="course-info-item">
<view class="info-label">上课人数</view>
<view class="info-data"
>{{ xkkc.hasNum || 0 }} | {{ xkkc.maxNum || 0 }}</view
>
</view>
<view class="course-btn-group">
<view class="xc-btn" @click.stop="goXc(xkkc)">巡查</view>
</view>
</view>
</view>
<!-- 暂无数据提示 -->
<view v-else class="empty-course-list">
<view class="empty-icon">
<u-icon name="list" size="50" color="#C8C9CC"></u-icon>
</view>
<view class="empty-text">暂无课程数据</view>
</view>
</view>
<view>
<!-- 选课选择弹窗 -->
<u-popup
:show="showXkFlag"
@close="showXkFlag = false"
mode="bottom"
round="10"
>
<view class="xk-selector">
<view class="selector-header">
<text class="selector-title">选择俱乐部</text>
<u-icon name="close" size="20" @click="showXkFlag = false"></u-icon>
</view>
<view class="xk-list">
<view
v-for="(xk, index) in xkList"
:key="index"
class="xk-item"
:class="{
'xk-item-active': xkData.id === xk.id,
}"
@click="switchXk(xk)"
>
<view class="xk-info">
<text class="xk-name">{{ xk.xkmc }}</text>
<text class="xk-type">{{ xk.xkmc }}</text>
</view>
<u-icon
v-if="xkData.id === xk.id"
name="checkmark"
color="#409EFF"
size="20"
></u-icon>
</view>
</view>
</view>
</u-popup>
</view>
</view>
</template>
<script setup lang="ts">
import { jsdXkListApi } from "@/api/base/server";
import { useDataStore } from "@/store/modules/data";
import { useUserStore } from "@/store/modules/user";
import { onBeforeUnmount, onMounted, ref } from "vue";
const { getJs } = useUserStore();
const { getData, setData } = useDataStore();
const wdNameList = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
//
const showXkFlag = ref(false);
const xkList = ref<any>([]);
const xkData = ref();
//
const xkkcList = ref<any[]>([]);
const xcBeforeMinute = ref<number>(0);
onMounted(async () => {
uni.showLoading({
title: "加载中...",
});
await loadCourseList();
uni.hideLoading();
});
//
const loadCourseList = async () => {
const res = await jsdXkListApi({
jsId: getJs.id,
});
if (res.resultCode == 1) {
if (res.result && res.result.length) {
xkList.value = res.result;
switchXk(res.result[0]);
} else {
xkList.value = [];
xkData.value = {};
xkkcList.value = [];
}
}
};
//
function clickShowXkSelector() {
if (xkList.value.length > 1) {
showXkFlag.value = true;
}
}
//
function switchXk(xk: any) {
xkData.value = xk;
xkkcList.value = xk.xkkcs;
showXkFlag.value = false;
for (let i = 0; i < xk.xkkcs.length; i++) {
let xkkc = xk.xkkcs[i];
//
switch (xkkc.skzqlx) {
case "每天":
xkkc.skzqmc = "每天";
break;
case "每周":
const daysOfWeek = xkkc.skzq.split(",").map(Number);
xkkc.skzqmc = daysOfWeek
.map((day: number) => wdNameList[day - 1])
.join(",");
break;
case "每月":
const daysOfMonth = xkkc.skzq.split(",").map(Number);
xkkc.skzqmc = daysOfMonth.map((day: number) => day + "号").join(",");
break;
}
}
//
uni.showToast({
title: `已切换到${xk.xkmc}`,
icon: "none",
});
}
//
const goXc = (xkkc: any) => {
setData(xkkc);
uni.navigateTo({
url: `/pages/view/routine/kefuxuncha/xcXkkcDetail`,
});
};
//
onBeforeUnmount(() => {});
</script>
<style lang="scss" scoped>
.interest-course {
min-height: 100%;
background-color: #f5f7fa;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
.selection-header {
background: linear-gradient(135deg, #4a90e2, #2879ff);
padding: 20px 15px;
color: #fff;
border-radius: 0 0 15px 15px;
box-shadow: 0 4px 12px rgba(40, 121, 255, 0.2);
position: sticky;
top: 0;
left: 0;
right: 0;
z-index: 10;
.header-content {
display: flex;
flex-direction: column;
gap: 15px;
.title-section {
display: flex;
align-items: center;
.title {
flex: 1 0 1px;
font-size: 24px;
font-weight: bold;
}
.subtitle {
font-size: 14px;
opacity: 0.8;
}
.switch-btn {
padding: 5px 15px;
background-color: rgba(255, 255, 255, 0.2);
color: #fff;
border-radius: 15px;
font-size: 15px;
}
}
}
}
//
.scrollable-content {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.inspection-tabs {
padding: 15px 15px 0 15px;
background-color: #fff;
margin-bottom: 10px;
}
.course-list {
padding: 15px 15px 0 15px;
.course-item {
position: relative;
width: 100%;
margin-bottom: 15px;
background-color: #fff;
border-radius: 8px;
padding: 15px;
box-sizing: border-box;
border: 1px solid transparent;
transition: all 0.3s ease;
&.selected {
border: 1px solid #3fbf72;
background-color: rgba(63, 191, 114, 0.05);
box-shadow: 0 2px 8px rgba(63, 191, 114, 0.15);
}
.course-name {
font-size: 16px;
font-weight: 500;
color: #333;
margin-bottom: 10px;
}
.course-btn-group {
display: flex;
.xc-btn {
flex: 1 0 1px;
display: inline-block;
color: #2879ff;
font-size: 14px;
}
}
.course-info-item {
display: flex;
margin-bottom: 12px;
font-size: 12px;
.info-label {
color: #949aa4;
flex: 0 0 100px;
}
.info-data {
flex: 1 0 1px;
}
}
}
}
/* 学生选择器弹窗样式 */
.xk-selector {
background-color: #ffffff;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
padding-bottom: 20px;
.selector-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
border-bottom: 1px solid #f2f2f2;
.selector-title {
font-size: 16px;
font-weight: 500;
color: #303133;
}
}
.xk-list {
padding: 0 15px;
.xk-item {
display: flex;
align-items: center;
padding: 15px 0;
border-bottom: 1px solid #f2f2f2;
&:last-child {
border-bottom: none;
}
&-active {
background-color: rgba(64, 158, 255, 0.05);
}
.xk-info {
flex: 1;
margin-left: 12px;
.xk-name {
font-size: 15px;
font-weight: 500;
color: #303133;
margin-bottom: 4px;
}
.xk-type {
font-size: 13px;
color: #303133;
margin-bottom: 4px;
}
.xk-class {
font-size: 13px;
color: #606266;
}
}
}
}
}
/* 全局图片样式 */
.w-full {
width: 100%;
}
.h-full {
height: 100%;
}
//
.empty-course-list {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
text-align: center;
.empty-icon {
margin-bottom: 20px;
background-color: #f5f6f7;
width: 80px;
height: 80px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.empty-text {
font-size: 18px;
font-weight: 500;
color: #303133;
margin-bottom: 8px;
}
.empty-desc {
font-size: 14px;
color: #909399;
max-width: 80%;
line-height: 1.5;
}
}
/* 选课已结束样式 */
.enrollment-ended {
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 8px;
padding: 12px 15px;
font-size: 16px;
font-weight: 500;
color: #fff;
gap: 8px;
}
</style>

View File

@ -0,0 +1,857 @@
<template>
<BasicLayout>
<!-- 巡查状态切换 -->
<view class="inspection-tabs">
<uni-segmented-control
:current="currentTab"
:values="tabs"
style-type="text"
active-color="#2879ff"
@clickItem="onTabClick"
/>
</view>
<!-- 待巡查内容 -->
<view v-if="currentTab === 0" class="pending-inspection">
<!-- 课程信息卡片 -->
<view class="course-card mx-15 my-15 bg-white white-bg-color r-md p-15">
<view class="flex-row items-center mb-15">
<view class="course-icon flex-center mr-10">
<u-icon name="calendar" color="#4080ff" size="20"></u-icon>
</view>
<text class="font-16 font-bold">{{ xkkc.kcmc }}</text>
<text class="font-14 cor-999 ml-10"
>{{ todayInfo.date }} ({{ todayInfo.weekName }})</text
>
</view>
<!-- 上课时间信息 -->
<view class="course-time-info">
<view class="time-item">
<text class="time-label">上课周期类型</text>
<text class="time-value">{{ xkkc.skzqlx }}</text>
</view>
<view class="time-item">
<text class="time-label">上课周期</text>
<text class="time-value">{{ xkkc.skzqmc }}</text>
</view>
<view class="time-item">
<text class="time-label">上课时间</text>
<text class="time-value"
>{{ xkkc.skkstime }} - {{ xkkc.skjstime }}</text
>
</view>
<view class="time-item">
<text class="time-label">上课地点</text>
<text class="time-value">{{ xkkc.kcdd }}</text>
</view>
</view>
<!-- 巡查时间状态 -->
<view class="inspection-status" v-if="!canInspect">
<u-icon name="clock" color="#ff9900" size="16"></u-icon>
<text class="status-text">{{ inspectionStatusText }}</text>
</view>
</view>
<view v-if="canInspect">
<!-- 巡查项目 -->
<view class="section mx-15 mb-15">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">巡查项目</text>
</view>
<view class="check-card bg-white r-md p-15">
<checkbox-group class="check-list">
<label
v-for="item in checkItems"
:key="item.id"
class="check-item"
>
<view class="item-info">
<text class="item-text">{{ item.id }}{{ item.text }}</text>
<text class="item-deduction">{{ item.deduction }}</text>
</view>
<checkbox
:value="String(item.id)"
:checked="item.checked"
@click="item.checked = !item.checked"
color="#4080ff"
style="transform: scale(0.8)"
/>
</label>
</checkbox-group>
</view>
</view>
<!-- 拍照上传 -->
<view class="section mx-15 mb-15">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">拍照上传</text>
</view>
<view class="upload-card bg-white r-md p-15">
<view class="upload-area">
<uni-file-picker
v-model="uploadedImages"
fileMediatype="image"
mode="grid"
:limit="5"
@success="handleImageUploadSuccess"
/>
</view>
</view>
</view>
<!-- 拍视频上传 -->
<view class="section mx-15 mb-30">
<view class="section-title-bar">
<view class="decorator"></view>
<text class="title-text">拍视频上传</text>
</view>
<view class="upload-card bg-white r-md p-15">
<view class="upload-area">
<uni-file-picker
v-model="uploadedVideos"
fileMediatype="video"
mode="grid"
:limit="3"
@success="handleVideoUploadSuccess"
/>
</view>
</view>
</view>
</view>
</view>
<!-- 已巡查内容 -->
<view v-else class="completed-inspection">
<!-- 巡查记录列表 -->
<view class="inspection-list">
<view
v-for="(record, index) in inspectionRecords"
:key="record.id || index"
class="inspection-record bg-white r-md p-15 mb-15 mx-15"
>
<view class="record-header">
<view class="record-time">
<u-icon name="clock" color="#666" size="14"></u-icon>
<text class="time-text">{{ formatTime(record.xctime) }}</text>
</view>
<view class="record-status">
<text class="status-text">已巡查</text>
</view>
</view>
<view class="record-content">
<view class="content-item">
<text class="item-label">巡查教师</text>
<text class="item-value">{{ record.jsxm }}</text>
</view>
<view
class="content-item"
v-if="record.xcItems && record.xcItems.length > 0"
>
<text class="item-label">巡查项目</text>
<text class="item-value">{{ record.xcItems.join(", ") }}</text>
</view>
<view
class="content-item"
v-if="record.images && record.images.length > 0"
>
<text class="item-label">巡查图片</text>
<text class="item-value">{{ record.images.length }}</text>
</view>
<view
class="content-item"
v-if="record.videos && record.videos.length > 0"
>
<text class="item-label">巡查视频</text>
<text class="item-value">{{ record.videos.length }}</text>
</view>
</view>
</view>
</view>
<!-- 暂无记录提示 -->
<view v-if="inspectionRecords.length === 0" class="empty-records">
<view class="empty-icon">
<u-icon name="list" size="50" color="#C8C9CC"></u-icon>
</view>
<view class="empty-text">暂无巡查记录</view>
</view>
</view>
<!-- 状态选择弹窗 -->
<u-picker
:defaultIndex="defSel"
:show="statusPickerVisible"
:columns="[statusOptions]"
@confirm="confirmStatus"
@cancel="statusPickerVisible = false"
></u-picker>
<template #bottom>
<view
v-if="currentTab === 0 && canInspect"
class="submit-btn-wrap py-10 px-20 bg-white"
>
<button class="submit-btn" @click="submit">提交巡查</button>
</view>
</template>
</BasicLayout>
</template>
<script setup lang="ts">
import { jsdXkXsListApi } from "@/api/base/server";
import { xkscFindPageApi, xkscSaveApi } from "@/api/base/xkscApi";
import { xcBeforeMinuteApi } from "@/api/system/config/index";
import BasicLayout from "@/components/BasicLayout/Layout.vue";
import { useDataStore } from "@/store/modules/data";
import { useDicStore } from "@/store/modules/dic";
import { useUserStore } from "@/store/modules/user";
import { computed, onMounted, ref } from "vue";
const { findByPid } = useDicStore();
import dayjs from "dayjs";
const { getJs } = useUserStore();
const { getData } = useDataStore();
const js = computed(() => getJs);
const xkkc = computed(() => getData);
const now = dayjs();
let wDay = now.day();
if (wDay === 0) {
wDay = 7;
}
const wdNameList = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
const todayInfo = ref({
date: now.format("YYYY-MM-DD"),
weekName: wdNameList[wDay - 1],
});
//
const numInfo = ref({
yd: 18,
sd: 18,
qj: 0,
qq: 0,
zg: 18,
});
//
const xsList = ref<any>([]);
//
const statusPickerVisible = ref(false);
const statusOptions = ref<Array<{ text: string; value: string }>>([]);
const curXs = ref<any>(null);
const defSel = ref<any>([]);
//
const checkItems = ref<any[]>([
{ id: 1, text: "未按时上课", deduction: 1, checked: false },
{ id: 2, text: "上课迟到", deduction: 2, checked: false },
{ id: 3, text: "上课内容与教学计划不一致", deduction: 1, checked: false },
{ id: 4, text: "课堂纪律差", deduction: 2, checked: false },
{ id: 5, text: "教学设备使用不当", deduction: 1, checked: false },
]);
//
const uploadedImages = ref([]);
const uploadedVideos = ref([]);
//
const currentTab = ref(0); // 0: , 1:
const tabs = ref(["待巡查", "已巡查"]);
const inspectionStatusText = ref("");
const canInspect = ref(true); //
const xcBeforeMinute = ref<number>(0);
//
const inspectionRecords = ref<any[]>([]);
//
const getStatusClass = (status: string) => {
switch (status) {
case "正常":
return "status-normal";
case "请假":
return "status-leave";
case "缺勤":
return "status-absent";
default:
return "status-normal";
}
};
//
const loadStatusOptions = async () => {
try {
// pid763939514
const res = await findByPid({ pid: 763939514 });
if (res && res.result) {
statusOptions.value = res.result.map((item: any) => {
return {
text: item.dictionaryValue,
value: item.dictionaryCode,
};
});
}
} catch (error) {
console.error("获取状态选项失败", error);
// 使
statusOptions.value = [
{ text: "正常", value: "正常" },
{ text: "请假", value: "请假" },
{ text: "缺勤", value: "缺勤" },
];
}
};
const loadXsList = async () => {
const res = await jsdXkXsListApi({
xkkcId: xkkc.value.id,
});
if (res && res.resultCode === 1) {
xsList.value = res.result || [];
rebuildNumInfo();
}
};
const rebuildNumInfo = () => {
let sd = 0;
let qj = 0;
let qq = 0;
//
for (let i = 0; i < xsList.value.length; i++) {
const xs = xsList.value[i];
switch (xs.xszt) {
case "正常":
sd++;
break;
case "请假":
qj++;
break;
case "缺勤":
qq++;
break;
default:
break;
}
}
numInfo.value = {
zg: xsList.value.length,
yd: xsList.value.length - qj,
sd: sd,
qj: qj,
qq: qq,
};
};
//
const openStatusPicker = (xs: any) => {
curXs.value = xs;
for (let i = 0; i < statusOptions.value.length; i++) {
if (statusOptions.value[i].text === xs.xszt) {
defSel.value = [i];
break;
}
}
statusPickerVisible.value = true;
};
//
const confirmStatus = (e: any) => {
if (curXs.value && e.value && e.value[0]) {
const selectedStatus = statusOptions.value.find(
(option: any) => option.value === e.value[0].value
);
if (selectedStatus) {
//
curXs.value.xszt = selectedStatus.text;
}
rebuildNumInfo();
}
statusPickerVisible.value = false;
};
//
const handleImageUploadSuccess = (res: any) => {
console.log("图片上传成功:", res);
};
//
const handleVideoUploadSuccess = (res: any) => {
console.log("视频上传成功:", res);
};
// tab
const onTabClick = (e: any) => {
currentTab.value = e.currentIndex;
if (currentTab.value === 1) {
loadInspectionRecords();
}
};
//
const loadInspectionRecords = async () => {
try {
const res = await xkscFindPageApi({
xkkcId: xkkc.value.id,
jsId: js.value.id,
pageSize: 20,
pageNum: 1,
});
if (res && res.resultCode === 1) {
inspectionRecords.value = res.result?.rows || [];
}
} catch (error) {
console.error("加载巡查记录失败:", error);
inspectionRecords.value = [];
}
};
//
const formatTime = (timestamp: string) => {
return dayjs(timestamp).format("YYYY-MM-DD HH:mm");
};
//
const checkInspectionTime = () => {
const currentTime = now;
let wDay = currentTime.day();
if (wDay === 0) {
wDay = 7;
}
let mDay = currentTime.date();
const strDate = currentTime.format("YYYY-MM-DD") + " ";
let xcFlag = false;
let msg = "";
//
switch (xkkc.value.skzqlx) {
case "每天":
xcFlag = true;
break;
case "每周":
const daysOfWeek = xkkc.value.skzq.split(",").map(Number);
xcFlag = daysOfWeek.includes(wDay);
break;
case "每月":
const daysOfMonth = xkkc.value.skzq.split(",").map(Number);
xcFlag = daysOfMonth.includes(mDay);
break;
}
//
if (xcFlag) {
// xkkc.skkstimexcBeforeMinute
const startTime = dayjs(strDate + xkkc.value.skkstime).subtract(
xcBeforeMinute.value,
"minute"
);
const endTime = dayjs(strDate + xkkc.value.skjstime);
xcFlag = currentTime.isBefore(endTime) && currentTime.isAfter(startTime);
if (!xcFlag) {
msg = "没到巡查时间";
}
} else {
msg = "没到巡查日期";
}
canInspect.value = xcFlag;
inspectionStatusText.value = msg || "可以巡查";
};
//
const loadXcBeforeMinute = async () => {
try {
const res = await xcBeforeMinuteApi();
if (res.resultCode == 1) {
xcBeforeMinute.value = parseInt(res.result);
}
} catch (error) {
console.error("获取巡查时间配置失败:", error);
xcBeforeMinute.value = 0;
}
};
//
const submit = async () => {
if (!canInspect.value) {
uni.showToast({
title: inspectionStatusText.value,
icon: "none",
duration: 2000,
});
return;
}
try {
const res = await xkscSaveApi({
jsId: js.value.id,
xkkcId: xkkc.value.id,
xctime: now.format("YYYY-MM-DD HH:mm:ss"),
xkxcList: xsList.value,
xcItems: checkItems.value
.filter((item) => item.checked)
.map((item) => item.text),
images: uploadedImages.value,
videos: uploadedVideos.value,
});
if (res && res.resultCode === 1) {
uni.showToast({
title: "提交成功",
icon: "success",
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
} else {
uni.showToast({
title: "提交失败",
icon: "none",
});
}
} catch (error) {
console.error("提交巡查失败:", error);
uni.showToast({
title: "提交失败",
icon: "none",
});
}
};
//
onMounted(async () => {
// await loadXcBeforeMinute();
await loadXsList();
await loadStatusOptions();
checkInspectionTime();
});
</script>
<style scoped lang="scss">
.container {
min-height: 100vh;
background-color: #f5f5f5;
}
.header {
height: 44px;
background-color: #fff;
}
.inspection-tabs {
padding: 15px 15px 0 15px;
background-color: #fff;
margin-bottom: 10px;
position: sticky;
top: 0;
z-index: 10;
}
.pending-inspection,
.completed-inspection {
padding-top: 0;
}
.course-card {
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.course-icon {
width: 30px;
height: 30px;
border-radius: 4px;
background-color: rgba(64, 128, 255, 0.1);
}
.course-time-info {
margin-top: 15px;
padding: 10px 15px;
background-color: #f9f9f9;
border-radius: 4px;
border: 1px solid #eee;
.time-item {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
.time-label {
font-size: 14px;
color: #666;
}
.time-value {
font-size: 14px;
font-weight: bold;
color: #333;
}
}
}
.inspection-status {
display: flex;
align-items: center;
margin-top: 15px;
padding: 10px 15px;
background-color: #fffbe6;
border: 1px solid #ffe58f;
border-radius: 4px;
color: #faad14;
font-size: 14px;
.status-text {
margin-left: 5px;
}
}
.attendance-stats {
padding: 10px 0;
}
.stat-item {
flex: 1;
}
.stat-circle {
width: 60px;
height: 60px;
border-radius: 50%;
}
.student-list {
padding: 0 15px;
}
.student-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.student-item {
position: relative;
}
.avatar-container {
width: 46px;
height: 46px;
border-radius: 50%;
padding: 3px;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.student-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
background-color: #f5f5f5;
}
.status-tag {
font-size: 10px;
padding: 1px 5px;
border-radius: 4px;
display: flex;
align-items: center;
cursor: pointer;
}
.status-normal {
color: #4080ff;
}
.status-leave {
color: #ff9900;
}
.status-absent {
color: #ff4d4f;
}
.text-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 60px;
}
.contact-parent {
padding: 3px 8px;
border-radius: 4px;
border: 1px solid #4080ff;
display: inline-flex;
}
.section {
.section-title-bar {
display: flex;
align-items: center;
margin-bottom: 10px;
.decorator {
width: 4px;
height: 16px;
background-color: #4080ff;
margin-right: 8px;
border-radius: 2px;
}
.title-text {
font-size: 16px;
font-weight: bold;
color: #333;
}
}
}
.check-card {
background-color: white;
// .check-list {
// //
// }
.check-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 0;
border-bottom: 1px solid #eee;
&:last-child {
border-bottom: none;
}
}
.item-info {
display: flex;
flex-direction: column;
}
.item-text {
font-size: 14px;
color: #333;
margin-bottom: 4px;
}
.item-deduction {
font-size: 12px;
color: #999;
}
}
.upload-card {
background-color: white;
// .upload-area {
// //
// }
}
.inspection-list {
.inspection-record {
.record-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
.record-time {
display: flex;
align-items: center;
font-size: 14px;
color: #666;
.time-text {
margin-left: 5px;
}
}
.record-status {
padding: 3px 8px;
border-radius: 4px;
border: 1px solid #4080ff;
display: inline-flex;
font-size: 12px;
color: #4080ff;
}
}
.record-content {
.content-item {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
font-size: 14px;
color: #333;
.item-label {
font-weight: bold;
margin-right: 10px;
}
}
}
}
}
.empty-records {
display: flex;
flex-direction: column;
align-items: center;
padding: 50px 0;
.empty-icon {
margin-bottom: 15px;
}
.empty-text {
font-size: 16px;
color: #999;
}
}
.submit-btn {
background-color: #4080ff;
color: #fff;
height: 44px;
border-radius: 22px;
font-size: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.cor-primary {
color: #4080ff;
}
.cor-warning {
color: #ff9900;
}
.cor-danger {
color: #ff4d4f;
}
.cor-666 {
color: #666;
}
.cor-999 {
color: #999;
}
</style>