教师请假添加附件,封装附件展示模块

This commit is contained in:
ywyonui 2025-09-25 20:08:07 +08:00
parent 9aa15f7252
commit f42706629b
7 changed files with 1147 additions and 2 deletions

View File

@ -0,0 +1,56 @@
// BasicFile 组件配置文件
// 文件类型映射
export const FILE_TYPE_MAP = {
pdf: '/static/base/view/pdf.png',
doc: '/static/base/view/word.png',
docx: '/static/base/view/word.png',
xls: '/static/base/view/excel.png',
xlsx: '/static/base/view/excel.png',
ppt: '/static/base/view/ppt.png',
pptx: '/static/base/view/ppt.png',
zip: '/static/base/view/zip.png',
rar: '/static/base/view/zip.png',
'7z': '/static/base/view/zip.png',
} as const;
// 默认文件图标
export const DEFAULT_FILE_ICON = '/static/base/view/more.png';
// 可预览的文件扩展名
export const PREVIEWABLE_EXTENSIONS = [
'pdf',
'doc',
'docx',
'xls',
'xlsx',
'ppt',
'pptx',
'txt',
'jpg',
'jpeg',
'png',
'gif',
'bmp',
'webp'
];
// 视频文件扩展名
export const VIDEO_EXTENSIONS = [
'mp4',
'avi',
'mov',
'wmv',
'flv',
'webm'
];
// 图片文件扩展名
export const IMAGE_EXTENSIONS = [
'jpg',
'jpeg',
'png',
'gif',
'bmp',
'webp'
];

View File

