学生请假调整
This commit is contained in:
parent
091411cda0
commit
409f9f5108
@ -52,7 +52,7 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 抄送人 -->
|
||||
<!-- <!– 抄送人 –>
|
||||
<view class="info-section csr" v-if="csrSpList.length > 0">
|
||||
<view class="section-title">抄送人({{ csrSpList.length || 0 }})</view>
|
||||
<view class="sp-list">
|
||||
@ -66,14 +66,14 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 更多按钮 -->
|
||||
<!– 更多按钮 –>
|
||||
<view v-if="csrSpList.length > 2" class="more-button" @click="toggleCsrExpanded">
|
||||
<text class="more-text">
|
||||
{{ csrExpanded ? '收起' : `更多(${csrSpList.length - 2})` }}
|
||||
</text>
|
||||
<text class="more-icon" :class="{ expanded: csrExpanded }">▼</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>-->
|
||||
<!-- 操作记录 -->
|
||||
<view class="info-section log" v-if="logList.length > 0">
|
||||
<view class="section-title">操作记录({{ logList.length || 0 }})</view>
|
||||
|
||||
@ -1,8 +1,47 @@
|
||||
<template>
|
||||
<BasicLayout :fixed="false">
|
||||
<view class="p-15">
|
||||
<!-- 请假类型 -->
|
||||
<BasicForm @register="register" />
|
||||
|
||||
<!-- 间隔空白 -->
|
||||
<view class="section-gap"></view>
|
||||
|
||||
<!-- 时间选择区域 -->
|
||||
<view class="time-section">
|
||||
<view class="time-item" @click="startTimePicker?.open()">
|
||||
<text class="time-label">
|
||||
<text class="required-star">*</text>
|
||||
开始时间
|
||||
</text>
|
||||
<view class="time-value">
|
||||
<text :class="{ placeholder: !formData.qjkstime }">{{ formData.qjkstime || "请选择开始时间" }}</text>
|
||||
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="time-item" @click="endTimePicker?.open()">
|
||||
<text class="time-label">
|
||||
<text class="required-star">*</text>
|
||||
结束时间
|
||||
</text>
|
||||
<view class="time-value">
|
||||
<text :class="{ placeholder: !formData.qjjstime }">{{ formData.qjjstime || "请选择结束时间" }}</text>
|
||||
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="time-item time-item-readonly">
|
||||
<text class="time-label">请假时长</text>
|
||||
<view class="time-value">
|
||||
<text :class="{ placeholder: !formData.qjsc }">{{ formData.qjsc || "请输入选择开始时间和结束时间" }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 请假事由和是否离校 -->
|
||||
<BasicForm @register="register2" />
|
||||
|
||||
<!-- 审批信息显示区域 -->
|
||||
<view class="approver-section">
|
||||
<view class="section-title">审批信息</view>
|
||||
@ -14,6 +53,9 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 签名组件 -->
|
||||
<BasicSign ref="signCompRef" title="家长签名"></BasicSign>
|
||||
</view>
|
||||
<template #bottom>
|
||||
<view class="white-bg-color py-5">
|
||||
@ -33,6 +75,22 @@
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- 自定义时间选择器 -->
|
||||
<DatetimePicker
|
||||
ref="startTimePicker"
|
||||
:value="formData.qjkstime || new Date().getTime()"
|
||||
mode="datetime"
|
||||
title="选择开始时间"
|
||||
@confirm="handleStartTimeConfirm"
|
||||
/>
|
||||
<DatetimePicker
|
||||
ref="endTimePicker"
|
||||
:value="formData.qjjstime || new Date().getTime()"
|
||||
mode="datetime"
|
||||
title="选择结束时间"
|
||||
@confirm="handleEndTimeConfirm"
|
||||
/>
|
||||
</BasicLayout>
|
||||
</template>
|
||||
|
||||
@ -45,6 +103,12 @@ import dayjs from "dayjs";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useCommonStore } from "@/store/modules/common";
|
||||
import { useDebounce } from "@/utils/debounce";
|
||||
import DatetimePicker from "@/components/BasicPicker/TimePicker/DatetimePicker.vue";
|
||||
|
||||
// 定义事件
|
||||
const emit = defineEmits<{
|
||||
(e: 'submit-success'): void
|
||||
}>();
|
||||
|
||||
const { getCurXs, getUser } = useUserStore();
|
||||
const { findByPid } = useDicStore();
|
||||
@ -52,6 +116,14 @@ const commonStore = useCommonStore();
|
||||
// 替换 isSubmitting 状态为 useDebounce
|
||||
const { isProcessing: isSubmitting, debounce } = useDebounce(2000);
|
||||
|
||||
// 自定义时间选择器控制
|
||||
const startTimePicker = ref<any>(null);
|
||||
const endTimePicker = ref<any>(null);
|
||||
|
||||
// 签名组件引用
|
||||
const signCompRef = ref<any>(null);
|
||||
const signFile = ref<any>(null);
|
||||
|
||||
// 接收外部传入属性
|
||||
const props = withDefaults(defineProps<{
|
||||
data?: any
|
||||
@ -67,7 +139,11 @@ const props = withDefaults(defineProps<{
|
||||
})
|
||||
});
|
||||
|
||||
let formData = ref<any>({});
|
||||
let formData = ref<any>({
|
||||
qjkstime: "",
|
||||
qjjstime: "",
|
||||
qjsc: ""
|
||||
});
|
||||
let approverName = ref<string>(''); // 审批人姓名(班主任)
|
||||
|
||||
const [register, { getValue, setValue }] = useForm({
|
||||
@ -84,37 +160,11 @@ const [register, { getValue, setValue }] = useForm({
|
||||
savaKey: "dictionaryCode",
|
||||
},
|
||||
},
|
||||
{ interval: true },
|
||||
{
|
||||
field: "qjkstime",
|
||||
label: "开始时间",
|
||||
component: "BasicDateTimes",
|
||||
required: true,
|
||||
componentProps: {
|
||||
type: 'datetime',
|
||||
change: (e: string) => changeKsTime(e)
|
||||
},
|
||||
},
|
||||
{
|
||||
field: "qjjstime",
|
||||
label: "结束时间",
|
||||
component: "BasicDateTimes",
|
||||
required: true,
|
||||
componentProps: {
|
||||
type: 'datetime',
|
||||
change: (e: string) => changeJsTime(e)
|
||||
},
|
||||
},
|
||||
{
|
||||
field: "qjsc",
|
||||
label: "请假时长",
|
||||
component: "BasicInput",
|
||||
componentProps: {
|
||||
disabled: true,
|
||||
placeholder: "请输入选择开始时间和结束时间"
|
||||
},
|
||||
},
|
||||
{ interval: true },
|
||||
],
|
||||
});
|
||||
|
||||
const [register2, { getValue: getValue2, setValue: setValue2 }] = useForm({
|
||||
schema: [
|
||||
{
|
||||
field: "qjsy",
|
||||
label: "请假事由",
|
||||
@ -142,20 +192,11 @@ const [register, { getValue, setValue }] = useForm({
|
||||
],
|
||||
},
|
||||
},
|
||||
// {
|
||||
// field: "qjtp",
|
||||
// label: "请假图片",
|
||||
// component: "BasicUpload",
|
||||
// required: true,
|
||||
// itemProps: {
|
||||
// labelPosition: "top",
|
||||
// },
|
||||
// componentProps: {},
|
||||
// },
|
||||
],
|
||||
});
|
||||
|
||||
setValue(props.data)
|
||||
setValue2(props.data)
|
||||
|
||||
const goHome = () => {
|
||||
uni.reLaunch({
|
||||
@ -163,6 +204,30 @@ const goHome = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 日期格式化函数
|
||||
const formatDate = (dateString: string | null): string | null => {
|
||||
if (!dateString) return null;
|
||||
const date = new Date(dateString);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
// 自定义时间选择器确认事件处理
|
||||
const handleStartTimeConfirm = (e: any) => {
|
||||
formData.value.qjkstime = formatDate(e.value);
|
||||
calculateDuration();
|
||||
};
|
||||
|
||||
const handleEndTimeConfirm = (e: any) => {
|
||||
formData.value.qjjstime = formatDate(e.value);
|
||||
calculateDuration();
|
||||
};
|
||||
|
||||
// 获取默认审批人信息
|
||||
onMounted(async () => {
|
||||
await getDefaultApprover();
|
||||
@ -180,25 +245,37 @@ const getDefaultApprover = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const changeKsTime = (selectedTime?: string) => {
|
||||
if (!selectedTime) {
|
||||
// 计算请假时长(不显示错误提示)
|
||||
const calculateDuration = () => {
|
||||
const data = formData.value;
|
||||
// 如果两个时间都不存在,直接返回
|
||||
if (!data.qjkstime || !data.qjjstime) {
|
||||
data.qjsc = "";
|
||||
return;
|
||||
}
|
||||
formData.value.qjkstime = selectedTime;
|
||||
validateTime();
|
||||
};
|
||||
|
||||
const changeJsTime = (selectedTime?: string) => {
|
||||
if (!selectedTime) {
|
||||
// 使用dayjs库进行时间比较
|
||||
const ksTime = dayjs(data.qjkstime).valueOf();
|
||||
const jsTime = dayjs(data.qjjstime).valueOf();
|
||||
if (ksTime > jsTime) {
|
||||
uni.showToast({
|
||||
title: "请假开始时间不能大于请假结束时间!",
|
||||
icon: "none",
|
||||
});
|
||||
data.qjsc = "";
|
||||
return;
|
||||
}
|
||||
formData.value.qjjstime = selectedTime;
|
||||
validateTime();
|
||||
};
|
||||
// 计算请假时长(小时)
|
||||
data.qjsc = Math.round((jsTime - ksTime) / (1000 * 60 * 60)) + "小时";
|
||||
}
|
||||
|
||||
// 验证时间(用于提交时的完整验证)
|
||||
const validateTime = () => {
|
||||
const data = formData.value;
|
||||
if (!data.qjkstime || !data.qjjstime) {
|
||||
uni.showToast({
|
||||
title: "请选择开始时间和结束时间",
|
||||
icon: "none",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
// 使用dayjs库进行时间比较
|
||||
@ -213,16 +290,40 @@ const validateTime = () => {
|
||||
}
|
||||
// 计算请假时长(小时)
|
||||
data.qjsc = Math.round((jsTime - ksTime) / (1000 * 60 * 60)) + "小时";
|
||||
setValue({ qjsc: data.qjsc });
|
||||
return true;
|
||||
}
|
||||
|
||||
const submit = debounce(async () => {
|
||||
const fd = await getValue();
|
||||
if (!validateTime()) {
|
||||
return;
|
||||
}
|
||||
const params = { ...fd };
|
||||
|
||||
// 获取签名
|
||||
const signData = await signCompRef.value.getSyncSignature();
|
||||
if (!signData) {
|
||||
uni.showToast({
|
||||
title: "请签名",
|
||||
icon: "none",
|
||||
});
|
||||
return;
|
||||
}
|
||||
signFile.value = signData.base64;
|
||||
|
||||
const fd = await getValue();
|
||||
const fd2 = await getValue2();
|
||||
|
||||
// 组合班级别称:njbc + "(" + bjmc + ")"
|
||||
const bc = getCurXs.njbc ? `${getCurXs.njbc}(${getCurXs.bjmc || ''})` : (getCurXs.bjmc || '');
|
||||
|
||||
const params = {
|
||||
...fd,
|
||||
...fd2,
|
||||
qjkstime: formData.value.qjkstime,
|
||||
qjjstime: formData.value.qjjstime,
|
||||
qjsc: formData.value.qjsc,
|
||||
signFile: signFile.value, // 添加签名数据
|
||||
bc: bc // 添加班级别称
|
||||
};
|
||||
if (props.data && props.data.id) {
|
||||
params.id = props.data.id;
|
||||
} else {
|
||||
@ -241,7 +342,8 @@ const submit = debounce(async () => {
|
||||
setTimeout(() => {
|
||||
if (res.resultCode === 1) {
|
||||
showToast({ title: "提交成功", icon: "success" });
|
||||
goHome();
|
||||
// 触发提交成功事件,切换到请假记录页
|
||||
emit('submit-success');
|
||||
} else {
|
||||
showToast({ title: res.message, icon: "error" });
|
||||
}
|
||||
@ -251,6 +353,78 @@ const submit = debounce(async () => {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.section-gap {
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.required-star {
|
||||
color: #f56c6c;
|
||||
margin-right: 4px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.time-section {
|
||||
background-color: #ffffff;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
||||
|
||||
.time-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 14px 15px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
&.time-item-readonly {
|
||||
cursor: default;
|
||||
|
||||
&:active {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.time-label {
|
||||
font-size: 15px;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.time-value {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 15px;
|
||||
color: #909399;
|
||||
flex: 1;
|
||||
justify-content: flex-end;
|
||||
|
||||
text {
|
||||
margin-right: 5px;
|
||||
color: #606266;
|
||||
|
||||
&.placeholder {
|
||||
color: #c0c4cc;
|
||||
}
|
||||
}
|
||||
|
||||
.uni-icons {
|
||||
color: #c0c4cc !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.approver-section {
|
||||
margin: 20px 0;
|
||||
padding: 15px;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
:current="curTabIndex" @change="switchTab"
|
||||
/>
|
||||
<view class="leave-edit" v-if="curTabIndex === 0">
|
||||
<XsQjEdit />
|
||||
<XsQjEdit @submit-success="handleSubmitSuccess" />
|
||||
</view>
|
||||
<view class="leave-list" v-else>
|
||||
<XsQjList />
|
||||
@ -29,6 +29,11 @@ const curTabIndex = ref(0);
|
||||
const switchTab = (index : number) => {
|
||||
curTabIndex.value = index;
|
||||
}
|
||||
|
||||
const handleSubmitSuccess = () => {
|
||||
// 切换到请假记录tab页
|
||||
curTabIndex.value = 1;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -169,9 +169,13 @@ const courseDetail = computed(() => {
|
||||
// 教师信息
|
||||
const teacherInfo = computed(() => {
|
||||
const data = (kcData.value as CourseData) || {};
|
||||
|
||||
// 处理多个教师头像的情况
|
||||
const teacherAvatars = data.jstx ? data.jstx.split(',').map((avatar: string) => avatar.trim()) : [];
|
||||
|
||||
return {
|
||||
name: data.jsName || "暂无教师信息",
|
||||
avatar: imagUrl(data.jstx), // 默认头像
|
||||
avatar: teacherAvatars.length > 0 ? imagUrl(teacherAvatars[0]) : '', // 只取第一个头像
|
||||
introduction: data.kcjsms || "暂无教师介绍",
|
||||
};
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user