Compare commits
14 Commits
9f20ebcec6
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28b7d7af64 | ||
|
|
909238d898 | ||
| 8fb02b0d5d | |||
| 8246da4f48 | |||
| 68c06f273b | |||
|
|
bc78f7d2dd | ||
|
|
b69ea9f172 | ||
| f6e4fb3781 | |||
| 27f1a36e56 | |||
|
|
5837100fa2 | ||
| 980e392611 | |||
|
|
1d2eaa6683 | ||
| b03b8ab6fc | |||
| d05cfe8c30 |
11
api/affix.js
11
api/affix.js
@@ -7,4 +7,15 @@ export function getAffixItems(data) {
|
||||
'method': 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除附件
|
||||
export function deleteAffix (fileId){
|
||||
return request(
|
||||
{
|
||||
url:'/affix/delete',
|
||||
method:'post',
|
||||
data:{id: fileId}
|
||||
}
|
||||
)
|
||||
}
|
||||
76
api/dms/outsideAccommodation/outsideAccommodationApply.js
Normal file
76
api/dms/outsideAccommodation/outsideAccommodationApply.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询外宿申请列表
|
||||
export function listOutsideAccommodationApply(query) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApply/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询外宿申请详细
|
||||
export function getOutsideAccommodationApply(id) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApply/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询外宿申请详细
|
||||
export function getOutsideAccommodationApplyByProcessInstanceId(processInstanceId) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApply/process/' + processInstanceId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增外宿申请
|
||||
export function addOutsideAccommodationApply(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/outsideAccommodationApply/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改外宿申请
|
||||
export function updateOutsideAccommodationApply(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/outsideAccommodationApply/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除外宿申请
|
||||
export function delOutsideAccommodationApply(id) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApply/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function getOwnInfo(){
|
||||
return request({
|
||||
url:'/comprehensive/stuInfoView/getOwnInfo',
|
||||
method:'GET'
|
||||
})
|
||||
}
|
||||
|
||||
// 查询宿舍学生关联列表
|
||||
export function listStudent(query) {
|
||||
return request({
|
||||
url: '/dormitory/srs-dormitory-student/checkInInformation',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学生住宿
|
||||
export function getOwnLog() {
|
||||
return request({
|
||||
url: '/dormitory/srs-dormitory-student/getOwnLog',
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
53
api/dms/outsideAccommodation/outsideAccommodationApproval.js
Normal file
53
api/dms/outsideAccommodation/outsideAccommodationApproval.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询外宿申请审批记录列表
|
||||
export function listOutsideAccommodationApproval(query) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApproval/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询外宿申请审批记录详细
|
||||
export function getOutsideAccommodationApproval(id) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApproval/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增外宿申请审批记录
|
||||
export function addOutsideAccommodationApproval(data) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApproval/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 新增或修改外宿申请审批记录
|
||||
export function addOrUpdateAccommodationApproval(data) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApproval/addOrUpdate',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改外宿申请审批记录
|
||||
export function updateOutsideAccommodationApproval(data) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApproval/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除外宿申请审批记录
|
||||
export function delOutsideAccommodationApproval(id) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationApproval/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询外宿申请附件列表
|
||||
export function listOutsideAccommodationAttachment(query) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationAttachment/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询外宿申请附件详细
|
||||
export function getOutsideAccommodationAttachment(id) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationAttachment/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增外宿申请附件
|
||||
export function addOutsideAccommodationAttachment(data) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationAttachment/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 批量外宿申请附件
|
||||
export function batchAddOutsideAccommodationAttachment(data) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationAttachment/batchAdd',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改外宿申请附件
|
||||
export function updateOutsideAccommodationAttachment(data) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationAttachment/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除外宿申请附件
|
||||
export function delOutsideAccommodationAttachment(id) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationAttachment/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 删除外宿申请附件
|
||||
export function deleteOutsideAccommodationAttachmentNameAndStuName(query) {
|
||||
return request({
|
||||
url: '/dormitory/outsideAccommodationAttachment/OutsideAccommodationAttachment',
|
||||
method: 'post',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
@@ -18,6 +18,23 @@ export function addStudent(data) {
|
||||
})
|
||||
}
|
||||
|
||||
// 根据关联表id查看详情
|
||||
export function getStudentDetail(id) {
|
||||
return request({
|
||||
url: `/dormitory/srs-dormitory-student/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改学生宿舍关联
|
||||
export function updateStudent(data) {
|
||||
return request({
|
||||
url: '/dormitory/srs-dormitory-student/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取校区
|
||||
export function listAllCampus() {
|
||||
return request({
|
||||
|
||||
71
api/routine/enlistmentReserve/enlistmentReserve.js
Normal file
71
api/routine/enlistmentReserve/enlistmentReserve.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询应征入伍保留学籍申请列表
|
||||
export function listEnlistmentReserve(query) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询应征入伍保留学籍申请详细
|
||||
export function getEnlistmentReserve(id) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 查询应征入伍保留学籍申请详细
|
||||
export function getEnlistmentReserveByProcessInstanceId(processInstanceId) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/process/' + processInstanceId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增应征入伍保留学籍申请
|
||||
export function addEnlistmentReserve(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改应征入伍保留学籍申请
|
||||
export function updateEnlistmentReserve(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除应征入伍保留学籍申请
|
||||
export function delEnlistmentReserve(id) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserve/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取学生信息
|
||||
export function getOwnInfo(){
|
||||
return request({
|
||||
url:'/comprehensive/stuInfoView/getOwnInfo',
|
||||
method:'GET'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改学生信息
|
||||
export function updateStudent(data) {
|
||||
return request({
|
||||
url: '/system/student/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
54
api/routine/enlistmentReserve/enlistmentReserveApproval.js
Normal file
54
api/routine/enlistmentReserve/enlistmentReserveApproval.js
Normal file
@@ -0,0 +1,54 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询保留学籍审批记录列表
|
||||
export function listEnlistmentReserveApproval(query) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveApproval/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询保留学籍审批记录详细
|
||||
export function getEnlistmentReserveApproval(id) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveApproval/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增保留学籍审批记录
|
||||
export function addEnlistmentReserveApproval(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveApproval/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改保留学籍审批记录
|
||||
export function updateEnlistmentReserveApproval(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveApproval/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除保留学籍审批记录
|
||||
export function delEnlistmentReserveApproval(id) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveApproval/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 新增保留学籍审批记录
|
||||
export function insertOrUpdateByStuAndApprover(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveApproval/insertOrUpdateByStuAndApprover',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
62
api/routine/enlistmentReserve/enlistmentReserveAttach.js
Normal file
62
api/routine/enlistmentReserve/enlistmentReserveAttach.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 查询保留学籍申请附件(入伍通知书等)列表
|
||||
export function listEnlistmentReserveAttach(query) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveAttach/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
|
||||
// 查询保留学籍申请附件(入伍通知书等)详细
|
||||
export function getEnlistmentReserveAttach(id) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveAttach/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 新增保留学籍申请附件(入伍通知书等)
|
||||
export function addEnlistmentReserveAttach(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveAttach/add',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 批量新增保留学籍申请附件(入伍通知书等)
|
||||
export function batchAddEnlistmentReserveAttach(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveAttach/batchAdd',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 修改保留学籍申请附件(入伍通知书等)
|
||||
export function updateEnlistmentReserveAttach(data) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveAttach/update',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除保留学籍申请附件(入伍通知书等)
|
||||
export function delEnlistmentReserveAttach(id) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveAttach/' + id,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
// 删除保留学籍申请附件(入伍通知书等)
|
||||
export function deleteRtEnlistmentReserveAttachByFileNameAndStuName(query) {
|
||||
return request({
|
||||
url: '/routine/enlistmentReserveAttach/deleteRtEnlistmentReserve',
|
||||
method: 'post',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
48
api/task.js
48
api/task.js
@@ -1,33 +1,33 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function myProcess(data){
|
||||
return request({
|
||||
'url': '/flowable/task/myProcess',
|
||||
'method': 'get',
|
||||
data
|
||||
})
|
||||
export function myProcess(params){
|
||||
return request({
|
||||
url: '/flowable/task/myProcess',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function todoList(data){
|
||||
return request({
|
||||
'url': '/flowable/task/todoList',
|
||||
'method': 'get',
|
||||
data
|
||||
})
|
||||
export function todoList(params){
|
||||
return request({
|
||||
url: '/flowable/task/todoList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function finishedList(data){
|
||||
return request({
|
||||
'url': '/flowable/task/finishedList',
|
||||
'method': 'get',
|
||||
data
|
||||
})
|
||||
export function finishedList(params){
|
||||
return request({
|
||||
url: '/flowable/task/finishedList',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
export function flowRecord(data){
|
||||
return request({
|
||||
'url': '/flowable/task/flowRecord',
|
||||
'method': 'get',
|
||||
data
|
||||
})
|
||||
export function flowRecord(params){
|
||||
return request({
|
||||
url: '/flowable/task/flowRecord',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
export function complete(data){
|
||||
return request({
|
||||
|
||||
10
config.js
10
config.js
@@ -1,8 +1,12 @@
|
||||
// 应用全局配置
|
||||
module.exports = {
|
||||
// 统一通过本机 Nginx 反向代理访问后端
|
||||
// 若在同一台机器调试:使用 localhost:8066
|
||||
// 若手机在同一局域网:替换为本机局域网 IP,例如 172.16.96.111:8066
|
||||
// 页面在 https://zhxg.gxsdxy.cn 下访问,接口同域同协议以避免 CORS
|
||||
// baseUrl: 'https://zhxg.gxsdxy.cn/prod_api',
|
||||
// baseUrl: 'http://172.16.96.111:8085',
|
||||
// baseUrl: 'http://192.168.211.22:8085',
|
||||
// baseUrl: 'https://zhxg.gxsdxy.cn/prod_api',
|
||||
// 若本地/内网以 HTTP 访问页面,可改为:
|
||||
baseUrl: 'http://localhost:8085',
|
||||
// 应用信息
|
||||
appInfo: {
|
||||
@@ -38,5 +42,5 @@ module.exports = {
|
||||
/**
|
||||
* 单点登出url
|
||||
*/
|
||||
caslogoutUrl: 'https://rsso.gxsdxy.cn/logout?service=http://zhxg.gxsdxy.cn/prod_api_test/getinfo',
|
||||
caslogoutUrl: 'http://rsso.gxsdxy.cn/logout?service=http://zhxg.gxsdxy.cn/prod_api_test/getinfo',
|
||||
}
|
||||
28
pages.json
28
pages.json
@@ -1194,6 +1194,34 @@
|
||||
"navigationBarBackgroundColor": "#1890FF",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/dormitory/outsideAccommodation/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "外宿申请",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarBackgroundColor": "#1890FF",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/dormitory/outsideAccommodation/applicationForm",
|
||||
"style": {
|
||||
"navigationBarTitleText": "外宿申请填写",
|
||||
"enablePullDownRefresh": false,
|
||||
"renderingMode": "mixed", // 强制混合渲染模式
|
||||
"navigationBarBackgroundColor": "#1890FF",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/Approval/handleTask/processHandling/detail",
|
||||
"style": {
|
||||
"navigationBarTitleText": "流程处理表单详细",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarBackgroundColor": "#1890FF",
|
||||
"navigationBarTextStyle": "white"
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
|
||||
@@ -0,0 +1,579 @@
|
||||
<template>
|
||||
<view class="con">
|
||||
<!-- 基础信息区域 -->
|
||||
<view class="form-section">
|
||||
<view class="card-header">
|
||||
<uni-icons type="contact" size="41" color="#409EFF"></uni-icons>
|
||||
<text class="section-title">基础信息</text>
|
||||
</view>
|
||||
|
||||
<!--学号 -->
|
||||
<view class="form-item">
|
||||
<text class="label">学号:</text>
|
||||
<text class="uni-input">{{ form.studentNo || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--姓名 -->
|
||||
<view class="form-item">
|
||||
<text class="label">姓名:</text>
|
||||
<text class="uni-input">{{ form.studentName || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 性别 -->
|
||||
<view class="form-item">
|
||||
<text class="label">性别:</text>
|
||||
<text class="uni-input">{{ form.gender == 1 ? '男' : form.gender == 0 ? '女' : '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--民族 -->
|
||||
<view class="form-item">
|
||||
<text class="label">民族:</text>
|
||||
<text class="uni-input">{{ form.nation || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--年级 -->
|
||||
<view class="form-item">
|
||||
<text class="label">年级:</text>
|
||||
<text class="uni-input">{{ form.grade || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--专业名称 -->
|
||||
<view class="form-item">
|
||||
<text class="label">专业名称:</text>
|
||||
<text class="uni-input">{{ form.major || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--班级 -->
|
||||
<view class="form-item">
|
||||
<text class="label">班级:</text>
|
||||
<text class="uni-input">{{ form.className || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--申请编号 -->
|
||||
<view class="form-item">
|
||||
<text class="label">申请编号:</text>
|
||||
<text class="uni-input">{{ form.applyNo || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--保留学籍编号 -->
|
||||
<view class="form-item">
|
||||
<text class="label">保留学籍编号:</text>
|
||||
<text class="uni-input">{{ form.reserveNo || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--辅导员 -->
|
||||
<view class="form-item">
|
||||
<text class="label">辅导员:</text>
|
||||
<text class="uni-input">{{ form.teacherName || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--家庭地址 -->
|
||||
<view class="form-item">
|
||||
<text class="label">家庭地址:</text>
|
||||
<text class="uni-input">{{ form.familyAddress || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--家长联系电话 -->
|
||||
<view class="form-item">
|
||||
<text class="label">家长联系电话:</text>
|
||||
<text class="uni-input">{{ form.parentPhone || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--申请原因 -->
|
||||
<view class="form-item form-item-auto">
|
||||
<text class="label">申请原因:</text>
|
||||
<text class="uni-input uni-input-text">{{ form.applyReason || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--申请状态 -->
|
||||
<view class="form-item">
|
||||
<text class="label">申请状态:</text>
|
||||
<view class="uni-input status-tag" :class="getStatusClass(form.applyStatus)" style="text-align: center;">
|
||||
{{ getStatusText(form.applyStatus) }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!--保留学籍开始时间 -->
|
||||
<view class="form-item">
|
||||
<text class="label" style="width: 250rpx;">保留学籍开始时间:</text>
|
||||
<text class="uni-input">{{ formatDate(form.reserveStartDate) || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--保留学籍结束时间 -->
|
||||
<view class="form-item">
|
||||
<text class="label" style="width: 250rpx;">保留学籍结束时间:</text>
|
||||
<text class="uni-input">{{ formatDate(form.reserveEndDate) || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!--审批编号 -->
|
||||
<view class="form-item">
|
||||
<text class="label">审批编号:</text>
|
||||
<text class="uni-input">{{ form.approvalNo || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 附件区域 -->
|
||||
<view class="form-section" v-if="form.enlistmentReserveAttachList && form.enlistmentReserveAttachList.length">
|
||||
<view class="card-header">
|
||||
<uni-icons type="folder-add-filled" size="41" color="#409EFF"></uni-icons>
|
||||
<text class="section-title">材料附件</text>
|
||||
</view>
|
||||
<view class="form-item form-item-auto">
|
||||
<text class="label">附件列表:</text>
|
||||
<view class="uni-input file-list">
|
||||
<view class="file-item" v-for="(file, index) in form.enlistmentReserveAttachList" :key="index" @click="previewFile(file, '附件')">
|
||||
<uni-icons type="paper" size="24" color="#0092FF"></uni-icons>
|
||||
<text class="file-name">{{ file.fileName || '-' }}</text>
|
||||
<text class="file-size">{{ formatFileSize(file.fileSize) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审批记录区域 -->
|
||||
<view class="form-section" v-if="form.enlistmentReserveApprovalList && form.enlistmentReserveApprovalList.length">
|
||||
<view class="card-header">
|
||||
<uni-icons type="calendar-filled" size="41" color="#409EFF"></uni-icons>
|
||||
<text class="section-title">审批记录</text>
|
||||
</view>
|
||||
<view class="approval-list">
|
||||
<view class="approval-item" v-for="(approval, index) in form.enlistmentReserveApprovalList" :key="index">
|
||||
<!-- 审批节点信息 -->
|
||||
<view class="approval-header">
|
||||
<text class="approval-node">{{ approval.nodeName || '-' }}</text>
|
||||
<view class="approval-result-tag" :class="getApprovalResultClass(approval.approvalResult)">
|
||||
{{ getApprovalResultText(approval.approvalResult) }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审批详情 -->
|
||||
<view class="approval-details">
|
||||
<view class="form-item mini">
|
||||
<text class="label">审批人:</text>
|
||||
<text class="uni-input">{{ approval.approverName || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item mini">
|
||||
<text class="label">审批时间:</text>
|
||||
<text class="uni-input">{{ formatDate(approval.approvalTime) || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item mini">
|
||||
<text class="label">审批意见:</text>
|
||||
<text class="uni-input">{{ approval.approvalOpinion || '-' }}</text>
|
||||
</view>
|
||||
<!-- 审批签名 -->
|
||||
<view class="form-item mini" v-if="approval.signature">
|
||||
<text class="label">审批签名:</text>
|
||||
<image class="signature-img" :src="baseUrl + approval.signature" mode="aspectFit" @click="previewFile(approval, '签名')"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空数据提示 -->
|
||||
<view class="empty-tip" v-if="isEmptyForm">
|
||||
<uni-icons type="empty" size="60" color="#c0c4cc"></uni-icons>
|
||||
<text class="empty-text">暂无相关数据</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from '@/config'
|
||||
export default {
|
||||
name: "enlistmentReserve",
|
||||
props: {
|
||||
// props类型定义(Object类型+默认空对象)
|
||||
form: {
|
||||
type: Object, // 正确的对象类型声明
|
||||
default: () => ({}) // 函数返回空对象(避免所有实例共享同一个对象)
|
||||
},
|
||||
isShow: { // 修正拼写错误:isShwo → isShow
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 图片基础路径
|
||||
baseUrl: config.baseUrl
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 判断是否为空表单
|
||||
isEmptyForm() {
|
||||
return !this.form.id && Object.keys(this.form).length === 0;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 格式化日期
|
||||
* @param {String} dateStr 日期字符串
|
||||
* @returns {String} 格式化后的日期
|
||||
*/
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
// 处理带时区的日期字符串
|
||||
const date = new Date(dateStr);
|
||||
if (isNaN(date.getTime())) return dateStr;
|
||||
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 格式化文件大小
|
||||
* @param {Number} size 字节数
|
||||
* @returns {String} 格式化后的大小
|
||||
*/
|
||||
formatFileSize(size) {
|
||||
if (!size) return '0B';
|
||||
if (size < 1024) return `${size}B`;
|
||||
if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)}KB`;
|
||||
return `${(size / (1024 * 1024)).toFixed(2)}MB`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取申请状态文本
|
||||
* @param {Number} status 状态码
|
||||
* @returns {String} 状态文本
|
||||
*/
|
||||
getStatusText(status) {
|
||||
const statusMap = {
|
||||
1: '待审批',
|
||||
2: '审批中',
|
||||
3: '已通过',
|
||||
4: '已驳回'
|
||||
};
|
||||
return statusMap[status] || '未知状态';
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取申请状态样式类
|
||||
* @param {Number} status 状态码
|
||||
* @returns {String} 样式类名
|
||||
*/
|
||||
getStatusClass(status) {
|
||||
const classMap = {
|
||||
1: 'status-pending',
|
||||
2: 'status-processing',
|
||||
3: 'status-success',
|
||||
4: 'status-reject'
|
||||
};
|
||||
return classMap[status] || 'status-default';
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取审批结果文本
|
||||
* @param {Number} result 审批结果码
|
||||
* @returns {String} 审批结果文本
|
||||
*/
|
||||
getApprovalResultText(result) {
|
||||
const resultMap = {
|
||||
1: '同意',
|
||||
2: '驳回',
|
||||
0: '待审批'
|
||||
};
|
||||
return resultMap[result] || '未知结果';
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取审批结果样式类
|
||||
* @param {Number} result 审批结果码
|
||||
* @returns {String} 样式类名
|
||||
*/
|
||||
getApprovalResultClass(result) {
|
||||
const classMap = {
|
||||
1: 'result-approve',
|
||||
2: 'result-reject',
|
||||
0: 'result-pending'
|
||||
};
|
||||
return classMap[result] || 'result-default';
|
||||
},
|
||||
|
||||
/**
|
||||
* 预览附件文件
|
||||
* @param {Object} file 文件对象
|
||||
*/
|
||||
previewFile(file, text) {
|
||||
if (text == '附件') {
|
||||
if (!file.filePath) {
|
||||
uni.showToast({
|
||||
title: '文件路径不存在',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
// 拼接完整文件路径
|
||||
const fullUrl = this.baseUrl + file.filePath;
|
||||
// 预览图片(如果是图片文件)
|
||||
if (['png', 'jpg', 'jpeg', 'gif', 'bmp'].includes(file.fileType)) {
|
||||
uni.previewImage({
|
||||
urls: [fullUrl],
|
||||
current: fullUrl
|
||||
});
|
||||
} else {
|
||||
// 非图片文件可做下载处理
|
||||
uni.showToast({
|
||||
title: '暂不支持预览该类型文件',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
uni.previewImage({
|
||||
urls: [this.baseUrl + file.signature],
|
||||
current: this.baseUrl + file.signature
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.con {
|
||||
padding: 20rpx;
|
||||
background-color: #f8f8f8;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 区域标题
|
||||
.form-section {
|
||||
background-color: #fff;
|
||||
border-radius: 10rpx;
|
||||
padding: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10rpx 0rpx;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-left: 12rpx;
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: 2px solid #f0f0f0;
|
||||
}
|
||||
}
|
||||
|
||||
// 表单项样式
|
||||
.form-item {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
/* 移除justify-content: space-between,改为靠左排列 */
|
||||
// justify-content: space-between;
|
||||
border-bottom: 1px solid #ededee;
|
||||
|
||||
&.form-item-auto {
|
||||
height: auto;
|
||||
min-height: 80rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
|
||||
&.mini {
|
||||
height: 60rpx;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
/* 关键修改:移除右对齐,改为左对齐 */
|
||||
// text-align: right;
|
||||
text-align: left;
|
||||
margin-right: 10rpx; /* 减小右边距,更紧凑 */
|
||||
text-wrap: nowrap;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
width: 200rpx;
|
||||
/* 标签固定宽度,内容靠左 */
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.uni-input {
|
||||
color: #666;
|
||||
/* 关键修改:移除右对齐,改为左对齐 */
|
||||
// text-align: right;
|
||||
text-align: left;
|
||||
font-size: 28rpx;
|
||||
flex: 1;
|
||||
|
||||
&.uni-input-text {
|
||||
/* 保持左对齐 */
|
||||
text-align: left;
|
||||
white-space: pre-wrap;
|
||||
line-height: 1.5;
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
// ========== 修复:将&嵌套到.uni-input内部 ==========
|
||||
&.status-tag {
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
/* 状态标签内文本靠左 */
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.status-pending {
|
||||
background-color: #fffbe6;
|
||||
color: #ff9a2e;
|
||||
}
|
||||
|
||||
&.status-processing {
|
||||
background-color: #e8f4fd;
|
||||
color: #0092ff;
|
||||
}
|
||||
|
||||
&.status-success {
|
||||
background-color: #f0f9eb;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.status-reject {
|
||||
background-color: #fff2f0;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
&.status-default {
|
||||
background-color: #f5f5f5;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
|
||||
// 附件列表样式
|
||||
.file-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.file-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10rpx 0;
|
||||
width: 100%;
|
||||
border-bottom: 1px dashed #eee;
|
||||
/* 附件项整体靠左 */
|
||||
justify-content: flex-start;
|
||||
|
||||
.file-name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
margin: 0 10rpx;
|
||||
flex: 1;
|
||||
/* 文件名靠左 */
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.file-size {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
/* 文件大小靠左 */
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
// 审批记录样式
|
||||
.approval-list {
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.approval-item {
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 8rpx;
|
||||
padding: 15rpx;
|
||||
margin-bottom: 15rpx;
|
||||
/* 审批项整体靠左 */
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.approval-header {
|
||||
display: flex;
|
||||
/* 审批头部改为靠左排列,结果标签在右侧 */
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
margin-bottom: 10rpx;
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: 1px dashed #eee;
|
||||
|
||||
.approval-node {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
/* 审批节点名靠左 */
|
||||
text-align: left;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
// ========== 修复:将&嵌套到.approval-header内部 ==========
|
||||
.approval-result-tag {
|
||||
padding: 6rpx 12rpx;
|
||||
border-radius: 15rpx;
|
||||
font-size: 24rpx;
|
||||
/* 审批结果标签内文本靠左 */
|
||||
text-align: left;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.approval-result-tag.result-approve {
|
||||
background-color: #f0f9eb;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.approval-result-tag.result-reject {
|
||||
background-color: #fff2f0;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
.approval-result-tag.result-pending {
|
||||
background-color: #fffbe6;
|
||||
color: #ff9a2e;
|
||||
}
|
||||
|
||||
.approval-result-tag.result-default {
|
||||
background-color: #f5f5f5;
|
||||
color: #888;
|
||||
}
|
||||
}
|
||||
|
||||
.approval-details {
|
||||
padding-top: 10rpx;
|
||||
/* 审批详情整体靠左 */
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
// 签名图片样式
|
||||
.signature-img {
|
||||
width: 120rpx;
|
||||
height: 60rpx;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 4rpx;
|
||||
/* 签名图片靠左 */
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// 空数据提示
|
||||
.empty-tip {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 100rpx 0;
|
||||
color: #c0c4cc;
|
||||
|
||||
.empty-text {
|
||||
margin-top: 20rpx;
|
||||
font-size: 28rpx;
|
||||
/* 空数据提示文本靠左 */
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,774 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 主内容区 -->
|
||||
<scroll-view class="content-scroll" scroll-y enhanced :show-scrollbar="false">
|
||||
<!-- 申请概览(顶部卡片) -->
|
||||
<view class="card overview-card">
|
||||
<view class="overview-header">
|
||||
<view class="overview-left">
|
||||
<text class="apply-no">申请编号:{{ form.applyNo || '-' }}</text>
|
||||
<text class="student-name">{{ form.studentName || '-' }} {{ form.studentNo || '-' }}</text>
|
||||
</view>
|
||||
<view class="status-tag" :class="getStatusClass(form.status)">
|
||||
{{ getStatusText(form.status) }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="overview-info">
|
||||
<view class="overview-item">
|
||||
<text class="info-label">申请时间</text>
|
||||
<text class="info-value">{{ formatDate(form.createTime) || '-' }}</text>
|
||||
</view>
|
||||
<view class="overview-item">
|
||||
<text class="info-label">外宿周期</text>
|
||||
<text class="info-value">{{ formatDate(form.startDate) || '-' }} 至 {{ formatDate(form.endDate) || '-' }}</text>
|
||||
</view>
|
||||
<view class="overview-item">
|
||||
<text class="info-label">状态有效性:</text>
|
||||
<text class="info-value" :class="form.isValid == 1 ? 'text-success' : 'text-danger'">
|
||||
{{ form.isValid == 1 ? '有效' : '到期' }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 学生基础信息 -->
|
||||
<view class="card">
|
||||
<view class="card-header">
|
||||
<uni-icons type="contact" size="24" color="#409EFF"></uni-icons>
|
||||
<text class="card-title">学生基础信息</text>
|
||||
</view>
|
||||
<view class="form-list">
|
||||
<view class="form-item">
|
||||
<text class="label">姓名:</text>
|
||||
<text class="value">{{ form.studentName || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">学号:</text>
|
||||
<text class="value">{{ form.studentNo || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">性别:</text>
|
||||
<text class="value">{{ form.gender == '1' ? '男' : form.gender == '0' ? '女' : '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">班级:</text>
|
||||
<text class="value">{{ form.className || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">辅导员:</text>
|
||||
<text class="value">{{ form.teacherName || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">原宿舍:</text>
|
||||
<text class="value">{{ form.originalDormitory || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">住宿费:</text>
|
||||
<text class="value">
|
||||
<view class="fee-tag" :class="form.accommodationFeeStatus == 1 ? 'fee-paid' : 'fee-unpaid'">
|
||||
{{ form.accommodationFeeStatus == 1 ? '已交' : '未交' }}
|
||||
</view>
|
||||
({{ form.accommodationFee || '-' }})
|
||||
</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">出生日期:</text>
|
||||
<text class="value">{{ formatDate(form.birthDate) || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">身份证号:</text>
|
||||
<text class="value">{{ form.idCard || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">联系电话:</text>
|
||||
<text class="value">{{ form.studentPhone || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">学院/专业:</text>
|
||||
<text class="value">{{ form.deptName || '-' }} / {{ form.majorName || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 学生电子签名 -->
|
||||
<view class="form-item signature-item" v-if="form.studentSignature">
|
||||
<text class="label">学生签名:</text>
|
||||
<image class="signature-img" :src="getFullUrl(form.studentSignature)" mode="aspectFit" @click="previewImage(form.studentSignature)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 外宿信息 -->
|
||||
<view class="card">
|
||||
<view class="card-header">
|
||||
<uni-icons type="location" size="24" color="#409EFF"></uni-icons>
|
||||
<text class="card-title">外宿信息</text>
|
||||
</view>
|
||||
<view class="form-list">
|
||||
<view class="form-item">
|
||||
<text class="label">外宿原因:</text>
|
||||
<text class="value">{{ form.applyReason || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">外宿地址:</text>
|
||||
<text class="value">{{ form.address || '-' }} {{ form.outsideAddress || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">紧急联系人:</text>
|
||||
<text class="value">{{ form.emergencyContact || '-' }} ({{ form.emergencyPhone || '-' }})</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 家长信息 -->
|
||||
<view class="card">
|
||||
<view class="card-header">
|
||||
<uni-icons type="person-filled" size="24" color="#409EFF"></uni-icons>
|
||||
<text class="card-title">家长信息</text>
|
||||
</view>
|
||||
<view class="form-list">
|
||||
<view class="form-item">
|
||||
<text class="label">家长意见:</text>
|
||||
<text class="value">
|
||||
<view class="opinion-tag" :class="form.parentOpinion == 1 ? 'opinion-agree' : 'opinion-disagree'">
|
||||
{{ form.parentOpinion == 1 ? '同意' : '不同意' }}
|
||||
</view>
|
||||
</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">家长电话:</text>
|
||||
<text class="value">{{ form.parentPhone || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="label">家长地址:</text>
|
||||
<text class="value">{{ form.parentAddress || '-' }} {{ form.parentDetailAddress || '-' }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 家长签字附件 -->
|
||||
<view class="form-item signature-item" v-if="form.parentSignAttachment">
|
||||
<text class="label">家长签字:</text>
|
||||
<image class="signature-img" :src="getFullUrl(form.parentSignAttachment)" mode="aspectFit" @click="previewImage(form.parentSignAttachment)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 承诺书信息 -->
|
||||
<view class="card">
|
||||
<view class="card-header">
|
||||
<uni-icons type="gift-filled" size="24" color="#409EFF"></uni-icons>
|
||||
<text class="card-title">外宿承诺书</text>
|
||||
</view>
|
||||
<view class="form-list">
|
||||
<view class="form-item">
|
||||
<text class="label">签署日期:</text>
|
||||
<text class="value">{{ formatDate(form.promiseDate) || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item promise-item">
|
||||
<text class="label">承诺内容:</text>
|
||||
<view class="value promise-content" v-html="form.promiseContent || '-'"></view>
|
||||
</view>
|
||||
|
||||
<!-- 承诺签名 -->
|
||||
<view class="form-item signature-item" v-if="form.studentPromiseSign">
|
||||
<text class="label">承诺签名:</text>
|
||||
<image class="signature-img" :src="getFullUrl(form.studentPromiseSign)" mode="aspectFit" @click="previewImage(form.studentPromiseSign)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 附件列表 -->
|
||||
<view class="card" v-if="form.outsideAccommodationAttachments && form.outsideAccommodationAttachments.length">
|
||||
<view class="card-header">
|
||||
<uni-icons type="download-filled" size="24" color="#409EFF"></uni-icons>
|
||||
<text class="card-title">佐证材料</text>
|
||||
</view>
|
||||
<view class="attachment-list">
|
||||
<view class="attachment-item" v-for="(item, index) in form.outsideAccommodationAttachments" :key="index" @click="previewImage(item.attachmentUrl)">
|
||||
<view class="file-icon">
|
||||
<uni-icons type="file" size="32" color="#409EFF"></uni-icons>
|
||||
</view>
|
||||
<view class="file-info">
|
||||
<text class="file-name">{{ item.attachmentName || '未命名文件' }}</text>
|
||||
<text class="file-size">{{ formatFileSize(item.fileSize) }}</text>
|
||||
</view>
|
||||
<uni-icons type="right" size="24" color="#ccc"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 审批记录 -->
|
||||
<view class="card" v-if="form.outsideAccommodationApprovals && form.outsideAccommodationApprovals.length">
|
||||
<view class="card-header">
|
||||
<uni-icons type="checkbox" size="24" color="#409EFF"></uni-icons>
|
||||
<text class="card-title">审批记录</text>
|
||||
</view>
|
||||
<view class="approval-list">
|
||||
<view class="approval-item" v-for="(item, index) in form.outsideAccommodationApprovals" :key="index">
|
||||
<view class="approval-line">
|
||||
<view class="approval-dot" :class="item.approvalResult == 1 ? 'dot-success' : item.approvalResult == 0 ? 'dot-pending' : 'dot-danger'"></view>
|
||||
<view class="approval-content">
|
||||
<view class="approval-header">
|
||||
<text class="approval-node">{{ item.approvalNode || '未知节点' }}</text>
|
||||
<text class="approval-time">{{ formatDate(item.approvalTime) || '-' }}</text>
|
||||
</view>
|
||||
<view class="approval-body">
|
||||
<view class="approval-info">
|
||||
<text class="info-key">审批人:</text>
|
||||
<text class="info-val">{{ item.approverName || '-' }}</text>
|
||||
</view>
|
||||
<view class="approval-info">
|
||||
<text class="info-key">审批结果:</text>
|
||||
<view class="approval-result-tag" :class="item.approvalResult == 1 ? 'result-approve' : item.approvalResult == 0 ? 'result-pending' : 'result-reject'">
|
||||
{{ item.approvalResult == 1 ? '通过' : '驳回' }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="approval-info" v-if="item.approvalOpinion">
|
||||
<text class="info-key">审批意见:</text>
|
||||
<text class="info-val">{{ item.approvalOpinion }}</text>
|
||||
</view>
|
||||
<!-- 审批签名 -->
|
||||
<view class="approval-info" v-if="item.signature">
|
||||
<text class="info-key">审批签名:</text>
|
||||
<!-- <image class="signature-img" :src="baseUrl + approval.signature" mode="aspectFit" @click="previewFile(approval, '签名')"></image> -->
|
||||
<image style="width: 100px; height: 50px;border: 1px solid #eee" :src="getFullUrl(item.signature)" mode="aspectFit" @click="previewImage(item.signature)"></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空审批记录提示 -->
|
||||
<view class="card empty-card" v-if="form.outsideAccommodationApprovals && form.outsideAccommodationApprovals.length === 0">
|
||||
<view class="card-header">
|
||||
<uni-icons type="checkbox" size="24" color="#409EFF"></uni-icons>
|
||||
<text class="card-title">审批记录</text>
|
||||
</view>
|
||||
<view class="empty-tip">
|
||||
<uni-icons type="empty" size="60" color="#ccc"></uni-icons>
|
||||
<text class="empty-text">暂无审批记录</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部留白 -->
|
||||
<view class="bottom-space"></view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from '@/config'
|
||||
export default {
|
||||
name: "OutsideAccommodationDetail",
|
||||
props: {
|
||||
form: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 文件服务器基础地址
|
||||
baseFileUrl: config.baseUrl
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 格式化日期
|
||||
* @param {String} dateStr 日期字符串
|
||||
* @returns {String} 格式化后的日期
|
||||
*/
|
||||
formatDate(dateStr) {
|
||||
if (!dateStr) return '';
|
||||
try {
|
||||
const date = new Date(dateStr);
|
||||
if (isNaN(date.getTime())) return dateStr;
|
||||
return `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date.getDate().toString().padStart(2, '0')}`;
|
||||
} catch (e) {
|
||||
return dateStr;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 格式化文件大小
|
||||
* @param {Number} size 字节数
|
||||
* @returns {String} 格式化后的大小
|
||||
*/
|
||||
formatFileSize(size) {
|
||||
if (!size) return '0B';
|
||||
if (size < 1024) return `${size}B`;
|
||||
if (size < 1024 * 1024) return `${(size / 1024).toFixed(2)}KB`;
|
||||
return `${(size / (1024 * 1024)).toFixed(2)}MB`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取申请状态文本
|
||||
* @param {Number} status 状态码
|
||||
* @returns {String} 状态文本
|
||||
*/
|
||||
getStatusText(status) {
|
||||
const statusMap = {
|
||||
0: '待提交',
|
||||
1: '待辅导员审批',
|
||||
2: '待学院书记审批',
|
||||
3: '待学工处审批',
|
||||
4: '待学校领导审批',
|
||||
5: '审核通过',
|
||||
6: '已驳回'
|
||||
};
|
||||
return statusMap[status] || '未知状态';
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取申请状态样式类
|
||||
* @param {Number} status 状态码
|
||||
* @returns {String} 样式类名
|
||||
*/
|
||||
getStatusClass(status) {
|
||||
const classMap = {
|
||||
0: 'status-pending',
|
||||
1: 'status-processing',
|
||||
2: 'status-processing',
|
||||
3: 'status-processing',
|
||||
4: 'status-processing',
|
||||
5: 'status-success',
|
||||
6: 'status-reject'
|
||||
};
|
||||
return classMap[status] || 'status-default';
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取完整的文件URL
|
||||
* @param {String} path 相对路径
|
||||
* @returns {String} 完整URL
|
||||
*/
|
||||
getFullUrl(path) {
|
||||
if (!path) return '';
|
||||
// 如果是完整URL直接返回,否则拼接基础地址
|
||||
if (path.startsWith('http')) return path;
|
||||
return this.baseFileUrl + path;
|
||||
},
|
||||
|
||||
/**
|
||||
* 预览图片
|
||||
* @param {String} url 图片地址
|
||||
*/
|
||||
previewImage(url) {
|
||||
if (!url) {
|
||||
uni.showToast({
|
||||
title: '图片地址不存在',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
const fullUrl = this.getFullUrl(url);
|
||||
uni.previewImage({
|
||||
urls: [fullUrl],
|
||||
current: fullUrl
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 全局样式
|
||||
.container {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
// 页面头部
|
||||
.page-header {
|
||||
padding: 24rpx 30rpx;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
.page-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动容器
|
||||
.content-scroll {
|
||||
width: 100%;
|
||||
height: calc(100vh - 96rpx);
|
||||
}
|
||||
|
||||
// 通用卡片样式
|
||||
.card {
|
||||
margin: 20rpx 30rpx;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
||||
overflow: hidden;
|
||||
|
||||
&.overview-card {
|
||||
padding: 30rpx;
|
||||
background: linear-gradient(135deg, #e8f4fd 0%, #f0f8fb 100%);
|
||||
|
||||
.overview-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.overview-left {
|
||||
.apply-no {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.student-name {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overview-info {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx 0;
|
||||
|
||||
.overview-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.info-label {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.empty-card {
|
||||
.empty-tip {
|
||||
padding: 60rpx 0;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx 30rpx;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
.card-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.form-list {
|
||||
padding: 24rpx 30rpx;
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16rpx 0;
|
||||
border-bottom: 1px solid #f9f9f9;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.signature-item {
|
||||
align-items: flex-start;
|
||||
|
||||
.signature-img {
|
||||
width: 220rpx;
|
||||
height: 88rpx;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8rpx;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.promise-item {
|
||||
align-items: flex-start;
|
||||
|
||||
.promise-content {
|
||||
line-height: 1.8;
|
||||
color: #333;
|
||||
font-size: 26rpx;
|
||||
flex: 1;
|
||||
|
||||
p {
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
min-width: 120rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
flex: 1;
|
||||
word-break: break-all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.attachment-list {
|
||||
padding: 24rpx 30rpx;
|
||||
|
||||
.attachment-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1px solid #f9f9f9;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: #e8f4fd;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.file-info {
|
||||
flex: 1;
|
||||
margin: 0 20rpx;
|
||||
|
||||
.file-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-bottom: 4rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.file-size {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.approval-list {
|
||||
padding: 24rpx 30rpx;
|
||||
|
||||
.approval-item {
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.approval-line {
|
||||
display: flex;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 10rpx;
|
||||
top: 30rpx;
|
||||
bottom: -20rpx;
|
||||
width: 2rpx;
|
||||
background-color: #eee;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&:last-child::after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.approval-dot {
|
||||
width: 20rpx;
|
||||
height: 20rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #ddd;
|
||||
z-index: 2;
|
||||
flex-shrink: 0;
|
||||
|
||||
&.dot-success {
|
||||
background-color: #67c23a;
|
||||
}
|
||||
|
||||
&.dot-danger {
|
||||
background-color: #f56c6c;
|
||||
}
|
||||
|
||||
&.dot-pending {
|
||||
background-color: #e6a23c;
|
||||
}
|
||||
}
|
||||
|
||||
.approval-content {
|
||||
flex: 1;
|
||||
margin-left: 20rpx;
|
||||
|
||||
.approval-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12rpx;
|
||||
|
||||
.approval-node {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.approval-time {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.approval-body {
|
||||
.approval-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 26rpx;
|
||||
|
||||
.info-key {
|
||||
color: #666;
|
||||
min-width: 80rpx;
|
||||
}
|
||||
|
||||
.info-val {
|
||||
color: #333;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 标签样式
|
||||
.status-tag, .fee-tag, .opinion-tag, .approval-result-tag {
|
||||
padding: 8rpx 16rpx;
|
||||
border-radius: 24rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
display: inline-block;
|
||||
|
||||
// 申请状态
|
||||
&.status-pending {
|
||||
background-color: #fdf6ec;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
&.status-processing {
|
||||
background-color: #e8f4fd;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
&.status-success {
|
||||
background-color: #f0f9eb;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
&.status-reject {
|
||||
background-color: #fef0f0;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
&.status-default {
|
||||
background-color: #f5f5f5;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
// 费用状态
|
||||
&.fee-paid {
|
||||
background-color: #f0f9eb;
|
||||
color: #67c23a;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
&.fee-unpaid {
|
||||
background-color: #fef0f0;
|
||||
color: #f56c6c;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
// 家长意见
|
||||
&.opinion-agree {
|
||||
background-color: #f0f9eb;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
&.opinion-disagree {
|
||||
background-color: #fef0f0;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
// 审批结果
|
||||
&.result-approve {
|
||||
background-color: #f0f9eb;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
&.result-reject {
|
||||
background-color: #fef0f0;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
&.result-pending {
|
||||
background-color: #fdf6ec;
|
||||
color: #e6a23c;
|
||||
}
|
||||
}
|
||||
|
||||
// 文本颜色
|
||||
.text-success {
|
||||
color: #67c23a !important;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #f56c6c !important;
|
||||
}
|
||||
|
||||
// 空提示
|
||||
.empty-tip {
|
||||
empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #ccc;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 底部留白
|
||||
.bottom-space {
|
||||
height: 40rpx;
|
||||
}
|
||||
</style>
|
||||
663
pages/Approval/handleTask/processHandling/detail.vue
Normal file
663
pages/Approval/handleTask/processHandling/detail.vue
Normal file
@@ -0,0 +1,663 @@
|
||||
<template>
|
||||
<view class="detail">
|
||||
<Nav :navs="navs" @change="navChange" />
|
||||
<view class="form" v-if="navIndex==0">
|
||||
<view class="container" style="padding-bottom: 60px;" v-if="form!=null">
|
||||
<!-- 入伍保留学籍申请 -->
|
||||
<view v-if="category == 'enlistmentReserve'" style="width: 100%;">
|
||||
<enlistmentReserve :form="form"></enlistmentReserve>
|
||||
</view>
|
||||
<!-- 外宿申请 -->
|
||||
<view v-if="category == 'outsideAccommodation'" style="width: 100%;">
|
||||
<outsideAccommodation :form="form"></outsideAccommodation>
|
||||
</view>
|
||||
<view class="btns" v-if="tag==1">
|
||||
<button class="turn-down" @tap="onReject" v-if="role!=='学生'">驳回</button>
|
||||
<button class="return" @tap="onReturn" v-if="returnTaskList.length>0">回退</button>
|
||||
<button class="submit" @tap="onComplete">审批</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="progress" v-if="navIndex==1">
|
||||
<FlowStep :procInsId="taskForm.procInsId" :deployId="taskForm.deployId" />
|
||||
</view>
|
||||
|
||||
<uni-popup class="popup" ref="approveDialog" type="dialog" background-color="#fff">
|
||||
<view class="popup-content">
|
||||
<view class="title">
|
||||
流程审批
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="form-item">
|
||||
<label class="label"><text class="required">*</text>审批意见</label>
|
||||
<input type="text" placeholder-class="placeholderColor" placeholder="审批意见"
|
||||
v-model="taskForm.variables.approvalOpinion" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="btns">
|
||||
<button type="default" @tap="onCancel">取消</button>
|
||||
<button type="primary" @tap="approveDialogConfirm" :disabled="isSubmitting">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Nav from "@/components/navs/navs.vue";
|
||||
import FlowStep from "@/components/flow-step/flow-step.vue";
|
||||
import {
|
||||
baseUrl
|
||||
} from "@/config.js";
|
||||
import {
|
||||
getDiseaseTypeByDictValue
|
||||
} from "@/utils/dict.js";
|
||||
import {
|
||||
complete,
|
||||
reject,
|
||||
returnList,
|
||||
returnTask
|
||||
} from "@/api/task.js";
|
||||
import {
|
||||
getDicts
|
||||
} from "@/api/system/dict/data";
|
||||
import {
|
||||
getEnlistmentReserveByProcessInstanceId,
|
||||
updateStudent
|
||||
} from "@/api/routine/enlistmentReserve/enlistmentReserve";
|
||||
import {
|
||||
getOutsideAccommodationApplyByProcessInstanceId,
|
||||
updateOutsideAccommodationApply
|
||||
} from "@/api/dms/outsideAccommodation/outsideAccommodationApply";
|
||||
import {
|
||||
insertOrUpdateByStuAndApprover
|
||||
} from "@/api/routine/enlistmentReserve/enlistmentReserveApproval";
|
||||
import {
|
||||
getUserProfile
|
||||
} from '@/api/system/user'
|
||||
import enlistmentReserve from "@/pages/Approval/handleTask/processHandling/components/enlistmentReserve.vue"
|
||||
import outsideAccommodation from "@/pages/Approval/handleTask/processHandling/components/outsideAccommodation.vue"
|
||||
export default {
|
||||
components: {
|
||||
Nav,
|
||||
FlowStep,
|
||||
enlistmentReserve,
|
||||
outsideAccommodation
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isSubmitting: false, //表单提交标志位
|
||||
navs: [{
|
||||
text: "表单信息",
|
||||
val: 0
|
||||
},
|
||||
{
|
||||
text: "流程跟踪",
|
||||
val: 1
|
||||
}
|
||||
],
|
||||
taskDotIndex: 0,
|
||||
navIndex: 0,
|
||||
form: null,
|
||||
ImageUrl: baseUrl,
|
||||
role: uni.getStorageSync("roles"),
|
||||
inputReject: "",
|
||||
taskName: "", //节点名
|
||||
category: "",
|
||||
taskForm: {
|
||||
multiple: false,
|
||||
comment: '', // 意见内容
|
||||
procInsId: '', // 流程实例编号
|
||||
instanceId: '', // 流程实例编号
|
||||
deployId: '', // 流程定义编号
|
||||
taskId: '', // 流程任务编号
|
||||
procDefId: '', // 流程编号
|
||||
vars: '',
|
||||
targetKey: '',
|
||||
variables: {
|
||||
approvalOpinion: '', // 必须初始化,避免 null 报错
|
||||
approvalResult: '',
|
||||
targetNodeName: '',
|
||||
signature: ''
|
||||
},
|
||||
},
|
||||
returnTaskList: [], // 回退列表数据
|
||||
tag: '',
|
||||
user: []
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
let query = JSON.parse(option.query);
|
||||
this.category = query.category;
|
||||
this.tag = query.tag;
|
||||
this.taskForm.deployId = query.deployId;
|
||||
this.taskForm.instanceId = query.procInsId
|
||||
this.taskForm.procInsId = query.procInsId
|
||||
this.taskForm.executionId = query.executionId
|
||||
this.taskForm.taskId = query.taskId
|
||||
this.taskName = query.taskName
|
||||
if (this.category == 'enlistmentReserve') { // 入伍保留学籍申请表单
|
||||
this.getEnlistmentReserve(this.taskForm.procInsId);
|
||||
// 页面标题修改
|
||||
uni.setNavigationBarTitle({
|
||||
title: '入伍保留学籍申请详情'
|
||||
});
|
||||
} else if (this.category == 'outsideAccommodation') { // 外宿申请表单
|
||||
this.getOutsideAccommodation(this.taskForm.procInsId);
|
||||
// 页面标题修改
|
||||
uni.setNavigationBarTitle({
|
||||
title: '外宿申请详情'
|
||||
});
|
||||
}
|
||||
getUserProfile().then(res => {
|
||||
this.user = res.data
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
navChange(index) {
|
||||
this.navIndex = index;
|
||||
},
|
||||
// 请求 入伍保留学籍表单数据
|
||||
async getEnlistmentReserve(procInsId) {
|
||||
try {
|
||||
const res = await getEnlistmentReserveByProcessInstanceId(procInsId.toString());
|
||||
this.form = res.data;
|
||||
// 将字典中的民族提取
|
||||
let nation = await getDicts("rt_nation")
|
||||
let nationArr = nation.data
|
||||
if (!Array.isArray(nationArr) || nationArr.length === 0 || !this.form.nation) {
|
||||
console.warn("民族字典数据为空或表单民族值未设置");
|
||||
return;
|
||||
}
|
||||
// 使用find方法查找匹配项(性能更优,匹配到即停止)
|
||||
const matchItem = nationArr.find(item => {
|
||||
return String(item.dictValue) === String(this.form.nation);
|
||||
});
|
||||
console.log(matchItem);
|
||||
// 如果找到匹配项,更新值;否则保留原值或置空
|
||||
if (matchItem) {
|
||||
this.form.nation = matchItem.dictLabel;
|
||||
} else {
|
||||
console.warn(`未找到民族值【${this.form.nation}】对应的字典标签`);
|
||||
// 可选:如果需要,匹配不到时置空
|
||||
// this.form.nation = "未知民族";
|
||||
}
|
||||
|
||||
// 处理审批意见列表,添加意见类型
|
||||
if (this.form?.enlistmentReserveApprovalList) {
|
||||
// 定义意见类型数组(与索引对应:0=辅导员,1=学务,2=二级学院,3=学籍管理科,4=教务处主管领导)
|
||||
const opinionTypes = [
|
||||
"辅导员意见",
|
||||
"学务意见",
|
||||
"二级学院意见",
|
||||
"学籍管理科意见",
|
||||
"教务处主管领导意见"
|
||||
];
|
||||
// 遍历审批列表,为每条数据添加 opinionType 字段
|
||||
this.form.enlistmentReserveApprovalList.forEach((item, index) => {
|
||||
// 只处理前5条数据(超出部分不添加,或可根据实际需求调整)
|
||||
if (index < opinionTypes.length) {
|
||||
item.opinionType = opinionTypes[index];
|
||||
} else {
|
||||
// 若超过5条,可设置默认值或不设置
|
||||
item.opinionType = "其他意见";
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
// 错误捕获,避免接口调用失败导致页面异常
|
||||
console.error("获取数据失败:", error);
|
||||
uni.showToast({
|
||||
title: "数据加载失败",
|
||||
icon: "none"
|
||||
});
|
||||
}
|
||||
},
|
||||
// 请求 外宿申请表单数据
|
||||
getOutsideAccommodation(procInsId) {
|
||||
getOutsideAccommodationApplyByProcessInstanceId(procInsId.toString()).then((res) => {
|
||||
this.form = res.data
|
||||
if (this.form?.outsideAccommodationApprovals) {
|
||||
// 定义外宿审批意见类型数组(与索引严格对应)
|
||||
const opinionTypes = [
|
||||
"辅导员意见",
|
||||
"二级学院书记意见",
|
||||
"学工处意见",
|
||||
"学校领导意见"
|
||||
];
|
||||
// 遍历审批列表,为每条数据添加 opinionType 字段
|
||||
this.form.outsideAccommodationApprovals.forEach((item, index) => {
|
||||
// 前4条数据按索引匹配意见类型,超出部分设为默认值
|
||||
if (index < opinionTypes.length) {
|
||||
item.opinionType = opinionTypes[index];
|
||||
} else {
|
||||
// 超出4条时的兜底值
|
||||
item.opinionType = "其他审批意见";
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
},
|
||||
onComplete() {
|
||||
this.taskForm.variables.signature = this.user.signature
|
||||
this.$refs.approveDialog.open();
|
||||
},
|
||||
onReturn() {
|
||||
this.$refs.returnDialog.open();
|
||||
},
|
||||
onReject() {
|
||||
this.$refs.rejectDialog.open();
|
||||
},
|
||||
onCancel() {
|
||||
this.$refs.approveDialog.close();
|
||||
this.$refs.returnDialog.close();
|
||||
},
|
||||
approveDialogConfirm() {
|
||||
if (this.taskForm.variables.approvalOpinion == '') {
|
||||
uni.showToast({
|
||||
title: `请填写审批意见`,
|
||||
icon: "none"
|
||||
})
|
||||
return;
|
||||
}
|
||||
uni.showLoading({
|
||||
title: "正在审批"
|
||||
});
|
||||
this.isSubmitting = true; // 设置为正在提交
|
||||
this.taskForm.comment = this.taskForm.variables.approvalOpinion != '' ? this.taskForm.variables
|
||||
.approvalOpinion : '同意'
|
||||
this.taskForm.variables.approvalResult = 1
|
||||
complete(this.taskForm).then(res => {
|
||||
if (res.code == 200) {
|
||||
if (this.taskName ==
|
||||
'教务处主管领导审批') { // (最后一个领导审核完成之后,修改学生学籍状态, status:07是入伍保留学籍)
|
||||
updateStudent({
|
||||
stuId: this.form.studentId,
|
||||
status: '07'
|
||||
}).then(response => {})
|
||||
}
|
||||
uni.showToast({
|
||||
title: "审批成功"
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: "审批失败"
|
||||
});
|
||||
}
|
||||
uni.hideLoading();
|
||||
uni.navigateBack({
|
||||
success: () => {
|
||||
const pages = getCurrentPages();
|
||||
if (pages && pages.length > 0) {
|
||||
const prevPage = pages[pages.length - 2] || pages[pages
|
||||
.length - 1];
|
||||
if (prevPage && typeof prevPage.handleChange ===
|
||||
'function') {
|
||||
prevPage.handleChange(this.tag || 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail {
|
||||
padding-top: 90rpx;
|
||||
|
||||
.progress {
|
||||
padding: 0 30rpx 30rpx;
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
color: #202020;
|
||||
display: inline-block;
|
||||
font-size: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 10rpx;
|
||||
|
||||
.form-item {
|
||||
width: 95%;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #ededee;
|
||||
|
||||
}
|
||||
|
||||
.custom-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
width: 95%;
|
||||
margin-bottom: 20rpx;
|
||||
border-bottom: 1px solid #ededee;
|
||||
}
|
||||
|
||||
.form-img {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
margin-bottom: 20rpx;
|
||||
border-bottom: 1px solid #ededee;
|
||||
}
|
||||
|
||||
.example-body {
|
||||
margin-top: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.txt {
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.label {
|
||||
text-align: right;
|
||||
margin-right: 20rpx;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
.select {
|
||||
color: #888889;
|
||||
white-space: nowrap;
|
||||
/* 防止换行 */
|
||||
overflow: hidden;
|
||||
/* 隐藏溢出部分 */
|
||||
text-overflow: ellipsis;
|
||||
/* 显示省略号 */
|
||||
}
|
||||
|
||||
.uni-input {
|
||||
color: #888889;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 30%;
|
||||
background-color: #87CEFA;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.form-address {
|
||||
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.labelsafe {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.form-canvas {
|
||||
width: 95%;
|
||||
height: 700rpx;
|
||||
}
|
||||
|
||||
.tab-box {
|
||||
width: 80%;
|
||||
height: 100vh;
|
||||
background-color: #f0f0f0;
|
||||
|
||||
.success-img {
|
||||
width: 90%;
|
||||
height: 300rpx;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.btns {
|
||||
display: flex;
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
|
||||
button {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
// width: 50%;
|
||||
flex: 1;
|
||||
border-radius: 0;
|
||||
|
||||
&.turn-down {
|
||||
background-color: #FF3334;
|
||||
}
|
||||
|
||||
&.return {
|
||||
background-color: #FFBA00;
|
||||
}
|
||||
|
||||
&.submit {
|
||||
background-color: #0092FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.popup {
|
||||
.popup-content {
|
||||
width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow: scroll;
|
||||
// padding: 0 40rpx;
|
||||
|
||||
.title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 0 40rpx;
|
||||
|
||||
.show-letter {
|
||||
.title {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.stu-name {
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #797979;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
button {
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.gaizhang {
|
||||
text-align: right;
|
||||
position: relative;
|
||||
|
||||
image {
|
||||
width: 200rpx;
|
||||
}
|
||||
|
||||
.time {
|
||||
position: absolute;
|
||||
right: 30rpx;
|
||||
bottom: 55rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.form-item {
|
||||
.required {
|
||||
color: red;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
&.download {
|
||||
margin: 50rpx 0 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #4097FE;
|
||||
justify-content: center;
|
||||
|
||||
.file-icon {
|
||||
width: 50rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
text {
|
||||
border-bottom: 1px solid #4097FE;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
margin: 30rpx 0 20rpx;
|
||||
color: #202020;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
||||
input {
|
||||
display: inline-block;
|
||||
padding: 0 20rpx;
|
||||
height: 70rpx;
|
||||
}
|
||||
|
||||
textarea {
|
||||
height: 200rpx;
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.placeholderColor {
|
||||
color: #D8D8D8;
|
||||
}
|
||||
|
||||
input,
|
||||
textarea {
|
||||
width: 100%;
|
||||
border: 1px solid #E1E1E1;
|
||||
border-radius: 16rpx;
|
||||
|
||||
}
|
||||
|
||||
picker {
|
||||
border: 1px solid #E1E1E1;
|
||||
height: 70rpx;
|
||||
line-height: 70rpx;
|
||||
padding: 0 30rpx;
|
||||
|
||||
.uni-input {
|
||||
display: flex;
|
||||
color: #202020;
|
||||
opacity: 0.35;
|
||||
|
||||
&.select {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.val {
|
||||
flex: 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.uni-file-picker {
|
||||
/deep/ .uni-progress-bar {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.btns {
|
||||
display: flex;
|
||||
margin-top: 80rpx;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
border-radius: 0;
|
||||
border-bottom: 0;
|
||||
|
||||
&:first-child {
|
||||
background-color: transparent;
|
||||
border: 1px solid #4097FE;
|
||||
border-bottom: 0;
|
||||
color: #4097FE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.return-dialog {
|
||||
.form-item {
|
||||
label {
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.list {
|
||||
height: auto;
|
||||
max-height: 200px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
// height: 200px;
|
||||
// display: flex;
|
||||
// flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
|
||||
&.active {
|
||||
background-color: #0092FF;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -371,6 +371,7 @@
|
||||
getRtStuQuitSchoolByProcInsId(procInsId) {
|
||||
getRtStuQuitSchoolByProcInsId(procInsId).then((res) => {
|
||||
this.formData = res.data;
|
||||
console.log(this.formData)
|
||||
this.get_penalty_type(this.formData.quitType);
|
||||
this.get_category(this.formData.quitCategory);
|
||||
if (this.tag == 1) {
|
||||
@@ -422,9 +423,9 @@
|
||||
const pages = getCurrentPages();
|
||||
if (pages && pages.length > 0) {
|
||||
const prevPage = pages[pages.length - 2] || pages[pages.length - 1];
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(this.tag || 1);
|
||||
}
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -495,18 +496,18 @@
|
||||
});
|
||||
}
|
||||
uni.hideLoading();
|
||||
uni.navigateBack({
|
||||
success: () => {
|
||||
const pages = getCurrentPages();
|
||||
if (pages && pages.length > 0) {
|
||||
const prevPage = pages[pages.length - 2] || pages[pages.length - 1];
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(this.tag || 1);
|
||||
}
|
||||
uni.navigateBack({
|
||||
success: () => {
|
||||
const pages = getCurrentPages();
|
||||
if (pages.length > 0) {
|
||||
const prevPage = pages[pages.length - 2]
|
||||
if (prevPage && typeof prevPage.getList === 'function') {
|
||||
prevPage.handleChange(2);
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
rejectDialogConfirm() {
|
||||
@@ -528,10 +529,10 @@
|
||||
const pages = getCurrentPages();
|
||||
if (pages && pages.length > 0) {
|
||||
const prevPage = pages[pages.length - 2] || pages[pages.length - 1];
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(this.tag || 1);
|
||||
console.log('刷新任务数据');
|
||||
}
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(2);
|
||||
console.log('刷新已办任务数据');
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -8,6 +8,14 @@
|
||||
</view>
|
||||
</view>
|
||||
<view class="content" v-if="processes.length!==0">
|
||||
<view class="search-bar">
|
||||
<input class="input" placeholder="姓名" v-model="searchName" @confirm="doSearch" />
|
||||
<picker mode="date" :value="searchDate" @change="onDateChange">
|
||||
<view class="picker-text">{{ searchDate || '时间' }}</view>
|
||||
</picker>
|
||||
<button class="primary" @tap="doSearch">搜索</button>
|
||||
<button class="reset" @tap="resetSearch">重置</button>
|
||||
</view>
|
||||
<view class="list">
|
||||
<view class="item" v-for="(process,index) in processes" :key="index">
|
||||
<view class="top">
|
||||
@@ -75,7 +83,9 @@
|
||||
currentPage: 1,
|
||||
loading: false, // 加载状态标志
|
||||
topLoading: true,
|
||||
role: uni.getStorageSync("roles")
|
||||
role: uni.getStorageSync("roles"),
|
||||
searchName: '',
|
||||
searchDate: ''
|
||||
};
|
||||
},
|
||||
onLoad(option) {
|
||||
@@ -130,12 +140,42 @@
|
||||
this.topLoading = true;
|
||||
this.getList();
|
||||
},
|
||||
doSearch() {
|
||||
this.currentPage = 1;
|
||||
this.processes = [];
|
||||
this.topLoading = true;
|
||||
this.getList();
|
||||
},
|
||||
resetSearch() {
|
||||
this.searchName = '';
|
||||
this.searchDate = '';
|
||||
this.currentPage = 1;
|
||||
this.processes = [];
|
||||
this.topLoading = true;
|
||||
this.getList();
|
||||
},
|
||||
onDateChange(e) {
|
||||
this.searchDate = e.detail.value;
|
||||
},
|
||||
getList() {
|
||||
this.loading = true;
|
||||
let sdata = {
|
||||
pageNum: this.currentPage,
|
||||
pageSize: 10
|
||||
pageSize: 10,
|
||||
};
|
||||
if (this.searchName) {
|
||||
sdata.startUserName = this.searchName;
|
||||
}
|
||||
if (this.searchDate) {
|
||||
if (this.currentTab === 2) {
|
||||
// 已办任务:PC端使用 startTime/endTime;时间对应“提交时间”
|
||||
sdata.startTime = this.searchDate;
|
||||
sdata.endTime = this.searchDate;
|
||||
} else {
|
||||
// 我发起的、待办任务:PC端使用 deployTime;时间对应“提交时间”
|
||||
sdata.deployTime = this.searchDate;
|
||||
}
|
||||
}
|
||||
console.log(this.processes);
|
||||
if (this.currentTab == 0) {
|
||||
myProcess(sdata).then(res => {
|
||||
@@ -253,6 +293,12 @@
|
||||
uni.navigateTo({
|
||||
url: `/pages/applyleave/editLeave?id=${process.procInsId}&type=task&taskId=${process.taskId}`,
|
||||
})
|
||||
}
|
||||
// 入伍保留学籍申请、外宿申请
|
||||
else if (process.category == 'enlistmentReserve' || process.category == 'outsideAccommodation') {
|
||||
uni.navigateTo({
|
||||
url: `/pages/Approval/handleTask/processHandling/detail?query=${JSON.stringify(query)}`,
|
||||
})
|
||||
}
|
||||
else {
|
||||
uni.navigateTo({
|
||||
@@ -320,6 +366,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 10px;
|
||||
background-color: #ffffff;
|
||||
border-bottom: 1px solid #EDEDED;
|
||||
position: sticky;
|
||||
top: 58px;
|
||||
z-index: 998;
|
||||
.input {
|
||||
flex: 1;
|
||||
border: 1px solid #EDEDED;
|
||||
border-radius: 4px;
|
||||
padding: 6px 8px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.picker-text {
|
||||
border: 1px solid #EDEDED;
|
||||
border-radius: 4px;
|
||||
padding: 6px 8px;
|
||||
color: #555555;
|
||||
}
|
||||
button.primary {
|
||||
border: 1px solid #007aff;
|
||||
color: #007aff;
|
||||
}
|
||||
button.reset {
|
||||
border: 1px solid #909399;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -337,6 +418,7 @@
|
||||
.content {
|
||||
padding-top: 58px;
|
||||
|
||||
|
||||
.list {
|
||||
.item {
|
||||
padding: 20px 10px;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -418,12 +418,12 @@
|
||||
const pages = getCurrentPages();
|
||||
if (pages.length > 0) {
|
||||
const prevPage = pages[pages.length - 2] || pages[pages.length - 1]
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(2);
|
||||
console.log('刷新已办任务数据');
|
||||
} else if (prevPage && typeof prevPage.getLeaveList === 'function') {
|
||||
prevPage.getLeaveList();
|
||||
}
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(1);
|
||||
console.log('切回待办任务');
|
||||
} else if (prevPage && typeof prevPage.getLeaveList === 'function') {
|
||||
prevPage.getLeaveList();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -623,12 +623,12 @@
|
||||
const pages = getCurrentPages();
|
||||
if (pages.length > 0) {
|
||||
const prevPage = pages[pages.length - 2] || pages[pages.length - 1]
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(2);
|
||||
} else if (prevPage && typeof prevPage.getLeaveList ===
|
||||
'function') {
|
||||
prevPage.getLeaveList();
|
||||
}
|
||||
if (prevPage && typeof prevPage.handleChange === 'function') {
|
||||
prevPage.handleChange(1);
|
||||
} else if (prevPage && typeof prevPage.getLeaveList ===
|
||||
'function') {
|
||||
prevPage.getLeaveList();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
2084
pages/dormitory/outsideAccommodation/applicationForm.vue
Normal file
2084
pages/dormitory/outsideAccommodation/applicationForm.vue
Normal file
File diff suppressed because it is too large
Load Diff
953
pages/dormitory/outsideAccommodation/index.vue
Normal file
953
pages/dormitory/outsideAccommodation/index.vue
Normal file
@@ -0,0 +1,953 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 搜索区(仅非学生角色显示) -->
|
||||
<view class="fixed-search-wrap" id="search" v-if="roleGroup != '学生'">
|
||||
<view class="search-content">
|
||||
<view class="search-card">
|
||||
<!-- 姓名搜索输入框 -->
|
||||
<view class="search-row">
|
||||
<uni-icons type="search" size="28rpx" color="#1890FF" class="search-icon"></uni-icons>
|
||||
<input v-model="queryParams.studentName" placeholder="输入学生姓名搜索" @input="handleQuery"
|
||||
class="search-input" />
|
||||
</view>
|
||||
|
||||
<!-- 筛选行:学号/学院/班级 -->
|
||||
<view class="filter-row">
|
||||
<view class="filter-item">
|
||||
<text class="filter-label">学号</text>
|
||||
<input class="picker-content" v-model="queryParams.studentNo" type="text"
|
||||
placeholder="请输入" />
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<text class="filter-label">学院</text>
|
||||
<input class="picker-content" v-model="queryParams.deptName" type="text"
|
||||
placeholder="请输入" />
|
||||
</view>
|
||||
<view class="filter-item">
|
||||
<text class="filter-label">班级</text>
|
||||
<input class="picker-content" v-model="queryParams.className" type="text"
|
||||
placeholder="请输入" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="action-row">
|
||||
<button class="reset-btn" @click="resetQuery">
|
||||
<uni-icons type="clear" size="24rpx" color="#1890FF" class="btn-icon"></uni-icons>
|
||||
重置
|
||||
</button>
|
||||
<button class="search-btn" @click="handleQuery">
|
||||
<uni-icons type="search" size="24rpx" color="#fff" class="btn-icon"></uni-icons>
|
||||
搜索
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="app-container">
|
||||
<!-- 数据列表滚动容器 -->
|
||||
<scroll-view class="list-container" id="list-container" scroll-y @scrolltolower="handleLoadMore"
|
||||
lower-threshold="50" enhanced :show-scrollbar="false">
|
||||
<!-- 初始加载状态 -->
|
||||
<uni-load-more :status="loading ? 'loading' : 'done'" v-if="loading" class="loading-wrap"></uni-load-more>
|
||||
|
||||
<!-- 空数据状态 -->
|
||||
<view class="empty-state" v-if="!loading && !hasData">
|
||||
<uni-icons type="empty" size="80" color="#c0c4cc"></uni-icons>
|
||||
<text class="empty-text">暂无外宿申请数据</text>
|
||||
<text class="empty-tip" v-if="roleGroup.includes('学生')">点击右下角"+号"按钮提交新申请</text>
|
||||
</view>
|
||||
|
||||
<!-- 数据列表 -->
|
||||
<view class="card-list" v-if="!loading && hasData">
|
||||
<view class="apply-card" v-for="(item, index) in validDataList" :key="index" hover-class="card-hover"
|
||||
:hover-stop-propagation="true">
|
||||
<!-- 卡片头部 -->
|
||||
<view class="card-header">
|
||||
<view class="apply-no">
|
||||
<text class="label-text">申请编号:</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 class="valid-label"
|
||||
:class="getSafeValue(item, 'isValid') == 1 ? 'valid-success' : 'valid-info'">
|
||||
{{ getSafeValue(item, 'isValid') == 1 ? '有效' : '到期' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 卡片主体折叠面板 -->
|
||||
<uni-collapse accordion v-model="item.activeCollapse">
|
||||
<uni-collapse-item title="基本信息" name="basic" class="collapse-item">
|
||||
<view class="info-grid">
|
||||
<view class="info-item"><text class="label">学号:</text><text
|
||||
class="value">{{ getSafeValue(item, 'studentNo', '-') }}</text></view>
|
||||
<view class="info-item"><text class="label">姓名:</text><text
|
||||
class="value">{{ getSafeValue(item, 'studentName', '-') }}</text></view>
|
||||
<view class="info-item"><text class="label">性别:</text><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>
|
||||
</uni-collapse-item>
|
||||
|
||||
<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>
|
||||
</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 class="load-more-wrap" v-if="hasData">
|
||||
<uni-load-more :status="loadingMore ? 'loading' : (hasMore ? 'more' : 'nomore')"
|
||||
:content-text="loadMoreText"></uni-load-more>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
<!-- 添加外宿申请按钮 -->
|
||||
<view class="add" @click="addOutsideAccommodation" v-if="roleGroup == '学生'">+</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listOutsideAccommodationApply
|
||||
} from "@/api/dms/outsideAccommodation/outsideAccommodationApply";
|
||||
import {
|
||||
getUserProfile
|
||||
} from '@/api/system/user';
|
||||
|
||||
export default {
|
||||
name: "OutsideAccommodationApplyList",
|
||||
data() {
|
||||
return {
|
||||
// 加载状态
|
||||
loading: true,
|
||||
loadingMore: false,
|
||||
hasMore: true,
|
||||
// 总数据量
|
||||
totalCount: 0,
|
||||
// 原始数据
|
||||
outsideAccommodationApplyList: [],
|
||||
// 查询参数
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 5,
|
||||
studentNo: null,
|
||||
studentName: null,
|
||||
deptName: null,
|
||||
className: null,
|
||||
teacherName: null
|
||||
},
|
||||
// 用户角色
|
||||
roleGroup: '',
|
||||
user: {},
|
||||
// 加载更多文本
|
||||
loadMoreText: {
|
||||
contentdown: '上拉加载更多',
|
||||
contentrefresh: '正在加载...',
|
||||
contentnomore: '没有更多数据了'
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 过滤后的有效数据列表
|
||||
validDataList() {
|
||||
return this.outsideAccommodationApplyList.filter(item => {
|
||||
return item !== null && item !== undefined && typeof item === 'object';
|
||||
}).map(item => {
|
||||
if (!item.hasOwnProperty('activeCollapse')) {
|
||||
item.activeCollapse = 'basic';
|
||||
}
|
||||
return item;
|
||||
});
|
||||
},
|
||||
// 是否有有效数据
|
||||
hasData() {
|
||||
return this.validDataList.length > 0;
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.getUser();
|
||||
},
|
||||
methods: {
|
||||
/** 安全取值方法 */
|
||||
getSafeValue(obj, key, defaultValue = '') {
|
||||
if (!obj || typeof obj !== 'object') return defaultValue;
|
||||
return obj[key] !== undefined && obj[key] !== null ? obj[key] : defaultValue;
|
||||
},
|
||||
|
||||
/** 获取状态样式类 */
|
||||
getStatusClass(item) {
|
||||
const rejectInfo = this.getRejectInfo(item);
|
||||
if (rejectInfo.isReject) {
|
||||
return 'status-error';
|
||||
}
|
||||
const status = this.getSafeValue(item, 'status');
|
||||
const typeMap = {
|
||||
'0': 'status-info',
|
||||
'1': 'status-warning',
|
||||
'2': 'status-warning',
|
||||
'3': 'status-warning',
|
||||
'4': 'status-warning',
|
||||
'5': 'status-success'
|
||||
};
|
||||
return typeMap[status] || 'status-default';
|
||||
},
|
||||
|
||||
/** 获取驳回信息 */
|
||||
getRejectInfo(item) {
|
||||
const approvalList = this.getSafeValue(item, 'outsideAccommodationApprovals', []);
|
||||
if (!Array.isArray(approvalList) || approvalList.length === 0) {
|
||||
return {
|
||||
isReject: false,
|
||||
rejectText: ''
|
||||
};
|
||||
}
|
||||
|
||||
const rejectItem = approvalList.find(approval => {
|
||||
return this.getSafeValue(approval, 'approvalResult') === 0;
|
||||
});
|
||||
|
||||
if (rejectItem) {
|
||||
const nodeName = this.getSafeValue(rejectItem, 'approvalNode', '未知').replace('审批', '');
|
||||
return {
|
||||
isReject: true,
|
||||
rejectText: `${nodeName}驳回`
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
isReject: false,
|
||||
rejectText: ''
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取状态文本 */
|
||||
getStatusText(item) {
|
||||
const rejectInfo = this.getRejectInfo(item);
|
||||
if (rejectInfo.isReject) {
|
||||
return rejectInfo.rejectText;
|
||||
}
|
||||
|
||||
const status = this.getSafeValue(item, 'status');
|
||||
const statusMap = {
|
||||
'0': '待提交',
|
||||
'1': '待辅导员审批',
|
||||
'2': '待学院书记审批',
|
||||
'3': '待学工处审批',
|
||||
'4': '待学校领导审批',
|
||||
'5': '审核通过'
|
||||
};
|
||||
return statusMap[status] || '未知状态';
|
||||
},
|
||||
|
||||
/** 时间格式化 */
|
||||
parseTime(time, format = '{y}-{m}-{d}') {
|
||||
if (!time) return '';
|
||||
|
||||
try {
|
||||
const date = new Date(time);
|
||||
if (isNaN(date.getTime())) return '';
|
||||
|
||||
const year = date.getFullYear();
|
||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||
const day = date.getDate().toString().padStart(2, '0');
|
||||
return format.replace('{y}', year).replace('{m}', month).replace('{d}', day);
|
||||
} catch (error) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
|
||||
/** 查询数据 */
|
||||
getList(isRefresh = false) {
|
||||
if (isRefresh) {
|
||||
this.loading = true;
|
||||
this.hasMore = true;
|
||||
this.queryParams.pageNum = 1;
|
||||
this.outsideAccommodationApplyList = [];
|
||||
} else {
|
||||
this.loadingMore = true;
|
||||
}
|
||||
|
||||
listOutsideAccommodationApply(this.queryParams).then(response => {
|
||||
const res = response || {};
|
||||
const newData = Array.isArray(res.rows) ? res.rows : [];
|
||||
this.totalCount = Number(res.total) || 0;
|
||||
|
||||
if (isRefresh) {
|
||||
this.outsideAccommodationApplyList = newData;
|
||||
} else {
|
||||
this.outsideAccommodationApplyList = [...this.outsideAccommodationApplyList, ...newData];
|
||||
}
|
||||
|
||||
// 更新状态
|
||||
this.loading = false;
|
||||
this.loadingMore = false;
|
||||
this.hasMore = this.outsideAccommodationApplyList.length < this.totalCount;
|
||||
|
||||
}).catch((error) => {
|
||||
console.error('数据加载失败:', error);
|
||||
this.loading = false;
|
||||
this.loadingMore = false;
|
||||
uni.showToast({
|
||||
title: '数据加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
},
|
||||
// 计算列表内容顶部外边距
|
||||
setList() {
|
||||
// 获取搜索框元素高度
|
||||
let search = document.getElementById("search")
|
||||
// 获取列表内容元素
|
||||
let listContainer = document.getElementById("list-container")
|
||||
// 设置列表内容的顶部外边距,让内容不被搜索框遮挡
|
||||
listContainer.style.marginTop = `${search.offsetHeight}px`
|
||||
},
|
||||
/** 获取用户信息 */
|
||||
getUser() {
|
||||
getUserProfile().then(response => {
|
||||
const res = response || {};
|
||||
this.user = res.data || {};
|
||||
this.roleGroup = res.roleGroup || '';
|
||||
// 填充查询条件
|
||||
if (this.roleGroup.includes("学生")) {
|
||||
this.queryParams.studentName = this.user.nickName || '';
|
||||
} else if (this.roleGroup.includes("辅导员")) {
|
||||
this.queryParams.teacherName = this.user.nickName || '';
|
||||
this.setList()
|
||||
} else if (this.roleGroup.includes("二级学院")) {
|
||||
this.queryParams.deptName = this.user.dept?.deptName || '';
|
||||
this.setList()
|
||||
} else {
|
||||
this.setList()
|
||||
}
|
||||
|
||||
this.getList(true);
|
||||
}).catch((error) => {
|
||||
console.error('用户信息获取失败:', error);
|
||||
this.loading = false;
|
||||
uni.showToast({
|
||||
title: '用户信息加载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/** 搜索 */
|
||||
handleQuery() {
|
||||
this.getList(true);
|
||||
},
|
||||
|
||||
/** 重置 */
|
||||
resetQuery() {
|
||||
this.queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 5,
|
||||
studentNo: null,
|
||||
studentName: null,
|
||||
deptName: null,
|
||||
className: null,
|
||||
teacherName: null
|
||||
};
|
||||
|
||||
// 重新填充角色相关的默认查询条件
|
||||
if (this.roleGroup.includes("学生")) {
|
||||
this.queryParams.studentName = this.user.nickName || '';
|
||||
} else if (this.roleGroup.includes("辅导员")) {
|
||||
this.queryParams.teacherName = this.user.nickName || '';
|
||||
} else if (this.roleGroup.includes("二级学院")) {
|
||||
this.queryParams.deptName = this.user.dept?.deptName || '';
|
||||
}
|
||||
|
||||
this.getList(true);
|
||||
},
|
||||
|
||||
/** 加载更多 */
|
||||
handleLoadMore() {
|
||||
if (this.loadingMore || !this.hasMore) return;
|
||||
|
||||
this.queryParams.pageNum += 1;
|
||||
this.getList(false);
|
||||
},
|
||||
|
||||
/** 查看详情 */
|
||||
detail(item, text) {
|
||||
const id = this.getSafeValue(item, 'id');
|
||||
if (!id) {
|
||||
uni.showToast({
|
||||
title: '数据异常,无法查看详情',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (text == '详情') {
|
||||
uni.navigateTo({
|
||||
url: `/pages/dormitory/outsideAccommodation/applicationForm?id=${id}&type=detail`
|
||||
});
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: `/pages/dormitory/outsideAccommodation/applicationForm?id=${id}`
|
||||
});
|
||||
}
|
||||
},
|
||||
// 跳转添加页面
|
||||
addOutsideAccommodation() {
|
||||
if (this.roleGroup === "学生") {
|
||||
if (this.outsideAccommodationApplyList.length > 0) {
|
||||
uni.showToast({
|
||||
title: '请勿重复提交',
|
||||
icon: 'none'
|
||||
});
|
||||
return
|
||||
}
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: `/pages/dormitory/outsideAccommodation/applicationForm`
|
||||
})
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.add {
|
||||
position: fixed;
|
||||
bottom: 50rpx;
|
||||
right: 50rpx;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #1890FF;
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 60rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.3);
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
/* 全局样式 */
|
||||
.app-container {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f7fa;
|
||||
min-height: 100vh;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.mr-5 {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* 搜索区样式 */
|
||||
.fixed-search-wrap {
|
||||
z-index: 90;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #eee;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.search-content {
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.search-card {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 60rpx;
|
||||
padding: 14rpx 20rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.filter-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
flex: 1;
|
||||
min-width: 120rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.filter-label {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
.picker-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
padding: 14rpx 16rpx;
|
||||
background-color: #f5f7fa;
|
||||
border-radius: 12rpx;
|
||||
height: 60rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.action-row {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.reset-btn,
|
||||
.search-btn {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
line-height: 72rpx;
|
||||
border-radius: 36rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.reset-btn {
|
||||
background-color: #fff;
|
||||
color: #1890FF;
|
||||
border: 1px solid #1890FF;
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
background-color: #1890FF;
|
||||
color: #fff;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
/* 列表滚动容器 */
|
||||
.list-container {
|
||||
width: 100%;
|
||||
height: calc(100vh - 100rpx);
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.loading-wrap {
|
||||
padding: 60rpx 0;
|
||||
}
|
||||
|
||||
/* 加载更多区域 */
|
||||
.load-more-wrap {
|
||||
padding: 30rpx 0;
|
||||
text-align: center;
|
||||
height: 80rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 空数据状态 */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 0;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin-top: 30rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.empty-tip {
|
||||
margin-top: 16rpx;
|
||||
font-size: 26rpx;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
|
||||
/* 卡片列表 */
|
||||
.card-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
/* 申请卡片 */
|
||||
.apply-card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.card-hover {
|
||||
transform: translateY(-4rpx);
|
||||
box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 卡片头部 */
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 24rpx;
|
||||
background: linear-gradient(135deg, #e8f4f8 0%, #f0f8fb 100%);
|
||||
border-bottom: 1rpx solid #f2f2f2;
|
||||
}
|
||||
|
||||
.apply-no {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.label-text {
|
||||
font-size: 26rpx;
|
||||
color: #606266;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.no-text {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
/* 状态标签样式 */
|
||||
.status-label {
|
||||
height: 44rpx;
|
||||
line-height: 44rpx;
|
||||
font-size: 24rpx;
|
||||
padding: 0 16rpx;
|
||||
border-radius: 22rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.status-success {
|
||||
background-color: #67c23a;
|
||||
}
|
||||
|
||||
.status-warning {
|
||||
background-color: #e6a23c;
|
||||
}
|
||||
|
||||
.status-error {
|
||||
background-color: #f56c6c;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
background-color: #909399;
|
||||
}
|
||||
|
||||
.status-default {
|
||||
background-color: #409eff;
|
||||
}
|
||||
|
||||
/* 有效/到期标签 */
|
||||
.valid-label {
|
||||
height: 44rpx;
|
||||
line-height: 44rpx;
|
||||
font-size: 22rpx;
|
||||
padding: 0 12rpx;
|
||||
border-radius: 22rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.valid-success {
|
||||
background-color: #67c23a;
|
||||
}
|
||||
|
||||
.valid-info {
|
||||
background-color: #909399;
|
||||
}
|
||||
|
||||
/* 住宿费状态标签 */
|
||||
.fee-label {
|
||||
display: inline-block;
|
||||
height: 36rpx;
|
||||
line-height: 36rpx;
|
||||
font-size: 22rpx;
|
||||
padding: 0 12rpx;
|
||||
border-radius: 18rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fee-success {
|
||||
background-color: #67c23a;
|
||||
}
|
||||
|
||||
.fee-info {
|
||||
background-color: #f56c6c;
|
||||
}
|
||||
|
||||
/* 折叠面板 */
|
||||
.collapse-item {
|
||||
--uni-collapse-item-header-padding: 24rpx;
|
||||
--uni-collapse-item-content-padding: 0;
|
||||
--uni-collapse-item-header-font-size: 28rpx;
|
||||
--uni-collapse-item-header-color: #303133;
|
||||
}
|
||||
|
||||
/* 信息网格 */
|
||||
.info-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 24rpx;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.info-grid .info-item {
|
||||
/* width: calc(50% - 10rpx); */
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* 信息表单 */
|
||||
.info-form {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.info-form .form-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 24rpx;
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.info-form .form-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.split-text {
|
||||
margin: 0 10rpx;
|
||||
color: #c0c4cc;
|
||||
}
|
||||
|
||||
/* 标签和值样式 */
|
||||
.label {
|
||||
color: #606266;
|
||||
margin-right: 12rpx;
|
||||
font-weight: 500;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.info-form .label {
|
||||
margin-bottom: 8rpx;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #303133;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 审批记录 */
|
||||
.approval-list {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.approval-item {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
padding: 12rpx 0;
|
||||
border-bottom: 1rpx dashed #f2f2f2;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
.approval-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.approval-node {
|
||||
color: #606266;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.approval-result {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.result-pass {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.result-reject {
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
.approval-time {
|
||||
color: #909399;
|
||||
font-size: 24rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.approval-remark {
|
||||
color: #303133;
|
||||
font-size: 24rpx;
|
||||
width: 100%;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.empty-approval {
|
||||
padding: 24rpx;
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
/* 卡片操作区 */
|
||||
.card-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 20rpx 24rpx;
|
||||
border-top: 1rpx solid #f2f2f2;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.detail-btn {
|
||||
color: #409eff;
|
||||
font-size: 26rpx;
|
||||
padding: 0 20rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
/* 适配小屏幕 */
|
||||
@media (max-width: 650rpx) {
|
||||
.info-grid .info-item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.list-container {
|
||||
/* height: calc(100vh - 420rpx); */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="form-container">
|
||||
<view class="form-title">2025-2026学年学生宿舍入住收集表</view>
|
||||
<view class="form-title">学生宿舍入住收集表</view>
|
||||
<view class="form-desc">涉及住宿费核算,请同学们按照实际入住情况填写。</view>
|
||||
|
||||
<!-- 1. 校区 -->
|
||||
@@ -81,6 +81,16 @@
|
||||
</picker>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="item-label">中国农业银行卡号</view>
|
||||
<input class="input" v-model="form.xhk" placeholder="请输入中国农业银行卡号" />
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<view class="item-label">开户行</view>
|
||||
<input class="input" v-model="form.bankAddr" placeholder="请输入开户行" />
|
||||
</view>
|
||||
|
||||
<!-- 9. 本人证件照 -->
|
||||
<view class="form-item">
|
||||
<view class="item-label">
|
||||
@@ -103,408 +113,530 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listAllCampus,
|
||||
listParkByCampus,
|
||||
listBuildingByPark,
|
||||
listFloorByBuilding,
|
||||
listAllRoomByFloor,
|
||||
addStudent,
|
||||
submitOwnInfo as submitExtraInfo
|
||||
} from "@/api/dms/studentDormInfo/index.js"
|
||||
import {
|
||||
getUserProfile
|
||||
} from '@/api/system/user'
|
||||
import {
|
||||
previewImg
|
||||
} from "@/utils/uploadImg.js"
|
||||
import {
|
||||
checkPic
|
||||
} from "@/utils/checkPic.js"
|
||||
import uploadFile from "@/plugins/upload.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
user: [],
|
||||
form: {
|
||||
campusName: '',
|
||||
parkName: '',
|
||||
buildingName: '',
|
||||
floorName: '',
|
||||
roomNo: '',
|
||||
stuNo: '',
|
||||
isDormitoryHead: '',
|
||||
isDormHead: '',
|
||||
checkinTime: '',
|
||||
photo: '',
|
||||
teacherName: '',
|
||||
className: '',
|
||||
deptName: '',
|
||||
stuName: '',
|
||||
displayText: '',
|
||||
isInStudentsleep: '是',
|
||||
photoData: ''
|
||||
},
|
||||
// 校区选项
|
||||
campusOptions: [],
|
||||
// 园区选项(按校区联动)
|
||||
parkOptions: [],
|
||||
// 楼栋选项(按园区联动)
|
||||
buildingOptions: [],
|
||||
// 楼层选项(下拉框)
|
||||
floorOptions: [],
|
||||
// 宿舍号选项(下拉框)
|
||||
dormOptions: [],
|
||||
// 宿舍长选项
|
||||
dormHeadOptions: ['否', '是'],
|
||||
// 当前选中项的id
|
||||
selectedCampus: null, // 选中的校区({id, name})
|
||||
selectedPark: null, // 选中的园区
|
||||
selectedBuilding: null, // 选中的楼栋
|
||||
selectedFloor: null, // 选中的楼层
|
||||
selectedDorm: null, //选中的宿舍
|
||||
};
|
||||
import {
|
||||
addStudent,
|
||||
listAllCampus,
|
||||
listAllRoomByFloor,
|
||||
listBuildingByPark,
|
||||
listFloorByBuilding,
|
||||
listParkByCampus,
|
||||
submitOwnInfo as submitExtraInfo,
|
||||
getStudentDetail,
|
||||
updateStudent
|
||||
} from "@/api/dms/studentDormInfo/index.js";
|
||||
import { alipayVali } from "@/api/helpFunc/bank.js";
|
||||
import {
|
||||
getUserProfile
|
||||
} from '@/api/system/user';
|
||||
import uploadFile from "@/plugins/upload.js";
|
||||
import config from '@/config'
|
||||
import {
|
||||
checkPic
|
||||
} from "@/utils/checkPic.js";
|
||||
import request from "@/utils/request";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
user: [],
|
||||
form: {
|
||||
campusName: '',
|
||||
parkName: '',
|
||||
buildingName: '',
|
||||
floorName: '',
|
||||
roomNo: '',
|
||||
stuNo: '',
|
||||
isDormitoryHead: '',
|
||||
isDormHead: '',
|
||||
checkinTime: '',
|
||||
photo: '',
|
||||
xhk: '',
|
||||
bankAddr: '',
|
||||
teacherName: '',
|
||||
className: '',
|
||||
deptName: '',
|
||||
stuName: '',
|
||||
displayText: '',
|
||||
isInStudentsleep: '是',
|
||||
photoData: ''
|
||||
},
|
||||
// 校区选项
|
||||
campusOptions: [],
|
||||
// 园区选项(按校区联动)
|
||||
parkOptions: [],
|
||||
// 楼栋选项(按园区联动)
|
||||
buildingOptions: [],
|
||||
// 楼层选项(下拉框)
|
||||
floorOptions: [],
|
||||
// 宿舍号选项(下拉框)
|
||||
dormOptions: [],
|
||||
// 宿舍长选项
|
||||
dormHeadOptions: ['否', '是'],
|
||||
// 当前选中项的id
|
||||
selectedCampus: null, // 选中的校区({id, name})
|
||||
selectedPark: null, // 选中的园区
|
||||
selectedBuilding: null, // 选中的楼栋
|
||||
selectedFloor: null, // 选中的楼层
|
||||
selectedDorm: null, //选中的宿舍
|
||||
mode: 'add',
|
||||
editId: null
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.getUserProfile()
|
||||
this.listAllCampus()
|
||||
if (options && options.mode === 'edit' && options.id) {
|
||||
this.mode = 'edit'
|
||||
this.editId = Number(options.id)
|
||||
this.initEdit(this.editId)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取用户信息
|
||||
async getUserProfile() {
|
||||
try {
|
||||
const res = await getUserProfile()
|
||||
this.user = res
|
||||
this.form.stuNo = this.user.data.userName
|
||||
console.log('当前用户信息:', res)
|
||||
} catch (err) {
|
||||
console.error('获取用户信息失败:', err)
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getUserProfile()
|
||||
this.listAllCampus()
|
||||
// 获取校区数据
|
||||
async listAllCampus() {
|
||||
let res = await listAllCampus()
|
||||
if (res.code == 200) {
|
||||
this.campusOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
// 编辑模式初始化
|
||||
async initEdit(id) {
|
||||
try {
|
||||
const res = await getStudentDetail(id)
|
||||
if (res.code !== 200) {
|
||||
uni.showToast({ title: '加载详情失败', icon: 'none' })
|
||||
return
|
||||
}
|
||||
const d = res.data
|
||||
this.form.stuNo = d.stuNo || this.form.stuNo
|
||||
this.form.isDormHead = d.isDormitoryHead === 1 ? '是' : '否'
|
||||
this.form.checkinTime = d.checkinTime ? String(d.checkinTime).slice(0, 10) : ''
|
||||
this.form.isInStudentsleep = d.isInStudentsleep || this.form.isInStudentsleep
|
||||
|
||||
const own = await request({ url: '/system/student/getOwnInfo', method: 'get' })
|
||||
if (own && own.data) {
|
||||
this.form.xhk = own.data.xhk || ''
|
||||
this.form.bankAddr = own.data.bankAddr || ''
|
||||
}
|
||||
|
||||
const extra = await request({ url: '/comprehensive/extraInfo/getOwnInfo', method: 'get' })
|
||||
if (extra && extra.data) {
|
||||
this.form.photo = extra.data.whitePhoto || ''
|
||||
this.form.photoData = extra.data.whitePhoto ? (config.baseUrl + extra.data.whitePhoto) : ''
|
||||
}
|
||||
|
||||
const campusName = d.campusName
|
||||
const parkName = d.parkName
|
||||
const buildingName = d.buildingName
|
||||
const floorName = d.floorName
|
||||
const roomNo = d.roomNo
|
||||
|
||||
const campus = this.campusOptions.find(c => c.name === campusName)
|
||||
if (campus) {
|
||||
this.form.campusName = campus.name
|
||||
this.selectedCampus = campus.id
|
||||
await this.listParkByCampus(this.selectedCampus)
|
||||
const park = this.parkOptions.find(p => p.name === parkName)
|
||||
if (park) {
|
||||
this.form.parkName = park.name
|
||||
this.selectedPark = park.id
|
||||
await this.listBuildingByPark(this.selectedPark)
|
||||
const building = this.buildingOptions.find(b => b.name === buildingName)
|
||||
if (building) {
|
||||
this.form.buildingName = building.name
|
||||
this.selectedBuilding = building.id
|
||||
await this.listFloorByBuilding(this.selectedBuilding)
|
||||
let floor = this.floorOptions.find(f => String(f.floor) === String(floorName))
|
||||
if (!floor) {
|
||||
for (const f of this.floorOptions) {
|
||||
await this.listAllRoomByFloor(f.id)
|
||||
const dormTry = this.dormOptions.find(r => r.roomNo === roomNo)
|
||||
if (dormTry) {
|
||||
floor = f
|
||||
this.selectedDorm = dormTry.id
|
||||
this.form.roomNo = dormTry.roomNo
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (floor) {
|
||||
this.form.floorName = floor.floor
|
||||
this.selectedFloor = floor.id
|
||||
if (!this.selectedDorm) {
|
||||
await this.listAllRoomByFloor(this.selectedFloor)
|
||||
const dorm = this.dormOptions.find(r => r.roomNo === roomNo)
|
||||
if (dorm) {
|
||||
this.form.roomNo = dorm.roomNo
|
||||
this.selectedDorm = dorm.id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
},
|
||||
// 根据校区id获取园区
|
||||
async listParkByCampus(id) {
|
||||
let res = await listParkByCampus(id)
|
||||
if (res.code == 200) {
|
||||
this.parkOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取用户信息
|
||||
async getUserProfile() {
|
||||
try {
|
||||
const res = await getUserProfile()
|
||||
this.user = res
|
||||
this.form.stuNo = this.user.data.userName
|
||||
console.log('当前用户信息:', res)
|
||||
} catch (err) {
|
||||
console.error('获取用户信息失败:', err)
|
||||
}
|
||||
},
|
||||
// 获取校区数据
|
||||
async listAllCampus() {
|
||||
let res = await listAllCampus()
|
||||
if (res.code == 200) {
|
||||
this.campusOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
// 根据校区id获取园区
|
||||
async listParkByCampus(id) {
|
||||
let res = await listParkByCampus(id)
|
||||
if (res.code == 200) {
|
||||
this.parkOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
// 根据园区id获取楼栋
|
||||
async listBuildingByPark(id) {
|
||||
let res = await listBuildingByPark(id)
|
||||
if (res.code == 200) {
|
||||
this.buildingOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
// 根据楼栋id获取楼层
|
||||
async listFloorByBuilding(id) {
|
||||
let res = await listFloorByBuilding(id)
|
||||
if (res.code == 200) {
|
||||
this.floorOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
// 根据楼层id获取宿舍号
|
||||
async listAllRoomByFloor(id) {
|
||||
let res = await listAllRoomByFloor(id)
|
||||
if (res.code == 200) {
|
||||
this.dormOptions = [...res.data]
|
||||
// 遍历数据,为每个对象添加 displayText 属性
|
||||
this.dormOptions = res.data.map(v => ({
|
||||
...v, // 保留原对象所有属性
|
||||
// 新增拼接后的显示文本属性
|
||||
displayText: `${v.roomNo} -- ${v.gender} -- 床位 ${v.bedNum} -- 已住 ${v.occupancy}`,
|
||||
isFull: v.occupancy >= v.bedNum // 新增:判断是否满人
|
||||
}));
|
||||
}
|
||||
},
|
||||
// 校区选择变化
|
||||
handleCampusChange(e) {
|
||||
this.form.campusName = this.campusOptions[e.detail.value].name;
|
||||
this.form.parkName = ''; // 重置园区
|
||||
this.form.buildingName = ''; // 重置楼栋
|
||||
this.form.floorName = ''; // 重置楼层
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的校区id
|
||||
this.selectedCampus = this.campusOptions[e.detail.value].id;
|
||||
// 获取对应校区下面的园区
|
||||
this.listParkByCampus(this.selectedCampus)
|
||||
},
|
||||
// 园区选择变化
|
||||
handleParkChange(e) {
|
||||
this.form.parkName = this.parkOptions[e.detail.value].name;
|
||||
this.form.buildingName = ''; // 重置楼栋
|
||||
this.form.floorName = ''; // 重置楼层
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的园区的id
|
||||
this.selectedPark = this.parkOptions[e.detail.value].id;
|
||||
// 获取对应园区下面的楼栋
|
||||
this.listBuildingByPark(this.selectedPark)
|
||||
},
|
||||
// 楼栋选择变化
|
||||
handleBuildingChange(e) {
|
||||
this.form.buildingName = this.buildingOptions[e.detail.value].name;
|
||||
this.form.floorName = ''; // 重置楼层
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的楼栋的id
|
||||
this.selectedBuilding = this.buildingOptions[e.detail.value].id;
|
||||
// 获取选中的楼栋下面的楼层
|
||||
this.listFloorByBuilding(this.selectedBuilding)
|
||||
},
|
||||
// 楼层选择变化(下拉框)
|
||||
handleFloorChange(e) {
|
||||
this.form.floorName = this.floorOptions[e.detail.value].floor;
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的楼层的id
|
||||
this.selectedFloor = this.floorOptions[e.detail.value].id;
|
||||
// 获取选中的楼层下面的宿舍号
|
||||
this.listAllRoomByFloor(this.selectedFloor)
|
||||
},
|
||||
// 宿舍号选择变化(行拉框)
|
||||
handleDormChange(e) {
|
||||
const index = e.detail.value;
|
||||
const selectedDorm = this.dormOptions[index]; // 获取选中的宿舍对象
|
||||
// 根据园区id获取楼栋
|
||||
async listBuildingByPark(id) {
|
||||
let res = await listBuildingByPark(id)
|
||||
if (res.code == 200) {
|
||||
this.buildingOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
// 根据楼栋id获取楼层
|
||||
async listFloorByBuilding(id) {
|
||||
let res = await listFloorByBuilding(id)
|
||||
if (res.code == 200) {
|
||||
this.floorOptions = [...res.data]
|
||||
}
|
||||
},
|
||||
// 根据楼层id获取宿舍号
|
||||
async listAllRoomByFloor(id) {
|
||||
let res = await listAllRoomByFloor(id)
|
||||
if (res.code == 200) {
|
||||
this.dormOptions = [...res.data]
|
||||
// 遍历数据,为每个对象添加 displayText 属性
|
||||
this.dormOptions = res.data.map(v => ({
|
||||
...v, // 保留原对象所有属性
|
||||
// 新增拼接后的显示文本属性
|
||||
displayText: `${v.roomNo} -- ${v.gender} -- 床位 ${v.bedNum} -- 已住 ${v.occupancy}`,
|
||||
isFull: v.occupancy >= v.bedNum // 新增:判断是否满人
|
||||
}));
|
||||
}
|
||||
},
|
||||
// 校区选择变化
|
||||
handleCampusChange(e) {
|
||||
this.form.campusName = this.campusOptions[e.detail.value].name;
|
||||
this.form.parkName = ''; // 重置园区
|
||||
this.form.buildingName = ''; // 重置楼栋
|
||||
this.form.floorName = ''; // 重置楼层
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的校区id
|
||||
this.selectedCampus = this.campusOptions[e.detail.value].id;
|
||||
// 获取对应校区下面的园区
|
||||
this.listParkByCampus(this.selectedCampus)
|
||||
},
|
||||
// 园区选择变化
|
||||
handleParkChange(e) {
|
||||
this.form.parkName = this.parkOptions[e.detail.value].name;
|
||||
this.form.buildingName = ''; // 重置楼栋
|
||||
this.form.floorName = ''; // 重置楼层
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的园区的id
|
||||
this.selectedPark = this.parkOptions[e.detail.value].id;
|
||||
// 获取对应园区下面的楼栋
|
||||
this.listBuildingByPark(this.selectedPark)
|
||||
},
|
||||
// 楼栋选择变化
|
||||
handleBuildingChange(e) {
|
||||
this.form.buildingName = this.buildingOptions[e.detail.value].name;
|
||||
this.form.floorName = ''; // 重置楼层
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的楼栋的id
|
||||
this.selectedBuilding = this.buildingOptions[e.detail.value].id;
|
||||
// 获取选中的楼栋下面的楼层
|
||||
this.listFloorByBuilding(this.selectedBuilding)
|
||||
},
|
||||
// 楼层选择变化(下拉框)
|
||||
handleFloorChange(e) {
|
||||
this.form.floorName = this.floorOptions[e.detail.value].floor;
|
||||
this.form.roomNo = ''; // 重置宿舍
|
||||
// 获取选中的楼层的id
|
||||
this.selectedFloor = this.floorOptions[e.detail.value].id;
|
||||
// 获取选中的楼层下面的宿舍号
|
||||
this.listAllRoomByFloor(this.selectedFloor)
|
||||
},
|
||||
// 宿舍号选择变化(行拉框)
|
||||
handleDormChange(e) {
|
||||
const index = e.detail.value;
|
||||
const selectedDorm = this.dormOptions[index]; // 获取选中的宿舍对象
|
||||
|
||||
// 判断是否满人
|
||||
if (selectedDorm.isFull) {
|
||||
// 满人时提示并重置选择
|
||||
uni.showToast({
|
||||
title: `宿舍 ${selectedDorm.roomNo} 已住满,无法选择`,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
// 重置宿舍选择(如果之前有选中值则保留,否则为空)
|
||||
if (!this.form.roomNo) {
|
||||
this.form.roomNo = '';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 未满人时正常选中
|
||||
this.form.roomNo = selectedDorm.roomNo; // 显示拼接文本
|
||||
this.selectedDorm = selectedDorm.id; // 存储宿舍ID(用于提交)
|
||||
},
|
||||
// 宿舍长选择变化
|
||||
handleDormHeadChange(e) {
|
||||
this.form.isDormitoryHead = this.dormHeadOptions[e.detail.value] == '是' ? 1 : 0;
|
||||
this.form.isDormHead = this.dormHeadOptions[e.detail.value]
|
||||
},
|
||||
// 入住时间选择变化
|
||||
handleCheckinTimeChange(e) {
|
||||
this.form.checkinTime = e.detail.value;
|
||||
},
|
||||
// 证件照上传
|
||||
handleUpload() {
|
||||
uni.chooseImage({
|
||||
count: 3,
|
||||
success: async (img) => {
|
||||
let bool = await checkPic(img.tempFiles[0]);
|
||||
if (bool) {
|
||||
uploadFile('/common/upload', img.tempFilePaths[0]).then((res) => {
|
||||
// if (this.form.photo !== "") {
|
||||
// this.form.photo = this.form.photo + "," + JSON.parse(res)
|
||||
// .fileName;
|
||||
// } else {
|
||||
// this.form.photo = JSON.parse(res).fileName;
|
||||
// }
|
||||
this.form.photoData = img.tempFilePaths[0];
|
||||
this.form.photo = JSON.parse(res).fileName;
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
// 提交表单
|
||||
async handleSubmit() {
|
||||
console.log(this.form);
|
||||
// 验证必填项
|
||||
if (
|
||||
!this.form.campusName || // 校区名称(字符串,空则false)
|
||||
!this.form.parkName || // 园区名称(字符串,空则false)
|
||||
!this.form.buildingName || // 楼栋名称(字符串,空则false)
|
||||
(!this.form.floorName && this.form.floorName !== 0) || // 楼层(数值,排除0的误判)
|
||||
(!this.form.roomNo && this.form.roomNo !== 0) || // 宿舍号(数值,排除0的误判)
|
||||
!this.form.isDormHead || // 是否宿舍长(值为"是"/"否")
|
||||
!this.form.checkinTime || // 入住时间(日期字符串,空则false)
|
||||
!this.form.photo // 证件照(blob路径,空则false,若必填需加)
|
||||
) {
|
||||
uni.showToast({
|
||||
title: '带*号的为必填项,请填写完整',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.form.dormitoryId = this.selectedDorm;
|
||||
// 模拟提交
|
||||
uni.showLoading({
|
||||
title: '提交中...'
|
||||
// 判断是否满人
|
||||
if (selectedDorm.isFull) {
|
||||
// 满人时提示并重置选择
|
||||
uni.showToast({
|
||||
title: `宿舍 ${selectedDorm.roomNo} 已住满,无法选择`,
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
// 添加入住信息
|
||||
let res = await addStudent(this.form);
|
||||
if (res.code == 200) {
|
||||
uni.hideLoading();
|
||||
uni.showToast({
|
||||
title: '提交成功',
|
||||
icon: 'success'
|
||||
});
|
||||
// 上次图片头像
|
||||
let data = submitExtraInfo({
|
||||
userId: this.user.data.userId,
|
||||
whitePhoto: this.form.photo
|
||||
})
|
||||
// if (data.code == 200) {
|
||||
// console.log(data);
|
||||
// }
|
||||
|
||||
setTimeout(() => {
|
||||
// 重置表单
|
||||
this.form = {
|
||||
campusName: '',
|
||||
parkName: '',
|
||||
buildingName: '',
|
||||
floorName: '',
|
||||
roomNo: '',
|
||||
stuNo: '',
|
||||
isDormitoryHead: '',
|
||||
checkinTime: '',
|
||||
photo: ''
|
||||
};
|
||||
uni.redirectTo({
|
||||
url: `/pages/dormitory/studentDormInfo/index`
|
||||
// 重置宿舍选择(如果之前有选中值则保留,否则为空)
|
||||
if (!this.form.roomNo) {
|
||||
this.form.roomNo = '';
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 未满人时正常选中
|
||||
this.form.roomNo = selectedDorm.roomNo; // 显示拼接文本
|
||||
this.selectedDorm = selectedDorm.id; // 存储宿舍ID(用于提交)
|
||||
},
|
||||
// 宿舍长选择变化
|
||||
handleDormHeadChange(e) {
|
||||
this.form.isDormitoryHead = this.dormHeadOptions[e.detail.value] == '是' ? 1 : 0;
|
||||
this.form.isDormHead = this.dormHeadOptions[e.detail.value]
|
||||
},
|
||||
// 入住时间选择变化
|
||||
handleCheckinTimeChange(e) {
|
||||
this.form.checkinTime = e.detail.value;
|
||||
},
|
||||
// 证件照上传
|
||||
handleUpload() {
|
||||
uni.chooseImage({
|
||||
count: 3,
|
||||
success: async (img) => {
|
||||
let bool = await checkPic(img.tempFiles[0]);
|
||||
if (bool) {
|
||||
uploadFile('/common/upload', img.tempFilePaths[0]).then((res) => {
|
||||
// if (this.form.photo !== "") {
|
||||
// this.form.photo = this.form.photo + "," + JSON.parse(res)
|
||||
// .fileName;
|
||||
// } else {
|
||||
// this.form.photo = JSON.parse(res).fileName;
|
||||
// }
|
||||
this.form.photoData = img.tempFilePaths[0];
|
||||
this.form.photo = JSON.parse(res).fileName;
|
||||
})
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
// 提交表单
|
||||
async handleSubmit() {
|
||||
console.log(this.form);
|
||||
// 验证必填项
|
||||
if (
|
||||
!this.form.campusName || // 校区名称(字符串,空则false)
|
||||
!this.form.parkName || // 园区名称(字符串,空则false)
|
||||
!this.form.buildingName || // 楼栋名称(字符串,空则false)
|
||||
(!this.form.floorName && this.form.floorName !== 0) || // 楼层(数值,排除0的误判)
|
||||
(!this.form.roomNo && this.form.roomNo !== 0) || // 宿舍号(数值,排除0的误判)
|
||||
!this.form.isDormHead || // 是否宿舍长(值为"是"/"否")
|
||||
!this.form.checkinTime || // 入住时间(日期字符串,空则false)
|
||||
!this.form.photo
|
||||
) {
|
||||
uni.showToast({
|
||||
title: '带*号的为必填项,请填写完整',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.form.xhk) {
|
||||
let cardRes = await alipayVali(this.form.xhk);
|
||||
if (!cardRes || cardRes.validated == false) {
|
||||
uni.showToast({
|
||||
title: '请输入正确的银行卡号',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (cardRes.bank != 'ABC') {
|
||||
uni.showToast({
|
||||
title: '请输入正确的中国农业银行银行卡号',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
this.form.dormitoryId = this.selectedDorm;
|
||||
uni.showLoading({ title: '提交中...' });
|
||||
let res;
|
||||
if (this.mode === 'edit') {
|
||||
const dto = {
|
||||
id: this.editId,
|
||||
dormitoryId: this.form.dormitoryId,
|
||||
stuNo: this.form.stuNo,
|
||||
isDormitoryHead: this.form.isDormHead === '是' ? 1 : 0,
|
||||
checkinTime: this.form.checkinTime ? new Date(this.form.checkinTime) : null,
|
||||
isInStudentsleep: this.form.isInStudentsleep || '是'
|
||||
}
|
||||
res = await updateStudent(dto)
|
||||
} else {
|
||||
res = await addStudent(this.form);
|
||||
}
|
||||
if (res.code == 200) {
|
||||
// 上次图片头像
|
||||
let data = submitExtraInfo({
|
||||
userId: this.user.data.userId,
|
||||
whitePhoto: this.form.photo
|
||||
})
|
||||
let own = await request({ url: '/system/student/getOwnInfo', method: 'get' });
|
||||
let payload = {
|
||||
phone: own.data.phone,
|
||||
xhk: this.form.xhk ? this.form.xhk.replace(' ', '') : own.data.xhk,
|
||||
idCard: own.data.idCard,
|
||||
birthday: own.data.birthday,
|
||||
bankAddr: this.form.bankAddr ? this.form.bankAddr : own.data.bankAddr
|
||||
};
|
||||
await request({ url: '/system/student/changeOwnInfo', method: 'POST', data: payload });
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '提交成功', icon: 'success' });
|
||||
// if (data.code == 200) {
|
||||
// console.log(data);
|
||||
// }
|
||||
|
||||
setTimeout(() => {
|
||||
// 重置表单
|
||||
this.form = {
|
||||
campusName: '',
|
||||
parkName: '',
|
||||
buildingName: '',
|
||||
floorName: '',
|
||||
roomNo: '',
|
||||
stuNo: '',
|
||||
isDormitoryHead: '',
|
||||
checkinTime: '',
|
||||
photo: '',
|
||||
xhk: '',
|
||||
bankAddr: ''
|
||||
};
|
||||
uni.redirectTo({ url: `/pages/dormitory/studentDormInfo/index` })
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.form-container {
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
min-height: 100vh;
|
||||
}
|
||||
.form-container {
|
||||
padding: 30rpx;
|
||||
background-color: #fff;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.form-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.form-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.form-desc {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
.form-desc {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
.form-item {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.item-label {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.item-label {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
// 红色*号样式
|
||||
.required {
|
||||
color: #ff4d4f;
|
||||
margin-right: 6rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
// 红色*号样式
|
||||
.required {
|
||||
color: #ff4d4f;
|
||||
margin-right: 6rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.item-desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
// 下拉框样式
|
||||
.picker-input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
// 下拉框样式
|
||||
.picker-input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
// 输入框样式
|
||||
.input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
// 输入框样式
|
||||
.input {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8rpx;
|
||||
padding: 0 20rpx;
|
||||
box-sizing: border-box;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
// 图片上传样式
|
||||
.upload-btn {
|
||||
width: 200rpx;
|
||||
height: 80rpx;
|
||||
border: 1px dashed #ccc;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
// 图片上传样式
|
||||
.upload-btn {
|
||||
width: 200rpx;
|
||||
height: 80rpx;
|
||||
border: 1px dashed #ccc;
|
||||
border-radius: 8rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 10rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.upload-icon {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.upload-tip {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.upload-tip {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.upload-preview {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.upload-preview {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
border-radius: 8rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.upload-preview image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.upload-preview image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// 提交按钮样式
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
border-radius: 45rpx;
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
// 提交按钮样式
|
||||
.submit-btn {
|
||||
width: 100%;
|
||||
height: 90rpx;
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
border-radius: 45rpx;
|
||||
margin-top: 60rpx;
|
||||
}
|
||||
</style>
|
||||
BIN
static/images/workbench/outsideAccommodation.png
Normal file
BIN
static/images/workbench/outsideAccommodation.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Reference in New Issue
Block a user