@ -0,0 +1,341 @@
<template>
<view class="basic-file-detail">
<view class="section-title">附件</view>
<view class="file-list" v-if="hasAttachments">
<!-- 显示所有解析后的附件 -->
<view
v-for="(file, index) in parsedAttachments"
:key="(file as any).id || index"
class="file-item"
>
<view class="file-icon">
<image
:src="getFileIcon(getFileSuffix(file))"
class="icon-image"
mode="aspectFit"
/>
</view>
<view class="file-info">
<text class="file-name">{{ getFileName(file) }}</text>
</view>
<view class="file-actions">
<u-button
text="查看"
size="mini"
type="primary"
@click="previewFile(file)"
/>
</view>
</view>
</view>
<view v-else class="no-files">
<text>暂无附件</text>
</view>
</view>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import {
previewFile as previewFileUtil
} from "@/utils/filePreview";
import { imagUrl } from "@/utils";
//
interface Props {
fileUrl?: string;
fileName?: string;
fileFormat?: string;
files?: FileInfo[];
}
interface FileInfo {
id?: string;
name: string;
size: number;
url: string;
resourName?: string;
resourUrl?: string;
resSuf?: string;
}
//
const props = withDefaults(defineProps<Props>(), {
fileUrl: '',
fileName: '',
fileFormat: '',
files: () => []
});
//
const emit = defineEmits<{
(e: 'preview', file: FileInfo): void;
}>();
//
const hasAttachments = computed(() => {
const attachments = [];
// files
if (props.files && props.files.length > 0) {
attachments.push(...props.files);
}
// fileUrl
else if (props.fileUrl) {
const fileUrls = props.fileUrl.split(',').map(url => url.trim()).filter(url => url);
// fileName
let fileNames: string[] = [];
if (props.fileName) {
fileNames = props.fileName.split(',').map(name => name.trim()).filter(name => name);
}
// URL
fileUrls.forEach((url, index) => {
// 使URL
let displayName = fileNames[index] || url.split('/').pop() || `文件${index + 1}`;
const fileFormat = url.split('.').pop() || 'unknown';
// resourName
let resourName = displayName;
if (displayName.includes('.' + fileFormat)) {
resourName = displayName.replace('.' + fileFormat, '');
}
attachments.push({
id: `file_${index}`,
name: displayName,
url: url,
resourUrl: url,
resourName: resourName,
resSuf: fileFormat,
size: 0
});
});
}
return attachments.length > 0;
});
//
const parsedAttachments = computed(() => {
const attachments = [];
// files
if (props.files && props.files.length > 0) {
attachments.push(...props.files);
}
// fileUrl
else if (props.fileUrl) {
const fileUrls = props.fileUrl.split(',').map(url => url.trim()).filter(url => url);
// fileName
let fileNames: string[] = [];
if (props.fileName) {
fileNames = props.fileName.split(',').map(name => name.trim()).filter(name => name);
}
// URL
fileUrls.forEach((url, index) => {
// 使URL
let displayName = fileNames[index] || url.split('/').pop() || `文件${index + 1}`;
const fileFormat = url.split('.').pop() || 'unknown';
// resourName
let resourName = displayName;
if (displayName.includes('.' + fileFormat)) {
resourName = displayName.replace('.' + fileFormat, '');
}
attachments.push({
id: `file_${index}`,
name: displayName,
url: url,
resourUrl: url,
resourName: resourName,
resSuf: fileFormat,
size: 0
});
});
}
return attachments;
});
//
const getFileName = (file: FileInfo) => {
if (file.resourName) {
return file.resourName;
}
if (file.name) {
// name
const lastDotIndex = file.name.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.name.substring(0, lastDotIndex);
}
return file.name;
}
return '未知文件';
};
//
const getFileSuffix = (file: FileInfo) => {
if (file.resSuf) {
return file.resSuf;
}
if (file.url) {
const lastDotIndex = file.url.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.url.substring(lastDotIndex + 1);
}
}
if (file.name) {
const lastDotIndex = file.name.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.name.substring(lastDotIndex + 1);
}
}
return 'unknown';
};
//
const getFileIcon = (fileType: string) => {
const type = fileType.toLowerCase();
switch (type) {
case 'pdf':
return '/static/base/view/pdf.png';
case 'doc':
case 'docx':
return '/static/base/view/word.png';
case 'xls':
case 'xlsx':
return '/static/base/view/excel.png';
case 'ppt':
case 'pptx':
return '/static/base/view/ppt.png';
case 'zip':
case 'rar':
case '7z':
return '/static/base/view/zip.png';
default:
return '/static/base/view/more.png';
}
};
//
const previewFile = (file: FileInfo) => {
emit('preview', file);
// URL
const fileUrl = file.resourUrl ? imagUrl(file.resourUrl) : file.url;
const fileName = file.resourName ? `${file.resourName}.${file.resSuf}` : file.name;
const fileSuf = file.resSuf || file.name.split('.').pop() || '';
// 使 kkview
const fullFileName = fileSuf ? `${fileName}.${fileSuf}` : fileName;
previewFileUtil(fileUrl, fullFileName, fileSuf)
.catch((error: any) => {
uni.showToast({
title: '预览失败',
icon: 'error'
});
});
};
</script>
<style lang="scss" scoped>
.basic-file-detail {
margin-bottom: 20px;
padding: 15px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.section-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 15px;
color: #333;
border-bottom: 2px solid #007aff;
padding-bottom: 5px;
}
.file-item {
display: flex;
align-items: center;
padding: 12px;
border: 1px solid #eee;
border-radius: 8px;
margin-bottom: 10px;
background: #fafafa;
transition: all 0.3s ease;
&:active {
transform: translateY(1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.file-icon {
margin-right: 12px;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
.icon-image {
width: 28px;
height: 28px;
}
}
.file-info {
flex: 1;
.file-name {
display: block;
font-weight: 500;
margin-bottom: 4px;
color: #333;
font-size: 14px;
}
.file-size {
font-size: 12px;
color: #666;
margin-right: 8px;
}
.file-type {
font-size: 11px;
color: #999;
background: #f0f0f0;
padding: 2px 6px;
border-radius: 4px;
}
}
.file-actions {
display: flex;
gap: 4px;
flex-wrap: wrap;
justify-content: flex-end;
.u-button {
min-width: 20px;
height: 26px;
font-size: 12px;
border-radius: 13px;
padding: 0 6px;
}
}
}
.no-files {
text-align: center;
padding: 40px 20px;
color: #999;
font-size: 14px;
}
</style>

View File

@ -0,0 +1,231 @@
<template>
<view class="basic-file-item" v-if="hasAttachments">
<view class="attachments-list">
<view
v-for="(file, fileIndex) in parsedFileList"
:key="fileIndex"
class="attachment-item"
@click="handlePreview(file)"
>
<view class="attachment-icon">
<image
:src="getFileIcon(getFileSuffix(file))"
class="icon-image"
mode="aspectFit"
/>
</view>
<text class="attachment-name">{{ getFileName(file) }}</text>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import {
previewFile as previewFileUtil
} from "@/utils/filePreview";
import { imagUrl } from "@/utils";
//
interface Props {
fileUrl?: string;
fileName?: string;
fileFormat?: string;
files?: FileInfo[];
}
interface FileInfo {
name: string;
size: number;
url: string;
resourName?: string;
resourUrl?: string;
resSuf?: string;
resourSuf?: string;
}
//
const props = withDefaults(defineProps<Props>(), {
fileUrl: '',
fileName: '',
fileFormat: '',
files: () => []
});
//
const emit = defineEmits<{
(e: 'preview', file: FileInfo): void;
}>();
//
const hasAttachments = computed(() => {
return props.fileUrl || (props.files && props.files.length > 0);
});
//
const parsedFileList = computed(() => {
const fileList: FileInfo[] = [];
//
if (props.fileUrl && props.fileName) {
const urls = props.fileUrl.split(',').map((url: string) => url.trim());
const names = props.fileName.split(',').map((name: string) => name.trim());
urls.forEach((url: string, index: number) => {
if (url) {
const fileName = names[index] || `文件${index + 1}`;
const fileSuffix = url.split('.').pop() || '';
fileList.push({
name: fileName,
url: url,
resourName: fileName,
resourUrl: url,
resourSuf: fileSuffix,
size: 0
});
}
});
}
// files
if (props.files && props.files.length > 0) {
fileList.push(...props.files);
}
return fileList;
});
//
const getFileName = (file: FileInfo) => {
if (file.resourName) {
return file.resourName;
}
if (file.name) {
const lastDotIndex = file.name.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.name.substring(0, lastDotIndex);
}
return file.name;
}
return '未知文件';
};
//
const getFileSuffix = (file: FileInfo) => {
if (file.resSuf) {
return file.resSuf;
}
if (file.url) {
const lastDotIndex = file.url.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.url.substring(lastDotIndex + 1);
}
}
if (file.name) {
const lastDotIndex = file.name.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.name.substring(lastDotIndex + 1);
}
}
return 'unknown';
};
//
const getFileIcon = (fileType: string) => {
const type = fileType.toLowerCase();
switch (type) {
case 'pdf':
return '/static/base/view/pdf.png';
case 'doc':
case 'docx':
return '/static/base/view/word.png';
case 'xls':
case 'xlsx':
return '/static/base/view/excel.png';
case 'ppt':
case 'pptx':
return '/static/base/view/ppt.png';
case 'zip':
case 'rar':
case '7z':
return '/static/base/view/zip.png';
default:
return '/static/base/view/more.png';
}
};
//
const handlePreview = (file: FileInfo) => {
emit('preview', file);
const fileUrl = file.resourUrl ? imagUrl(file.resourUrl) : (file.url ? imagUrl(file.url) : '');
const fileName = file.resourName || file.name || '未知文件';
const fileSuf = getFileSuffix(file);
if (!fileUrl) {
return;
}
// 使 kkview
const fullFileName = fileSuf ? `${fileName}.${fileSuf}` : fileName;
previewFileUtil(fileUrl, fullFileName, fileSuf)
.catch((error: any) => {
uni.showToast({
title: '预览失败',
icon: 'error'
});
});
};
</script>
<style lang="scss" scoped>
.basic-file-item {
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid #f0f0f0;
}
.attachments-list {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.attachment-item {
display: flex;
align-items: center;
padding: 6px 10px;
background-color: #f5f7fa;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #ebeff5;
}
}
.attachment-icon {
margin-right: 8px;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
.icon-image {
width: 16px;
height: 16px;
}
}
.attachment-name {
font-size: 14px;
color: #606266;
max-width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>

View File

@ -0,0 +1,458 @@
<template>
<view class="basic-file-preview">
<view class="section-title">附件</view>
<view class="file-list" v-if="hasAttachments">
<!-- 显示所有解析后的附件 -->
<view
v-for="(file, index) in parsedAttachments"
:key="(file as any).id || index"
class="file-item"
>
<view class="file-icon">
<image
:src="getFileIcon(getFileSuffix(file))"
class="icon-image"
mode="aspectFit"
/>
</view>
<view class="file-info">
<text class="file-name">{{ getFileName(file) }}</text>
</view>
<view class="file-actions">
<u-button
v-if="canPreview(getFileSuffix(file)) && !isVideo(getFileSuffix(file))"
text="预览"
size="mini"
type="primary"
@click="previewFile(file)"
/>
<u-button
v-if="isVideo(getFileSuffix(file))"
text="播放"
size="mini"
type="success"
@click="previewFile(file)"
/>
<u-button
v-if="isImage(getFileSuffix(file))"
text="查看"
size="mini"
type="warning"
@click="previewFile(file)"
/>
<u-button
text="下载"
size="mini"
type="info"
@click="downloadFileAction(file)"
/>
</view>
</view>
</view>
<view v-else class="no-files">
<text>暂无附件</text>
</view>
</view>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import {
isVideo,
isImage,
canPreview,
previewFile as previewFileUtil,
previewVideo as previewVideoUtil,
previewImage as previewImageUtil,
downloadFile as downloadFileUtil
} from "@/utils/filePreview";
import { imagUrl } from "@/utils";
//
interface Props {
fileUrl?: string;
fileName?: string;
fileFormat?: string;
files?: FileInfo[];
}
interface FileInfo {
id?: string;
name: string;
size: number;
url: string;
resourName?: string;
resourUrl?: string;
resSuf?: string;
}
//
const props = withDefaults(defineProps<Props>(), {
fileUrl: '',
fileName: '',
fileFormat: '',
files: () => []
});
//
const emit = defineEmits<{
(e: 'preview', file: FileInfo): void;
(e: 'download', file: FileInfo): void;
}>();
//
const hasAttachments = computed(() => {
const attachments = [];
// files
if (props.files && props.files.length > 0) {
attachments.push(...props.files);
}
// fileUrl
else if (props.fileUrl) {
const fileUrls = props.fileUrl.split(',').map(url => url.trim()).filter(url => url);
// fileName
let fileNames: string[] = [];
if (props.fileName) {
fileNames = props.fileName.split(',').map(name => name.trim()).filter(name => name);
}
// URL
fileUrls.forEach((url, index) => {
// 使URL
let displayName = fileNames[index] || url.split('/').pop() || `文件${index + 1}`;
const fileFormat = url.split('.').pop() || 'unknown';
// resourName
let resourName = displayName;
if (displayName.includes('.' + fileFormat)) {
resourName = displayName.replace('.' + fileFormat, '');
}
attachments.push({
id: `file_${index}`,
name: displayName,
url: url,
resourUrl: url,
resourName: resourName,
resSuf: fileFormat,
size: 0
});
});
}
return attachments.length > 0;
});
//
const parsedAttachments = computed(() => {
const attachments = [];
// files
if (props.files && props.files.length > 0) {
attachments.push(...props.files);
}
// fileUrl
else if (props.fileUrl) {
const fileUrls = props.fileUrl.split(',').map(url => url.trim()).filter(url => url);
// fileName
let fileNames: string[] = [];
if (props.fileName) {
fileNames = props.fileName.split(',').map(name => name.trim()).filter(name => name);
}
// URL
fileUrls.forEach((url, index) => {
// 使URL
let displayName = fileNames[index] || url.split('/').pop() || `文件${index + 1}`;
const fileFormat = url.split('.').pop() || 'unknown';
// resourName
let resourName = displayName;
if (displayName.includes('.' + fileFormat)) {
resourName = displayName.replace('.' + fileFormat, '');
}
attachments.push({
id: `file_${index}`,
name: displayName,
url: url,
resourUrl: url,
resourName: resourName,
resSuf: fileFormat,
size: 0
});
});
console.log('parsedAttachments', fileNames, fileUrls);
}
return attachments;
});
//
const getFileName = (file: FileInfo) => {
if (file.resourName) {
return file.resourName;
}
if (file.name) {
// name
const lastDotIndex = file.name.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.name.substring(0, lastDotIndex);
}
return file.name;
}
return '未知文件';
};
//
const getFileSuffix = (file: FileInfo) => {
if (file.resSuf) {
return file.resSuf;
}
if (file.url) {
const lastDotIndex = file.url.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.url.substring(lastDotIndex + 1);
}
}
if (file.name) {
const lastDotIndex = file.name.lastIndexOf('.');
if (lastDotIndex > 0) {
return file.name.substring(lastDotIndex + 1);
}
}
return 'unknown';
};
//
const getFileIcon = (fileType: string) => {
const type = fileType.toLowerCase();
switch (type) {
case 'pdf':
return '/static/base/view/pdf.png';
case 'doc':
case 'docx':
return '/static/base/view/word.png';
case 'xls':
case 'xlsx':
return '/static/base/view/excel.png';
case 'ppt':
case 'pptx':
return '/static/base/view/ppt.png';
case 'zip':
case 'rar':
case '7z':
return '/static/base/view/zip.png';
default:
return '/static/base/view/more.png';
}
};
//
const previewFile = (file: FileInfo) => {
emit('preview', file);
// URL
const fileUrl = file.resourUrl ? imagUrl(file.resourUrl) : file.url;
const fileName = file.resourName ? `${file.resourName}.${file.resSuf}` : file.name;
const fileSuf = file.resSuf || file.name.split('.').pop() || '';
//
if (isVideo(fileSuf)) {
handlePreviewVideo(file);
} else if (isImage(fileSuf)) {
handlePreviewImage(file);
} else if (canPreview(fileSuf)) {
handlePreviewDocument(file);
} else {
//
downloadFileAction(file);
}
};
//
const handlePreviewDocument = (file: FileInfo) => {
const fileUrl = file.resourUrl ? imagUrl(file.resourUrl) : file.url;
const fileName = file.resourName ? `${file.resourName}.${file.resSuf}` : file.name;
const fileSuf = file.resSuf || file.name.split('.').pop() || '';
previewFileUtil(fileUrl, fileName, fileSuf)
.catch((error: any) => {
//
downloadFileAction(file);
});
};
//
const handlePreviewVideo = (file: FileInfo) => {
const videoUrl = file.resourUrl ? imagUrl(file.resourUrl) : file.url;
const videoName = file.resourName || file.name;
previewVideoUtil(videoUrl, videoName)
.catch((error: any) => {
//
});
};
//
const handlePreviewImage = (file: FileInfo) => {
const imageUrl = file.resourUrl ? imagUrl(file.resourUrl) : file.url;
previewImageUtil(imageUrl)
.catch((error: any) => {
//
});
};
//
const downloadFileAction = (file: FileInfo) => {
emit('download', file);
const finalUrl = file.resourUrl ? imagUrl(file.resourUrl) : imagUrl(file.url);
//
const originalFileName = getOriginalFileName(file);
//
downloadFileUtil(finalUrl, originalFileName)
.then(() => {
uni.showToast({
title: "下载成功",
icon: "success",
});
})
.catch((error) => {
console.error('下载失败:', error);
uni.showToast({
title: "下载失败",
icon: "error",
});
});
};
//
const getOriginalFileName = (file: FileInfo) => {
// 使resourName使name
let fileName = '';
if (file.resourName) {
// resourName使
if (file.resSuf && !file.resourName.includes('.' + file.resSuf)) {
fileName = `${file.resourName}.${file.resSuf}`;
} else {
fileName = file.resourName;
}
} else if (file.name) {
// name使
if (file.resSuf && !file.name.includes('.' + file.resSuf)) {
fileName = `${file.name}.${file.resSuf}`;
} else {
fileName = file.name;
}
} else {
// URL
const urlFileName = file.url.split('/').pop() || '未知文件';
fileName = urlFileName;
}
return fileName;
};
</script>
<style lang="scss" scoped>
.basic-file-preview {
margin-bottom: 20px;
padding: 15px;
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.section-title {
font-size: 16px;
font-weight: bold;
margin-bottom: 15px;
color: #333;
border-bottom: 2px solid #007aff;
padding-bottom: 5px;
}
.file-item {
display: flex;
align-items: center;
padding: 12px;
border: 1px solid #eee;
border-radius: 8px;
margin-bottom: 10px;
background: #fafafa;
transition: all 0.3s ease;
&:active {
transform: translateY(1px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.file-icon {
margin-right: 12px;
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
.icon-image {
width: 28px;
height: 28px;
}
}
.file-info {
flex: 1;
.file-name {
display: block;
font-weight: 500;
margin-bottom: 4px;
color: #333;
font-size: 14px;
}
.file-size {
font-size: 12px;
color: #666;
margin-right: 8px;
}
.file-type {
font-size: 11px;
color: #999;
background: #f0f0f0;
padding: 2px 6px;
border-radius: 4px;
}
}
.file-actions {
display: flex;
gap: 4px;
flex-wrap: wrap;
justify-content: flex-end;
.u-button {
min-width: 20px;
height: 26px;
font-size: 12px;
border-radius: 13px;
padding: 0 6px;
}
}
}
.no-files {
text-align: center;
padding: 40px 20px;
color: #999;
font-size: 14px;
}
</style>

View File

@ -22,6 +22,15 @@
</view>
</view>
</view>
<!-- 附件预览 -->
<BasicFilePreview
v-if="qjData.fileUrl"
:file-url="qjData.fileUrl"
:file-name="qjData.fileName"
:file-format="qjData.fileFormat"
class="m-15"
/>
</view>
</template>
@ -29,6 +38,8 @@
import { findQjById } from "@/api/base/jsQjApi";
import { useDataStore } from "@/store/modules/data";
import { ref, computed, watch, onMounted } from "vue";
import BasicFilePreview from "@/components/BasicFile/preview.vue";
import BasicTitle from "@/components/BasicTitle/Title.vue";
const { getXxts } = useDataStore();

View File

@ -175,7 +175,7 @@ const getPkkbList = async () => {
const newList = await QjPageUtils.getPkkbList(props.data);
if (!newList || !newList.length) {
console.log("没有排课信息");
return;
return [];
}
//
const srcData: any = {};
@ -196,6 +196,7 @@ const getPkkbList = async () => {
})
// kmMapvalue
kmDkList.value = Object.values(kmMap);
return dkList.value;
};
const changeJsByTy = (selected: any, item: any) => {

View File

@ -3,7 +3,7 @@
<view class="p-15">
<BasicForm @register="register">
<template #dkmx>
<view class="mt-15" v-if="formData.dkfs === 0">
<view class="mt-15" v-show="formData.dkfs === 0">
<JsQjDkEdit :data="formData" ref="dkRef" />
</view>
</template>
@ -65,6 +65,10 @@ let formData = ref<any>({
const dkRef = ref<any>(null);
//
const fileName = ref<string>('');
const fileFormat = ref<string>('');
const [register, { setValue, getValue }] = useForm({
schema: [
{
@ -121,6 +125,34 @@ const [register, { setValue, getValue }] = useForm({
},
},
{ interval: true },
{
field: "fileUrl",
label: "上传附件",
component: "BasicUpload",
required: true,
itemProps: {
labelPosition: "top",
},
componentProps: {
multiple: false,
accept: "*/*",
maxCount: 1,
disabled: false,
limit: 1,
beforeUpload: (file: any) => {
const fileFullName = file.name || '';
const fileExt = fileFullName.split('.').pop() || '';
const fileWithoutExt = fileFullName.replace(/\.[^/.]+$/, '');
//
fileName.value = fileWithoutExt;
fileFormat.value = fileExt;
return true;
}
},
},
{ interval: true },
{
field: "dkfs",
label: "代课方式",
@ -210,6 +242,8 @@ const submit = async () => {
// /
params.sprList = formData.value.sprList || [];
params.csrList = formData.value.csrList || [];
params.fileName = fileName.value;
params.fileFormat = fileFormat.value;
if (fd.dkfs === 0) {
const dkList = dkRef.value.getDkList();
if (!dkList.length) {
@ -246,6 +280,19 @@ const submit = async () => {
} else {
params.dkList = [];
}
} else if (fd.dkfs === 2) {
let dkList = dkRef.value.getDkList();
if (!dkList.length) {
dkList = await dkRef.value.getPkkbList();
}
if (dkList.length > 0) {
uni.showToast({
title: "您在请假期间有课程,请选择自行协调或教科处协调",
icon: "none",
});
return;
}
return;
}
let submitApi = jsQjSqApi;
if (props.data && props.data.id) {