提交代码
No files matched your search
@@ -323,4 +323,5 @@ docs/变更管理/
|
||||
移动端附件组件规范.md
|
||||
移动端违纪记录模块开发规范.md
|
||||
.playwright-mcp/
|
||||
|
||||
查找界面中涉及到的权限字符.md
|
||||
docs/部署文档/nginx配置/hzdyjsweb.camasort.com.conf
|
||||
@@ -73,7 +73,39 @@ public class HqSatQuestionServiceImpl implements IHqSatQuestionService {
|
||||
private LambdaQueryWrapper<HqSatQuestion> buildQueryWrapper(HqSatQuestionBo bo) {
|
||||
Map<String, Object> params = bo.getParams();
|
||||
LambdaQueryWrapper<HqSatQuestion> lqw = Wrappers.lambdaQuery();
|
||||
lqw.orderByAsc(HqSatQuestion::getId);
|
||||
|
||||
// 处理排序参数
|
||||
if (params != null && params.containsKey("orderByColumn") && params.containsKey("isAsc")) {
|
||||
String orderByColumn = (String) params.get("orderByColumn");
|
||||
String isAsc = (String) params.get("isAsc");
|
||||
|
||||
if ("createTime".equals(orderByColumn)) {
|
||||
if ("desc".equals(isAsc)) {
|
||||
lqw.orderByDesc(HqSatQuestion::getCreateTime);
|
||||
} else {
|
||||
lqw.orderByAsc(HqSatQuestion::getCreateTime);
|
||||
}
|
||||
} else if ("updateTime".equals(orderByColumn)) {
|
||||
if ("desc".equals(isAsc)) {
|
||||
lqw.orderByDesc(HqSatQuestion::getUpdateTime);
|
||||
} else {
|
||||
lqw.orderByAsc(HqSatQuestion::getUpdateTime);
|
||||
}
|
||||
} else if ("sortOrder".equals(orderByColumn)) {
|
||||
if ("desc".equals(isAsc)) {
|
||||
lqw.orderByDesc(HqSatQuestion::getSortOrder);
|
||||
} else {
|
||||
lqw.orderByAsc(HqSatQuestion::getSortOrder);
|
||||
}
|
||||
} else {
|
||||
// 默认按创建时间倒序
|
||||
lqw.orderByDesc(HqSatQuestion::getCreateTime);
|
||||
}
|
||||
} else {
|
||||
// 默认按创建时间倒序
|
||||
lqw.orderByDesc(HqSatQuestion::getCreateTime);
|
||||
}
|
||||
|
||||
// 添加ID查询条件
|
||||
lqw.eq(bo.getId() != null, HqSatQuestion::getId, bo.getId());
|
||||
lqw.eq(bo.getDeleted() != null, HqSatQuestion::getDeleted, bo.getDeleted());
|
||||
|
||||
@@ -15,11 +15,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
|
||||
INNER JOIN sys_user_role ur ON u.user_id = ur.user_id
|
||||
INNER JOIN sys_role r ON ur.role_id = r.role_id
|
||||
WHERE (r.role_key = 'maintenance_worker'
|
||||
OR r.role_name = '维修人员'
|
||||
OR r.role_id = 5
|
||||
OR r.role_name LIKE '%维修%'
|
||||
OR r.role_key LIKE '%worker%')
|
||||
WHERE r.role_key = 'maintenance_worker'
|
||||
AND u.status = '0'
|
||||
AND u.del_flag = '0'
|
||||
ORDER BY u.user_id
|
||||
|
||||
@@ -41,17 +41,65 @@ server {
|
||||
add_header Pragma "no-cache";
|
||||
}
|
||||
|
||||
# API代理配置(如果需要避免CORS问题)
|
||||
# location /api/ {
|
||||
# proxy_pass http://47.121.125.41:8080/;
|
||||
# proxy_set_header Host $host;
|
||||
# proxy_set_header X-Real-IP $remote_addr;
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# proxy_set_header X-Forwarded-Proto $scheme;
|
||||
# proxy_connect_timeout 60s;
|
||||
# proxy_send_timeout 60s;
|
||||
# proxy_read_timeout 60s;
|
||||
# }
|
||||
# Warm-Flow工作流UI代理配置(重要:必须放在Vue路由配置之前,使用^~确保优先级)
|
||||
location ^~ /prod-api/warm-flow-ui/ {
|
||||
proxy_pass http://47.121.125.41:8080/warm-flow-ui/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 支持WebSocket和SSE
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 86400s;
|
||||
|
||||
# CORS处理
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,clientid';
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
# API代理配置(使用^~确保优先级,避免被Vue路由配置干扰)
|
||||
location ^~ /prod-api/ {
|
||||
proxy_pass http://47.121.125.41:8080/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 支持WebSocket和SSE
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 86400s;
|
||||
|
||||
# CORS处理
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
|
||||
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization,clientid';
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
# Gzip压缩配置
|
||||
gzip on;
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
<GridLayout :columns="3" gap="16px">
|
||||
<!-- 卡片开始 -->
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:info:list'])"
|
||||
v-if="hasPermi(['student:info:listapp'])"
|
||||
title="学生信息"
|
||||
@click="handleServiceClick"
|
||||
>
|
||||
@@ -87,7 +87,7 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
<!-- 卡片结束 -->
|
||||
<ServiceItem
|
||||
<!-- <ServiceItem
|
||||
v-if="hasPermi(['student:dorm:list'])"
|
||||
title="宿舍管理"
|
||||
@click="handleServiceClick"
|
||||
@@ -95,10 +95,10 @@
|
||||
<template #icon>
|
||||
<u-icon name="home" size="24" />
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</ServiceItem> -->
|
||||
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:leave:list'])"
|
||||
v-if="hasPermi(['student:leave:listapp'])"
|
||||
title="学生请假"
|
||||
@click="gotoStudentLeave"
|
||||
>
|
||||
@@ -111,7 +111,7 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
|
||||
<ServiceItem
|
||||
<!-- <ServiceItem
|
||||
v-if="hasPermi(['student:psychology:list'])"
|
||||
title="心理健康"
|
||||
@click="handleServiceClick"
|
||||
@@ -119,9 +119,9 @@
|
||||
<template #icon>
|
||||
<u-icon name="heart" size="24" />
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</ServiceItem> -->
|
||||
|
||||
<ServiceItem
|
||||
<!-- <ServiceItem
|
||||
v-if="hasPermi(['student:club:list'])"
|
||||
title="社团管理"
|
||||
@click="handleServiceClick"
|
||||
@@ -129,9 +129,9 @@
|
||||
<template #icon>
|
||||
<u-icon name="star" size="24" />
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</ServiceItem> -->
|
||||
|
||||
<ServiceItem
|
||||
<!-- <ServiceItem
|
||||
v-if="hasPermi(['student:counsel:list'])"
|
||||
title="心理咨询"
|
||||
@click="handleServiceClick"
|
||||
@@ -139,10 +139,10 @@
|
||||
<template #icon>
|
||||
<u-icon name="chat" size="24" />
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</ServiceItem> -->
|
||||
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:info:edit'])"
|
||||
v-if="hasPermi(['student:info:editapp'])"
|
||||
title="学生信息完善"
|
||||
@click="gotoStudentInfoComplete"
|
||||
>
|
||||
@@ -182,7 +182,7 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:dormviolation:list'])"
|
||||
v-if="hasPermi(['student:dormviolation:listapp'])"
|
||||
title="宿舍违纪"
|
||||
@click="gotoDormViolation"
|
||||
>
|
||||
@@ -195,7 +195,7 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:dormhygiene:list'])"
|
||||
v-if="hasPermi(['student:dormhygiene:listapp'])"
|
||||
title="宿舍卫生检查"
|
||||
@click="gotoDormHygiene"
|
||||
>
|
||||
@@ -208,7 +208,7 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:dormhygiene:studentlist'])"
|
||||
v-if="hasPermi(['student:dormhygiene:studentlistapp'])"
|
||||
title="宿舍卫生检查(学生)"
|
||||
@click="gotoStudentDormHygiene"
|
||||
>
|
||||
@@ -236,7 +236,7 @@
|
||||
</ServiceItem>
|
||||
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:violation:list'])"
|
||||
v-if="hasPermi(['student:violation:listapp'])"
|
||||
title="违纪记录(学生)"
|
||||
@click="gotoStudentViolation"
|
||||
>
|
||||
@@ -250,7 +250,7 @@
|
||||
</ServiceItem>
|
||||
|
||||
<ServiceItem
|
||||
v-if="hasPermi(['student:assessment:apply'])"
|
||||
v-if="hasPermi(['student:assessment:applyapp'])"
|
||||
title="考核申请"
|
||||
@click="gotoAssessmentApply"
|
||||
>
|
||||
@@ -266,7 +266,7 @@
|
||||
</Card>
|
||||
|
||||
<!-- 后勤管理 -->
|
||||
<Card v-if="hasLogisticsServices">
|
||||
<!-- <Card v-if="hasLogisticsServices">
|
||||
<template #header>
|
||||
<view class="section-header">
|
||||
<u-icon name="setting" size="18" color="#52c41a" />
|
||||
@@ -334,10 +334,10 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</GridLayout>
|
||||
</Card>
|
||||
</Card> -->
|
||||
|
||||
<!-- 招生就业 -->
|
||||
<Card v-if="hasRecruitmentServices">
|
||||
<!-- <Card v-if="hasRecruitmentServices">
|
||||
<template #header>
|
||||
<view class="section-header">
|
||||
<u-icon name="trophy" size="18" color="#fa8c16" />
|
||||
@@ -375,10 +375,10 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</GridLayout>
|
||||
</Card>
|
||||
</Card> -->
|
||||
|
||||
<!-- 人事管理 -->
|
||||
<Card v-if="hasHRServices">
|
||||
<!-- <Card v-if="hasHRServices">
|
||||
<template #header>
|
||||
<view class="section-header">
|
||||
<u-icon name="friends" size="18" color="#722ed1" />
|
||||
@@ -416,10 +416,10 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</GridLayout>
|
||||
</Card>
|
||||
</Card> -->
|
||||
|
||||
<!-- 财务管理 -->
|
||||
<Card v-if="hasFinanceServices">
|
||||
<!-- <Card v-if="hasFinanceServices">
|
||||
<template #header>
|
||||
<view class="section-header">
|
||||
<u-icon name="rmb-circle" size="18" color="#13c2c2" />
|
||||
@@ -457,10 +457,10 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</GridLayout>
|
||||
</Card>
|
||||
</Card> -->
|
||||
|
||||
<!-- 系统管理 -->
|
||||
<Card v-if="hasSystemServices">
|
||||
<!-- <Card v-if="hasSystemServices">
|
||||
<template #header>
|
||||
<view class="section-header">
|
||||
<u-icon name="setting" size="18" color="#f5222d" />
|
||||
@@ -532,14 +532,14 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</GridLayout>
|
||||
</Card>
|
||||
</Card> -->
|
||||
|
||||
<!-- 工作流 -->
|
||||
<Card v-if="hasWorkflowServices">
|
||||
<template #header>
|
||||
<view class="section-header">
|
||||
<u-icon name="share" size="18" color="#eb2f96" />
|
||||
<text class="card-title">工作流</text>
|
||||
<text class="card-title">请销假待办</text>
|
||||
</view>
|
||||
</template>
|
||||
<GridLayout :columns="2" gap="16px">
|
||||
@@ -586,7 +586,7 @@
|
||||
</Card>
|
||||
|
||||
<!-- 微信SDK测试 -->
|
||||
<Card v-if="hasWechatTestAccess">
|
||||
<!-- <Card v-if="hasWechatTestAccess">
|
||||
<template #header>
|
||||
<view class="section-header">
|
||||
<u-icon name="chat" size="18" color="#07c160" />
|
||||
@@ -606,7 +606,7 @@
|
||||
</template>
|
||||
</ServiceItem>
|
||||
</GridLayout>
|
||||
</Card>
|
||||
</Card> -->
|
||||
|
||||
<!-- 底部间距 -->
|
||||
<view class="bottom-spacer"></view>
|
||||
@@ -677,20 +677,20 @@ export default {
|
||||
// 检查各模块是否有权限
|
||||
hasStudentServices() {
|
||||
return (
|
||||
this.hasPermi(['student:info:list']) ||
|
||||
this.hasPermi(['student:info:listapp']) ||
|
||||
this.hasPermi(['student:dorm:list']) ||
|
||||
this.hasPermi(['student:leave:list']) ||
|
||||
this.hasPermi(['student:leave:listapp']) ||
|
||||
this.hasPermi(['student:psychology:list']) ||
|
||||
this.hasPermi(['student:club:list']) ||
|
||||
this.hasPermi(['student:counsel:list']) ||
|
||||
this.hasPermi(['student:info:edit']) ||
|
||||
this.hasPermi(['student:info:editapp']) ||
|
||||
this.hasPermi(['student:internship:list']) ||
|
||||
this.hasPermi(['student:dorm:violation:list']) ||
|
||||
this.hasPermi(['student:dormviolation:listapp']) ||
|
||||
this.hasPermi(['student:visit:list']) ||
|
||||
this.hasPermi(['student:dorm:hygiene:list']) ||
|
||||
this.hasPermi(['student:dormhygiene:listapp']) ||
|
||||
this.hasPermi(['student:workstudy:list']) ||
|
||||
this.hasPermi(['student:violation:list']) ||
|
||||
this.hasPermi(['student:assessment:apply'])
|
||||
this.hasPermi(['student:violation:listapp']) ||
|
||||
this.hasPermi(['student:assessment:applyapp'])
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 529 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 25 MiB |
|
After Width: | Height: | Size: 3.9 MiB |
|
After Width: | Height: | Size: 2.3 MiB |
|
After Width: | Height: | Size: 564 KiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 529 KiB |
|
After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 1.9 MiB |
@@ -429,7 +429,7 @@ const auditorList = ref<any[]>([]);
|
||||
/** 获取具有审核权限的人员列表 */
|
||||
const getAuditorList = async () => {
|
||||
try {
|
||||
const res = await listUsersByPermission('hq:hallAudit:list');
|
||||
const res = await listUsersByPermission('hq:hallAudit:hallAudit');
|
||||
auditorList.value = res.data || [];
|
||||
console.log('审核人员列表:', auditorList.value);
|
||||
} catch (error) {
|
||||
|
||||
@@ -174,6 +174,8 @@ const data = reactive<PageData<SatCategoryForm, SatCategoryQuery>>({
|
||||
categoryDesc: undefined,
|
||||
sortOrder: undefined,
|
||||
status: undefined,
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc',
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
@@ -215,6 +217,9 @@ const handleQuery = () => {
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
// 保持排序设置
|
||||
queryParams.value.orderByColumn = 'createTime';
|
||||
queryParams.value.isAsc = 'desc';
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
|
||||
@@ -319,7 +319,10 @@ const data = reactive<PageData<SatQuestionForm, SatQuestionQuery>>({
|
||||
isRequired: undefined,
|
||||
sortOrder: undefined,
|
||||
status: undefined,
|
||||
params: {}
|
||||
params: {
|
||||
orderByColumn: 'createTime',
|
||||
isAsc: 'desc'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
id: [{ required: true, message: '主键ID不能为空', trigger: 'blur' }],
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
<template>
|
||||
<div class="app-container home">
|
||||
<!-- 上半部分:校园风景图片轮播 -->
|
||||
<div class="carousel-section">
|
||||
<el-carousel :interval="4000" type="card" height="400px" indicator-position="outside" arrow="always" class="campus-carousel">
|
||||
<el-carousel-item v-for="(image, index) in campusImages" :key="index">
|
||||
<div class="carousel-item">
|
||||
<img :src="image.url" :alt="image.title" class="carousel-image" />
|
||||
<div class="carousel-overlay">
|
||||
<h3 class="carousel-title">{{ image.title }}</h3>
|
||||
<p class="carousel-description">{{ image.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
|
||||
<!-- 下半部分:原有内容 -->
|
||||
<div class="construction-container">
|
||||
<div class="construction-content">
|
||||
<!-- 系统标题 -->
|
||||
@@ -58,8 +74,28 @@
|
||||
</template>
|
||||
|
||||
<script setup name="Index" lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { Tools, Calendar, Service, Phone, Message } from '@element-plus/icons-vue';
|
||||
|
||||
// 校园风景图片数据
|
||||
const campusImages = [
|
||||
{
|
||||
url: '/assets/images/01.jpg',
|
||||
title: '校园正门',
|
||||
description: '绿意盎然的校园入口,展现学院的自然之美'
|
||||
},
|
||||
{
|
||||
url: '/assets/images/02.jpg',
|
||||
title: '校园风光',
|
||||
description: '现代化的校园建筑与自然景观的完美融合'
|
||||
},
|
||||
{
|
||||
url: '/assets/images/03.jpg',
|
||||
title: '校园全景',
|
||||
description: '鸟瞰校园全景,展现学院的整体风貌'
|
||||
}
|
||||
];
|
||||
|
||||
// 计算预计完成时间(当前时间后30天)
|
||||
const expectedDate = computed(() => {
|
||||
const date = new Date();
|
||||
@@ -75,16 +111,79 @@ const expectedDate = computed(() => {
|
||||
<style lang="scss" scoped>
|
||||
.home {
|
||||
min-height: calc(100vh - 200px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
||||
}
|
||||
|
||||
// 上半部分:轮播图样式
|
||||
.carousel-section {
|
||||
padding: 40px 20px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.campus-carousel {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
border-radius: 16px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
|
||||
|
||||
:deep(.el-carousel__item) {
|
||||
border-radius: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.carousel-item {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.carousel-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.carousel-item:hover .carousel-image {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.carousel-overlay {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
|
||||
color: white;
|
||||
padding: 40px 30px 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.carousel-title {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 10px 0;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.carousel-description {
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
opacity: 0.9;
|
||||
text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
// 下半部分:原有样式
|
||||
.construction-container {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
padding: 40px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.construction-content {
|
||||
@@ -212,6 +311,26 @@ const expectedDate = computed(() => {
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 768px) {
|
||||
.carousel-section {
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
||||
.campus-carousel {
|
||||
height: 300px !important;
|
||||
}
|
||||
|
||||
.carousel-overlay {
|
||||
padding: 30px 20px 20px;
|
||||
}
|
||||
|
||||
.carousel-title {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.carousel-description {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.construction-container {
|
||||
padding: 20px;
|
||||
}
|
||||
@@ -237,6 +356,10 @@ const expectedDate = computed(() => {
|
||||
|
||||
// 深色主题适配
|
||||
html.dark {
|
||||
.carousel-section {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.construction-content {
|
||||
background: rgba(30, 30, 30, 0.95);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
|
||||
@@ -10,12 +10,12 @@
|
||||
<h3 class="title">{{ title }}</h3>
|
||||
<!-- <lang-select /> -->
|
||||
</div>
|
||||
<el-form-item v-if="tenantEnabled" prop="tenantId" class="el_select_coopr">
|
||||
<!-- <el-form-item v-if="tenantEnabled" prop="tenantId" class="el_select_coopr">
|
||||
<el-select v-model="loginForm.tenantId" filterable :placeholder="proxy.$t('login.selectPlaceholder')" style="width: 100%">
|
||||
<el-option v-for="item in tenantList" :key="item.tenantId" :label="item.companyName" :value="item.tenantId"></el-option>
|
||||
<template #prefix><svg-icon icon-class="company" class="el-input__icon input-icon" /></template>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="loginForm.username" type="text" auto-complete="off" :placeholder="proxy.$t('login.username')">
|
||||
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<!-- 分页组件已移除,因为列表接口不支持分页 -->
|
||||
</el-card>
|
||||
<!-- 添加或修改学生信息收集批次对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
@@ -313,7 +313,6 @@ const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const stuColBatchFormRef = ref<ElFormInstance>();
|
||||
@@ -384,8 +383,6 @@ const initFormData: StuColBatchForm = {
|
||||
const data = reactive<PageData<StuColBatchForm, StuColBatchQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
batchName: undefined,
|
||||
status: undefined,
|
||||
collectionType: undefined,
|
||||
@@ -419,16 +416,13 @@ const getList = async () => {
|
||||
if (res && res.code === 200) {
|
||||
// 将返回的数据转换为表格需要的格式
|
||||
stuColBatchList.value = res.data || [];
|
||||
total.value = res.data ? res.data.length : 0;
|
||||
} else {
|
||||
stuColBatchList.value = [];
|
||||
total.value = 0;
|
||||
proxy?.$modal.msgError(res?.msg || '获取数据失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取学生可参与批次信息失败:', error);
|
||||
stuColBatchList.value = [];
|
||||
total.value = 0;
|
||||
proxy?.$modal.msgError('获取数据失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
@@ -449,7 +443,6 @@ const reset = () => {
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
};
|
||||
|
||||
|
||||
@@ -145,6 +145,12 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column v-if="columns[9].visible" label="宿舍房间" align="center" prop="dormitoryRoom" width="120">
|
||||
<template #default="scope">
|
||||
<span>{{ getRoomDisplayName(scope.row.dormitoryRoom) }}</span>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
|
||||
<el-table-column label="操作" fixed="right" width="240" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
@@ -826,8 +832,13 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="宿舍房间号" prop="dormitoryRoom">
|
||||
<el-input disabled v-model="form.dormitoryRoom" placeholder="请输入宿舍房间号" maxlength="20" />
|
||||
<el-form-item label="宿舍房间" prop="dormitoryRoom">
|
||||
<el-input disabled :value="getRoomDisplayName(form.dormitoryRoom)" placeholder="宿舍房间" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="床位" prop="extField1">
|
||||
<el-input disabled :value="getBedDisplayName(form.extField1)" placeholder="床位" maxlength="20" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -1389,8 +1400,13 @@
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="宿舍房间号">
|
||||
<span class="form-value">{{ detailForm.dormitoryRoom }}</span>
|
||||
<el-form-item label="宿舍房间">
|
||||
<span class="form-value">{{ getRoomDisplayName(detailForm.dormitoryRoom) }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="床位">
|
||||
<span class="form-value">{{ getBedDisplayName(detailForm.extField1) }}</span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -1603,6 +1619,8 @@ const classOptions = ref([]);
|
||||
const regionOptions = ref([]); // 行政区划选项
|
||||
const dormBuildingOptions = ref([]); // 宿舍楼栋选项
|
||||
const currentSelectedNode = ref<any>(null); // 当前选中的部门节点
|
||||
const roomCache = ref<Map<string | number, string>>(new Map()); // 房间名称缓存
|
||||
const bedCache = ref<Map<string | number, string>>(new Map()); // 床位名称缓存
|
||||
|
||||
// 计算属性:判断是否显示新增按钮(只有班级节点才显示)
|
||||
const showAddButton = computed(() => {
|
||||
@@ -1623,7 +1641,8 @@ const columns = ref([
|
||||
{ key: 5, label: `班级`, visible: true },
|
||||
{ key: 6, label: `手机号码`, visible: true },
|
||||
{ key: 7, label: `状态`, visible: true },
|
||||
{ key: 8, label: `创建时间`, visible: true }
|
||||
{ key: 8, label: `创建时间`, visible: true },
|
||||
{ key: 9, label: `宿舍房间`, visible: true }
|
||||
]);
|
||||
|
||||
const deptTreeRef = ref<any>();
|
||||
@@ -1686,7 +1705,7 @@ const initFormData: StudentMsgForm = {
|
||||
photoUrl: '',
|
||||
photoPath: '',
|
||||
phone: '',
|
||||
isBoarder: 0,
|
||||
isBoarder: '0',
|
||||
|
||||
// // 扩展信息字段
|
||||
educationLevel: '2',
|
||||
@@ -1700,14 +1719,14 @@ const initFormData: StudentMsgForm = {
|
||||
emergencyContactName: '',
|
||||
emergencyContactPhone: '',
|
||||
emergencyContactRelation: '',
|
||||
isPoorStudent: 0,
|
||||
isMinority: 0,
|
||||
isDisabled: 0,
|
||||
isOrphan: 0,
|
||||
isLeftBehindChild: 0,
|
||||
isSingleChild: 0,
|
||||
isLowIncome: 0,
|
||||
hasLoan: 0,
|
||||
isPoorStudent: '0',
|
||||
isMinority: '0',
|
||||
isDisabled: '0',
|
||||
isOrphan: '0',
|
||||
isLeftBehindChild: '0',
|
||||
isSingleChild: '0',
|
||||
isLowIncome: '0',
|
||||
hasLoan: '0',
|
||||
loanAmount: undefined,
|
||||
specialties: '',
|
||||
awards: '',
|
||||
@@ -1762,6 +1781,7 @@ const initFormData: StudentMsgForm = {
|
||||
classTeacherName: '',
|
||||
dormitoryBuilding: '',
|
||||
dormitoryRoom: '',
|
||||
extField1: '', // 床位ID
|
||||
|
||||
// // 银行卡信息字段
|
||||
bankCardNo: '',
|
||||
@@ -1873,6 +1893,152 @@ const getDormBuildingName = (id: string | number) => {
|
||||
return findBuildingName(dormBuildingOptions.value, id) || String(id);
|
||||
};
|
||||
|
||||
/** 根据房间ID获取房间名称 */
|
||||
const getRoomName = async (roomId: string | number): Promise<string> => {
|
||||
if (!roomId) return '';
|
||||
|
||||
// 检查缓存
|
||||
if (roomCache.value.has(roomId)) {
|
||||
return roomCache.value.get(roomId) || '';
|
||||
}
|
||||
|
||||
try {
|
||||
// 调用房间信息接口
|
||||
const res = await service.get(`/xgss/dormRoom/${roomId}`);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const roomName = res.data.roomName || res.data.roomCode || String(roomId);
|
||||
// 缓存结果
|
||||
roomCache.value.set(roomId, roomName);
|
||||
return roomName;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取房间信息失败:', error);
|
||||
}
|
||||
|
||||
// 如果获取失败,返回ID并缓存
|
||||
roomCache.value.set(roomId, String(roomId));
|
||||
return String(roomId);
|
||||
};
|
||||
|
||||
/** 根据床位ID获取床位名称 */
|
||||
const getBedName = async (bedId: string | number): Promise<string> => {
|
||||
if (!bedId) return '';
|
||||
|
||||
// 检查缓存
|
||||
if (bedCache.value.has(bedId)) {
|
||||
return bedCache.value.get(bedId) || '';
|
||||
}
|
||||
|
||||
try {
|
||||
// 调用床位信息接口
|
||||
const res = await service.get(`/dormbed/dormBed/${bedId}`);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const bedName = res.data.bedName || res.data.bedCode || String(bedId);
|
||||
// 缓存结果
|
||||
bedCache.value.set(bedId, bedName);
|
||||
return bedName;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取床位信息失败:', error);
|
||||
}
|
||||
|
||||
// 如果获取失败,返回ID并缓存
|
||||
bedCache.value.set(bedId, String(bedId));
|
||||
return String(bedId);
|
||||
};
|
||||
|
||||
/** 获取房间显示名称(同步方法,用于弹窗显示) */
|
||||
const getRoomDisplayName = (roomId: string | number): string => {
|
||||
if (!roomId) return '-';
|
||||
|
||||
// 优先从缓存中获取
|
||||
if (roomCache.value.has(roomId)) {
|
||||
return roomCache.value.get(roomId) || String(roomId);
|
||||
}
|
||||
|
||||
// 如果缓存中没有,返回ID,并异步加载
|
||||
setTimeout(() => {
|
||||
getRoomName(roomId);
|
||||
}, 0);
|
||||
|
||||
return String(roomId);
|
||||
};
|
||||
|
||||
/** 获取床位显示名称(同步方法,用于弹窗显示) */
|
||||
const getBedDisplayName = (bedId: string | number): string => {
|
||||
if (!bedId) return '-';
|
||||
|
||||
// 优先从缓存中获取
|
||||
if (bedCache.value.has(bedId)) {
|
||||
return bedCache.value.get(bedId) || String(bedId);
|
||||
}
|
||||
|
||||
// 如果缓存中没有,返回ID,并异步加载
|
||||
setTimeout(() => {
|
||||
getBedName(bedId);
|
||||
}, 0);
|
||||
|
||||
return String(bedId);
|
||||
};
|
||||
|
||||
/** 预加载房间信息 */
|
||||
const preloadRoomInfo = async () => {
|
||||
if (!studentList.value || studentList.value.length === 0) return;
|
||||
|
||||
// 收集所有需要查询的房间ID(兼容不同的字段名)
|
||||
const roomIds = studentList.value
|
||||
.map((student) => (student as any).dormitoryRoom || (student as any).dormitory_room)
|
||||
.filter((roomId) => roomId && !roomCache.value.has(roomId));
|
||||
|
||||
if (roomIds.length === 0) return;
|
||||
|
||||
// 批量查询房间信息
|
||||
const uniqueRoomIds = [...new Set(roomIds)];
|
||||
|
||||
for (const roomId of uniqueRoomIds) {
|
||||
try {
|
||||
const res = await service.get(`/xgss/dormRoom/${roomId}`);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const roomName = res.data.roomName || res.data.roomCode || String(roomId);
|
||||
roomCache.value.set(roomId, roomName);
|
||||
} else {
|
||||
roomCache.value.set(roomId, String(roomId));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`获取房间信息失败,房间ID: ${roomId}`, error);
|
||||
roomCache.value.set(roomId, String(roomId));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 预加载床位信息 */
|
||||
const preloadBedInfo = async () => {
|
||||
if (!studentList.value || studentList.value.length === 0) return;
|
||||
|
||||
// 收集所有需要查询的床位ID(从extField1字段获取)
|
||||
const bedIds = studentList.value.map((student) => (student as any).extField1).filter((bedId) => bedId && !bedCache.value.has(bedId));
|
||||
|
||||
if (bedIds.length === 0) return;
|
||||
|
||||
// 批量查询床位信息
|
||||
const uniqueBedIds = [...new Set(bedIds)];
|
||||
|
||||
for (const bedId of uniqueBedIds) {
|
||||
try {
|
||||
const res = await service.get(`/dormbed/dormBed/${bedId}`);
|
||||
if (res && res.code === 200 && res.data) {
|
||||
const bedName = res.data.bedName || res.data.bedCode || String(bedId);
|
||||
bedCache.value.set(bedId, bedName);
|
||||
} else {
|
||||
bedCache.value.set(bedId, String(bedId));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`获取床位信息失败,床位ID: ${bedId}`, error);
|
||||
bedCache.value.set(bedId, String(bedId));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 根据行政区划代码获取完整路径(省/市/区) */
|
||||
const getRegionFullPath = (code: string): string => {
|
||||
if (!code || !regionOptions.value) return code || '';
|
||||
@@ -1940,6 +2106,11 @@ const getList = async () => {
|
||||
if (res && res.code === 200) {
|
||||
studentList.value = res.rows || [];
|
||||
total.value = res.total || 0;
|
||||
|
||||
// 预加载房间信息
|
||||
await preloadRoomInfo();
|
||||
// 预加载床位信息
|
||||
await preloadBedInfo();
|
||||
} else {
|
||||
ElMessage.error(res?.msg || '查询学生列表失败');
|
||||
studentList.value = [];
|
||||
|
||||