This commit is contained in:
zlwu committed 2025-08-11 14:58:49 +08:00
1 parent d634846222
commit 866b510125
9 files changed
+392 -58

No files matched your search

@@ -6,8 +6,9 @@
:custom-style="{
width: '95vw',
height: '85vh',
maxWidth: '800px',
maxHeight: '700px',
maxWidth: '95vw',
maxHeight: '85vh',
overflow: 'auto',
}"
@close="handleClose"
>
+113 -29
View File
@@ -7,7 +7,7 @@
height="90%"
border-radius="12"
@close="cancel"
:custom-style="{ width: '90vw' }"
:custom-style="{ width: '90vw', maxHeight: '90vh', overflow: 'auto' }"
>
<view class="submit-verify-container">
<view class="header">
@@ -248,33 +248,37 @@
width="80%"
height="70%"
border-radius="12"
@close="backVisible = false"
z-index="20080"
@close="closeBackDialog"
:custom-style="{ width: '90vw' }"
>
<view class="back-container">
<view class="header">
<text class="title">驳回</text>
<u-icon name="close" size="24" @click="backVisible = false" />
<u-icon name="close" size="24" @click="closeBackDialog" />
</view>
<scroll-view scroll-y class="content" :show-scrollbar="false">
<!-- 驳回节点 -->
<view class="form-item">
<text class="label">驳回节点</text>
<u-picker
v-model="backForm.nodeCode"
mode="selector"
:range="taskNodeList"
range-key="nodeName"
@change="handleBackNodeChange"
>
<u-input
v-model="selectedBackNodeName"
placeholder="请选择驳回节点"
readonly
suffix-icon="arrow-down"
/>
</u-picker>
<view class="form-item horizontal-item">
<text class="label horizontal-label">驳回节点</text>
<view class="horizontal-control">
<u-picker
:columns="[taskNodeList]"
keyName="nodeName"
:defaultIndex="[selectedBackNodeIndex]"
:show="showBackNodePicker"
:closeOnClickOverlay="true"
@confirm="onBackNodeConfirm"
@cancel="onBackNodeClose"
></u-picker>
<view class="picker-input" @click="showBackNodePicker = true">
<text class="picker-text">
{{ selectedBackNodeName || '请选择驳回节点' }}
</text>
<u-icon name="arrow-down" size="16" color="#c0c4cc"></u-icon>
</view>
</view>
</view>
<!-- 消息提醒 -->
@@ -342,7 +346,7 @@
</u-button>
<u-button
type="info"
@click="backVisible = false"
@click="closeBackDialog"
class="action-btn cancel-btn"
>
取消
@@ -359,6 +363,7 @@
width="90%"
height="60%"
border-radius="12"
z-index="20080"
@close="deleteSignatureVisible = false"
>
<view class="delete-signature-container">
@@ -425,6 +430,8 @@ export default {
backButtonDisabled: true,
taskNodeList: [],
selectedBackNodeName: '',
selectedBackNodeIndex: 0,
showBackNodePicker: false,
nickName: {},
nodeCode: '',
buttonObj: {
@@ -650,6 +657,7 @@ export default {
this.backLoading = false;
this.backButtonDisabled = false;
if (this.taskNodeList.length > 0) {
this.selectedBackNodeIndex = 0;
this.backForm.nodeCode = this.taskNodeList[0].nodeCode;
this.selectedBackNodeName = this.taskNodeList[0].nodeName;
}
@@ -663,11 +671,26 @@ export default {
}
},
// 退回节点变化
handleBackNodeChange(e) {
const index = e.detail.value;
this.backForm.nodeCode = this.taskNodeList[index].nodeCode;
this.selectedBackNodeName = this.taskNodeList[index].nodeName;
// 确认选择驳回节点
onBackNodeConfirm(e) {
const { indexs, value } = e;
this.selectedBackNodeIndex = indexs[0];
this.backForm.nodeCode = value[0].nodeCode;
this.selectedBackNodeName = value[0].nodeName;
this.showBackNodePicker = false;
},
// 取消选择驳回节点
onBackNodeClose() {
this.showBackNodePicker = false;
},
// 关闭退回弹窗
closeBackDialog() {
this.backVisible = false;
this.showBackNodePicker = false;
this.selectedBackNodeIndex = 0;
this.selectedBackNodeName = '';
},
// 退回流程
@@ -689,7 +712,7 @@ export default {
if (response.code === 200) {
this.visible = false;
this.backVisible = false;
this.closeBackDialog();
this.$emit('submitCallback');
uni.showToast({
title: '操作成功',
@@ -1055,21 +1078,30 @@ export default {
// 显示确认对话框
showConfirm(content) {
return new Promise((resolve) => {
// 临时隐藏主弹窗,避免层级冲突
// 临时隐藏所有弹窗,避免层级冲突
const originalVisible = this.visible;
const originalBackVisible = this.backVisible;
const originalDeleteSignatureVisible = this.deleteSignatureVisible;
this.visible = false;
this.backVisible = false;
this.deleteSignatureVisible = false;
uni.showModal({
title: '提示',
content,
success: (res) => {
// 恢复主弹窗显示状态
// 恢复所有弹窗显示状态
this.visible = originalVisible;
this.backVisible = originalBackVisible;
this.deleteSignatureVisible = originalDeleteSignatureVisible;
resolve(res);
},
fail: () => {
// 恢复主弹窗显示状态
// 恢复所有弹窗显示状态
this.visible = originalVisible;
this.backVisible = originalBackVisible;
this.deleteSignatureVisible = originalDeleteSignatureVisible;
resolve({ confirm: false });
},
});
@@ -1146,6 +1178,12 @@ export default {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
max-height: 200rpx;
overflow-y: auto;
padding: 8rpx;
border: 1rpx solid #e6e6e6;
border-radius: 8rpx;
background-color: #fafafa;
}
.copy-tag {
@@ -1300,4 +1338,50 @@ export default {
padding: 0 24rpx;
font-size: 24rpx;
}
.picker-input {
display: flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
padding: 0 24rpx;
background-color: #f8f9fa;
border: 1rpx solid #e6e6e6;
border-radius: 8rpx;
cursor: pointer;
}
.picker-input:active {
background-color: #f0f0f0;
}
.picker-text {
flex: 1;
font-size: 28rpx;
color: #333;
}
.picker-text:empty::before {
content: attr(placeholder);
color: #999;
}
.horizontal-item {
display: flex;
align-items: center;
gap: 20rpx;
}
.horizontal-label {
flex-shrink: 0;
}
.horizontal-control {
flex: 1;
width: 100%;
}
.horizontal-control .picker-input {
width: 80% !important;
}
</style>
+27 -11
View File
@@ -6,7 +6,7 @@
height="85%"
border-radius="12"
@close="close"
:custom-style="{ width: '90vw' }"
:custom-style="{ width: '90vw', maxHeight: '90vh', overflow: 'auto' }"
>
<view class="user-select-container">
<!-- 标题栏 -->
@@ -34,7 +34,11 @@
<u-search
v-model="searchKeyword"
placeholder="请输入用户名称或手机号"
:show-action="true"
action-text="搜索"
:animation="true"
@search="handleSearch"
@custom="handleSearch"
@clear="handleSearch"
bg-color="#f5f5f5"
/>
@@ -171,7 +175,7 @@ export default {
// 初始化数据
async initData() {
try {
await this.getDeptList();
// await this.getDeptList();
await this.getUserList();
await this.initSelectUser();
} catch (error) {
@@ -223,6 +227,8 @@ export default {
this.loadStatus = 'loading';
}
this.queryParams.status = 0;
try {
// 设置查询参数
this.queryParams.userIds = this.userIds;
@@ -232,22 +238,24 @@ export default {
this.queryParams.userName = '';
} else {
this.queryParams.userName = this.searchKeyword;
this.queryParams.nickName = this.searchKeyword;
this.queryParams.phonenumber = '';
}
} else {
this.queryParams.userName = '';
this.queryParams.phonenumber = '';
this.queryParams.nickName = '';
}
// 设置部门ID
if (this.currentDeptIndex > 0) {
this.queryParams.deptId = this.deptList[this.currentDeptIndex].value;
} else {
this.queryParams.deptId = '';
}
// if (this.currentDeptIndex > 0) {
// this.queryParams.deptId = this.deptList[this.currentDeptIndex].value;
// } else {
// this.queryParams.deptId = '';
// }
const response = await request({
url: '/system/user/list',
url: '/system/user/listByOr',
method: 'GET',
data: this.queryParams,
});
@@ -290,6 +298,7 @@ export default {
// 搜索处理
handleSearch() {
console.log('执行到此-------------------');
this.getUserList();
},
@@ -364,14 +373,15 @@ export default {
// 初始化已选用户
async initSelectUser() {
console.log('this.data:', this.data);
if (this.data) {
const userIds = this.computedIds(this.data);
if (userIds.length > 0) {
try {
const response = await request({
url: '/system/user/optionselect',
method: 'POST',
data: userIds,
url: '/system/user/optionselect?userIds=' + userIds,
method: 'GET',
// data: userIds,
});
if (response.code === 200) {
@@ -441,10 +451,16 @@ export default {
border-bottom: 1rpx solid #f0f0f0;
max-height: 200rpx;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
align-items: center;
}
.user-tag {
margin: 8rpx 16rpx 8rpx 0;
display: inline-block;
width: auto;
flex-shrink: 0;
}
.search-section {
+2 -1
View File
@@ -76,6 +76,7 @@
</view>
</template>
<GridLayout :columns="3" gap="16px">
<!-- 卡片开始 -->
<ServiceItem
v-if="hasPermi(['student:info:list'])"
title="学生信息"
@@ -89,7 +90,7 @@
/>
</template>
</ServiceItem>
<!-- 卡片结束 -->
<ServiceItem
v-if="hasPermi(['student:dorm:list'])"
title="宿舍管理"
+110 -10
View File
@@ -158,7 +158,7 @@
style="height: 60rpx !important"
></u-search>
<scroll-view scroll-y class="user-list">
<scroll-view scroll-y class="user-list" @scrolltolower="loadMoreUsers">
<view
v-for="user in userList"
:key="user.userId"
@@ -178,6 +178,18 @@
@click.stop
></u-checkbox>
</view>
<!-- 用户列表加载更多 -->
<u-loadmore
v-if="userList.length > 0"
:status="userLoadmoreStatus"
:load-text="{
loadmore: '轻轻上拉',
loading: '努力加载中',
nomore: '没有更多了',
}"
@loadmore="loadMoreUsers"
></u-loadmore>
</scroll-view>
</view>
@@ -224,6 +236,15 @@ export default {
userList: [], // 用户列表
userSearchKeyword: '', // 用户搜索关键词
userSearchTimer: null, // 搜索防抖定时器
// 用户列表分页参数
userListParams: {
pageNum: 1,
pageSize: 20,
total: 0,
},
userListLoading: false, // 用户列表加载状态
userLoadmoreStatus: 'loadmore', // 用户列表加载更多状态
};
},
@@ -459,6 +480,11 @@ export default {
// 打开申请人选择
openUserSelect() {
this.userSelectDialog.visible = true;
// 重置分页数据
this.userListParams.pageNum = 1;
this.userListParams.total = 0;
this.userLoadmoreStatus = 'loadmore';
this.userSearchKeyword = '';
this.loadUserList();
},
@@ -466,6 +492,10 @@ export default {
cancelUserSelect() {
this.userSelectDialog.visible = false;
this.userSearchKeyword = '';
// 重置用户列表分页数据
this.userListParams.pageNum = 1;
this.userListParams.total = 0;
this.userLoadmoreStatus = 'loadmore';
},
// 确认申请人选择
@@ -505,40 +535,90 @@ export default {
},
// 加载用户列表
async loadUserList() {
async loadUserList(isLoadMore = false) {
if (!isLoadMore) {
this.userListLoading = true;
this.userListParams.pageNum = 1;
} else {
this.userLoadmoreStatus = 'loading';
}
try {
const res = await request({
url: '/system/user/list',
url: '/system/user/listByOr',
method: 'GET',
params: {
pageNum: 1,
pageSize: 100,
pageNum: this.userListParams.pageNum,
pageSize: this.userListParams.pageSize,
status: '0',
userName: this.userSearchKeyword || undefined,
nickName: this.userSearchKeyword || undefined,
},
});
if (res && res.code === 200) {
// 每次加载用户列表时,所有用户默认都不选中
this.userList = (res.rows || []).map((user) => ({
const newUsers = (res.rows || []).map((user) => ({
...user,
selected: false,
}));
console.log('加载用户列表完成,用户数量:', this.userList.length);
if (isLoadMore) {
// 加载更多,追加数据
this.userList = [...this.userList, ...newUsers];
// 判断是否还有更多数据
if (newUsers.length < this.userListParams.pageSize) {
this.userLoadmoreStatus = 'nomore';
} else {
this.userLoadmoreStatus = 'loadmore';
}
} else {
// 首次加载或搜索,替换数据
this.userList = newUsers;
this.userListParams.total = res.total || 0;
// 重置加载更多状态
if (this.userList.length >= this.userListParams.total) {
this.userLoadmoreStatus = 'nomore';
} else {
this.userLoadmoreStatus = 'loadmore';
}
}
console.log(
'加载用户列表完成,当前用户数量:',
this.userList.length,
'总数量:',
this.userListParams.total,
);
} else {
this.userList = [];
if (!isLoadMore) {
this.userList = [];
this.userListParams.total = 0;
}
uni.showToast({
title: res?.msg || '获取用户列表失败',
icon: 'none',
});
if (isLoadMore) {
this.userLoadmoreStatus = 'loadmore';
}
}
} catch (error) {
console.error('获取用户列表失败:', error);
this.userList = [];
if (!isLoadMore) {
this.userList = [];
this.userListParams.total = 0;
}
uni.showToast({
title: '获取用户列表失败',
icon: 'none',
});
if (isLoadMore) {
this.userLoadmoreStatus = 'loadmore';
}
} finally {
if (!isLoadMore) {
this.userListLoading = false;
}
}
},
@@ -549,10 +629,24 @@ export default {
}
this.userSearchTimer = setTimeout(() => {
// 搜索时重置分页数据
this.userListParams.pageNum = 1;
this.userListParams.total = 0;
this.userLoadmoreStatus = 'loadmore';
this.loadUserList();
}, 500);
},
// 加载更多用户
loadMoreUsers() {
if (this.userLoadmoreStatus === 'nomore' || this.userLoadmoreStatus === 'loading') {
return;
}
this.userListParams.pageNum++;
this.loadUserList(true);
},
// 获取头像显示文字(取前两个字符)
getAvatarText(nickName) {
if (!nickName) return '';
@@ -769,6 +863,12 @@ export default {
}
}
// 用户列表的loadmore样式
::v-deep .u-loadmore {
padding: 20rpx 0;
font-size: 24rpx;
}
.user-info {
display: flex;
align-items: center;
@@ -3050,7 +3050,15 @@ export default {
return false;
}
// 1. 校验是否需要上传地理位置
// 1. 校验请假时间
const startTime = new Date(this.form.startTime);
const endTime = new Date(this.form.endTime);
if (endTime.getTime() <= startTime.getTime()) {
uni.showToast({ title: '请假结束时间必须大于开始时间', icon: 'none' });
return false;
}
// 2. 校验是否需要上传地理位置
if (leaveType.needLocationOnApply === '1') {
if (!this.form.leaveLocation) {
uni.showToast({ title: '该请假类型需要上传地理位置', icon: 'none' });
@@ -3058,7 +3066,7 @@ export default {
}
}
// 2. 校验和设置销假状态
// 3. 校验和设置销假状态
if (leaveType.needCancelForNonLeave === '0' && this.form.isLeaveSchool === '0') {
// 非离校请假且该类型不需要销假时,自动设置为不需要销假
this.form.needCancel = '0';
@@ -3067,7 +3075,7 @@ export default {
this.form.needCancel = '1';
}
// 3. 校验是否可以提前请假
// 4. 校验是否可以提前请假
if (leaveType.canApplyInAdvance === '0') {
const now = new Date();
now.setHours(23, 59, 59, 999);
@@ -3078,7 +3086,7 @@ export default {
}
}
// 4. 校验最大申请时长
// 5. 校验最大申请时长
if (leaveType.maxApplyDuration && leaveType.maxApplyDuration > 0) {
const start = new Date(this.form.startTime);
const end = new Date(this.form.endTime);