diff --git a/src/components/BasicNjBjSelect/demo.vue b/src/components/BasicNjBjSelect/demo.vue
index 4f83ca9..63c54a7 100644
--- a/src/components/BasicNjBjSelect/demo.vue
+++ b/src/components/BasicNjBjSelect/demo.vue
@@ -158,3 +158,9 @@ const setDefaultValue = () => {
+
+
+
+
+
+
diff --git a/src/components/BasicNjBjSelect/index.vue b/src/components/BasicNjBjSelect/index.vue
index e1b991c..e4e41dc 100644
--- a/src/components/BasicNjBjSelect/index.vue
+++ b/src/components/BasicNjBjSelect/index.vue
@@ -16,17 +16,17 @@
@@ -258,6 +253,14 @@ const displayText = computed(() => {
return ''
})
+// 获取选中数量
+const getSelectedCount = () => {
+ if (!props.modelValue) return 0
+ const gradeCount = props.modelValue.selectedGrades?.length || 0
+ const classCount = props.modelValue.selectedClasses?.length || 0
+ return gradeCount + classCount
+}
+
// 监听 modelValue 变化
watch(() => props.modelValue, (newVal) => {
if (newVal) {
@@ -522,36 +525,31 @@ onMounted(() => {
flex-direction: column;
.popup-header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 15px 20px;
+ padding: 10px 15px;
+ background-color: #fff;
border-bottom: 1px solid #eee;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
flex-shrink: 0;
+ .cancel-btn {
+ font-size: 14px;
+ color: #666;
+ padding: 4px 8px;
+ }
+
.popup-title {
font-size: 16px;
- font-weight: 600;
+ font-weight: bold;
color: #333;
}
-
- .popup-actions {
- display: flex;
- gap: 20px;
-
- .action-btn {
- font-size: 14px;
- padding: 4px 8px;
-
- &.cancel-btn {
- color: #999;
- }
-
- &.confirm-btn {
- color: #1890ff;
- font-weight: 500;
- }
- }
+
+ .confirm-btn {
+ font-size: 14px;
+ color: #409eff;
+ font-weight: 500;
+ padding: 4px 8px;
}
}
@@ -564,7 +562,8 @@ onMounted(() => {
.tree-scroll {
flex: 1;
background-color: #fff;
- min-height: 0;
+ box-sizing: border-box;
+ overflow-y: auto;
.tree-container {
padding: 0;
@@ -572,6 +571,10 @@ onMounted(() => {
.tree-node {
.tree-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 15px;
border-bottom: 1px solid #f0f0f0;
&:last-child {
@@ -587,13 +590,13 @@ onMounted(() => {
border-bottom: 1px solid #e0e0e0;
.tree-item-content {
- padding: 5px 12px;
display: flex;
align-items: center;
- min-height: 30px;
+ flex-grow: 1;
+ margin-right: 15px;
.expand-icon {
- margin-right: 5px;
+ margin-right: 10px;
display: flex;
align-items: center;
justify-content: center;
@@ -603,13 +606,13 @@ onMounted(() => {
.grade-text {
flex: 1;
- font-size: 14px;
- font-weight: 500;
+ font-size: 15px;
color: #333;
}
- .grade-checkbox {
- margin-left: 5px;
+ .grade-checkbox,
+ .grade-radio {
+ flex-shrink: 0;
}
}
}
@@ -618,26 +621,27 @@ onMounted(() => {
background-color: #fff;
.tree-item-content {
- padding: 3px 12px 3px 26px;
display: flex;
align-items: center;
- min-height: 26px;
+ flex-grow: 1;
+ margin-right: 15px;
.class-indent {
width: 10px;
height: 1px;
background-color: #e0e0e0;
- margin-right: 5px;
+ margin-right: 10px;
}
.class-text {
flex: 1;
- font-size: 13px;
- color: #666;
+ font-size: 15px;
+ color: #333;
}
- .class-checkbox {
- margin-left: 5px;
+ .class-checkbox,
+ .class-radio {
+ flex-shrink: 0;
}
}
}
@@ -659,8 +663,7 @@ onMounted(() => {
}
.tree-item-content {
- padding: 2px 12px 2px 26px;
- min-height: 24px;
+ padding: 8px 15px 8px 26px;
}
}
}
@@ -668,6 +671,15 @@ onMounted(() => {
}
}
}
+
+ }
+
+ .loading-indicator,
+ .empty-state {
+ text-align: center;
+ color: #999;
+ padding: 30px 15px;
+ font-size: 14px;
}
}
diff --git a/src/components/ImageVideoUpload/ImageVideoUpload.vue b/src/components/ImageVideoUpload/ImageVideoUpload.vue
new file mode 100644
index 0000000..b1553ce
--- /dev/null
+++ b/src/components/ImageVideoUpload/ImageVideoUpload.vue
@@ -0,0 +1,845 @@
+
+
+
+
+
+ 图片
+ ({{ imageList.length }}/{{ maxImageCount }})
+
+
+
+
+
+
+
+
+
+
+
+ 已压缩
+
+
+
+
+
+ 添加图片
+
+
+
+
+
+
+
+ 视频
+ ({{ videoList.length }}/{{ maxVideoCount }})
+
+
+
+
+
+
+
+
+
+
+ {{ formatDuration(video.duration) }}
+
+
+
+
+
+
+
+
+ {{ video.name }}
+ {{ formatFileSize(video.size) }}
+
+
+
+
+
+ 添加视频
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ImageVideoUpload/README.md b/src/components/ImageVideoUpload/README.md
new file mode 100644
index 0000000..0dd099e
--- /dev/null
+++ b/src/components/ImageVideoUpload/README.md
@@ -0,0 +1,223 @@
+# ImageVideoUpload 图片视频上传组件
+
+一个功能完整的图片和视频上传组件,支持压缩、预览、删除等功能。
+
+## 功能特性
+
+- ✅ 图片和视频上传
+- ✅ 智能图片压缩(支持H5和APP环境)
+- ✅ 文件大小和时长限制
+- ✅ 预览功能
+- ✅ 删除功能
+- ✅ 上传进度显示
+- ✅ 自定义压缩配置
+- ✅ 自动上传或手动上传
+- ✅ 完整的事件回调
+
+## 基本使用
+
+```vue
+
+
+
+
+
+
+
+```
+
+## Props 属性
+
+| 属性名 | 类型 | 默认值 | 说明 |
+|--------|------|--------|------|
+| enableImage | boolean | true | 是否启用图片上传 |
+| enableVideo | boolean | true | 是否启用视频上传 |
+| maxImageCount | number | 5 | 最大图片数量 |
+| maxVideoCount | number | 3 | 最大视频数量 |
+| imageList | ImageItem[] | [] | 图片列表 |
+| videoList | VideoItem[] | [] | 视频列表 |
+| compressConfig | CompressConfig | 默认配置 | 压缩配置 |
+| autoUpload | boolean | true | 是否自动上传 |
+| uploadApi | Function | - | 上传API函数 |
+
+## Events 事件
+
+| 事件名 | 参数 | 说明 |
+|--------|------|------|
+| update:imageList | images: ImageItem[] | 图片列表更新 |
+| update:videoList | videos: VideoItem[] | 视频列表更新 |
+| image-upload-success | image: ImageItem, index: number | 图片上传成功 |
+| image-upload-error | error: any, index: number | 图片上传失败 |
+| video-upload-success | video: VideoItem, index: number | 视频上传成功 |
+| video-upload-error | error: any, index: number | 视频上传失败 |
+| upload-progress | type: 'image' \| 'video', current: number, total: number | 上传进度 |
+
+## 压缩配置
+
+### 使用预设配置
+
+```javascript
+import { COMPRESS_PRESETS } from '@/components/ImageVideoUpload'
+
+// 高质量配置
+const highQualityConfig = COMPRESS_PRESETS.high
+
+// 平衡配置(默认)
+const mediumConfig = COMPRESS_PRESETS.medium
+
+// 高压缩配置
+const lowQualityConfig = COMPRESS_PRESETS.low
+```
+
+### 自定义配置
+
+```javascript
+const customConfig = {
+ image: {
+ quality: 70, // 压缩质量 (1-100)
+ maxWidth: 1600, // 最大宽度
+ maxHeight: 900, // 最大高度
+ maxSize: 300 * 1024, // 最大文件大小 300KB
+ minQuality: 25 // 最低压缩质量
+ },
+ video: {
+ maxDuration: 45, // 最大时长45秒
+ maxSize: 8 * 1024 * 1024, // 最大文件大小 8MB
+ quality: 'medium' // 视频质量
+ }
+}
+```
+
+## 高级用法
+
+### 手动上传
+
+```vue
+
+
+
+
+
+
+```
+
+### 监听上传进度
+
+```vue
+
+
+
+ 上传进度: {{ currentProgress }}/{{ totalProgress }}
+
+
+
+
+```
+
+## 样式自定义
+
+组件使用 scoped 样式,如需自定义样式,可以通过以下方式:
+
+```vue
+
+```
+
+## 注意事项
+
+1. **H5环境**:使用Canvas进行图片压缩
+2. **APP环境**:使用uni.compressImage进行压缩
+3. **文件大小**:建议根据实际需求调整压缩配置
+4. **上传API**:需要返回标准的响应格式
+5. **内存管理**:上传成功后会自动清理临时文件
+
+## 响应格式要求
+
+上传API需要返回以下格式的响应:
+
+```javascript
+{
+ resultCode: 1, // 1表示成功
+ result: [
+ {
+ filePath: "服务器文件路径"
+ }
+ ]
+}
+```
diff --git a/src/components/ImageVideoUpload/example.vue b/src/components/ImageVideoUpload/example.vue
new file mode 100644
index 0000000..d913310
--- /dev/null
+++ b/src/components/ImageVideoUpload/example.vue
@@ -0,0 +1,65 @@
+
+
+ 图片视频上传组件示例
+
+
+
+
+
+
+
+
diff --git a/src/components/ImageVideoUpload/index.ts b/src/components/ImageVideoUpload/index.ts
new file mode 100644
index 0000000..2409d19
--- /dev/null
+++ b/src/components/ImageVideoUpload/index.ts
@@ -0,0 +1,6 @@
+// 导出组件和类型
+export { default as ImageVideoUpload } from './ImageVideoUpload.vue'
+export * from './types'
+
+// 默认导出
+export { default } from './ImageVideoUpload.vue'
diff --git a/src/components/ImageVideoUpload/types.ts b/src/components/ImageVideoUpload/types.ts
new file mode 100644
index 0000000..44cf045
--- /dev/null
+++ b/src/components/ImageVideoUpload/types.ts
@@ -0,0 +1,132 @@
+// 图片项接口
+export interface ImageItem {
+ tempPath?: string // 临时路径(用于预览)
+ url?: string // 服务器路径(上传成功后)
+ name?: string // 文件名
+ originalPath?: string // 原始路径(用于调试)
+ isCompressed?: boolean // 是否已压缩
+}
+
+// 视频项接口
+export interface VideoItem {
+ tempPath?: string // 临时路径(用于预览)
+ url?: string // 服务器路径(上传成功后)
+ name?: string // 文件名
+ duration?: number // 视频时长(秒)
+ size?: number // 文件大小(字节)
+ thumbnail?: string // 缩略图路径
+}
+
+// 压缩配置接口
+export interface CompressConfig {
+ image: {
+ quality: number // 压缩质量 (1-100)
+ maxWidth: number // 最大宽度
+ maxHeight: number // 最大高度
+ maxSize: number // 最大文件大小(字节)
+ minQuality: number // 最低压缩质量
+ }
+ video: {
+ maxDuration: number // 最大时长(秒)
+ maxSize: number // 最大文件大小(字节)
+ quality: string // 视频质量
+ }
+}
+
+// 组件Props接口
+export interface ImageVideoUploadProps {
+ // 图片相关
+ enableImage?: boolean
+ maxImageCount?: number
+ imageList?: ImageItem[]
+
+ // 视频相关
+ enableVideo?: boolean
+ maxVideoCount?: number
+ videoList?: VideoItem[]
+
+ // 压缩配置
+ compressConfig?: CompressConfig
+
+ // 上传配置
+ autoUpload?: boolean
+ uploadApi?: (file: any) => Promise
+}
+
+// 组件Emits接口
+export interface ImageVideoUploadEmits {
+ 'update:imageList': [images: ImageItem[]]
+ 'update:videoList': [videos: VideoItem[]]
+ 'image-upload-success': [image: ImageItem, index: number]
+ 'image-upload-error': [error: any, index: number]
+ 'video-upload-success': [video: VideoItem, index: number]
+ 'video-upload-error': [error: any, index: number]
+ 'upload-progress': [type: 'image' | 'video', current: number, total: number]
+}
+
+// 默认压缩配置
+export const DEFAULT_COMPRESS_CONFIG: CompressConfig = {
+ image: {
+ quality: 60,
+ maxWidth: 1280,
+ maxHeight: 720,
+ maxSize: 200 * 1024, // 200KB
+ minQuality: 20
+ },
+ video: {
+ maxDuration: 60,
+ maxSize: 10 * 1024 * 1024, // 10MB
+ quality: 'medium'
+ }
+}
+
+// 预设压缩配置
+export const COMPRESS_PRESETS = {
+ // 高质量配置
+ high: {
+ image: {
+ quality: 80,
+ maxWidth: 1920,
+ maxHeight: 1080,
+ maxSize: 500 * 1024, // 500KB
+ minQuality: 40
+ },
+ video: {
+ maxDuration: 60,
+ maxSize: 20 * 1024 * 1024, // 20MB
+ quality: 'high'
+ }
+ },
+
+ // 平衡配置
+ medium: {
+ image: {
+ quality: 60,
+ maxWidth: 1280,
+ maxHeight: 720,
+ maxSize: 200 * 1024, // 200KB
+ minQuality: 20
+ },
+ video: {
+ maxDuration: 60,
+ maxSize: 10 * 1024 * 1024, // 10MB
+ quality: 'medium'
+ }
+ },
+
+ // 高压缩配置
+ low: {
+ image: {
+ quality: 40,
+ maxWidth: 960,
+ maxHeight: 540,
+ maxSize: 100 * 1024, // 100KB
+ minQuality: 15
+ },
+ video: {
+ maxDuration: 30,
+ maxSize: 5 * 1024 * 1024, // 5MB
+ quality: 'low'
+ }
+ }
+}
diff --git a/src/components/ImageVideoUpload/使用说明.md b/src/components/ImageVideoUpload/使用说明.md
new file mode 100644
index 0000000..cc1b59e
--- /dev/null
+++ b/src/components/ImageVideoUpload/使用说明.md
@@ -0,0 +1,204 @@
+# ImageVideoUpload 图片视频上传组件
+
+## 组件位置
+`D:\code\zhxy-jsd\src\components\ImageVideoUpload\`
+
+## 文件结构
+```
+ImageVideoUpload/
+├── ImageVideoUpload.vue # 主组件文件
+├── types.ts # 类型定义
+├── index.ts # 导出文件
+├── example.vue # 使用示例
+├── README.md # 详细文档
+└── 使用说明.md # 中文说明
+```
+
+## 快速使用
+
+### 1. 基本用法
+```vue
+
+
+
+
+
+```
+
+### 2. 完整配置
+```vue
+
+
+
+
+
+```
+
+## 主要功能
+
+### ✅ 图片功能
+- 拍照/相册选择
+- 智能压缩(H5/APP自适应)
+- 预览功能
+- 删除功能
+- 压缩状态显示
+
+### ✅ 视频功能
+- 拍摄/相册选择
+- 文件大小检查
+- 时长限制
+- 预览播放
+- 删除功能
+
+### ✅ 压缩功能
+- 尺寸压缩(降低分辨率)
+- 质量压缩(调整JPEG质量)
+- 智能压缩(根据文件大小自动调整)
+- 多级压缩(确保达到目标大小)
+
+## 压缩配置
+
+### 预设配置
+```javascript
+import { COMPRESS_PRESETS } from '@/components/ImageVideoUpload'
+
+// 高质量(文件较大)
+const highConfig = COMPRESS_PRESETS.high
+
+// 平衡(推荐)
+const mediumConfig = COMPRESS_PRESETS.medium
+
+// 高压缩(文件很小)
+const lowConfig = COMPRESS_PRESETS.low
+```
+
+### 自定义配置
+```javascript
+const customConfig = {
+ image: {
+ quality: 70, // 压缩质量 1-100
+ maxWidth: 1600, // 最大宽度
+ maxHeight: 900, // 最大高度
+ maxSize: 300 * 1024, // 最大文件大小(字节)
+ minQuality: 25 // 最低压缩质量
+ },
+ video: {
+ maxDuration: 45, // 最大时长(秒)
+ maxSize: 8 * 1024 * 1024, // 最大文件大小(字节)
+ quality: 'medium' // 视频质量
+ }
+}
+```
+
+## 事件回调
+
+```javascript
+// 图片上传成功
+@image-upload-success="(image, index) => {}"
+
+// 图片上传失败
+@image-upload-error="(error, index) => {}"
+
+// 视频上传成功
+@video-upload-success="(video, index) => {}"
+
+// 视频上传失败
+@video-upload-error="(error, index) => {}"
+
+// 上传进度
+@upload-progress="(type, current, total) => {}"
+```
+
+## 在 xcXkkcDetail.vue 中的使用
+
+原来的代码已经替换为:
+
+```vue
+
+```
+
+## 注意事项
+
+1. **环境兼容**:自动检测H5/APP环境,使用不同的压缩方案
+2. **文件大小**:建议根据实际需求调整压缩配置
+3. **上传API**:需要返回标准格式的响应
+4. **内存管理**:上传成功后自动清理临时文件
+5. **错误处理**:完善的错误处理和用户提示
+
+## 响应格式要求
+
+上传API需要返回:
+```javascript
+{
+ resultCode: 1, // 1表示成功
+ result: [
+ {
+ filePath: "服务器文件路径"
+ }
+ ]
+}
+```
+
+## 样式自定义
+
+组件使用scoped样式,如需自定义:
+
+```css
+/* 全局样式覆盖 */
+.image-video-upload .add-btn {
+ border-color: #007aff;
+}
+```
+
+## 测试
+
+可以运行 `example.vue` 来测试组件功能。
diff --git a/src/config.ts b/src/config.ts
index a58b5aa..0b64be4 100644
--- a/src/config.ts
+++ b/src/config.ts
@@ -1,7 +1,9 @@
const ip: string = "127.0.0.1:8897";
-// const ip: string = "yufangzc.com";
-// const ip: string = "lzcxsx.cn";
-const fwqip: string = "lzcxsx.cn";
+const fwqip: string = "127.0.0.1:8897";
+//const ip: string = "lzcxsx.cn";
+//const fwqip: string = "lzcxsx.cn";
+//const ip: string = "zhxy.yufangzc.com";//
+//const fwqip: string = "zhxy.yufangzc.com";
//打包服务器接口代理标识
const SERVERAGENT: string = "/jsd-api";
//本地代理url地址,配置了就启动代理,没配置就不启动代理
@@ -15,7 +17,7 @@ export const BASE_WS_URL: string = `wss://${ip}`;
// export const BASE_IMAGE_URL: string = process.env.NODE_ENV == "development" ? `https://${ip}` : `https://${fwqip}`;
export const BASE_IMAGE_URL = `https://${fwqip}`;
// kkFileView预览服务地址
-export const KK_FILE_VIEW_URL: string = `http://${fwqip}:8891`;
+export const KK_FILE_VIEW_URL: string = `https://${fwqip}/kkpro`;
//存token的key
export const AUTH_KEY: string = "satoken";
//token过期返回状态码
diff --git a/src/pages.json b/src/pages.json
index 355cc1d..efce466 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -241,6 +241,13 @@
"enablePullDownRefresh": false
}
},
+ {
+ "path": "pages/view/routine/ShiTangXunCha/edit",
+ "style": {
+ "navigationBarTitleText": "食堂巡查修改",
+ "enablePullDownRefresh": false
+ }
+ },
{
"path": "pages/view/routine/JiFenPingJia/detail",
"style": {
diff --git a/src/pages/base/service/index.vue b/src/pages/base/service/index.vue
index d2eda67..5b7c155 100644
--- a/src/pages/base/service/index.vue
+++ b/src/pages/base/service/index.vue
@@ -242,7 +242,7 @@ const sections = reactive([
{
id: "r6",
icon: "kfxc",
- text: "课服巡查",
+ text: "教学巡查",
show: true,
permissionKey: "routine-kfxc", // 课服巡查权限编码
path: "/pages/view/routine/kefuxuncha/xcPbList",
diff --git a/src/pages/view/homeSchool/BanJiKeBiao.vue b/src/pages/view/homeSchool/BanJiKeBiao.vue
index b9487b9..cd14a9e 100644
--- a/src/pages/view/homeSchool/BanJiKeBiao.vue
+++ b/src/pages/view/homeSchool/BanJiKeBiao.vue
@@ -85,8 +85,12 @@ let bjId = '';
// 改变了年级班级
const changeNjBj = (nj: any, bj: any) => {
bjId = bj.key;
- selectDay(curRqIndex.value);
- console.log(nj, bj);
+ console.log("班级选择变更:", { nj, bj, bjId });
+
+ // 重新加载当前日期的课表数据
+ if (rqList.value.length > 0) {
+ selectDay(curRqIndex.value);
+ }
};
// 这是当年的第几周
@@ -153,7 +157,8 @@ const selectWeek = (zc: any) => {
// 关闭弹窗
closeWeekPicker();
- // 选中第一天
+ // 重置为第一天并加载数据
+ curRqIndex.value = 0;
selectDay(0);
};
@@ -163,9 +168,18 @@ const selectDay = (index: number) => {
if (!rqList.value.length) {
return;
}
+
+ console.log("查询课表参数:", {
+ jsId: "",
+ bjId: bjId || "",
+ xqId: xqId,
+ rq: rqList.value[index].rq,
+ zj: rqList.value[index].zj
+ });
+
drpkkbApi({
jsId: "", // getJs.id,
- bjId: bjId,
+ bjId: bjId || "", // 如果没有选择班级,传空字符串
xqId: xqId,
rq: rqList.value[index].rq, // 用于查询代课信息
zj: rqList.value[index].zj
@@ -173,14 +187,17 @@ const selectDay = (index: number) => {
// 根据接口返回的result判断是否已报名
if (res && res.resultCode === 1) {
sjList.value = res.result;
+ console.log("课表数据加载成功:", res.result);
} else {
// 接口调用成功但返回错误
- console.warn("检查报名状态接口返回错误:", res);
+ console.warn("课表接口返回错误:", res);
+ sjList.value = [];
}
})
.catch((error) => {
// 接口调用失败
- console.error("调用检查报名状态接口失败:", error);
+ console.error("调用课表接口失败:", error);
+ sjList.value = [];
});
};
@@ -194,17 +211,38 @@ const getCourseColorClass = (subject: string | undefined): string => {
};
onMounted(async () => {
- const res = await dqpkApi();
- const result = res.result;
- dqZc = res.result.dqZc;
- xqId = res.result.dqXq.id;
- zcList.value = result.zcList;
- sjList.value = result.sjList;
- let zc = zcList.value.find((item:any) => item.djz === dqZc);
- if (!zc) {
- zc = zcList.value[0];
+ try {
+ const res = await dqpkApi();
+ const result = res.result;
+ dqZc = res.result.dqZc;
+ xqId = res.result.dqXq.id;
+ zcList.value = result.zcList;
+ sjList.value = result.sjList;
+
+ // 1. 默认定位到当前周
+ let zc = zcList.value.find((item:any) => item.djz === dqZc);
+ if (!zc) {
+ zc = zcList.value[0];
+ }
+
+ // 设置周次和日期
+ Object.assign(curZc.value, zc);
+ Object.assign(rqList.value, curZc.value.drList);
+
+ // 2. 默认定位到当前周几(周三)
+ const currentDayOfWeek = dayjs().day(); // 0=周日, 1=周一, ..., 6=周六
+ const targetDayIndex = currentDayOfWeek === 0 ? 6 : currentDayOfWeek - 1; // 转换为1=周一, 7=周日的格式
+
+ // 确保索引在有效范围内
+ const validDayIndex = Math.min(Math.max(targetDayIndex, 0), rqList.value.length - 1);
+ curRqIndex.value = validDayIndex;
+
+
+ // 自动加载当前日期的课表数据
+ selectDay(validDayIndex);
+ } catch (error) {
+ console.error("初始化失败:", error);
}
- selectWeek(zc);
});
@@ -380,6 +418,7 @@ onMounted(async () => {
}
}
+
.loading-overlay {
position: absolute;
top: 0;
diff --git a/src/pages/view/routine/ShiTangXunCha/detail.vue b/src/pages/view/routine/ShiTangXunCha/detail.vue
index cf8f9ba..be8f7f4 100644
--- a/src/pages/view/routine/ShiTangXunCha/detail.vue
+++ b/src/pages/view/routine/ShiTangXunCha/detail.vue
@@ -62,7 +62,7 @@
+
+
diff --git a/src/pages/view/routine/ShiTangXunCha/index.vue b/src/pages/view/routine/ShiTangXunCha/index.vue
index 077c836..dcd777e 100644
--- a/src/pages/view/routine/ShiTangXunCha/index.vue
+++ b/src/pages/view/routine/ShiTangXunCha/index.vue
@@ -55,16 +55,30 @@
-
+
+
+
@@ -170,6 +184,7 @@ const getHcList = async () => {
// 跳转到详情页
const goToDetail = (hcId: string) => {
+ console.log('点击卡片,跳转详情页,ID:', hcId);
uni.navigateTo({
url: `/pages/view/routine/ShiTangXunCha/detail?id=${hcId}`,
});
@@ -182,6 +197,14 @@ const goToAdd = () => {
});
};
+// 跳转到修改页
+const goToEdit = (hcId: string) => {
+ console.log('点击修改按钮,ID:', hcId);
+ uni.navigateTo({
+ url: `/pages/view/routine/ShiTangXunCha/edit?id=${hcId}`,
+ });
+};
+
// 格式化时间
const formatTime = (timeStr: string) => {
if (!timeStr) return "";
@@ -200,6 +223,14 @@ const getImageUrl = (imagePath: string) => {
return imagUrl(firstImage);
};
+// 获取图片列表(最多3张)
+const getImageList = (imagePath: string) => {
+ if (!imagePath) return [];
+ // 按逗号分割图片路径,最多取3张
+ const imagePaths = imagePath.split(',').slice(0, 3);
+ return imagePaths.map(path => imagUrl(path.trim()));
+};
+
onShow(() => {
getHcList();
});
@@ -371,12 +402,23 @@ onMounted(() => {
}
.image-preview {
+ display: flex;
+ gap: 8px;
+ flex-wrap: wrap;
+ margin-top: 8px;
+
+ .preview-image-wrapper {
+ position: relative;
+ flex-shrink: 0;
+ }
+
.preview-image {
width: 80px;
height: 60px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
object-fit: cover;
+ display: block;
}
}
}
@@ -409,6 +451,36 @@ onMounted(() => {
flex-shrink: 0;
}
}
+
+ .footer-actions {
+ margin-left: auto;
+ flex-shrink: 0;
+
+ .edit-btn {
+ background: linear-gradient(135deg, #28a745 0%, #20c997 100%);
+ border: none;
+ border-radius: 6px;
+ font-size: 12px;
+ font-weight: 500;
+ padding: 4px 12px;
+ min-width: 50px;
+ height: 28px;
+ box-shadow: 0 2px 6px rgba(40, 167, 69, 0.3);
+ position: relative;
+ z-index: 10;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #ffffff;
+ cursor: pointer;
+ transition: all 0.2s ease;
+
+ &:active {
+ transform: translateY(1px);
+ box-shadow: 0 1px 3px rgba(40, 167, 69, 0.4);
+ }
+ }
+ }
}
// 新增按钮 - 固定在底部
diff --git a/src/pages/view/routine/jc/components/dm.vue b/src/pages/view/routine/jc/components/dm.vue
index ecd6143..a1e8c3b 100644
--- a/src/pages/view/routine/jc/components/dm.vue
+++ b/src/pages/view/routine/jc/components/dm.vue
@@ -3,22 +3,10 @@
选择班级
-
+
+ {{ selectedClassText || "请选择班级" }}
+
+
ℹ️
@@ -38,16 +26,18 @@
ref="dmXsRef"
/>
-
+
-
@@ -69,15 +59,30 @@
提交点名
+
+
+
\ No newline at end of file
diff --git a/src/pages/view/routine/kefuxuncha/kyRecord.vue b/src/pages/view/routine/kefuxuncha/kyRecord.vue
index 799ffec..a98af46 100644
--- a/src/pages/view/routine/kefuxuncha/kyRecord.vue
+++ b/src/pages/view/routine/kefuxuncha/kyRecord.vue
@@ -7,10 +7,18 @@
style="position: absolute"
>
-
+
+
+
+
+
+
+
+
+
+
+ 年级班级:
+ {{ data.njbj }}
+
巡查教师:
{{ data.jsxm }}
+
+ 任课老师:
+ {{ data.rkjsxm }}
+
巡查项目:
- {{ idx + 1 }}、{{ xm.xcMc }}
-
- 分值:{{ xm.xmFz }}分
- 巡查结果:{{
- xm.xcJg === "A" ? "有" : "无"
- }}
+
+
+ {{ idx + 1 }}、{{ xm.xcMc }}
+
+
+
+
+
+
+ 扣分:-{{ xm.xmFz }}分
+
+
+ 不扣分
+
+
@@ -173,12 +194,15 @@ const xkkc = computed(() => getData);
let inspectionParams = ref({
rows: 10,
kyXcId: xkkc.value.id,
- jsId: js.value.id,
njId: xkkc.value.njId,
bjId: xkkc.value.bjId,
njmcId: xkkc.value.njmcId,
+ // 移除时间参数,不传时间
});
+// 添加调试信息
+console.log('课业辅导巡查记录查询参数:', inspectionParams.value);
+
// 巡查记录列表
const [registerInspection, { reload }] = useLayout({
api: getKyXcPageApi,
@@ -189,9 +213,10 @@ const [registerInspection, { reload }] = useLayout({
// 图片预览
const handlePreviewImage = (img: string, images: string[]) => {
// 兼容uni-app的图片预览API
+ const processedImages = images.map(image => imagUrl(image));
uni.previewImage({
- current: img,
- urls: images,
+ current: imagUrl(img),
+ urls: processedImages,
});
};
@@ -202,7 +227,7 @@ const handlePreviewVideo = (videos: string[], index: number) => {
uni.previewMedia({
current: index,
sources: videos.map((url) => ({
- url,
+ url: imagUrl(url),
type: "video",
})),
});
@@ -210,7 +235,10 @@ const handlePreviewVideo = (videos: string[], index: number) => {
// 格式化时间
const formatTime = (timestamp: string) => {
- return dayjs(timestamp).format("YYYY-MM-DD HH:mm");
+ const date = dayjs(timestamp);
+ const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
+ const weekDay = weekDays[date.day()];
+ return `${weekDay} ${date.format("YYYY-MM-DD HH:mm")}`;
};
// 将逗号分隔的字符串转换为数组
@@ -235,52 +263,170 @@ onMounted(() => {
.inspection-list {
position: relative;
height: calc(100vh - 50px);
+ padding-left: 12px; // 为时间轴留出空间
.inspection-record {
+ position: relative;
+ margin-left: 0; // 去掉左边距
+ background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+ border-radius: 12px;
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
+ border: 1px solid #e8f4fd;
+ transition: all 0.3s ease;
+ overflow: hidden;
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.12);
+ border-color: #4080ff;
+ }
+
+ // 时间轴连接线
+ .timeline-line {
+ position: absolute;
+ left: -12px;
+ top: 0;
+ width: 2px;
+ height: 100%;
+ background: linear-gradient(180deg, #4080ff 0%, #e8f4fd 100%);
+ z-index: 1;
+ }
+
+ // 时间轴节点
+ .timeline-dot {
+ position: absolute;
+ left: -18px;
+ top: 20px;
+ width: 12px;
+ height: 12px;
+ background: #4080ff;
+ border-radius: 50%;
+ z-index: 2;
+ box-shadow: 0 0 0 4px #ffffff, 0 0 0 6px #e8f4fd;
+
+ .dot-inner {
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(135deg, #4080ff 0%, #66b3ff 100%);
+ border-radius: 50%;
+ animation: pulse 2s infinite;
+ }
+ }
+
.record-header {
display: flex;
justify-content: space-between;
align-items: center;
- margin-bottom: 10px;
- padding-bottom: 10px;
- border-bottom: 1px solid #eee;
+ margin-bottom: 15px;
+ padding: 12px 8px;
+ background: linear-gradient(135deg, #f0f7ff 0%, #e8f4fd 100%);
+ border-radius: 8px 8px 0 0;
+ border-bottom: 1px solid #d1e7ff;
.record-time {
display: flex;
align-items: center;
- font-size: 14px;
- color: #666;
+ font-size: 15px;
+ color: #2c5aa0;
+ font-weight: 600;
.time-text {
- margin-left: 5px;
+ margin-left: 8px;
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
}
.record-status {
- padding: 3px 8px;
- border-radius: 4px;
- border: 1px solid #4080ff;
- display: inline-flex;
+ padding: 6px 12px;
+ border-radius: 20px;
+ background: linear-gradient(135deg, #4080ff 0%, #66b3ff 100%);
+ color: #ffffff;
font-size: 12px;
- color: #4080ff;
+ font-weight: 600;
+ box-shadow: 0 2px 8px rgba(64, 128, 255, 0.3);
+ text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
}
.record-content {
+ padding: 0 8px 12px 8px;
+
.content-item {
display: flex;
- margin-bottom: 5px;
+ margin-bottom: 6px;
font-size: 14px;
color: #333;
+ padding: 6px 8px;
+ background: #fafbfc;
+ border-radius: 6px;
+ border-left: 3px solid #e8f4fd;
+ transition: all 0.2s ease;
+
+ &:hover {
+ background: #f0f7ff;
+ border-left-color: #4080ff;
+ }
.item-label {
- font-weight: bold;
- flex: 0 0 80px;
+ font-weight: 600;
+ flex: 0 0 70px;
+ color: #2c5aa0;
+ }
+
+ .item-value {
+ color: #4a5568;
}
}
}
}
+ // 第一个时间轴节点特殊样式
+ .inspection-record:first-child {
+ .timeline-dot {
+ background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
+ box-shadow: 0 0 0 4px #ffffff, 0 0 0 6px #f0f9ff;
+ }
+ }
+
+ // 最后一个时间轴节点
+ .inspection-record:last-child {
+ .timeline-line {
+ display: none;
+ }
+ }
+
+ // 动画效果
+ @keyframes pulse {
+ 0% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ 50% {
+ transform: scale(1.1);
+ opacity: 0.8;
+ }
+ 100% {
+ transform: scale(1);
+ opacity: 1;
+ }
+ }
+
+ // 渐入动画
+ .timeline-item {
+ animation: fadeInUp 0.6s ease-out;
+ }
+
+ @keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(30px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+ }
+
::v-deep .zp-loading-fixed {
position: absolute;
}
diff --git a/src/pages/view/routine/kefuxuncha/kyXkList.vue b/src/pages/view/routine/kefuxuncha/kyXkList.vue
index faf5300..7188d60 100644
--- a/src/pages/view/routine/kefuxuncha/kyXkList.vue
+++ b/src/pages/view/routine/kefuxuncha/kyXkList.vue
@@ -5,7 +5,7 @@