外宿申请移动端申请完成

This commit is contained in:
2025-12-19 11:42:11 +08:00
parent bc78f7d2dd
commit 68c06f273b
3 changed files with 264 additions and 186 deletions

View File

@@ -9,7 +9,7 @@
<!-- 表单主体容器 --> <!-- 表单主体容器 -->
<view class="main-container"> <view class="main-container">
<!-- 选项卡容器 - 原生选项卡 --> <!-- 选项卡容器 - 原生选项卡 -->
<view class="tabs-container"> <view class="tabs-container" id="tabs">
<view class="tabs-header"> <view class="tabs-header">
<!-- 详情模式下禁用选项卡切换 --> <!-- 详情模式下禁用选项卡切换 -->
<view class="tab-item" :class="{ active: activeTab === 0 }" @click="switchTab(0)"> <view class="tab-item" :class="{ active: activeTab === 0 }" @click="switchTab(0)">
@@ -37,7 +37,7 @@
</view> </view>
<!-- 表单内容区域 --> <!-- 表单内容区域 -->
<scroll-view scroll-y class="form-scroll" :style="{ height: formScrollHeight }"> <scroll-view scroll-y class="form-scroll" :style="{ height: formScrollHeight }" id="form-scroll">
<view class="form-wrapper"> <view class="form-wrapper">
<!-- 1. 基本信息标签页 --> <!-- 1. 基本信息标签页 -->
<view v-show="activeTab === 0" class="tab-panel"> <view v-show="activeTab === 0" class="tab-panel">
@@ -46,13 +46,14 @@
<view class="form-item"> <view class="form-item">
<label class="form-label">原宿舍号</label> <label class="form-label">原宿舍号</label>
<!-- 详情模式下禁用输入框 --> <!-- 详情模式下禁用输入框 -->
<input v-model="form.originalDormitory" placeholder="如1栋302" <input v-model="form.originalDormitory" placeholder="如1栋302" class="form-input"
class="form-input" :disabled="isDetailMode"></input> :disabled="isDetailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
<label class="form-label">姓名</label> <label class="form-label">姓名</label>
<input v-model="form.studentName" placeholder="请输入姓名" class="form-input" :disabled="isDetailMode"></input> <input v-model="form.studentName" placeholder="请输入姓名" class="form-input"
:disabled="isDetailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
@@ -68,7 +69,8 @@
<view class="form-item"> <view class="form-item">
<label class="form-label">出生年月</label> <label class="form-label">出生年月</label>
<picker mode="date" :value="form.birthDate" @change="handleBirthDateChange" :disabled="isDetailMode"> <picker mode="date" :value="form.birthDate" @change="handleBirthDateChange"
:disabled="isDetailMode">
<view class="picker-input"> <view class="picker-input">
{{ form.birthDate || '请选择出生年月' }} {{ form.birthDate || '请选择出生年月' }}
</view> </view>
@@ -77,22 +79,26 @@
<view class="form-item"> <view class="form-item">
<label class="form-label">专业系</label> <label class="form-label">专业系</label>
<input v-model="form.majorName" placeholder="请输入专业系" class="form-input" :disabled="isDetailMode"></input> <input v-model="form.majorName" placeholder="请输入专业系" class="form-input"
:disabled="isDetailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
<label class="form-label">班级</label> <label class="form-label">班级</label>
<input v-model="form.className" placeholder="请输入班级" class="form-input" :disabled="isDetailMode"></input> <input v-model="form.className" placeholder="请输入班级" class="form-input"
:disabled="isDetailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
<label class="form-label">学号</label> <label class="form-label">学号</label>
<input v-model="form.studentNo" placeholder="请输入学号" class="form-input" :disabled="isDetailMode"></input> <input v-model="form.studentNo" placeholder="请输入学号" class="form-input"
:disabled="isDetailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
<label class="form-label">身份证号码</label> <label class="form-label">身份证号码</label>
<input v-model="form.idCard" placeholder="请输入身份证号码" class="form-input" :disabled="isDetailMode"></input> <input v-model="form.idCard" placeholder="请输入身份证号码" class="form-input"
:disabled="isDetailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
@@ -127,12 +133,13 @@
</view> </view>
<view class="file-list" v-if="affixFiles.length"> <view class="file-list" v-if="affixFiles.length">
<view class="file-item" v-for="(file, index) in affixFiles" :key="index"> <view class="file-item" v-for="(file, index) in affixFiles" :key="index">
<text class="file-name" @click="previewImage(baseUrl + file.savePath)">{{ file.attachmentName || file.trueName }}</text> <text class="file-name"
@click="previewImage(baseUrl + file.savePath)">{{ file.attachmentName || file.trueName }}</text>
<!-- 详情模式下禁用删除按钮 --> <!-- 详情模式下禁用删除按钮 -->
<!-- <button size="mini" type="warn" @click="deleteAffixFile(index)" v-if="!isDetailMode" <!-- <button size="mini" type="warn" @click="deleteAffixFile(index)" v-if="!isDetailMode"
class="delete-btn" :disabled="isDetailMode">删除</button> --> class="delete-btn" :disabled="isDetailMode">删除</button> -->
<uni-icons type="trash-filled" size="30" @click="deleteAffixFile(index)" v-if="!isDetailMode" <uni-icons type="trash-filled" size="30" @click="deleteAffixFile(index)"
class="delete-btn"></uni-icons> v-if="!isDetailMode" class="delete-btn"></uni-icons>
</view> </view>
</view> </view>
<!-- <uni-file-picker :auto-upload="false" @select="chooseAffixFile" @delete="deleteAffixFile"></uni-file-picker> --> <!-- <uni-file-picker :auto-upload="false" @select="chooseAffixFile" @delete="deleteAffixFile"></uni-file-picker> -->
@@ -143,8 +150,9 @@
<label class="form-label">电子签名</label> <label class="form-label">电子签名</label>
<view class="signature-container"> <view class="signature-container">
<!-- 详情模式下隐藏签名按钮 --> <!-- 详情模式下隐藏签名按钮 -->
<button size="mini" type="primary" @click="!isDetailMode && openSignature('student')" <button size="mini" type="primary"
class="sign-btn" v-if="!isDetailMode"> @click="!isDetailMode && openSignature('student')" class="sign-btn"
v-if="!isDetailMode">
签署电子签名 签署电子签名
</button> </button>
<image v-if="form.studentSignature" :src="baseUrl + form.studentSignature" <image v-if="form.studentSignature" :src="baseUrl + form.studentSignature"
@@ -163,7 +171,8 @@
<view class="form-item"> <view class="form-item">
<label class="form-label">外宿地区</label> <label class="form-label">外宿地区</label>
<!-- 详情模式下禁用省市区选择器 --> <!-- 详情模式下禁用省市区选择器 -->
<view class="area-picker" @click="!isDetailMode && (showAreaPicker = true)" :class="{disabled: isDetailMode}"> <view class="area-picker" @click="!isDetailMode && (showAreaPicker = true)"
:class="{disabled: isDetailMode}">
<text class="picker-text">{{ areaText || '请选择省/市/区' }}</text> <text class="picker-text">{{ areaText || '请选择省/市/区' }}</text>
<uni-icons type="arrowright" size="16" color="#999" class="picker-icon"></uni-icons> <uni-icons type="arrowright" size="16" color="#999" class="picker-icon"></uni-icons>
</view> </view>
@@ -177,8 +186,8 @@
<view class="form-item"> <view class="form-item">
<label class="form-label">紧急联系人</label> <label class="form-label">紧急联系人</label>
<input v-model="form.emergencyContact" placeholder="请输入紧急联系人姓名" <input v-model="form.emergencyContact" placeholder="请输入紧急联系人姓名" class="form-input"
class="form-input" :disabled="isDetailMode"></input> :disabled="isDetailMode"></input>
</view> </view>
<view class="form-item"> <view class="form-item">
@@ -197,7 +206,8 @@
<label class="form-label">家长意见</label> <label class="form-label">家长意见</label>
<!-- 详情模式下禁用选择器 --> <!-- 详情模式下禁用选择器 -->
<picker mode="selector" :range="parentOpinionOptions" :range-key="'text'" <picker mode="selector" :range="parentOpinionOptions" :range-key="'text'"
v-model="form.parentOpinion" @change="handleParentOpinionChange" :disabled="isDetailMode"> v-model="form.parentOpinion" @change="handleParentOpinionChange"
:disabled="isDetailMode">
<view class="picker-input"> <view class="picker-input">
{{ form.parentOpinion ? getParentOpinionText(form.parentOpinion) : '请选择家长意见' }} {{ form.parentOpinion ? getParentOpinionText(form.parentOpinion) : '请选择家长意见' }}
</view> </view>
@@ -227,7 +237,8 @@
<view class="form-item"> <view class="form-item">
<label class="form-label">家长通讯地区</label> <label class="form-label">家长通讯地区</label>
<!-- 详情模式下禁用省市区选择器 --> <!-- 详情模式下禁用省市区选择器 -->
<view class="area-picker" @click="!isDetailMode && (showParentAreaPicker = true)" :class="{disabled: isDetailMode}"> <view class="area-picker" @click="!isDetailMode && (showParentAreaPicker = true)"
:class="{disabled: isDetailMode}">
<text class="picker-text">{{ parentAreaText || '请选择省/市/区' }}</text> <text class="picker-text">{{ parentAreaText || '请选择省/市/区' }}</text>
<uni-icons type="arrowright" size="16" color="#999" class="picker-icon"></uni-icons> <uni-icons type="arrowright" size="16" color="#999" class="picker-icon"></uni-icons>
</view> </view>
@@ -235,8 +246,8 @@
<view class="form-item"> <view class="form-item">
<label class="form-label">家长详细地址</label> <label class="form-label">家长详细地址</label>
<input v-model="form.parentDetailAddress" placeholder="请输入家长详细通讯地址" <input v-model="form.parentDetailAddress" placeholder="请输入家长详细通讯地址" class="form-input"
class="form-input" :disabled="isDetailMode"></input> :disabled="isDetailMode"></input>
</view> </view>
</view> </view>
</view> </view>
@@ -259,8 +270,9 @@
<label class="form-label">承诺签名</label> <label class="form-label">承诺签名</label>
<view class="signature-container"> <view class="signature-container">
<!-- 详情模式下隐藏签名按钮 --> <!-- 详情模式下隐藏签名按钮 -->
<button size="mini" type="primary" @click="!isDetailMode && openSignature('promise')" <button size="mini" type="primary"
class="sign-btn" v-if="!isDetailMode"> @click="!isDetailMode && openSignature('promise')" class="sign-btn"
v-if="!isDetailMode">
签署承诺签名 签署承诺签名
</button> </button>
<image v-if="form.studentPromiseSign" :src="baseUrl + form.studentPromiseSign" <image v-if="form.studentPromiseSign" :src="baseUrl + form.studentPromiseSign"
@@ -269,7 +281,8 @@
<view class="date-item"> <view class="date-item">
<label class="form-label">签署日期</label> <label class="form-label">签署日期</label>
<!-- 详情模式下禁用日期选择器 --> <!-- 详情模式下禁用日期选择器 -->
<picker mode="date" :value="form.promiseDate" @change="handlePromiseDateChange" :disabled="isDetailMode"> <picker mode="date" :value="form.promiseDate" @change="handlePromiseDateChange"
:disabled="isDetailMode">
<view class="picker-input"> <view class="picker-input">
{{ form.promiseDate || '请选择签署日期' }} {{ form.promiseDate || '请选择签署日期' }}
</view> </view>
@@ -287,7 +300,7 @@
<uni-icons type="folder" size="16"></uni-icons> 保存 <uni-icons type="folder" size="16"></uni-icons> 保存
</button> </button>
<button type="primary" @click="submitForm(1)" class="submit-btn submit-primary" <button type="primary" @click="submitForm(1)" class="submit-btn submit-primary"
v-if="form.status == 0"> v-if="form.status == 0 || form.processInstanceId == ''">
<uni-icons type="checkmark" size="16"></uni-icons> 提交申请 <uni-icons type="checkmark" size="16"></uni-icons> 提交申请
</button> </button>
<button type="default" @click="resetForm" class="reset-btn" v-if="!currentId"> <button type="default" @click="resetForm" class="reset-btn" v-if="!currentId">
@@ -410,7 +423,8 @@
} from "@/utils/checkPic.js"; } from "@/utils/checkPic.js";
import uploadFile from "@/plugins/upload.js"; import uploadFile from "@/plugins/upload.js";
import { import {
getAffixItems, deleteAffix getAffixItems,
deleteAffix
} from "@/api/affix.js"; } from "@/api/affix.js";
export default { export default {
name: 'OutsideAccommodationApply', name: 'OutsideAccommodationApply',
@@ -502,6 +516,7 @@
// 文件上传相关 // 文件上传相关
affixFiles: [], affixFiles: [],
parentSignFiles: "", parentSignFiles: "",
reasonFileList: [],
// 页面状态 // 页面状态
currentId: null, currentId: null,
loading: false, loading: false,
@@ -514,7 +529,7 @@
onLoad(options) { onLoad(options) {
// 新增:判断是否为详情模式(核心逻辑) // 新增:判断是否为详情模式(核心逻辑)
this.isDetailMode = options.type === 'detail'; this.isDetailMode = options.type === 'detail';
// 1. 初始化省市区数据 // 1. 初始化省市区数据
this.initAreaData(); this.initAreaData();
// 2. 初始化页面高度 // 2. 初始化页面高度
@@ -917,8 +932,9 @@
if (!isDuplicate) { if (!isDuplicate) {
this.affixFiles.push(fileInfo); this.affixFiles.push(fileInfo);
this.reasonFileList.push(fileInfo)
} }
console.log(this.affixFiles); // console.log(this.affixFiles);
uni.showToast({ uni.showToast({
title: `文件 ${file.name} 上传成功`, title: `文件 ${file.name} 上传成功`,
icon: 'success', icon: 'success',
@@ -957,7 +973,7 @@
const deletedFile = this.affixFiles[index]; const deletedFile = this.affixFiles[index];
this.affixFiles.splice(index, 1); this.affixFiles.splice(index, 1);
// this.form.affixId = this.affixFiles.length ? 'uploaded' : ''; // this.form.affixId = this.affixFiles.length ? 'uploaded' : '';
let fileId = deletedFile.id || deletedFile.fileId let fileId = deletedFile.id || deletedFile.fileId
deleteAffix(fileId).then(() => { deleteAffix(fileId).then(() => {
deleteOutsideAccommodationAttachmentNameAndStuName({ deleteOutsideAccommodationAttachmentNameAndStuName({
attachmentName: deletedFile.trueName || deletedFile.attachmentName, attachmentName: deletedFile.trueName || deletedFile.attachmentName,
@@ -974,7 +990,7 @@
}); });
}); });
}) })
}, },
// 家长附件上传 // 家长附件上传
handleUpload() { handleUpload() {
@@ -1026,9 +1042,9 @@
// url: this.baseUrl + this.form.parentSignAttachment // url: this.baseUrl + this.form.parentSignAttachment
// }]; // }];
// } // }
this.getAffixs(this.form.affixId)
this.getAffixs(this.form.affixId)
this.setFormScroll()
this.loading = false; this.loading = false;
}).catch(() => { }).catch(() => {
this.loading = false; this.loading = false;
@@ -1038,6 +1054,16 @@
}); });
}); });
}, },
// 计算表单内容顶部外边距
setFormScroll() {
// 获取搜索框元素高度
let tabs = document.getElementById("tabs")
// 获取列表内容元素
let formScroll = document.getElementById("form-scroll")
// 设置列表内容的顶部外边距,让内容不被搜索框遮挡
formScroll.style.marginTop = `${tabs.offsetHeight}px`
console.log(formScroll.style.marginTop);
},
getUser() { getUser() {
this.loading = true; this.loading = true;
getUserProfile().then((response) => { getUserProfile().then((response) => {
@@ -1045,7 +1071,7 @@
if (response.data) { if (response.data) {
this.form.studentName = response.data.nickName; this.form.studentName = response.data.nickName;
this.form.gender = response.data.sex || ''; this.form.gender = response.data.sex || '';
this.setFormScroll()
getOwnInfo().then((res) => { getOwnInfo().then((res) => {
if (res.data) { if (res.data) {
this.form.studentId = res.data.stuId; this.form.studentId = res.data.stuId;
@@ -1143,11 +1169,11 @@
}, },
// 获取上传的附件数据 // 获取上传的附件数据
getAffixs(affix) { getAffixs(affix) {
getAffixItems({ getAffixItems({
affixId: affix affixId: affix
}).then(file => { }).then(file => {
this.affixFiles = file.data; this.affixFiles = file.data;
}) })
}, },
submitForm(status) { submitForm(status) {
// 定义英文字段名和中文提示的映射关系 // 定义英文字段名和中文提示的映射关系
@@ -1189,6 +1215,36 @@
return; return;
} }
// 定义手机号正则表达式11位数字以1开头
const phoneReg = /^1[3-9]\d{9}$/;
// 校验学生手机号码格式
if (!phoneReg.test(this.form.studentPhone)) {
uni.showToast({
title: '请填写正确的手机号码',
icon: 'none'
});
return;
}
// 校验家长手机号码
if (!phoneReg.test(this.form.parentPhone)) {
uni.showToast({
title: '请填写正确的家长手机号码',
icon: 'none'
});
return;
}
// 校验紧急联系人电话
if (!phoneReg.test(this.form.emergencyPhone)) {
uni.showToast({
title: '请填写正确的紧急联系电话',
icon: 'none'
});
return;
}
if (!this.form.studentSignature) { if (!this.form.studentSignature) {
uni.showToast({ uni.showToast({
title: '请完成电子签名', title: '请完成电子签名',
@@ -1245,11 +1301,11 @@
addOutsideAccommodationApply(submitForm); addOutsideAccommodationApply(submitForm);
requestPromise.then((response) => { requestPromise.then((response) => {
if (this.affixFiles.length > 0) { if (this.reasonFileList.length > 0) {
this.affixFiles.forEach(item => { this.reasonFileList.forEach(item => {
item.applyId = this.form.id || response.data.id; item.applyId = this.form.id || response.data.id;
}); });
batchAddOutsideAccommodationAttachment(this.affixFiles); batchAddOutsideAccommodationAttachment(this.reasonFileList);
} }
uni.showToast({ uni.showToast({
@@ -1378,6 +1434,10 @@
width: 100%; width: 100%;
background-color: #fff; background-color: #fff;
border-bottom: 1px solid #e8eaec; border-bottom: 1px solid #e8eaec;
position: fixed;
left: 0;
right: 0;
z-index: 100;
} }
.tabs-header { .tabs-header {
@@ -1597,7 +1657,7 @@
.area-picker:active { .area-picker:active {
border-color: #409EFF; border-color: #409EFF;
} }
/* 新增:禁用状态样式(可选) */ /* 新增:禁用状态样式(可选) */
.area-picker.disabled { .area-picker.disabled {
opacity: 0.7; opacity: 0.7;

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="app-container"> <view>
<!-- 搜索区仅非学生角色显示 --> <!-- 搜索区仅非学生角色显示 -->
<view class="fixed-search-wrap" v-if="roleGroup != '学生'"> <view class="fixed-search-wrap" id="search" v-if="roleGroup != '学生'">
<view class="search-content"> <view class="search-content">
<view class="search-card"> <view class="search-card">
<!-- 姓名搜索输入框 --> <!-- 姓名搜索输入框 -->
@@ -44,151 +44,153 @@
</view> </view>
</view> </view>
</view> </view>
<view class="app-container">
<!-- 数据列表滚动容器 --> <!-- 数据列表滚动容器 -->
<scroll-view class="list-container" scroll-y @scrolltolower="handleLoadMore" lower-threshold="50" enhanced <scroll-view class="list-container" id="list-container" scroll-y @scrolltolower="handleLoadMore"
:show-scrollbar="false"> lower-threshold="50" enhanced :show-scrollbar="false">
<!-- 初始加载状态 --> <!-- 初始加载状态 -->
<uni-load-more :status="loading ? 'loading' : 'done'" v-if="loading" class="loading-wrap"></uni-load-more> <uni-load-more :status="loading ? 'loading' : 'done'" v-if="loading" class="loading-wrap"></uni-load-more>
<!-- 空数据状态 --> <!-- 空数据状态 -->
<view class="empty-state" v-if="!loading && !hasData"> <view class="empty-state" v-if="!loading && !hasData">
<uni-icons type="empty" size="80" color="#c0c4cc"></uni-icons> <uni-icons type="empty" size="80" color="#c0c4cc"></uni-icons>
<text class="empty-text">暂无外宿申请数据</text> <text class="empty-text">暂无外宿申请数据</text>
<text class="empty-tip" v-if="roleGroup.includes('学生')">点击右下角"+"按钮提交新申请</text> <text class="empty-tip" v-if="roleGroup.includes('学生')">点击右下角"+"按钮提交新申请</text>
</view> </view>
<!-- 数据列表 --> <!-- 数据列表 -->
<view class="card-list" v-if="!loading && hasData"> <view class="card-list" v-if="!loading && hasData">
<view class="apply-card" v-for="(item, index) in validDataList" :key="index" hover-class="card-hover" <view class="apply-card" v-for="(item, index) in validDataList" :key="index" hover-class="card-hover"
:hover-stop-propagation="true"> :hover-stop-propagation="true">
<!-- 卡片头部 --> <!-- 卡片头部 -->
<view class="card-header"> <view class="card-header">
<view class="apply-no"> <view class="apply-no">
<text class="label-text">申请编号</text> <text class="label-text">申请编号</text>
<text class="no-text">{{ getSafeValue(item, 'applyNo', '无') }}</text> <text class="no-text">{{ getSafeValue(item, 'applyNo', '无') }}</text>
</view>
<view class="status-wrap">
<view class="status-label" :class="getStatusClass(item)">
{{ getStatusText(item) }}
</view> </view>
<view class="valid-label" <view class="status-wrap">
:class="getSafeValue(item, 'isValid') == 1 ? 'valid-success' : 'valid-info'"> <view class="status-label" :class="getStatusClass(item)">
{{ getSafeValue(item, 'isValid') == 1 ? '有效' : '到期' }} {{ getStatusText(item) }}
</view>
<view class="valid-label"
:class="getSafeValue(item, 'isValid') == 1 ? 'valid-success' : 'valid-info'">
{{ getSafeValue(item, 'isValid') == 1 ? '有效' : '到期' }}
</view>
</view> </view>
</view> </view>
</view>
<!-- 卡片主体折叠面板 -->
<!-- 卡片主体折叠面板 --> <uni-collapse accordion v-model="item.activeCollapse">
<uni-collapse accordion v-model="item.activeCollapse"> <uni-collapse-item title="基本信息" name="basic" class="collapse-item">
<uni-collapse-item title="基本信息" name="basic" class="collapse-item"> <view class="info-grid">
<view class="info-grid"> <view class="info-item"><text class="label">学号</text><text
<view class="info-item"><text class="label">学号</text><text class="value">{{ getSafeValue(item, 'studentNo', '-') }}</text></view>
class="value">{{ getSafeValue(item, 'studentNo', '-') }}</text></view> <view class="info-item"><text class="label">姓名</text><text
<view class="info-item"><text class="label">姓名</text><text class="value">{{ getSafeValue(item, 'studentName', '-') }}</text></view>
class="value">{{ getSafeValue(item, 'studentName', '-') }}</text></view> <view class="info-item"><text class="label">性别</text><text
<view class="info-item"><text class="label">性别</text><text class="value">{{ getSafeValue(item, 'gender') == 1 ? '男' : getSafeValue(item, 'gender') == 0 ? '女' : '-' }}</text>
class="value">{{ getSafeValue(item, 'gender') == 1 ? '男' : getSafeValue(item, 'gender') == 0 ? '女' : '-' }}</text> </view>
<view class="info-item"><text class="label">出生年月</text><text
class="value">{{ parseTime(getSafeValue(item, 'birthDate')) || '-' }}</text>
</view>
<view class="info-item"><text class="label">学院</text><text
class="value">{{ getSafeValue(item, 'deptName', '-') }}</text></view>
<view class="info-item"><text class="label">专业</text><text
class="value">{{ getSafeValue(item, 'majorName', '-') }}</text></view>
<view class="info-item"><text class="label">班级</text><text
class="value">{{ getSafeValue(item, 'className', '-') }}</text></view>
<view class="info-item"><text class="label">辅导员</text><text
class="value">{{ getSafeValue(item, 'teacherName', '-') }}</text></view>
<view class="info-item"><text class="label">原宿舍号</text><text
class="value">{{ getSafeValue(item, 'originalDormitory', '-') }}</text></view>
<view class="info-item">
<text class="label">住宿费状态</text>
<text class="value">
<view class="fee-label"
:class="getSafeValue(item, 'accommodationFeeStatus') === 1 ? 'fee-success' : 'fee-info'">
{{ getSafeValue(item, 'accommodationFeeStatus') === 1 ? '已交' : '未交' }}
</view>
</text>
</view>
<view class="info-item"><text class="label">宿费交纳</text><text
class="value">{{ getSafeValue(item, 'accommodationFee', '-') }}</text></view>
</view> </view>
<view class="info-item"><text class="label">出生年月</text><text </uni-collapse-item>
class="value">{{ parseTime(getSafeValue(item, 'birthDate')) || '-' }}</text>
<uni-collapse-item title="外宿信息" name="outside" class="collapse-item">
<view class="info-form">
<view class="form-item"><text class="label">外宿原因</text><text
class="value">{{ getSafeValue(item, 'applyReason', '-') }}</text></view>
<view class="form-item"><text class="label">外宿地址</text><text
class="value">{{ (getSafeValue(item, 'address', '') + ' ' + getSafeValue(item, 'outsideAddress', '')) || '-' }}</text>
</view>
<view class="form-item">
<text class="label">外宿时间</text>
<text class="value">{{ parseTime(getSafeValue(item, 'startDate')) || '-' }}
<text class="split-text"></text>
{{ parseTime(getSafeValue(item, 'endDate')) || '-' }}
</text>
</view>
<view class="form-item"><text class="label">紧急联系人</text><text
class="value">{{ getSafeValue(item, 'emergencyContact', '-') }}
({{ getSafeValue(item, 'emergencyPhone', '-') }})</text></view>
<view class="form-item"><text class="label">家长意见</text><text
class="value">{{ getSafeValue(item, 'parentOpinion') == 1 ? '同意' : getSafeValue(item, 'parentOpinion') == 0 ? '不同意' : '-' }}</text>
</view>
<view class="form-item"><text class="label">家长联系方式</text><text
class="value">{{ getSafeValue(item, 'parentPhone', '-') }}</text></view>
</view> </view>
<view class="info-item"><text class="label">学院</text><text </uni-collapse-item>
class="value">{{ getSafeValue(item, 'deptName', '-') }}</text></view>
<view class="info-item"><text class="label">专业</text><text <uni-collapse-item title="审批记录" name="approval" class="collapse-item">
class="value">{{ getSafeValue(item, 'majorName', '-') }}</text></view> <view class="approval-list"
<view class="info-item"><text class="label">班级</text><text v-if="getSafeValue(item, 'outsideAccommodationApprovals', []).length > 0">
class="value">{{ getSafeValue(item, 'className', '-') }}</text></view> <view class="approval-item"
<view class="info-item"><text class="label">辅导员</text><text v-for="(approval, idx) in getSafeValue(item, 'outsideAccommodationApprovals', [])"
class="value">{{ getSafeValue(item, 'teacherName', '-') }}</text></view> :key="idx">
<view class="info-item"><text class="label">原宿舍号</text><text <text
class="value">{{ getSafeValue(item, 'originalDormitory', '-') }}</text></view> class="approval-node">{{ getSafeValue(approval, 'approvalNode', '未知节点') }}</text>
<view class="info-item"> <text class="approval-result"
<text class="label">住宿费状态</text> :class="getSafeValue(approval, 'approvalResult') == 1 ? 'result-pass' : 'result-reject'">
<text class="value"> {{ getSafeValue(approval, 'approvalResult') == 1 ? '通过' : '驳回' }}
<view class="fee-label" </text>
:class="getSafeValue(item, 'accommodationFeeStatus') === 1 ? 'fee-success' : 'fee-info'"> <text class="approval-time"
{{ getSafeValue(item, 'accommodationFeeStatus') === 1 ? '已交' : '未交' }} v-if="getSafeValue(approval, 'approvalTime')">{{ parseTime(getSafeValue(approval, 'approvalTime')) }}</text>
</view> <text class="approval-remark"
</text> v-if="getSafeValue(approval, 'approvalRemark')">备注{{ getSafeValue(approval, 'approvalRemark') }}</text>
</view>
</view> </view>
<view class="info-item"><text class="label">宿费交纳</text><text <view class="empty-approval" v-else>暂无审批记录</view>
class="value">{{ getSafeValue(item, 'accommodationFee', '-') }}</text></view> </uni-collapse-item>
</uni-collapse>
<!-- 卡片操作区 -->
<view class="card-actions">
<view>
<uni-button type="text" size="mini" @click="detail(item, '修改')"
v-if="item.status == 0 || getRejectInfo(item.outsideAccommodationApprovals).isReject">
<uni-icons type="eye-filled" size="14" class="mr-5"></uni-icons>修改
</uni-button>
</view> </view>
</uni-collapse-item> <view>
<uni-button type="text" size="mini" @click="detail(item, '详情')" class="detail-btn"
<uni-collapse-item title="外宿信息" name="outside" class="collapse-item"> :disabled="!getSafeValue(item, 'id')">
<view class="info-form"> <uni-icons type="info" size="14" class="mr-5"></uni-icons>查看详情
<view class="form-item"><text class="label">外宿原因</text><text </uni-button>
class="value">{{ getSafeValue(item, 'applyReason', '-') }}</text></view>
<view class="form-item"><text class="label">外宿地址</text><text
class="value">{{ (getSafeValue(item, 'address', '') + ' ' + getSafeValue(item, 'outsideAddress', '')) || '-' }}</text>
</view>
<view class="form-item">
<text class="label">外宿时间</text>
<text class="value">{{ parseTime(getSafeValue(item, 'startDate')) || '-' }}
<text class="split-text"></text>
{{ parseTime(getSafeValue(item, 'endDate')) || '-' }}
</text>
</view>
<view class="form-item"><text class="label">紧急联系人</text><text
class="value">{{ getSafeValue(item, 'emergencyContact', '-') }}
({{ getSafeValue(item, 'emergencyPhone', '-') }})</text></view>
<view class="form-item"><text class="label">家长意见</text><text
class="value">{{ getSafeValue(item, 'parentOpinion') == 1 ? '同意' : getSafeValue(item, 'parentOpinion') == 0 ? '不同意' : '-' }}</text>
</view>
<view class="form-item"><text class="label">家长联系方式</text><text
class="value">{{ getSafeValue(item, 'parentPhone', '-') }}</text></view>
</view> </view>
</uni-collapse-item>
<uni-collapse-item title="审批记录" name="approval" class="collapse-item">
<view class="approval-list"
v-if="getSafeValue(item, 'outsideAccommodationApprovals', []).length > 0">
<view class="approval-item"
v-for="(approval, idx) in getSafeValue(item, 'outsideAccommodationApprovals', [])"
:key="idx">
<text
class="approval-node">{{ getSafeValue(approval, 'approvalNode', '未知节点') }}</text>
<text class="approval-result"
:class="getSafeValue(approval, 'approvalResult') == 1 ? 'result-pass' : 'result-reject'">
{{ getSafeValue(approval, 'approvalResult') == 1 ? '通过' : '驳回' }}
</text>
<text class="approval-time"
v-if="getSafeValue(approval, 'approvalTime')">{{ parseTime(getSafeValue(approval, 'approvalTime')) }}</text>
<text class="approval-remark"
v-if="getSafeValue(approval, 'approvalRemark')">备注{{ getSafeValue(approval, 'approvalRemark') }}</text>
</view>
</view>
<view class="empty-approval" v-else>暂无审批记录</view>
</uni-collapse-item>
</uni-collapse>
<!-- 卡片操作区 -->
<view class="card-actions">
<view>
<uni-button type="text" size="mini" @click="detail(item, '修改')" v-if="item.status == 0 || getRejectInfo(item.outsideAccommodationApprovals).isReject">
<uni-icons type="eye-filled" size="14" class="mr-5"></uni-icons>修改
</uni-button>
</view>
<view>
<uni-button type="text" size="mini" @click="detail(item, '详情')" class="detail-btn"
:disabled="!getSafeValue(item, 'id')">
<uni-icons type="info" size="14" class="mr-5"></uni-icons>查看详情
</uni-button>
</view> </view>
</view> </view>
</view> </view>
</view>
<!-- 加载更多状态 -->
<!-- 加载更多状态 --> <view class="load-more-wrap" v-if="hasData">
<view class="load-more-wrap" v-if="hasData"> <uni-load-more :status="loadingMore ? 'loading' : (hasMore ? 'more' : 'nomore')"
<uni-load-more :status="loadingMore ? 'loading' : (hasMore ? 'more' : 'nomore')" :content-text="loadMoreText"></uni-load-more>
:content-text="loadMoreText"></uni-load-more> </view>
</view> </scroll-view>
</scroll-view> </view>
<!-- 添加外宿申请按钮 --> <!-- 添加外宿申请按钮 -->
<view class="add" @click="addOutsideAccommodation">+</view> <view class="add" @click="addOutsideAccommodation" v-if="roleGroup == '学生'">+</view>
</view> </view>
</template> </template>
@@ -379,21 +381,32 @@
}); });
}); });
}, },
// 计算列表内容顶部外边距
setList() {
// 获取搜索框元素高度
let search = document.getElementById("search")
// 获取列表内容元素
let listContainer = document.getElementById("list-container")
// 设置列表内容的顶部外边距,让内容不被搜索框遮挡
listContainer.style.marginTop = `${search.offsetHeight}px`
},
/** 获取用户信息 */ /** 获取用户信息 */
getUser() { getUser() {
getUserProfile().then(response => { getUserProfile().then(response => {
const res = response || {}; const res = response || {};
this.user = res.data || {}; this.user = res.data || {};
this.roleGroup = res.roleGroup || ''; this.roleGroup = res.roleGroup || '';
// 填充查询条件 // 填充查询条件
if (this.roleGroup.includes("学生")) { if (this.roleGroup.includes("学生")) {
this.queryParams.studentName = this.user.nickName || ''; this.queryParams.studentName = this.user.nickName || '';
} else if (this.roleGroup.includes("辅导员")) { } else if (this.roleGroup.includes("辅导员")) {
this.queryParams.teacherName = this.user.nickName || ''; this.queryParams.teacherName = this.user.nickName || '';
this.setList()
} else if (this.roleGroup.includes("二级学院")) { } else if (this.roleGroup.includes("二级学院")) {
this.queryParams.deptName = this.user.dept?.deptName || ''; this.queryParams.deptName = this.user.dept?.deptName || '';
this.setList()
} else {
this.setList()
} }
this.getList(true); this.getList(true);
@@ -506,6 +519,8 @@
padding: 20rpx; padding: 20rpx;
background-color: #f5f7fa; background-color: #f5f7fa;
min-height: 100vh; min-height: 100vh;
width: 100%;
box-sizing: border-box;
} }
.mr-5 { .mr-5 {
@@ -517,7 +532,9 @@
z-index: 90; z-index: 90;
background-color: #fff; background-color: #fff;
border-bottom: 1px solid #eee; border-bottom: 1px solid #eee;
margin-bottom: 15rpx; position: fixed;
left: 0;
right: 0;
} }
.search-content { .search-content {
@@ -616,7 +633,7 @@
/* 列表滚动容器 */ /* 列表滚动容器 */
.list-container { .list-container {
width: 100%; width: 100%;
height: calc(100vh - 380rpx); height: calc(100vh - 100rpx);
overflow-y: auto; overflow-y: auto;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
} }
@@ -794,7 +811,8 @@
} }
.info-grid .info-item { .info-grid .info-item {
width: calc(50% - 10rpx); /* width: calc(50% - 10rpx); */
width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 26rpx; font-size: 26rpx;
@@ -913,7 +931,7 @@
} }
/* 适配小屏幕 */ /* 适配小屏幕 */
@media (max-width: 750rpx) { @media (max-width: 650rpx) {
.info-grid .info-item { .info-grid .info-item {
width: 100%; width: 100%;
} }
@@ -929,7 +947,7 @@
} }
.list-container { .list-container {
height: calc(100vh - 420rpx); /* height: calc(100vh - 420rpx); */
} }
} }
</style> </style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB