Merge branch 'master' of http://47.99.164.66:3000/hzdyjs-xg/all-project
This commit is contained in:
commit
3c62f1f6de
64 files changed
+5288
-4353
No files matched your search
+9
@@ -295,4 +295,13 @@ public class JcbtScholarshipTypeController extends BaseController {
|
||||
return R.ok(compatibleTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取奖学金类型的互斥关系显示文本
|
||||
*/
|
||||
@SaCheckPermission("jcbt:scholarshipType:query")
|
||||
@GetMapping("/{id}/exclusiveRelationDisplay")
|
||||
public R<String> getExclusiveRelationDisplay(@NotNull(message = "主键不能为空") @PathVariable Long id) {
|
||||
return R.ok(scholarshipTypeService.getExclusiveRelationDisplay(id));
|
||||
}
|
||||
|
||||
}
|
||||
+8
@@ -91,4 +91,12 @@ public interface IJcbtScholarshipTypeService {
|
||||
*/
|
||||
List<JcbtScholarshipTypeVo> queryOptions();
|
||||
|
||||
/**
|
||||
* 获取奖学金类型的互斥关系显示文本
|
||||
*
|
||||
* @param scholarshipTypeId 奖学金类型ID
|
||||
* @return 互斥关系显示文本
|
||||
*/
|
||||
String getExclusiveRelationDisplay(Long scholarshipTypeId);
|
||||
|
||||
}
|
||||
+47
@@ -14,10 +14,12 @@ import org.dromara.jcbt.domain.vo.JcbtScholarshipTypeVo;
|
||||
import org.dromara.jcbt.domain.JcbtScholarshipType;
|
||||
import org.dromara.jcbt.mapper.JcbtScholarshipTypeMapper;
|
||||
import org.dromara.jcbt.service.IJcbtScholarshipTypeService;
|
||||
import org.dromara.jcbt.service.IJcbtScholarshipCompatibilityService;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* 奖学金类型Service业务层处理
|
||||
@@ -30,6 +32,7 @@ import java.util.Collection;
|
||||
public class JcbtScholarshipTypeServiceImpl implements IJcbtScholarshipTypeService {
|
||||
|
||||
private final JcbtScholarshipTypeMapper baseMapper;
|
||||
private final IJcbtScholarshipCompatibilityService compatibilityService;
|
||||
|
||||
/**
|
||||
* 查询奖学金类型
|
||||
@@ -231,4 +234,48 @@ public class JcbtScholarshipTypeServiceImpl implements IJcbtScholarshipTypeServi
|
||||
JcbtScholarshipType::getTypeCategory, JcbtScholarshipType::getAwardAmount);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取奖学金类型的互斥关系显示文本
|
||||
*/
|
||||
@Override
|
||||
public String getExclusiveRelationDisplay(Long scholarshipTypeId) {
|
||||
// 1. 获取当前奖学金类型信息
|
||||
JcbtScholarshipTypeVo currentType = queryById(scholarshipTypeId);
|
||||
if (currentType == null) {
|
||||
return "互斥(无)";
|
||||
}
|
||||
|
||||
// 2. 如果是EXCLUSIVE类型,显示"互斥(与全部其他奖学金类型)"
|
||||
if ("EXCLUSIVE".equals(currentType.getCompatibilityType())) {
|
||||
return "互斥(与全部其他奖学金类型)";
|
||||
}
|
||||
|
||||
// 3. 如果是CUSTOM类型,查询具体的互斥关系
|
||||
if ("CUSTOM".equals(currentType.getCompatibilityType())) {
|
||||
List<Long> exclusiveTypeIds = compatibilityService.getExclusiveTypeIds(scholarshipTypeId);
|
||||
|
||||
if (exclusiveTypeIds == null || exclusiveTypeIds.isEmpty()) {
|
||||
return "互斥(无)";
|
||||
}
|
||||
|
||||
// 查询互斥的奖学金类型名称
|
||||
List<String> exclusiveTypeNames = new ArrayList<>();
|
||||
for (Long exclusiveTypeId : exclusiveTypeIds) {
|
||||
JcbtScholarshipTypeVo exclusiveType = queryById(exclusiveTypeId);
|
||||
if (exclusiveType != null) {
|
||||
exclusiveTypeNames.add(exclusiveType.getTypeName());
|
||||
}
|
||||
}
|
||||
|
||||
if (exclusiveTypeNames.isEmpty()) {
|
||||
return "互斥(无)";
|
||||
}
|
||||
|
||||
return "互斥(与" + String.join("、", exclusiveTypeNames) + ")";
|
||||
}
|
||||
|
||||
// 4. 其他情况(如COMPATIBLE),显示"互斥(无)"
|
||||
return "互斥(无)";
|
||||
}
|
||||
}
|
||||
+11
-12
@@ -11,7 +11,6 @@ import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.rs.domain.RsTrainingApplication;
|
||||
import org.dromara.rs.domain.RsTrainingCourse;
|
||||
import org.dromara.rs.service.IRsTrainingApplicationService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@@ -42,7 +41,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 查询培训申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:list")
|
||||
@SaCheckPermission("rs:trainingapplication:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<RsTrainingApplication> list(RsTrainingApplication application, PageQuery pageQuery) {
|
||||
return trainingApplicationService.selectPageRsTrainingApplicationList(application, pageQuery);
|
||||
@@ -51,7 +50,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 导出培训申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:export")
|
||||
@SaCheckPermission("rs:trainingapplication:export")
|
||||
@Log(title = "培训申请", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, RsTrainingApplication application) {
|
||||
@@ -62,7 +61,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 获取培训申请详细信息
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:query")
|
||||
@SaCheckPermission("rs:trainingapplication:query")
|
||||
@GetMapping("/{applicationId}")
|
||||
public R<RsTrainingApplication> getInfo(@PathVariable("applicationId") Long applicationId) {
|
||||
return R.ok(trainingApplicationService.selectRsTrainingApplicationById(applicationId));
|
||||
@@ -71,7 +70,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 新增培训申请
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:add")
|
||||
@SaCheckPermission("rs:trainingapplication:add")
|
||||
@Log(title = "培训申请", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping
|
||||
@@ -124,7 +123,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 修改培训申请
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:edit")
|
||||
@SaCheckPermission("rs:trainingapplication:edit")
|
||||
@Log(title = "培训申请", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping
|
||||
@@ -135,7 +134,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 删除培训申请
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:remove")
|
||||
@SaCheckPermission("rs:trainingapplication:remove")
|
||||
@Log(title = "培训申请", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{applicationIds}")
|
||||
public R<Void> remove(@PathVariable Long[] applicationIds) {
|
||||
@@ -145,7 +144,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 取消培训申请
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:edit")
|
||||
@SaCheckPermission("rs:trainingapplication:edit")
|
||||
@Log(title = "培训申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/cancel/{applicationId}")
|
||||
public R<Void> cancel(@PathVariable("applicationId") Long applicationId) {
|
||||
@@ -155,7 +154,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 查询我的培训申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:query")
|
||||
@SaCheckPermission("rs:trainingapplication:query")
|
||||
@GetMapping("/my")
|
||||
public TableDataInfo<RsTrainingApplication> listMyApplications(RsTrainingApplication application, PageQuery pageQuery) {
|
||||
return trainingApplicationService.selectPageMyApplications(StpUtil.getLoginIdAsLong(), application, pageQuery);
|
||||
@@ -164,7 +163,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 查询指定课程的申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:list")
|
||||
@SaCheckPermission("rs:trainingapplication:list")
|
||||
@GetMapping("/list/{courseId}")
|
||||
public TableDataInfo<RsTrainingApplication> listByCourse(@PathVariable("courseId") Long courseId, RsTrainingApplication application, PageQuery pageQuery) {
|
||||
return trainingApplicationService.selectPageApplicationsByCourse(courseId, application, pageQuery);
|
||||
@@ -227,7 +226,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 更新培训申请状态
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:edit")
|
||||
@SaCheckPermission("rs:trainingapplication:edit")
|
||||
@Log(title = "培训申请状态", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/status/{applicationId}/{status}")
|
||||
public R<Void> updateStatus(
|
||||
@@ -240,7 +239,7 @@ public class RsTrainingApplicationController extends BaseController {
|
||||
/**
|
||||
* 重新提交被拒绝的培训申请
|
||||
*/
|
||||
@SaCheckPermission("rs:training:application:edit")
|
||||
@SaCheckPermission("rs:trainingapplication:edit")
|
||||
@Log(title = "重新提交培训申请", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/resubmit/{applicationId}")
|
||||
|
||||
+8
-8
@@ -38,7 +38,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 查询培训审批列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:list")
|
||||
@SaCheckPermission("rs:trainingapproval:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<RsTrainingApproval> list(RsTrainingApproval approval, PageQuery pageQuery) {
|
||||
// 使用带详细信息的查询方法,返回申请人姓名和课程名称
|
||||
@@ -48,7 +48,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 获取培训审批详细信息
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:query")
|
||||
@SaCheckPermission("rs:trainingapproval:query")
|
||||
@GetMapping("/{approvalId}")
|
||||
public R<RsTrainingApproval> getInfo(@PathVariable("approvalId") Long approvalId) {
|
||||
return R.ok(trainingApprovalService.selectRsTrainingApprovalById(approvalId));
|
||||
@@ -57,7 +57,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 新增培训审批
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:add")
|
||||
@SaCheckPermission("rs:trainingapproval:add")
|
||||
@Log(title = "培训审批", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping
|
||||
@@ -68,7 +68,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 修改培训审批
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:edit")
|
||||
@SaCheckPermission("rs:trainingapproval:edit")
|
||||
@Log(title = "培训审批", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping
|
||||
@@ -79,7 +79,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 删除培训审批
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:remove")
|
||||
@SaCheckPermission("rs:trainingapproval:remove")
|
||||
@Log(title = "培训审批", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{approvalIds}")
|
||||
public R<Void> remove(@PathVariable Long[] approvalIds) {
|
||||
@@ -89,7 +89,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 查询待我审批的列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:process")
|
||||
@SaCheckPermission("rs:trainingapproval:process")
|
||||
@GetMapping("/pending")
|
||||
public TableDataInfo<RsTrainingApproval> listPendingApprovals(RsTrainingApproval approval, PageQuery pageQuery) {
|
||||
return trainingApprovalService.selectPagePendingApprovals(StpUtil.getLoginIdAsLong(), approval, pageQuery);
|
||||
@@ -98,7 +98,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 处理审批
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:process")
|
||||
@SaCheckPermission("rs:trainingapproval:process")
|
||||
@Log(title = "培训审批", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/process/{applicationId}/{status}")
|
||||
public R<Void> processApproval(@PathVariable("applicationId") Long applicationId, @PathVariable("status") String status, @RequestBody(required = false) Map<String, String> params) {
|
||||
@@ -109,7 +109,7 @@ public class RsTrainingApprovalController extends BaseController {
|
||||
/**
|
||||
* 查询申请审批历史
|
||||
*/
|
||||
@SaCheckPermission("rs:training:approval:query")
|
||||
@SaCheckPermission("rs:trainingapproval:query")
|
||||
@GetMapping("/history/{applicationId}")
|
||||
public R<List<RsTrainingApproval>> getApprovalHistory(@PathVariable("applicationId") Long applicationId) {
|
||||
System.out.println("查询审批历史记录 - applicationId: " + applicationId);
|
||||
|
||||
-124
@@ -1,124 +0,0 @@
|
||||
package org.dromara.rs.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
import org.dromara.common.idempotent.annotation.RepeatSubmit;
|
||||
import org.dromara.common.log.annotation.Log;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.web.core.BaseController;
|
||||
import org.dromara.rs.domain.RsTrainingCourse;
|
||||
import org.dromara.rs.service.IRsTrainingCourseService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaIgnore;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 培训课程控制器
|
||||
*
|
||||
* @author weizzzz
|
||||
* @date 2025-07-16
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/rs/training/course")
|
||||
public class RsTrainingCourseController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private IRsTrainingCourseService trainingCourseService;
|
||||
|
||||
/**
|
||||
* 查询培训课程列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:course:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<RsTrainingCourse> list(RsTrainingCourse course, PageQuery pageQuery) {
|
||||
return trainingCourseService.selectPageRsTrainingCourseList(course, pageQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出培训课程列表
|
||||
*/
|
||||
@SaCheckPermission("rs:training:course:export")
|
||||
@Log(title = "培训课程", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, RsTrainingCourse course) {
|
||||
List<RsTrainingCourse> list = trainingCourseService.selectRsTrainingCourseList(course);
|
||||
ExcelUtil.exportExcel(list, "培训课程", RsTrainingCourse.class, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取培训课程详细信息
|
||||
*/
|
||||
@SaCheckPermission("rs:training:course:query")
|
||||
@GetMapping("/{courseId}")
|
||||
public R<RsTrainingCourse> getInfo(@PathVariable("courseId") Long courseId) {
|
||||
return R.ok(trainingCourseService.selectRsTrainingCourseById(courseId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增培训课程
|
||||
*/
|
||||
@SaCheckPermission("rs:training:course:add")
|
||||
@Log(title = "培训课程", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit()
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated @RequestBody RsTrainingCourse course) {
|
||||
return toAjax(trainingCourseService.insertRsTrainingCourse(course));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改培训课程
|
||||
*/
|
||||
@SaCheckPermission("rs:training:course:edit")
|
||||
@Log(title = "培训课程", businessType = BusinessType.UPDATE)
|
||||
@RepeatSubmit()
|
||||
@PutMapping
|
||||
public R<Void> edit(@Validated @RequestBody RsTrainingCourse course) {
|
||||
return toAjax(trainingCourseService.updateRsTrainingCourse(course));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除培训课程
|
||||
*/
|
||||
@SaCheckPermission("rs:training:course:remove")
|
||||
@Log(title = "培训课程", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{courseIds}")
|
||||
public R<Void> remove(@PathVariable Long[] courseIds) {
|
||||
return toAjax(trainingCourseService.deleteRsTrainingCourseByIds(courseIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换培训课程状态
|
||||
*/
|
||||
@SaCheckPermission("rs:training:course:edit")
|
||||
@Log(title = "培训课程", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/toggle/{courseId}")
|
||||
public R<Void> toggleStatus(@PathVariable("courseId") Long courseId) {
|
||||
return toAjax(trainingCourseService.toggleCourseStatus(courseId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可用培训课程列表(不分页)
|
||||
*/
|
||||
@SaIgnore
|
||||
@GetMapping("/available")
|
||||
public R<List<RsTrainingCourse>> getAvailableCourses() {
|
||||
RsTrainingCourse course = new RsTrainingCourse();
|
||||
course.setStatus("0"); // 只查询状态为正常的课程
|
||||
return R.ok(trainingCourseService.selectRsTrainingCourseList(course));
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -7,6 +7,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@@ -26,7 +27,7 @@ public class RsTrainingApplication extends BaseEntity {
|
||||
/**
|
||||
* 申请ID
|
||||
*/
|
||||
@TableId(value = "application_id")
|
||||
@TableId(value = "application_id", type = IdType.ASSIGN_ID)
|
||||
private Long applicationId;
|
||||
|
||||
/**
|
||||
@@ -34,6 +35,11 @@ public class RsTrainingApplication extends BaseEntity {
|
||||
*/
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 培训名称
|
||||
*/
|
||||
private String courseName;
|
||||
|
||||
/**
|
||||
* 申请人ID
|
||||
*/
|
||||
@@ -107,11 +113,6 @@ public class RsTrainingApplication extends BaseEntity {
|
||||
*/
|
||||
private Long createDept;
|
||||
|
||||
/**
|
||||
* 自定义课程名称
|
||||
*/
|
||||
private String courseName;
|
||||
|
||||
/**
|
||||
* 拒绝时间
|
||||
*/
|
||||
|
||||
-92
@@ -1,92 +0,0 @@
|
||||
package org.dromara.rs.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 培训课程对象 rs_training_course
|
||||
*
|
||||
* @author weizzzz
|
||||
* @date 2025-07-16
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("rs_training_course")
|
||||
public class RsTrainingCourse extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 课程ID
|
||||
*/
|
||||
@TableId(value = "course_id")
|
||||
private Long courseId;
|
||||
|
||||
/**
|
||||
* 课程名称
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 课程类别
|
||||
*/
|
||||
private String category;
|
||||
|
||||
/**
|
||||
* 课程描述
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date startTime;
|
||||
|
||||
/**
|
||||
* 结束时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 学时数
|
||||
*/
|
||||
private Integer duration;
|
||||
|
||||
/**
|
||||
* 培训地点
|
||||
*/
|
||||
private String location;
|
||||
|
||||
/**
|
||||
* 最大参与人数
|
||||
*/
|
||||
private Integer maxParticipants;
|
||||
|
||||
/**
|
||||
* 当前报名人数
|
||||
*/
|
||||
private Integer currentParticipants;
|
||||
|
||||
/**
|
||||
* 状态(0正常 1结束)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private String tenantId;
|
||||
|
||||
/** 非数据库字段 **/
|
||||
@TableField(exist = false)
|
||||
private Integer applicationCount;
|
||||
}
|
||||
+7
-1
@@ -7,6 +7,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
@@ -27,7 +28,7 @@ public class RsTrainingRecord extends BaseEntity {
|
||||
/**
|
||||
* 记录ID
|
||||
*/
|
||||
@TableId(value = "record_id")
|
||||
@TableId(value = "record_id", type = IdType.ASSIGN_ID)
|
||||
private Long recordId;
|
||||
|
||||
private Long applicationId;
|
||||
@@ -117,6 +118,11 @@ public class RsTrainingRecord extends BaseEntity {
|
||||
private String tenantId;
|
||||
private Long createDept;
|
||||
|
||||
/**
|
||||
* 部门ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
// 数据库字段 - 直接存储在培训记录表中
|
||||
private String courseName;
|
||||
private Integer duration;
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package org.dromara.rs.mapper;
|
||||
|
||||
import org.dromara.rs.domain.RsTrainingCourse;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
|
||||
/**
|
||||
* 培训课程Mapper接口
|
||||
*
|
||||
* @author weizzzz
|
||||
* @date 2025-07-16
|
||||
*/
|
||||
public interface RsTrainingCourseMapper extends BaseMapperPlus<RsTrainingCourse, RsTrainingCourse> {
|
||||
|
||||
}
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
package org.dromara.rs.service;
|
||||
|
||||
import java.util.List;
|
||||
import org.dromara.rs.domain.RsTrainingCourse;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 培训课程服务接口
|
||||
*
|
||||
* @author weizzzz
|
||||
* @date 2025-07-16
|
||||
*/
|
||||
public interface IRsTrainingCourseService {
|
||||
|
||||
/**
|
||||
* 查询培训课程列表
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @param pageQuery 分页参数
|
||||
* @return 培训课程分页列表
|
||||
*/
|
||||
TableDataInfo<RsTrainingCourse> selectPageRsTrainingCourseList(RsTrainingCourse course, PageQuery pageQuery);
|
||||
|
||||
/**
|
||||
* 查询培训课程列表
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @return 培训课程列表
|
||||
*/
|
||||
List<RsTrainingCourse> selectRsTrainingCourseList(RsTrainingCourse course);
|
||||
|
||||
/**
|
||||
* 查询培训课程详细信息
|
||||
*
|
||||
* @param courseId 培训课程ID
|
||||
* @return 培训课程
|
||||
*/
|
||||
RsTrainingCourse selectRsTrainingCourseById(Long courseId);
|
||||
|
||||
/**
|
||||
* 新增培训课程
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @return 结果
|
||||
*/
|
||||
int insertRsTrainingCourse(RsTrainingCourse course);
|
||||
|
||||
/**
|
||||
* 修改培训课程
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @return 结果
|
||||
*/
|
||||
int updateRsTrainingCourse(RsTrainingCourse course);
|
||||
|
||||
/**
|
||||
* 批量删除培训课程
|
||||
*
|
||||
* @param courseIds 需要删除的培训课程ID数组
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteRsTrainingCourseByIds(Long[] courseIds);
|
||||
|
||||
/**
|
||||
* 删除培训课程信息
|
||||
*
|
||||
* @param courseId 培训课程ID
|
||||
* @return 结果
|
||||
*/
|
||||
int deleteRsTrainingCourseById(Long courseId);
|
||||
|
||||
/**
|
||||
* 切换培训课程状态
|
||||
*
|
||||
* @param courseId 培训课程ID
|
||||
* @return 结果
|
||||
*/
|
||||
int toggleCourseStatus(Long courseId);
|
||||
}
|
||||
+125
-141
@@ -1,30 +1,32 @@
|
||||
package org.dromara.rs.service.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.dromara.rs.mapper.RsTrainingApplicationMapper;
|
||||
import org.dromara.rs.mapper.RsTrainingCourseMapper;
|
||||
import org.dromara.rs.domain.RsTrainingApplication;
|
||||
import org.dromara.rs.domain.RsTrainingCourse;
|
||||
import org.dromara.rs.domain.RsTrainingRecord;
|
||||
import org.dromara.rs.domain.bo.RsTrainingApplicationBo;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.dromara.rs.mapper.RsTrainingApplicationMapper;
|
||||
import org.dromara.rs.service.IRsTrainingApplicationService;
|
||||
import org.dromara.rs.service.IRsTrainingRecordService;
|
||||
import org.dromara.rs.domain.RsTrainingRecord;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 培训申请服务实现类
|
||||
@@ -33,29 +35,15 @@ import org.springframework.context.ApplicationContextAware;
|
||||
* @date 2025-07-16
|
||||
*/
|
||||
@Service
|
||||
public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationService, ApplicationContextAware {
|
||||
@RequiredArgsConstructor
|
||||
public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(RsTrainingApplicationServiceImpl.class);
|
||||
|
||||
@Autowired
|
||||
private RsTrainingApplicationMapper trainingApplicationMapper;
|
||||
|
||||
private final RsTrainingApplicationMapper trainingApplicationMapper;
|
||||
|
||||
@Autowired
|
||||
private RsTrainingCourseMapper trainingCourseMapper;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取培训记录服务(延迟获取以避免循环依赖)
|
||||
*/
|
||||
private IRsTrainingRecordService getRecordService() {
|
||||
return applicationContext.getBean(IRsTrainingRecordService.class);
|
||||
}
|
||||
private IRsTrainingRecordService trainingRecordService;
|
||||
|
||||
/**
|
||||
* 查询培训申请列表
|
||||
@@ -85,9 +73,9 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
// 使用自定义分页查询获取列表数据
|
||||
List<RsTrainingApplication> list = trainingApplicationMapper.selectRsTrainingApplicationListPage(application, offset, size);
|
||||
|
||||
// 处理自定义培训课程(courseId=0)的情况
|
||||
// 处理自定义培训课程的情况
|
||||
for (RsTrainingApplication app : list) {
|
||||
if (app.getCourseId() != null && app.getCourseId() == 0 && (app.getCourseName() == null || app.getCourseName().isEmpty())) {
|
||||
if (app.getCourseName() == null || app.getCourseName().isEmpty()) {
|
||||
app.setCourseName("自定义培训");
|
||||
}
|
||||
}
|
||||
@@ -194,7 +182,6 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int insertRsTrainingApplication(RsTrainingApplication application) {
|
||||
try {
|
||||
// 确保applicationId不为空
|
||||
@@ -212,41 +199,18 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
}
|
||||
|
||||
// 处理自定义培训课程的情况(courseId = 0 或 null)
|
||||
if (application.getCourseId() == null || application.getCourseId() == 0) {
|
||||
// 对于自定义培训课程,不需要验证课程和更新课程报名人数
|
||||
application.setCourseId(0L); // 确保courseId为0L而不是null
|
||||
// 确保courseName不为空
|
||||
if (application.getCourseName() == null || application.getCourseName().isEmpty()) {
|
||||
application.setCourseName("自定义培训");
|
||||
}
|
||||
application.setCreateTime(DateUtils.getNowDate());
|
||||
application.setApplyTime(DateUtils.getNowDate());
|
||||
application.setStatus("0"); // 待审核状态
|
||||
application.setTenantId("000000"); // 设置默认租户ID
|
||||
return trainingApplicationMapper.insert(application);
|
||||
// 确保courseName不为空
|
||||
if (application.getCourseName() == null || application.getCourseName().isEmpty()) {
|
||||
application.setCourseName("自定义培训");
|
||||
}
|
||||
|
||||
// 1. 验证课程是否存在并可申请
|
||||
RsTrainingCourse course = trainingCourseMapper.selectById(application.getCourseId());
|
||||
if (course == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 2. 检查是否已达到最大参与人数
|
||||
if (course.getCurrentParticipants() >= course.getMaxParticipants()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 3. 更新课程当前报名人数
|
||||
course.setCurrentParticipants(course.getCurrentParticipants() + 1);
|
||||
trainingCourseMapper.updateById(course);
|
||||
|
||||
// 4. 保存申请信息
|
||||
application.setCreateTime(DateUtils.getNowDate());
|
||||
application.setApplyTime(DateUtils.getNowDate());
|
||||
Date now = DateUtils.getNowDate();
|
||||
application.setCreateTime(now);
|
||||
application.setApplyTime(now);
|
||||
application.setStatus("0"); // 待审核状态
|
||||
application.setTenantId("000000"); // 设置默认租户ID
|
||||
return trainingApplicationMapper.insert(application);
|
||||
|
||||
// 以上代码已处理所有情况
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
@@ -272,18 +236,13 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteRsTrainingApplicationByIds(Long[] applicationIds) {
|
||||
// 查询所有要删除的申请
|
||||
List<RsTrainingApplication> applications = trainingApplicationMapper.selectBatchIds(Arrays.asList(applicationIds));
|
||||
|
||||
// 对每个申请,减少对应课程的当前报名人数
|
||||
for (RsTrainingApplication app : applications) {
|
||||
RsTrainingCourse course = trainingCourseMapper.selectById(app.getCourseId());
|
||||
if (course != null && course.getCurrentParticipants() > 0) {
|
||||
course.setCurrentParticipants(course.getCurrentParticipants() - 1);
|
||||
trainingCourseMapper.updateById(course);
|
||||
}
|
||||
// 培训课程功能已移除,无需更新课程报名人数
|
||||
}
|
||||
|
||||
return trainingApplicationMapper.deleteBatchIds(Arrays.asList(applicationIds));
|
||||
@@ -296,17 +255,11 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteRsTrainingApplicationById(Long applicationId) {
|
||||
// 查询申请
|
||||
RsTrainingApplication application = trainingApplicationMapper.selectById(applicationId);
|
||||
if (application != null) {
|
||||
// 减少课程的当前报名人数
|
||||
RsTrainingCourse course = trainingCourseMapper.selectById(application.getCourseId());
|
||||
if (course != null && course.getCurrentParticipants() > 0) {
|
||||
course.setCurrentParticipants(course.getCurrentParticipants() - 1);
|
||||
trainingCourseMapper.updateById(course);
|
||||
}
|
||||
// 培训课程功能已移除,无需更新课程报名人数
|
||||
}
|
||||
|
||||
return trainingApplicationMapper.deleteById(applicationId);
|
||||
@@ -319,23 +272,17 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int cancelApplication(Long applicationId) {
|
||||
// 查询申请
|
||||
RsTrainingApplication application = trainingApplicationMapper.selectById(applicationId);
|
||||
if (application != null) {
|
||||
// 只有待审核状态的申请才能取消
|
||||
if ("0".equals(application.getStatus())) {
|
||||
// 更新状态为已取消
|
||||
application.setStatus("3");
|
||||
application.setUpdateTime(DateUtils.getNowDate());
|
||||
// 更新状态为已取消
|
||||
application.setStatus("3");
|
||||
application.setUpdateTime(DateUtils.getNowDate());
|
||||
|
||||
// 减少课程的当前报名人数
|
||||
RsTrainingCourse course = trainingCourseMapper.selectById(application.getCourseId());
|
||||
if (course != null && course.getCurrentParticipants() > 0) {
|
||||
course.setCurrentParticipants(course.getCurrentParticipants() - 1);
|
||||
trainingCourseMapper.updateById(course);
|
||||
}
|
||||
// 培训课程功能已移除,无需更新课程报名人数
|
||||
|
||||
return trainingApplicationMapper.updateById(application);
|
||||
}
|
||||
@@ -353,51 +300,28 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
@Override
|
||||
public int updateApplicationStatus(Long applicationId, String status) {
|
||||
RsTrainingApplication application = trainingApplicationMapper.selectById(applicationId);
|
||||
if (application != null) {
|
||||
application.setStatus(status);
|
||||
application.setUpdateTime(DateUtils.getNowDate());
|
||||
|
||||
// 如果是拒绝,记录被拒绝时间
|
||||
if ("2".equals(status)) {
|
||||
application.setRejectTime(DateUtils.getNowDate());
|
||||
}
|
||||
if (application != null) {
|
||||
application.setStatus(status);
|
||||
Date now = DateUtils.getNowDate();
|
||||
application.setUpdateTime(now);
|
||||
|
||||
// 如果是拒绝,记录被拒绝时间
|
||||
if ("2".equals(status)) {
|
||||
application.setRejectTime(now);
|
||||
}
|
||||
|
||||
int result = trainingApplicationMapper.updateById(application);
|
||||
// 同步到培训记录表:状态为"1已通过""3进行中""4已完成"时自动写入
|
||||
if ("1".equals(status) || "3".equals(status) || "4".equals(status)) {
|
||||
log.info("【同步培训记录】触发,applicationId={}, status={}", applicationId, status);
|
||||
RsTrainingRecord exist = getRecordService().selectByApplicationId(applicationId);
|
||||
if (exist == null) {
|
||||
log.info("【同步培训记录】插入新记录,userId={}, courseId={}", application.getUserId(), application.getCourseId());
|
||||
RsTrainingRecord record = new RsTrainingRecord();
|
||||
// 设置记录ID(使用时间戳)
|
||||
record.setRecordId(System.currentTimeMillis());
|
||||
record.setApplicationId(application.getApplicationId());
|
||||
record.setCourseId(application.getCourseId());
|
||||
record.setUserId(application.getUserId());
|
||||
record.setUserName(application.getUserName());
|
||||
record.setDepartment(application.getDepartment());
|
||||
record.setPosition(application.getPosition());
|
||||
record.setReason(application.getReason());
|
||||
record.setStatus(application.getStatus());
|
||||
record.setApplyTime(application.getApplyTime());
|
||||
record.setCurrentApprover(application.getCurrentApprover());
|
||||
record.setLocation(application.getLocation());
|
||||
record.setDuration(application.getDuration());
|
||||
record.setStartTime(application.getStartTime());
|
||||
record.setEndTime(application.getEndTime());
|
||||
record.setCourseName(application.getCourseName());
|
||||
record.setTenantId(application.getTenantId());
|
||||
record.setCreateDept(application.getCreateDept());
|
||||
record.setCreateBy(1L); // 默认系统用户
|
||||
record.setCreateTime(DateUtils.getNowDate());
|
||||
// 默认完成状态为进行中
|
||||
record.setCompletionStatus("0");
|
||||
getRecordService().insertRsTrainingRecord(record);
|
||||
} else {
|
||||
log.info("【同步培训记录】已存在,不重复插入,applicationId={}", applicationId);
|
||||
|
||||
// 如果申请通过,自动创建培训记录
|
||||
if ("1".equals(status)) {
|
||||
try {
|
||||
createTrainingRecordFromApplication(application);
|
||||
} catch (Exception e) {
|
||||
log.error("创建培训记录失败: applicationId={}, error={}", applicationId, e.getMessage(), e);
|
||||
// 不影响申请状态更新的结果
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return 0;
|
||||
@@ -411,7 +335,6 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int resubmitApplication(Long applicationId, RsTrainingApplication applicationData) {
|
||||
// 查询原申请
|
||||
RsTrainingApplication existingApp = trainingApplicationMapper.selectById(applicationId);
|
||||
@@ -424,7 +347,7 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
return 0;
|
||||
}
|
||||
|
||||
log.info("【重新提交申请】原申请状态: {}, 申请ID: {}", existingApp.getStatus(), applicationId);
|
||||
|
||||
|
||||
// 更新申请数据
|
||||
if (applicationData.getReason() != null) {
|
||||
@@ -446,13 +369,74 @@ public class RsTrainingApplicationServiceImpl implements IRsTrainingApplicationS
|
||||
existingApp.setCourseName(applicationData.getCourseName());
|
||||
}
|
||||
|
||||
// 重置为待审核状态
|
||||
existingApp.setStatus("0");
|
||||
existingApp.setUpdateTime(DateUtils.getNowDate());
|
||||
existingApp.setApplyTime(DateUtils.getNowDate()); // 更新申请时间
|
||||
// 重置为待审核状态
|
||||
existingApp.setStatus("0");
|
||||
Date now = DateUtils.getNowDate();
|
||||
existingApp.setUpdateTime(now);
|
||||
existingApp.setApplyTime(now); // 更新申请时间
|
||||
|
||||
|
||||
log.info("【重新提交申请】更新为待审核状态");
|
||||
|
||||
return trainingApplicationMapper.updateById(existingApp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据培训申请创建培训记录
|
||||
*
|
||||
* @param application 培训申请
|
||||
*/
|
||||
private void createTrainingRecordFromApplication(RsTrainingApplication application) {
|
||||
try {
|
||||
// 检查是否已存在培训记录
|
||||
RsTrainingRecord existingRecord = trainingRecordService.selectByApplicationId(application.getApplicationId());
|
||||
if (existingRecord != null) {
|
||||
log.info("培训记录已存在,不重复创建: applicationId={}, recordId={}",
|
||||
application.getApplicationId(), existingRecord.getRecordId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 创建新的培训记录
|
||||
RsTrainingRecord record = new RsTrainingRecord();
|
||||
record.setApplicationId(application.getApplicationId());
|
||||
record.setCourseId(application.getCourseId());
|
||||
record.setUserId(application.getUserId());
|
||||
record.setUserName(application.getUserName());
|
||||
record.setDepartment(application.getDepartment());
|
||||
record.setPosition(application.getPosition());
|
||||
record.setReason(application.getReason());
|
||||
// 添加缺失的字段设置
|
||||
record.setCourseName(application.getCourseName());
|
||||
record.setDuration(application.getDuration());
|
||||
record.setLocation(application.getLocation());
|
||||
record.setStatus("3"); // 3=进行中
|
||||
record.setApplyTime(application.getApplyTime());
|
||||
record.setStartTime(application.getStartTime());
|
||||
record.setEndTime(application.getEndTime());
|
||||
record.setCompletionStatus("0"); // 0=进行中
|
||||
|
||||
// 设置基础字段 - 修复字段缺失问题
|
||||
Date now = DateUtils.getNowDate();
|
||||
record.setCreateTime(now);
|
||||
record.setUpdateTime(now);
|
||||
|
||||
// 设置租户和用户信息
|
||||
record.setTenantId(application.getTenantId() != null ? application.getTenantId() : "000000");
|
||||
record.setCreateBy(application.getUserId()); // 创建者设为申请人
|
||||
record.setUpdateBy(application.getUserId()); // 更新者设为申请人
|
||||
record.setCreateDept(application.getCreateDept() != null ? application.getCreateDept() : 1L); // 使用createDept,如果没有则设为默认值
|
||||
record.setDeptId(application.getCreateDept() != null ? application.getCreateDept() : 1L); // 设置部门ID
|
||||
|
||||
int result = trainingRecordService.insertRsTrainingRecord(record);
|
||||
if (result > 0) {
|
||||
log.info("培训记录创建成功: applicationId={}, recordId={}",
|
||||
application.getApplicationId(), record.getRecordId());
|
||||
} else {
|
||||
log.error("培训记录创建失败: applicationId={}", application.getApplicationId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("创建培训记录时发生异常: applicationId={}, error={}",
|
||||
application.getApplicationId(), e.getMessage(), e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
-138
@@ -1,138 +0,0 @@
|
||||
package org.dromara.rs.service.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.dromara.rs.mapper.RsTrainingCourseMapper;
|
||||
import org.dromara.rs.domain.RsTrainingCourse;
|
||||
import org.dromara.rs.service.IRsTrainingCourseService;
|
||||
|
||||
/**
|
||||
* 培训课程服务实现类
|
||||
*
|
||||
* @author weizzzz
|
||||
* @date 2025-07-16
|
||||
*/
|
||||
@Service
|
||||
public class RsTrainingCourseServiceImpl implements IRsTrainingCourseService {
|
||||
|
||||
@Autowired
|
||||
private RsTrainingCourseMapper trainingCourseMapper;
|
||||
|
||||
/**
|
||||
* 查询培训课程列表
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @param pageQuery 分页参数
|
||||
* @return 培训课程分页列表
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<RsTrainingCourse> selectPageRsTrainingCourseList(RsTrainingCourse course, PageQuery pageQuery) {
|
||||
com.baomidou.mybatisplus.extension.plugins.pagination.Page<RsTrainingCourse> page = trainingCourseMapper.selectPage(pageQuery.build(), buildQueryWrapper(course));
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询培训课程列表
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @return 培训课程列表
|
||||
*/
|
||||
@Override
|
||||
public List<RsTrainingCourse> selectRsTrainingCourseList(RsTrainingCourse course) {
|
||||
return trainingCourseMapper.selectList(buildQueryWrapper(course));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询培训课程详细信息
|
||||
*
|
||||
* @param courseId 培训课程ID
|
||||
* @return 培训课程
|
||||
*/
|
||||
@Override
|
||||
public RsTrainingCourse selectRsTrainingCourseById(Long courseId) {
|
||||
return trainingCourseMapper.selectById(courseId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增培训课程
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertRsTrainingCourse(RsTrainingCourse course) {
|
||||
course.setCreateTime(DateUtils.getNowDate());
|
||||
return trainingCourseMapper.insert(course);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改培训课程
|
||||
*
|
||||
* @param course 培训课程
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateRsTrainingCourse(RsTrainingCourse course) {
|
||||
course.setUpdateTime(DateUtils.getNowDate());
|
||||
return trainingCourseMapper.updateById(course);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除培训课程
|
||||
*
|
||||
* @param courseIds 需要删除的培训课程ID数组
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int deleteRsTrainingCourseByIds(Long[] courseIds) {
|
||||
return trainingCourseMapper.deleteBatchIds(Arrays.asList(courseIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除培训课程信息
|
||||
*
|
||||
* @param courseId 培训课程ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteRsTrainingCourseById(Long courseId) {
|
||||
return trainingCourseMapper.deleteById(courseId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换培训课程状态
|
||||
*
|
||||
* @param courseId 培训课程ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int toggleCourseStatus(Long courseId) {
|
||||
RsTrainingCourse course = trainingCourseMapper.selectById(courseId);
|
||||
if (course != null) {
|
||||
// 切换状态:0正常 -> 1停用,或 1停用 -> 0正常
|
||||
course.setStatus("0".equals(course.getStatus()) ? "1" : "0");
|
||||
course.setUpdateTime(DateUtils.getNowDate());
|
||||
return trainingCourseMapper.updateById(course);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询条件
|
||||
*/
|
||||
private com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<RsTrainingCourse> buildQueryWrapper(RsTrainingCourse course) {
|
||||
com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<RsTrainingCourse> lqw = new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<>();
|
||||
lqw.like(course.getTitle() != null, RsTrainingCourse::getTitle, course.getTitle());
|
||||
lqw.eq(course.getCategory() != null, RsTrainingCourse::getCategory, course.getCategory());
|
||||
lqw.eq(course.getStatus() != null, RsTrainingCourse::getStatus, course.getStatus());
|
||||
return lqw;
|
||||
}
|
||||
}
|
||||
+7
-23
@@ -15,8 +15,7 @@ import org.dromara.rs.domain.RsTrainingRecord;
|
||||
import org.dromara.rs.service.IRsTrainingRecordService;
|
||||
import org.dromara.rs.domain.RsTrainingApplication;
|
||||
import org.dromara.rs.service.IRsTrainingApplicationService;
|
||||
import org.dromara.rs.domain.RsTrainingCourse;
|
||||
import org.dromara.rs.service.IRsTrainingCourseService;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -37,8 +36,7 @@ public class RsTrainingRecordServiceImpl implements IRsTrainingRecordService, Ap
|
||||
@Autowired
|
||||
private RsTrainingRecordMapper trainingRecordMapper;
|
||||
|
||||
@Autowired
|
||||
private IRsTrainingCourseService courseService;
|
||||
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@@ -303,25 +301,11 @@ public class RsTrainingRecordServiceImpl implements IRsTrainingRecordService, Ap
|
||||
}
|
||||
}
|
||||
|
||||
// 如果申请表中也没有,尝试从课程表获取
|
||||
if ((StringUtils.isEmpty(record.getCourseName()) || StringUtils.isEmpty(record.getLocation()) || record.getDuration() == null)
|
||||
&& record.getCourseId() != null) {
|
||||
|
||||
RsTrainingCourse course = courseService.selectRsTrainingCourseById(record.getCourseId());
|
||||
if (course != null) {
|
||||
if (StringUtils.isEmpty(record.getCourseName())) {
|
||||
record.setCourseName(course.getTitle());
|
||||
needUpdate = true;
|
||||
}
|
||||
if (StringUtils.isEmpty(record.getLocation())) {
|
||||
record.setLocation(course.getLocation());
|
||||
needUpdate = true;
|
||||
}
|
||||
if (record.getDuration() == null) {
|
||||
record.setDuration(course.getDuration());
|
||||
needUpdate = true;
|
||||
}
|
||||
}
|
||||
// 培训课程功能已移除,不再从课程表获取信息
|
||||
// 如果记录中仍然缺少信息,设置默认值
|
||||
if (StringUtils.isEmpty(record.getCourseName())) {
|
||||
record.setCourseName("自定义培训");
|
||||
needUpdate = true;
|
||||
}
|
||||
|
||||
// 更新记录
|
||||
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.dromara.rs.mapper.RsTrainingCourseMapper">
|
||||
|
||||
<resultMap type="RsTrainingCourse" id="RsTrainingCourseResult">
|
||||
<id property="courseId" column="course_id"/>
|
||||
<result property="title" column="title"/>
|
||||
<result property="category" column="category"/>
|
||||
<result property="description" column="description"/>
|
||||
<result property="startTime" column="start_time"/>
|
||||
<result property="endTime" column="end_time"/>
|
||||
<result property="duration" column="duration"/>
|
||||
<result property="location" column="location"/>
|
||||
<result property="maxParticipants" column="max_participants"/>
|
||||
<result property="currentParticipants" column="current_participants"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="applicationCount" column="application_count"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectRsTrainingCourseVo">
|
||||
select c.course_id, c.title, c.category, c.description, c.start_time, c.end_time, c.duration,
|
||||
c.location, c.max_participants, c.current_participants, c.status, c.tenant_id, c.create_by,
|
||||
c.create_time, c.update_by, c.update_time, c.remark,
|
||||
(select count(1) from rs_training_application a where a.course_id = c.course_id and a.deleted = '0' and a.tenant_id = c.tenant_id) as application_count
|
||||
from rs_training_course c
|
||||
</sql>
|
||||
|
||||
<select id="selectRsTrainingCourseList" parameterType="RsTrainingCourse" resultMap="RsTrainingCourseResult">
|
||||
<include refid="selectRsTrainingCourseVo"/>
|
||||
<where>
|
||||
c.deleted = '0'
|
||||
<if test="title != null and title != ''">
|
||||
AND c.title like concat('%', #{title}, '%')
|
||||
</if>
|
||||
<if test="category != null and category != ''">
|
||||
AND c.category = #{category}
|
||||
</if>
|
||||
<if test="startTime != null">
|
||||
AND c.start_time = #{startTime}
|
||||
</if>
|
||||
<if test="endTime != null">
|
||||
AND c.end_time = #{endTime}
|
||||
</if>
|
||||
<if test="status != null and status != ''">
|
||||
AND c.status = #{status}
|
||||
</if>
|
||||
<if test="tenantId != null and tenantId != ''">
|
||||
AND c.tenant_id = #{tenantId}
|
||||
</if>
|
||||
</where>
|
||||
order by c.create_time desc
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
+7
-4
@@ -36,6 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="courseName" column="course_name"/>
|
||||
<result property="duration" column="duration"/>
|
||||
<result property="location" column="location"/>
|
||||
<result property="deptId" column="dept_id"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectRsTrainingRecordVo">
|
||||
@@ -43,7 +44,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
r.completion_status, r.completion_time, r.score, r.certificate_path, r.certificate_number, r.attachment_ids,
|
||||
r.feedback, r.tenant_id, r.create_dept, r.create_by, r.create_time, r.update_by, r.update_time,
|
||||
r.department, r.position, r.reason, r.status, r.apply_time, r.current_approver, r.start_time, r.end_time,
|
||||
r.course_name, r.duration, r.location
|
||||
r.course_name, r.duration, r.location, r.dept_id
|
||||
from rs_training_record r
|
||||
</sql>
|
||||
|
||||
@@ -51,6 +52,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<include refid="selectRsTrainingRecordVo"/>
|
||||
<where>
|
||||
r.deleted = '0'
|
||||
<if test="applicationId != null">and r.application_id = #{applicationId}</if>
|
||||
<if test="courseId != null">and r.course_id = #{courseId}</if>
|
||||
<if test="courseName != null and courseName != ''">and r.course_name like concat('%', #{courseName}, '%')</if>
|
||||
<if test="userId != null">and r.user_id = #{userId}</if>
|
||||
@@ -74,12 +76,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
record_id, application_id, course_id, user_id, user_name, completion_status, completion_time, score,
|
||||
certificate_path, certificate_number, attachment_ids, feedback, location, duration, apply_time,
|
||||
status, course_name, department, position, reason, current_approver, start_time, end_time,
|
||||
tenant_id, create_dept, create_by, create_time, deleted
|
||||
tenant_id, create_dept, create_by, create_time, deleted, dept_id
|
||||
) VALUES (
|
||||
#{recordId}, #{applicationId}, #{courseId}, #{userId}, #{userName}, #{completionStatus}, #{completionTime}, #{score},
|
||||
#{certificatePath}, #{certificateNumber}, #{attachmentIds}, #{feedback}, #{location}, #{duration}, #{applyTime},
|
||||
#{status}, #{courseName}, #{department}, #{position}, #{reason}, #{currentApprover}, #{startTime}, #{endTime},
|
||||
#{tenantId}, #{createDept}, #{createBy}, #{createTime}, '0'
|
||||
#{tenantId}, #{createDept}, #{createBy}, #{createTime}, '0', #{deptId}
|
||||
)
|
||||
</insert>
|
||||
|
||||
@@ -109,7 +111,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="startTime != null">start_time = #{startTime},</if>
|
||||
<if test="endTime != null">end_time = #{endTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime}</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="deptId != null">dept_id = #{deptId},</if>
|
||||
</set>
|
||||
where record_id = #{recordId}
|
||||
</update>
|
||||
|
||||
@@ -34,7 +34,7 @@ create table rs_training_course (
|
||||
drop table if exists rs_training_application;
|
||||
create table rs_training_application (
|
||||
application_id bigint(20) not null comment '申请ID',
|
||||
course_id bigint(20) not null comment '课程ID',
|
||||
course_name varchar(100) not null comment '培训名称',
|
||||
user_id bigint(20) not null comment '申请人ID',
|
||||
user_name varchar(50) not null comment '申请人姓名',
|
||||
department varchar(50) not null comment '所属部门',
|
||||
@@ -43,7 +43,13 @@ create table rs_training_application (
|
||||
status char(1) default '0' comment '状态(0待审核 1已通过 2已拒绝 3进行中 4已完成)',
|
||||
apply_time datetime comment '申请时间',
|
||||
current_approver varchar(50) comment '当前审批人',
|
||||
location varchar(200) comment '培训地点',
|
||||
duration int(11) comment '学时',
|
||||
start_time datetime comment '开始时间',
|
||||
end_time datetime comment '结束时间',
|
||||
tenant_id varchar(20) default '000000' comment '租户编号',
|
||||
create_dept bigint(20) comment '创建部门',
|
||||
reject_time datetime comment '拒绝时间',
|
||||
create_by bigint(20) comment '创建者',
|
||||
create_time datetime comment '创建时间',
|
||||
update_by bigint(20) comment '更新者',
|
||||
|
||||
+10
@@ -189,6 +189,16 @@ public class ZsjyGraduateInfo extends TenantEntity implements Serializable {
|
||||
*/
|
||||
private String workCity;
|
||||
|
||||
/**
|
||||
* 工作地点
|
||||
*/
|
||||
private String workLocation;
|
||||
|
||||
/**
|
||||
* 完整地址
|
||||
*/
|
||||
private String fullAddress;
|
||||
|
||||
/**
|
||||
* 月薪范围 (1-3000以下 2-3000-5000 3-5000-8000 4-8000-12000 5-12000以上)
|
||||
*/
|
||||
|
||||
+10
@@ -220,6 +220,16 @@ public class ZsjyGraduateInfoBo extends BaseEntity {
|
||||
*/
|
||||
private String workCity;
|
||||
|
||||
/**
|
||||
* 工作地点
|
||||
*/
|
||||
private String workLocation;
|
||||
|
||||
/**
|
||||
* 完整地址
|
||||
*/
|
||||
private String fullAddress;
|
||||
|
||||
/**
|
||||
* 月薪范围 (1-3000以下 2-3000-5000 3-5000-8000 4-8000-12000 5-12000以上)
|
||||
*/
|
||||
|
||||
+25
-5
@@ -43,7 +43,10 @@ public class ZsjyGraduateInfoServiceImpl implements IZsjyGraduateInfoService {
|
||||
*/
|
||||
@Override
|
||||
public ZsjyGraduateInfoVo queryById(Long id) {
|
||||
return baseMapper.selectVoById(id);
|
||||
ZsjyGraduateInfoBo bo = new ZsjyGraduateInfoBo();
|
||||
bo.setId(id);
|
||||
List<ZsjyGraduateInfoVo> list = baseMapper.selectGraduateInfoVoList(bo);
|
||||
return list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,8 +58,8 @@ public class ZsjyGraduateInfoServiceImpl implements IZsjyGraduateInfoService {
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<ZsjyGraduateInfoVo> queryPageList(ZsjyGraduateInfoBo bo, PageQuery pageQuery) {
|
||||
LambdaQueryWrapper<ZsjyGraduateInfo> lqw = buildQueryWrapper(bo);
|
||||
Page<ZsjyGraduateInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
||||
Page<ZsjyGraduateInfoVo> page = pageQuery.build();
|
||||
IPage<ZsjyGraduateInfoVo> result = baseMapper.selectGraduateInfoPageList(page, bo);
|
||||
return TableDataInfo.build(result);
|
||||
}
|
||||
|
||||
@@ -68,8 +71,7 @@ public class ZsjyGraduateInfoServiceImpl implements IZsjyGraduateInfoService {
|
||||
*/
|
||||
@Override
|
||||
public List<ZsjyGraduateInfoVo> queryList(ZsjyGraduateInfoBo bo) {
|
||||
LambdaQueryWrapper<ZsjyGraduateInfo> lqw = buildQueryWrapper(bo);
|
||||
return baseMapper.selectVoList(lqw);
|
||||
return baseMapper.selectGraduateInfoVoList(bo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,6 +213,24 @@ public class ZsjyGraduateInfoServiceImpl implements IZsjyGraduateInfoService {
|
||||
throw new RuntimeException("升学状态下,升学院校不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
// 自动设置组合字段
|
||||
// 设置工作地点(工作省份 + 工作城市)
|
||||
if (StringUtils.isNotBlank(entity.getWorkProvince()) || StringUtils.isNotBlank(entity.getWorkCity())) {
|
||||
String workLocation = StringUtils.defaultString(entity.getWorkProvince(), "") +
|
||||
StringUtils.defaultString(entity.getWorkCity(), "");
|
||||
entity.setWorkLocation(workLocation);
|
||||
}
|
||||
|
||||
// 设置完整地址(省份 + 城市 + 区县 + 详细地址)
|
||||
if (StringUtils.isNotBlank(entity.getProvince()) || StringUtils.isNotBlank(entity.getCity()) ||
|
||||
StringUtils.isNotBlank(entity.getDistrict()) || StringUtils.isNotBlank(entity.getDetailAddress())) {
|
||||
String fullAddress = StringUtils.defaultString(entity.getProvince(), "") +
|
||||
StringUtils.defaultString(entity.getCity(), "") +
|
||||
StringUtils.defaultString(entity.getDistrict(), "") +
|
||||
StringUtils.defaultString(entity.getDetailAddress(), "");
|
||||
entity.setFullAddress(fullAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+26
-21
@@ -25,7 +25,6 @@ import org.dromara.zsjy.service.IZsjyRecruitmentPosterService;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 招聘海报Service业务层处理
|
||||
@@ -138,14 +137,23 @@ public class ZsjyRecruitmentPosterServiceImpl implements IZsjyRecruitmentPosterS
|
||||
throw new ServiceException("企业信息不存在");
|
||||
}
|
||||
|
||||
// 生成海报路径
|
||||
String posterPath = generatePosterPath("enterprise");
|
||||
// 检查是否已存在企业海报
|
||||
LambdaQueryWrapper<ZsjyRecruitmentPoster> queryWrapper = Wrappers.lambdaQuery();
|
||||
queryWrapper.eq(ZsjyRecruitmentPoster::getEnterpriseId, enterpriseId)
|
||||
.eq(ZsjyRecruitmentPoster::getPosterType, "1")
|
||||
.isNull(ZsjyRecruitmentPoster::getPositionId);
|
||||
ZsjyRecruitmentPoster existingPoster = baseMapper.selectOne(queryWrapper);
|
||||
|
||||
// 创建海报记录
|
||||
if (existingPoster != null) {
|
||||
// 如果已存在,直接返回现有记录
|
||||
return baseMapper.selectVoById(existingPoster.getId());
|
||||
}
|
||||
|
||||
// 创建海报记录(不设置posterPath,等待用户上传)
|
||||
ZsjyRecruitmentPosterBo bo = new ZsjyRecruitmentPosterBo();
|
||||
bo.setEnterpriseId(enterpriseId);
|
||||
bo.setPosterPath(posterPath);
|
||||
bo.setPosterType("1"); // 企业海报
|
||||
// 注意:不设置posterPath,让用户后续上传图片
|
||||
|
||||
// 保存海报记录
|
||||
insertByBo(bo);
|
||||
@@ -169,15 +177,23 @@ public class ZsjyRecruitmentPosterServiceImpl implements IZsjyRecruitmentPosterS
|
||||
throw new ServiceException("岗位信息不存在");
|
||||
}
|
||||
|
||||
// 生成海报路径
|
||||
String posterPath = generatePosterPath("position");
|
||||
// 检查是否已存在岗位海报
|
||||
LambdaQueryWrapper<ZsjyRecruitmentPoster> queryWrapper = Wrappers.lambdaQuery();
|
||||
queryWrapper.eq(ZsjyRecruitmentPoster::getPositionId, positionId)
|
||||
.eq(ZsjyRecruitmentPoster::getPosterType, "2");
|
||||
ZsjyRecruitmentPoster existingPoster = baseMapper.selectOne(queryWrapper);
|
||||
|
||||
// 创建海报记录
|
||||
if (existingPoster != null) {
|
||||
// 如果已存在,直接返回现有记录
|
||||
return baseMapper.selectVoById(existingPoster.getId());
|
||||
}
|
||||
|
||||
// 创建海报记录(不设置posterPath,等待用户上传)
|
||||
ZsjyRecruitmentPosterBo bo = new ZsjyRecruitmentPosterBo();
|
||||
bo.setEnterpriseId(position.getEnterpriseId());
|
||||
bo.setPositionId(positionId);
|
||||
bo.setPosterPath(posterPath);
|
||||
bo.setPosterType("2"); // 岗位海报
|
||||
// 注意:不设置posterPath,让用户后续上传图片
|
||||
|
||||
// 保存海报记录
|
||||
insertByBo(bo);
|
||||
@@ -187,16 +203,5 @@ public class ZsjyRecruitmentPosterServiceImpl implements IZsjyRecruitmentPosterS
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成海报路径
|
||||
*
|
||||
* @param type 类型
|
||||
* @return 海报路径
|
||||
*/
|
||||
private String generatePosterPath(String type) {
|
||||
// 基于类型和UUID生成唯一的海报文件名
|
||||
String fileName = type + "_" + UUID.randomUUID().toString().replace("-", "") + ".png";
|
||||
// 海报存储路径
|
||||
return "/profile/upload/poster/" + fileName;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -139,6 +139,9 @@
|
||||
<select id="selectGraduateInfoPageList" resultMap="ZsjyGraduateInfoVoResult">
|
||||
<include refid="selectZsjyGraduateInfoVo"/>
|
||||
<if test="bo != null">
|
||||
<if test="bo.id != null">
|
||||
and g.id = #{bo.id}
|
||||
</if>
|
||||
<if test="bo.studentNo != null and bo.studentNo != ''">
|
||||
and g.student_no like concat('%', #{bo.studentNo}, '%')
|
||||
</if>
|
||||
@@ -239,6 +242,9 @@
|
||||
<!-- 查询毕业生信息列表(非分页) -->
|
||||
<select id="selectGraduateInfoVoList" parameterType="org.dromara.zsjy.domain.bo.ZsjyGraduateInfoBo" resultMap="ZsjyGraduateInfoVoResult">
|
||||
<include refid="selectZsjyGraduateInfoVo"/>
|
||||
<if test="id != null">
|
||||
and g.id = #{id}
|
||||
</if>
|
||||
<if test="studentNo != null and studentNo != ''">
|
||||
and g.student_no like concat('%', #{studentNo}, '%')
|
||||
</if>
|
||||
|
||||
@@ -329,3 +329,14 @@ export const getCompatibleTypes = (id: string | number): AxiosPromise<Scholarshi
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取奖学金类型的互斥关系显示文本
|
||||
* @param id 奖学金类型ID
|
||||
*/
|
||||
export const getExclusiveRelationDisplay = (id: string | number): AxiosPromise<string> => {
|
||||
return request({
|
||||
url: `/jcbt/scholarshipType/${id}/exclusiveRelationDisplay`,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
@@ -107,6 +107,8 @@ export interface RecordQuery {
|
||||
courseName?: string;
|
||||
userId?: number | string;
|
||||
userName?: string;
|
||||
location?: string;
|
||||
department?: string;
|
||||
completionStatus?: string;
|
||||
params?: Record<string, any>;
|
||||
}
|
||||
@@ -119,6 +121,7 @@ export interface RecordVO {
|
||||
courseName: string;
|
||||
userId: number | string;
|
||||
userName: string;
|
||||
location?: string;
|
||||
department?: string;
|
||||
completionStatus: string;
|
||||
score?: string;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { GraduateInfoVO, GraduateInfoForm, GraduateInfoQuery, GraduateStatisticsVO } from '@/api/zsjy/types';
|
||||
import { TableDataInfo } from '@/api/types';
|
||||
|
||||
/**
|
||||
* 查询毕业生信息列表
|
||||
* @param query 查询参数
|
||||
*/
|
||||
export const listGraduateInfo = (query?: GraduateInfoQuery): AxiosPromise<GraduateInfoVO[]> => {
|
||||
export const listGraduateInfo = (query?: GraduateInfoQuery): AxiosPromise<TableDataInfo<GraduateInfoVO[]>> => {
|
||||
return request({
|
||||
url: '/zsjy/graduate/list',
|
||||
method: 'get',
|
||||
|
||||
@@ -654,6 +654,7 @@ export interface GraduateInfoForm {
|
||||
city?: string;
|
||||
district?: string;
|
||||
detailAddress?: string;
|
||||
fullAddress?: string;
|
||||
postalCode?: string;
|
||||
employmentStatus?: string;
|
||||
employmentCompany?: string;
|
||||
@@ -661,6 +662,7 @@ export interface GraduateInfoForm {
|
||||
jobPosition?: string;
|
||||
workProvince?: string;
|
||||
workCity?: string;
|
||||
workLocation?: string;
|
||||
salaryRange?: string;
|
||||
furtherSchool?: string;
|
||||
furtherMajor?: string;
|
||||
|
||||
@@ -87,24 +87,24 @@
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="indicatorName" label="指标名称" min-width="150" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="description" label="指标描述" min-width="180" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="score" label="指标分值" width="80" align="center">
|
||||
<el-table-column prop="score" label="指标分值" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评分数" width="80" align="center">
|
||||
<el-table-column label="自评分数" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
<el-table-column label="自评意见" min-width="180" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
|
||||
<span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上级评分" width="100" align="center">
|
||||
<el-table-column label="上级评分" min-width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.superiorScore"
|
||||
@@ -118,7 +118,7 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批意见" width="200" align="center">
|
||||
<el-table-column label="审批意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.superiorComment"
|
||||
@@ -204,27 +204,27 @@
|
||||
<span>特色工作(加20分)</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-table border :data="specialWorkScores" style="width: 100%" class="special-work-table">
|
||||
<el-table border :data="specialWorkScores" style="width: 100%" max-height="200" class="special-work-table">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="indicatorName" label="特色工作项目" min-width="180" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="自评分数" width="80" align="center">
|
||||
<el-table-column label="自评分数" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score || scope.row.selfScore || 0 }}</span>
|
||||
<span>{{ scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
<el-table-column label="自评意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
|
||||
<span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上级评分" width="100" align="center">
|
||||
<el-table-column label="上级评分" min-width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.superiorScore"
|
||||
:min="0"
|
||||
:max="20"
|
||||
:max="scope.row.score || 20"
|
||||
:precision="2"
|
||||
controls-position="right"
|
||||
style="width: 100%"
|
||||
@@ -233,7 +233,7 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批意见" width="200" align="center">
|
||||
<el-table-column label="审批意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.superiorComment"
|
||||
|
||||
@@ -6,19 +6,19 @@
|
||||
<el-card shadow="hover">
|
||||
<el-form :model="queryParams" ref="queryFormRef" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="计划名称" prop="planName">
|
||||
<el-input v-model="queryParams.planName" placeholder="请输入计划名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="考核方案" prop="schemeName">
|
||||
<el-select v-model="queryParams.schemeName" placeholder="请选择考核方案" clearable style="width: 100%">
|
||||
<el-option v-for="item in schemeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="审批状态" prop="auditStatus">
|
||||
<el-select v-model="queryParams.auditStatus" placeholder="请选择审批状态" clearable style="width: 100%">
|
||||
<el-option label="待审核" value="0" />
|
||||
@@ -27,17 +27,21 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="班级名称" prop="className">
|
||||
<el-input v-model="queryParams.className" placeholder="请输入班级名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="班主任姓名" prop="teacherName">
|
||||
<el-input v-model="queryParams.teacherName" placeholder="请输入班主任姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24" style="text-align: right">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -59,21 +63,21 @@
|
||||
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" border :data="approvalList" @sort-change="sortChange">
|
||||
<el-table-column label="计划名称" align="center" prop="planName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" prop="schemeName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="学年学期" align="center" width="120">
|
||||
<el-table-column label="计划名称" align="center" prop="planName" min-width="180" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" prop="schemeName" min-width="180" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="学年学期" align="center" min-width="140">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.academicYear }}{{ scope.row.semester === '1' ? '上' : '下' }}学期</span>
|
||||
<span>{{ scope.row.academicYear }}{{ getSemesterLabel(scope.row.semester) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="班级名称" align="center" prop="className" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="班主任姓名" align="center" prop="evaluatedUserName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="申请时间" align="center" width="180" sortable="custom" prop="submitTime">
|
||||
<el-table-column label="班级名称" align="center" prop="className" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="班主任姓名" align="center" prop="evaluatedUserName" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="申请时间" align="center" min-width="180" sortable="custom" prop="submitTime">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.submitTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批状态" align="center" width="120">
|
||||
<el-table-column label="审批状态" align="center" min-width="120">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="!scope.row.auditStatus || scope.row.auditStatus === '0'" type="warning" effect="plain">待审核</el-tag>
|
||||
<el-tag v-else-if="scope.row.auditStatus === '1'" type="success" effect="plain">审核通过</el-tag>
|
||||
@@ -120,6 +124,13 @@ import ApprovalDialog from './approvalDialog.vue';
|
||||
import ViewDialog from './viewDialog.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { student_semester } = toRefs<any>(proxy?.useDict('student_semester'));
|
||||
|
||||
// 获取学期标签
|
||||
const getSemesterLabel = (semester: string) => {
|
||||
const semesterDict = student_semester.value?.find((item: any) => item.value === semester);
|
||||
return semesterDict ? semesterDict.label : '';
|
||||
};
|
||||
|
||||
const approvalList = ref<AssessmentApprovalVO[]>([]);
|
||||
const loading = ref(true);
|
||||
@@ -248,4 +259,15 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -85,29 +85,29 @@
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="indicatorName" label="指标名称" min-width="150" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="description" label="指标描述" min-width="180" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="score" label="指标分值" width="80" align="center">
|
||||
<el-table-column prop="score" label="指标分值" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评分数" width="80" align="center">
|
||||
<el-table-column label="自评分数" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
<el-table-column label="自评意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
|
||||
<span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上级评分" width="80" align="center">
|
||||
<el-table-column label="上级评分" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.superiorScore || '-' }}</span>
|
||||
<span>{{ scope.row.superiorScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批意见" width="180" align="center">
|
||||
<el-table-column label="审批意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip :content="scope.row.superiorComment || '无'" placement="top" :disabled="!scope.row.superiorComment">
|
||||
<span class="text-ellipsis">{{ scope.row.superiorComment || '无' }}</span>
|
||||
@@ -175,24 +175,24 @@
|
||||
<el-table border :data="specialWorkScores" style="width: 100%" max-height="200" class="special-work-table">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="indicatorName" label="特色工作项目" min-width="180" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="自评分数" width="80" align="center">
|
||||
<el-table-column label="自评分数" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
<el-table-column label="自评意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
|
||||
<span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上级评分" width="80" align="center">
|
||||
<el-table-column label="上级评分" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.superiorScore || '-' }}</span>
|
||||
<span>{{ scope.row.superiorScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批意见" width="180" align="center">
|
||||
<el-table-column label="审批意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip :content="scope.row.superiorComment || '无'" placement="top" :disabled="!scope.row.superiorComment">
|
||||
<span class="text-ellipsis">{{ scope.row.superiorComment || '无' }}</span>
|
||||
|
||||
@@ -5,24 +5,26 @@
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="指标名称" prop="indicatorName">
|
||||
<el-input v-model="queryParams.indicatorName" placeholder="请输入指标名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="指标编码" prop="indicatorCode">
|
||||
<el-input v-model="queryParams.indicatorCode" placeholder="请输入指标编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="指标类型" prop="indicatorType">
|
||||
<el-select v-model="queryParams.indicatorType" placeholder="请选择指标类型" clearable style="width: 100%">
|
||||
<el-option v-for="item in indicatorTypeOptions" :key="item.id" :label="item.indicatorTypeName" :value="item.indicatorTypeCode" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -54,17 +56,17 @@
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" border :data="assessmentIndicatorList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="指标编码" align="center" prop="indicatorCode" width="140" show-overflow-tooltip />
|
||||
<el-table-column label="指标编码" align="center" prop="indicatorCode" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column label="指标名称" align="center" prop="indicatorName" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="指标类型" align="center" prop="indicatorType" width="120">
|
||||
<el-table-column label="指标类型" align="center" prop="indicatorType" min-width="150" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ getIndicatorTypeName(scope.row.indicatorType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="最高分值" align="center" prop="maxScore" width="100" />
|
||||
<el-table-column label="分值" align="center" prop="score" width="80" />
|
||||
<el-table-column label="排序" align="center" prop="sortOrder" width="80" />
|
||||
<el-table-column label="状态" align="center" prop="status" width="80">
|
||||
<el-table-column label="最高分值" align="center" prop="maxScore" min-width="100" />
|
||||
<el-table-column label="分值" align="center" prop="score" min-width="80" />
|
||||
<el-table-column label="排序" align="center" prop="sortOrder" min-width="80" />
|
||||
<el-table-column label="状态" align="center" prop="status" min-width="80">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_item_enable" :value="scope.row.status" />
|
||||
</template>
|
||||
@@ -404,4 +406,15 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -5,24 +5,26 @@
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="指标类型编码" prop="indicatorTypeCode">
|
||||
<el-input v-model="queryParams.indicatorTypeCode" placeholder="请输入指标类型编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="指标类型名称" prop="indicatorTypeName">
|
||||
<el-input v-model="queryParams.indicatorTypeName" placeholder="请输入指标类型名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||||
<el-option v-for="dict in sys_item_enable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -55,20 +57,20 @@
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" border :data="assessmentIndicatorTypeList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="指标类型编码" align="center" prop="indicatorTypeCode" />
|
||||
<el-table-column label="指标类型名称" align="center" prop="indicatorTypeName" />
|
||||
<el-table-column label="状态" align="center" prop="status">
|
||||
<el-table-column label="指标类型编码" align="center" prop="indicatorTypeCode" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="指标类型名称" align="center" prop="indicatorTypeName" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="状态" align="center" prop="status" min-width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_item_enable" :value="scope.row.status" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<el-table-column label="备注" align="center" prop="remark" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" align="center" width="120" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
@@ -293,6 +295,17 @@ onMounted(() => {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
|
||||
@@ -5,44 +5,47 @@
|
||||
<el-card shadow="hover">
|
||||
<el-form :model="queryParams" ref="queryFormRef" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="计划名称" prop="planName">
|
||||
<el-input v-model="queryParams.planName" placeholder="请输入计划名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="计划编码" prop="planCode">
|
||||
<el-input v-model="queryParams.planCode" placeholder="请输入计划编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="考核方案" prop="schemeId">
|
||||
<el-select v-model="queryParams.schemeId" placeholder="请选择考核方案" clearable style="width: 100%">
|
||||
<el-option v-for="item in schemeOptions" :key="item.id" :label="item.schemeName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="学年" prop="academicYear">
|
||||
<el-input v-model="queryParams.academicYear" placeholder="请输入学年" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="学期" prop="semester">
|
||||
<el-select v-model="queryParams.semester" placeholder="请选择学期" clearable style="width: 100%">
|
||||
<el-option label="上学期" value="1" />
|
||||
<el-option label="下学期" value="2" />
|
||||
<el-option v-for="dict in student_semester" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="计划状态" prop="planStatus">
|
||||
<el-select v-model="queryParams.planStatus" placeholder="请选择计划状态" clearable style="width: 100%">
|
||||
<el-option v-for="option in planStatusOptions" :key="option.value" :label="option.label" :value="option.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="12" :md="24" :sm="24">
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="创建时间">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
@@ -56,7 +59,9 @@
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -87,24 +92,24 @@
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" border :data="assessmentPlanList" @selection-change="handleSelectionChange" @sort-change="sortChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="计划名称" align="center" prop="planName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="计划编码" align="center" prop="planCode" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" :show-overflow-tooltip="true">
|
||||
<el-table-column label="计划名称" align="center" prop="planName" min-width="180" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="计划编码" align="center" prop="planCode" min-width="150" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" min-width="180" :show-overflow-tooltip="true">
|
||||
<template #default="scope">
|
||||
<span>{{ schemeOptions.find((item) => item.id === scope.row.schemeId)?.schemeName || '' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学年学期" align="center" width="120">
|
||||
<el-table-column label="学年学期" align="center" min-width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.academicYear }}{{ scope.row.semester === '1' ? '上' : '下' }}学期</span>
|
||||
<span>{{ scope.row.academicYear }}{{ getSemesterLabel(scope.row.semester) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划时间" align="center" width="180">
|
||||
<el-table-column label="计划时间" align="center" min-width="200">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.planStartTime, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.planEndTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数据提取时间" align="center" width="180">
|
||||
<el-table-column label="数据提取时间" align="center" min-width="200">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.dataExtractStartTime && scope.row.dataExtractEndTime">
|
||||
{{ parseTime(scope.row.dataExtractStartTime, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.dataExtractEndTime, '{y}-{m}-{d}') }}
|
||||
@@ -112,7 +117,7 @@
|
||||
<span v-else class="text-gray-400">未设置</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划状态" align="center" width="100">
|
||||
<el-table-column label="计划状态" align="center" min-width="100">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.planStatus"
|
||||
@@ -123,12 +128,12 @@
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="120">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['bzrkh:assessmentPlan:edit']"></el-button>
|
||||
@@ -168,7 +173,7 @@
|
||||
<el-option
|
||||
v-for="item in schemeOptions"
|
||||
:key="item.id"
|
||||
:label="`${item.schemeName}(${item.academicYear}${item.semester === '1' ? '上' : '下'}学期)`"
|
||||
:label="`${item.schemeName}(${item.academicYear}${getSemesterLabel(item.semester)})`"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
@@ -184,8 +189,7 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学期" prop="semester">
|
||||
<el-select v-model="form.semester" placeholder="请选择学期" style="width: 100%">
|
||||
<el-option label="上学期" value="1" />
|
||||
<el-option label="下学期" value="2" />
|
||||
<el-option v-for="dict in student_semester" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -286,6 +290,13 @@ import { AssessmentPlanVO, AssessmentPlanQuery, AssessmentPlanForm } from '@/api
|
||||
import { BmzrAssessmentSchemeVO } from '@/api/bzrkh/assessmentScheme/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { student_semester } = toRefs<any>(proxy?.useDict('student_semester'));
|
||||
|
||||
// 获取学期标签
|
||||
const getSemesterLabel = (semester: string) => {
|
||||
const semesterDict = student_semester.value?.find((item: any) => item.value === semester);
|
||||
return semesterDict ? semesterDict.label : '';
|
||||
};
|
||||
|
||||
// 自定义计划状态选项(符合数据库设计:0=禁用 1=启用)
|
||||
const planStatusOptions = ref([
|
||||
@@ -534,4 +545,15 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -5,39 +5,40 @@
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="方案名称" prop="schemeName">
|
||||
<el-input v-model="queryParams.schemeName" placeholder="请输入方案名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="方案编码" prop="schemeCode">
|
||||
<el-input v-model="queryParams.schemeCode" placeholder="请输入方案编码" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="学年" prop="academicYear">
|
||||
<el-input v-model="queryParams.academicYear" placeholder="请输入学年" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="学期" prop="semester">
|
||||
<el-select v-model="queryParams.semester" placeholder="请选择学期" clearable style="width: 100%">
|
||||
<el-option label="上学期" value="1" />
|
||||
<el-option label="下学期" value="2" />
|
||||
<el-option v-for="dict in student_semester" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="18" :md="12" :sm="24">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -81,8 +82,7 @@
|
||||
<el-table-column label="学年" align="center" prop="academicYear" width="100" />
|
||||
<el-table-column label="学期" align="center" prop="semester" width="80">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.semester === '1'" type="primary">上学期</el-tag>
|
||||
<el-tag v-else-if="scope.row.semester === '2'" type="success">下学期</el-tag>
|
||||
<dict-tag :options="student_semester" :value="scope.row.semester" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评" align="center" prop="selfEvaluationRequired" width="70">
|
||||
@@ -164,8 +164,7 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="学期" prop="semester">
|
||||
<el-select v-model="form.semester" placeholder="请选择学期" style="width: 100%">
|
||||
<el-option label="上学期" value="1" />
|
||||
<el-option label="下学期" value="2" />
|
||||
<el-option v-for="dict in student_semester" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -234,7 +233,7 @@ import { BmzrAssessmentSchemeVO, BmzrAssessmentSchemeQuery, BmzrAssessmentScheme
|
||||
import IndicatorManagement from './IndicatorManagement.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { sys_normal_disable, sys_yesno } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_yesno'));
|
||||
const { sys_normal_disable, sys_yesno, student_semester } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_yesno', 'student_semester'));
|
||||
|
||||
const schemeList = ref<BmzrAssessmentSchemeVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
@@ -517,4 +516,15 @@ onMounted(() => {
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
</style>
|
||||
@@ -10,12 +10,14 @@
|
||||
<el-card shadow="hover">
|
||||
<el-form :model="queryParams" ref="queryFormRef" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="6" :md="12" :sm="24">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="计划名称" prop="planName">
|
||||
<el-input v-model="queryParams.planName" placeholder="请输入计划名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :lg="6" :md="24" :sm="24">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -37,20 +39,20 @@
|
||||
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" border :data="assessmentPlanList" @sort-change="sortChange">
|
||||
<el-table-column label="计划名称" align="center" prop="planName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="计划编码" align="center" prop="planCode" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" prop="schemeName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="学年学期" align="center" width="120">
|
||||
<el-table-column label="计划名称" align="center" prop="planName" min-width="180" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="计划编码" align="center" prop="planCode" min-width="150" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="考核方案" align="center" prop="schemeName" min-width="180" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="学年学期" align="center" min-width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.academicYear }}{{ scope.row.semester === '1' ? '上' : '下' }}学期</span>
|
||||
<span>{{ scope.row.academicYear }}{{ getSemesterLabel(scope.row.semester) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="计划时间" align="center" width="180">
|
||||
<el-table-column label="计划时间" align="center" min-width="200">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.planStartTime, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.planEndTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="数据提取时间" align="center" width="180">
|
||||
<el-table-column label="数据提取时间" align="center" min-width="200">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.dataExtractStartTime && scope.row.dataExtractEndTime">
|
||||
{{ parseTime(scope.row.dataExtractStartTime, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.dataExtractEndTime, '{y}-{m}-{d}') }}
|
||||
@@ -58,7 +60,7 @@
|
||||
<span v-else class="text-gray-400">未设置</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" align="center" width="120">
|
||||
<el-table-column label="审核状态" align="center" min-width="120">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="!scope.row.submitted" type="info" effect="plain">未提交</el-tag>
|
||||
<el-tag v-else-if="scope.row.auditStatus === '9'" type="primary" effect="plain">草稿</el-tag>
|
||||
@@ -68,12 +70,12 @@
|
||||
<el-tag v-else type="info" effect="plain">未知状态</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180">
|
||||
<template #default="scope">
|
||||
<!-- 审核通过状态:只显示查看考核按钮 -->
|
||||
<template v-if="scope.row.auditStatus === '1'">
|
||||
@@ -101,27 +103,18 @@
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<!-- 已提交状态(待审核):显示撤销按钮 -->
|
||||
<!-- 待审核状态:显示查看考核按钮 -->
|
||||
<template v-else-if="scope.row.auditStatus === '0'">
|
||||
<el-tooltip content="撤销提交" placement="top">
|
||||
<el-tooltip content="查看考核" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
icon="RefreshLeft"
|
||||
type="success"
|
||||
icon="View"
|
||||
:disabled="loading || !isDataReady"
|
||||
@click="handleWithdrawAssessment(scope.row)"
|
||||
@click="handleViewAssessment(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-tooltip content="查看考核" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="View"
|
||||
:disabled="loading || !isDataReady"
|
||||
@click="handleViewAssessment(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -170,6 +163,14 @@ import SubmitDialog from './submitDialog.vue';
|
||||
import ViewDialog from './viewDialog.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const { student_semester } = toRefs<any>(proxy?.useDict('student_semester'));
|
||||
|
||||
// 获取学期标签
|
||||
const getSemesterLabel = (semester: string) => {
|
||||
const semesterDict = student_semester.value?.find((item: any) => item.value === semester);
|
||||
return semesterDict ? semesterDict.label : '';
|
||||
};
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const teacherClasses = ref<TeacherClassVO[]>([]);
|
||||
@@ -496,6 +497,17 @@ onMounted(() => {
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* 标签页样式优化 */
|
||||
:deep(.el-tabs__header) {
|
||||
margin-bottom: 20px;
|
||||
|
||||
@@ -89,12 +89,12 @@
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="indicatorName" label="指标名称" min-width="180" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="description" label="指标描述" min-width="200" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="score" label="指标分值" width="80" align="center">
|
||||
<el-table-column prop="score" label="指标分值" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评分数" width="130" align="center">
|
||||
<el-table-column label="自评分数" min-width="130" align="center">
|
||||
<template #default="scope">
|
||||
<el-input-number
|
||||
v-model="scope.row.selfScore"
|
||||
@@ -105,21 +105,19 @@
|
||||
style="width: 100%"
|
||||
placeholder="请输入分数"
|
||||
size="small"
|
||||
class="score-input"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="220" align="center">
|
||||
<el-table-column label="自评意见" min-width="220" align="center">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.selfComment"
|
||||
type="textarea"
|
||||
:rows="1"
|
||||
:rows="2"
|
||||
placeholder="请输入自评意见"
|
||||
maxlength="200"
|
||||
show-word-limit
|
||||
size="small"
|
||||
class="comment-input"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -344,22 +342,22 @@
|
||||
<el-tab-pane label="违纪记录" name="discipline">
|
||||
<el-table :data="studentRecordsData?.disciplineRecords || []" border style="width: 100%" max-height="400" empty-text="暂无违纪记录">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="studentNo" label="学号" width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" width="100" align="center" />
|
||||
<el-table-column prop="disciplineTypeName" label="违纪类型" width="120" align="center" />
|
||||
<el-table-column prop="disciplineDate" label="违纪日期" width="110" align="center">
|
||||
<el-table-column prop="studentNo" label="学号" min-width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" min-width="100" align="center" />
|
||||
<el-table-column prop="disciplineTypeName" label="违纪类型" min-width="120" align="center" />
|
||||
<el-table-column prop="disciplineDate" label="违纪日期" min-width="110" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.disciplineDate?.split(' ')[0] || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="disciplineReason" label="违纪原因" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="disciplineContent" label="处分内容" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="scoreDeduction" label="扣分" width="80" align="center">
|
||||
<el-table-column prop="scoreDeduction" label="扣分" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="danger" size="small">{{ scope.row.scoreDeduction || 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||
<el-table-column prop="status" label="状态" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'danger' : 'info'" size="small">
|
||||
{{ scope.row.status === '1' ? '生效' : '已撤销' }}
|
||||
@@ -373,21 +371,21 @@
|
||||
<el-tab-pane label="奖励记录" name="reward">
|
||||
<el-table :data="studentRecordsData?.rewardRecords || []" border style="width: 100%" max-height="400" empty-text="暂无奖励记录">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="studentNo" label="学号" width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" width="100" align="center" />
|
||||
<el-table-column prop="rewardTypeName" label="奖励类型" width="120" align="center" />
|
||||
<el-table-column prop="rewardDate" label="奖励日期" width="110" align="center">
|
||||
<el-table-column prop="studentNo" label="学号" min-width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" min-width="100" align="center" />
|
||||
<el-table-column prop="rewardTypeName" label="奖励类型" min-width="120" align="center" />
|
||||
<el-table-column prop="rewardDate" label="奖励日期" min-width="110" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.rewardDate || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="rewardContent" label="奖励内容" min-width="300" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="scoreAddition" label="加分" width="80" align="center">
|
||||
<el-table-column prop="scoreAddition" label="加分" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" size="small">{{ scope.row.scoreAddition || 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||
<el-table-column prop="status" label="状态" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'success' : 'info'" size="small">
|
||||
{{ scope.row.status === '1' ? '生效' : '撤销' }}
|
||||
|
||||
@@ -89,37 +89,35 @@
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="indicatorName" label="指标名称" min-width="180" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="description" label="指标描述" min-width="200" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="score" label="指标分值" width="80" align="center">
|
||||
<el-table-column prop="score" label="指标分值" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.score || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评分数" width="80" align="center">
|
||||
<el-table-column label="自评分数" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<div class="readonly-field">
|
||||
{{ formatNumber(scope.row.selfScore, 2) }}
|
||||
</div>
|
||||
<span>{{ scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
<el-table-column label="自评意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<div class="readonly-field comment-field">
|
||||
{{ scope.row.selfComment || '-' }}
|
||||
</div>
|
||||
<el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
|
||||
<span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 审批模式下显示上级评分和审批意见 -->
|
||||
<template v-if="viewMode === 'approval'">
|
||||
<el-table-column label="上级评分" width="80" align="center">
|
||||
<el-table-column label="上级评分" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.superiorScore || '-' }}</span>
|
||||
<span>{{ scope.row.superiorScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批意见" width="180" align="center">
|
||||
<el-table-column label="审批意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<div class="readonly-field comment-field">
|
||||
{{ scope.row.superiorComment || '-' }}
|
||||
</div>
|
||||
<el-tooltip :content="scope.row.superiorComment || '无'" placement="top" :disabled="!scope.row.superiorComment">
|
||||
<span class="text-ellipsis">{{ scope.row.superiorComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
@@ -230,28 +228,28 @@
|
||||
<el-table border :data="approvalSpecialWorkScores" style="width: 100%" class="special-work-table">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="indicatorName" label="特色工作项目" min-width="180" align="center" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="自评分数" width="80" align="center">
|
||||
<el-table-column label="自评分数" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.selfScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="自评意见" width="180" align="center">
|
||||
<el-table-column label="自评意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<div class="readonly-field comment-field">
|
||||
{{ scope.row.selfComment || '-' }}
|
||||
</div>
|
||||
<el-tooltip :content="scope.row.selfComment || '无'" placement="top" :disabled="!scope.row.selfComment">
|
||||
<span class="text-ellipsis">{{ scope.row.selfComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="上级评分" width="80" align="center">
|
||||
<el-table-column label="上级评分" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.superiorScore || '-' }}</span>
|
||||
<span>{{ scope.row.superiorScore || 0 }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批意见" width="180" align="center">
|
||||
<el-table-column label="审批意见" min-width="200" align="center">
|
||||
<template #default="scope">
|
||||
<div class="readonly-field comment-field">
|
||||
{{ scope.row.superiorComment || '-' }}
|
||||
</div>
|
||||
<el-tooltip :content="scope.row.superiorComment || '无'" placement="top" :disabled="!scope.row.superiorComment">
|
||||
<span class="text-ellipsis">{{ scope.row.superiorComment || '无' }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -369,22 +367,22 @@
|
||||
<el-tab-pane label="违纪记录" name="discipline">
|
||||
<el-table :data="studentRecordsData?.disciplineRecords || []" border style="width: 100%" max-height="400" empty-text="暂无违纪记录">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="studentNo" label="学号" width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" width="100" align="center" />
|
||||
<el-table-column prop="disciplineTypeName" label="违纪类型" width="120" align="center" />
|
||||
<el-table-column prop="disciplineDate" label="违纪日期" width="110" align="center">
|
||||
<el-table-column prop="studentNo" label="学号" min-width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" min-width="100" align="center" />
|
||||
<el-table-column prop="disciplineTypeName" label="违纪类型" min-width="120" align="center" />
|
||||
<el-table-column prop="disciplineDate" label="违纪日期" min-width="110" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.disciplineDate?.split(' ')[0] || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="disciplineReason" label="违纪原因" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="disciplineContent" label="处分内容" min-width="200" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="scoreDeduction" label="扣分" width="80" align="center">
|
||||
<el-table-column prop="scoreDeduction" label="扣分" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="danger" size="small">{{ scope.row.scoreDeduction || 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||
<el-table-column prop="status" label="状态" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'danger' : 'info'" size="small">
|
||||
{{ scope.row.status === '1' ? '生效' : '已撤销' }}
|
||||
@@ -398,21 +396,21 @@
|
||||
<el-tab-pane label="奖励记录" name="reward">
|
||||
<el-table :data="studentRecordsData?.rewardRecords || []" border style="width: 100%" max-height="400" empty-text="暂无奖励记录">
|
||||
<el-table-column type="index" label="序号" width="60" align="center" />
|
||||
<el-table-column prop="studentNo" label="学号" width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" width="100" align="center" />
|
||||
<el-table-column prop="rewardTypeName" label="奖励类型" width="120" align="center" />
|
||||
<el-table-column prop="rewardDate" label="奖励日期" width="110" align="center">
|
||||
<el-table-column prop="studentNo" label="学号" min-width="120" align="center" />
|
||||
<el-table-column prop="studentName" label="学生姓名" min-width="100" align="center" />
|
||||
<el-table-column prop="rewardTypeName" label="奖励类型" min-width="120" align="center" />
|
||||
<el-table-column prop="rewardDate" label="奖励日期" min-width="110" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.rewardDate || '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="rewardContent" label="奖励内容" min-width="300" :show-overflow-tooltip="true" />
|
||||
<el-table-column prop="scoreAddition" label="加分" width="80" align="center">
|
||||
<el-table-column prop="scoreAddition" label="加分" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag type="success" size="small">{{ scope.row.scoreAddition || 0 }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="80" align="center">
|
||||
<el-table-column prop="status" label="状态" min-width="80" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'success' : 'info'" size="small">
|
||||
{{ scope.row.status === '1' ? '生效' : '撤销' }}
|
||||
|
||||
@@ -100,7 +100,9 @@
|
||||
<el-date-picker v-model="queryParams.year" type="year" placeholder="选择年份" value-format="YYYY" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -110,30 +112,31 @@
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<el-card class="button-card">
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="toolbar-title">项目申报管理</span>
|
||||
<div class="toolbar-actions">
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['cw:application:add']">新增申报</el-button>
|
||||
<el-button type="success" icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['cw:application:edit']">修改</el-button>
|
||||
<el-button type="danger" icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['cw:application:remove']">删除</el-button>
|
||||
<el-button type="info" icon="Upload" @click="handleSubmit" :disabled="multiple" v-hasPermi="['cw:application:submit']"
|
||||
>提交审批</el-button
|
||||
>
|
||||
<el-button type="warning" icon="Download" @click="handleExport" v-hasPermi="['cw:application:export']">导出</el-button>
|
||||
<right-toolbar :showSearch="showSearch" @update:showSearch="showSearch = $event" @queryTable="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['cw:application:add']">新增申报</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['cw:application:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['cw:application:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Upload" @click="handleSubmit" :disabled="multiple" v-hasPermi="['cw:application:submit']">提交审批</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['cw:application:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch="showSearch" @update:showSearch="showSearch = $event" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-card>
|
||||
|
||||
<!-- 数据表格区域 -->
|
||||
<el-card class="table-card">
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" :data="applicationList" @selection-change="handleSelectionChange" class="scroll-table">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table v-loading="loading" border :data="applicationList" @selection-change="handleSelectionChange" style="width: 100%" :scroll-x="true" class="scroll-table">
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="申报编号" align="center" prop="applicationNo" min-width="140" />
|
||||
<el-table-column label="项目名称" align="center" prop="projectName" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="项目负责人" align="center" prop="principal" min-width="100" />
|
||||
@@ -156,41 +159,38 @@
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="280" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" align="center" width="280" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<div class="action-buttons">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button type="primary" icon="View" circle size="small" @click="handleView(scope.row)" v-hasPermi="['cw:application:query']" />
|
||||
<el-button link type="info" icon="View" @click="handleView(scope.row)" v-hasPermi="['cw:application:query']" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="编辑" placement="top" v-if="['draft', 'returned'].includes(scope.row.approvalStatus)">
|
||||
<el-button type="success" icon="Edit" circle size="small" @click="handleUpdate(scope.row)" v-hasPermi="['cw:application:edit']" />
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['cw:application:edit']" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="提交审批" placement="top" v-if="['draft', 'returned'].includes(scope.row.approvalStatus)">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
icon="Upload"
|
||||
circle
|
||||
size="small"
|
||||
@click="handleSubmit(scope.row)"
|
||||
v-hasPermi="['cw:application:submit']"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="撤回" placement="top" v-if="scope.row.approvalStatus === 'submitted'">
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
icon="RefreshLeft"
|
||||
circle
|
||||
size="small"
|
||||
@click="handleWithdraw(scope.row)"
|
||||
v-hasPermi="['cw:application:withdraw']"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top" v-if="['draft', 'cancelled', 'returned'].includes(scope.row.approvalStatus)">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
circle
|
||||
size="small"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['cw:application:remove']"
|
||||
/>
|
||||
@@ -237,7 +237,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import {
|
||||
listProjectApplication,
|
||||
getProjectApplication,
|
||||
@@ -553,252 +553,238 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 继承后勤管理模块的样式风格 */
|
||||
/* 按照满意度调查页面样式重写 */
|
||||
.page-container {
|
||||
background-color: #f5f5f5;
|
||||
min-height: calc(100vh - 84px);
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.stats-row {
|
||||
margin-bottom: 20px;
|
||||
/* 统计卡片样式 */
|
||||
.stats-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
height: 90px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
height: 90px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 16px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
margin-right: 15px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.8;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格卡片布局 - 参考后勤管理功能 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
.stat-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 5px 16px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
margin-right: 15px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 20px;
|
||||
background: linear-gradient(135deg, rgb(93, 135, 255), rgb(73, 190, 255));
|
||||
border-radius: 2px;
|
||||
margin-right: 12px;
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格主体 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 表格样式 - 参考后勤管理功能 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-table__header-wrapper) {
|
||||
.el-table__header {
|
||||
th {
|
||||
background-color: #f8f9fa;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper) {
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.8;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 - 参考后勤管理功能 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #409eff #f0f0f0;
|
||||
&.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
&.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important;
|
||||
width: 12px !important;
|
||||
&.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important;
|
||||
&.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important;
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important;
|
||||
min-height: 20px !important;
|
||||
/* 搜索按钮居中样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important;
|
||||
}
|
||||
/* 卡片样式 */
|
||||
:deep(.el-card) {
|
||||
border: 1px solid #e4e7ed;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important;
|
||||
}
|
||||
/* 表格卡片头部样式 */
|
||||
.table-card :deep(.el-card__header) {
|
||||
background-color: #fafafa;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
padding: 18px 20px;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
/* 表格卡片内容样式 */
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
/* 表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
|
||||
.el-button {
|
||||
width: 27px !important;
|
||||
height: 27px !important;
|
||||
padding: 0 !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
:deep(.el-table__header-wrapper) {
|
||||
.el-table__header {
|
||||
th {
|
||||
background-color: #fafafa;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 金额文本样式 */
|
||||
.amount-text {
|
||||
font-weight: 600;
|
||||
color: #e74c3c;
|
||||
:deep(.el-table__body-wrapper) {
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 分页容器样式 - 参考后勤管理功能 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #409eff #f0f0f0;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important;
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important;
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important;
|
||||
min-height: 20px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 金额文本样式 */
|
||||
.amount-text {
|
||||
font-weight: 600;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 输入框样式 */
|
||||
:deep(.el-input .el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-select .el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-date-editor .el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@@ -811,11 +797,6 @@ export default {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
flex-direction: column;
|
||||
gap: 8px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,68 +1,106 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
|
||||
<el-form-item label="申报编号" prop="applicationNo">
|
||||
<el-input v-model="queryParams.applicationNo" placeholder="请输入申报编号" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="申报人" prop="applicantName">
|
||||
<el-input v-model="queryParams.applicantName" placeholder="请输入申报人" clearable style="width: 200px" @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="p-2 page-container">
|
||||
<transition :enter-active-class="animate.searchAnimate.enter" :leave-active-class="animate.searchAnimate.leave">
|
||||
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="申报编号" prop="applicationNo">
|
||||
<el-input v-model="queryParams.applicationNo" placeholder="请输入申报编号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="项目名称" prop="projectName">
|
||||
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="申报人" prop="applicantName">
|
||||
<el-input v-model="queryParams.applicantName" placeholder="请输入申报人" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="审批状态" prop="nodeStatus">
|
||||
<el-select v-model="queryParams.nodeStatus" placeholder="请选择审批状态" clearable>
|
||||
<el-option v-for="dict in cw_approval_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 快速操作按钮 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Check" @click="showPendingApprovals">待我审批</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="CircleCheck" @click="showMyApprovals">我已审批</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Check" @click="showPendingApprovals">待我审批</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="CircleCheck" @click="showMyApprovals">我已审批</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :showSearch="showSearch" @update:showSearch="showSearch = $event" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table v-loading="loading" :data="approvalRecordList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="申报编号" align="center" prop="applicationNo" />
|
||||
<el-table-column label="项目名称" align="center" prop="projectName" />
|
||||
<el-table-column label="申报人" align="center" prop="applicantName" />
|
||||
<el-table-column label="部门" align="center" prop="deptName" />
|
||||
<el-table-column label="审批节点" align="center" prop="nodeName" />
|
||||
<el-table-column label="审批状态" align="center" prop="nodeStatus">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="cw_approval_status" :value="scope.row.nodeStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批人" align="center" prop="approverName" />
|
||||
<el-table-column label="审批意见" align="center" prop="approveOpinion" />
|
||||
<el-table-column label="审批时间" align="center" prop="endTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="160">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="info" icon="View" @click="handleDetail(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="审批" placement="top" v-if="scope.row.nodeStatus === 'waiting'">
|
||||
<el-button link type="success" icon="Check" @click="handleApprove(scope.row)"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="approvalRecordList"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
class="scroll-table"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="申报编号" align="center" prop="applicationNo" width="140" show-overflow-tooltip />
|
||||
<el-table-column label="项目名称" align="center" prop="projectName" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="申报人" align="center" prop="applicantName" width="120" />
|
||||
<el-table-column label="部门" align="center" prop="deptName" width="150" />
|
||||
<el-table-column label="审批节点" align="center" prop="nodeName" width="120" />
|
||||
<el-table-column label="审批状态" align="center" prop="nodeStatus" width="120">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="cw_approval_status" :value="scope.row.nodeStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批人" align="center" prop="approverName" width="120" />
|
||||
<el-table-column label="审批意见" align="center" prop="approveOpinion" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="审批时间" align="center" prop="endTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.endTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="280" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="info" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['cw:approval:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="审批" placement="top" v-if="scope.row.nodeStatus === 'waiting'">
|
||||
<el-button link type="success" icon="Check" @click="handleApprove(scope.row)" v-hasPermi="['cw:approval:process']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @update:page="queryParams.pageNum = $event" @update:limit="queryParams.pageSize = $event" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 审批对话框 -->
|
||||
<el-dialog title="审批处理" v-model="approvalOpen" width="500px" append-to-body>
|
||||
@@ -97,7 +135,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { listApprovalRecord, exportApprovalRecord, approveApplication, getMyApprovals, getDepartmentApprovals } from '@/api/cw/approvalRecord';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import ApplicationSummary from '../application/summary.vue';
|
||||
@@ -129,6 +167,13 @@ export default {
|
||||
// 查看详情弹出层
|
||||
viewOpen: false,
|
||||
currentId: null,
|
||||
// 动画配置
|
||||
animate: {
|
||||
searchAnimate: {
|
||||
enter: 'animate__animated animate__fadeIn',
|
||||
leave: 'animate__animated animate__fadeOut'
|
||||
}
|
||||
},
|
||||
// 字典数据
|
||||
cw_approval_status: [],
|
||||
// 查询参数
|
||||
@@ -138,6 +183,7 @@ export default {
|
||||
applicationNo: '',
|
||||
projectName: '',
|
||||
applicantName: '',
|
||||
nodeStatus: '',
|
||||
deptId: 'current'
|
||||
},
|
||||
// 审批表单
|
||||
@@ -200,7 +246,7 @@ export default {
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm('queryRef');
|
||||
this.resetForm('queryFormRef');
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
@@ -308,4 +354,202 @@ export default {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器 - 右对齐 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
/* 表格头部样式 */
|
||||
.scroll-table :deep(.el-table__header) {
|
||||
th {
|
||||
background: #fafafa !important;
|
||||
color: #303133;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格边框样式 */
|
||||
.scroll-table :deep(.el-table) {
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 表格行样式 */
|
||||
.scroll-table :deep(.el-table__row) {
|
||||
border-bottom: 1px solid #f0f2f5;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__row:hover) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 操作列按钮样式 */
|
||||
.scroll-table :deep(.el-button--link) {
|
||||
padding: 4px 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Dialog footer样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 动画效果 */
|
||||
.animate__animated {
|
||||
animation-duration: 0.3s;
|
||||
}
|
||||
|
||||
.animate__fadeIn {
|
||||
animation-name: fadeIn;
|
||||
}
|
||||
|
||||
.animate__fadeOut {
|
||||
animation-name: fadeOut;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeOut {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translateY(-10px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -21,7 +21,9 @@
|
||||
<el-input v-model="queryParams.applicantName" placeholder="请输入申报人姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -81,7 +83,7 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['cw:approval:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
|
||||
<right-toolbar v-model="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@@ -125,7 +127,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" />
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 项目详情对话框 -->
|
||||
@@ -227,7 +229,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import {
|
||||
listApprovalRecord,
|
||||
exportApprovalRecord,
|
||||
@@ -707,4 +709,29 @@ export default {
|
||||
.animate__animated {
|
||||
animation-duration: 0.3s;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
</style>
|
||||
@@ -21,7 +21,9 @@
|
||||
<el-input v-model="queryParams.applicantName" placeholder="请输入申报人姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -81,7 +83,7 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['cw:approval:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
|
||||
<right-toolbar v-model="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@@ -125,7 +127,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" />
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 项目详情对话框 -->
|
||||
@@ -202,7 +204,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import {
|
||||
getPendingApprovals,
|
||||
getApprovalHistory,
|
||||
@@ -615,4 +617,29 @@ export default {
|
||||
.animate__animated {
|
||||
animation-duration: 0.3s;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<div class="page-container">
|
||||
<!-- 统计卡片区域 -->
|
||||
<div class="mb-10px">
|
||||
<el-row :gutter="16">
|
||||
@@ -146,9 +146,9 @@
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮行 -->
|
||||
<el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
@@ -159,37 +159,40 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<el-card class="button-card mb-10px" shadow="never">
|
||||
<div class="card-header-vertical">
|
||||
<span class="toolbar-title">我的助学金申请</span>
|
||||
<div class="button-group">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['jcbt:povertyApplication:add']"> 新增申请 </el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['jcbt:povertyApplication:edit']">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['jcbt:povertyApplication:remove']">
|
||||
删除
|
||||
</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['jcbt:povertyApplication:export']"> 导出 </el-button>
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['jcbt:povertyApplication:add']">新增申请</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['jcbt:povertyApplication:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['jcbt:povertyApplication:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['jcbt:povertyApplication:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :show-search="showSearch" @show-search="showSearch = $event" @query-table="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<el-card class="table-card" shadow="never">
|
||||
</el-row>
|
||||
</template>
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="applicationList"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
class="scroll-table"
|
||||
max-height="650"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="申请编号" align="center" prop="applicationNo" min-width="140" />
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="申请编号" align="center" prop="applicationNo" min-width="140" fixed="left" />
|
||||
<el-table-column label="学号" align="center" prop="studentNo" min-width="120" />
|
||||
<el-table-column label="学生姓名" align="center" prop="studentName" min-width="100" />
|
||||
<el-table-column label="班级" align="center" prop="className" min-width="120" />
|
||||
@@ -217,7 +220,7 @@
|
||||
<span>{{ parseTime(scope.row.submitTime || scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)"></el-button>
|
||||
@@ -274,13 +277,13 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改贫困生认定申请对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="800px" append-to-body>
|
||||
<el-form ref="applicationFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
@@ -1299,10 +1302,10 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 继承后勤管理的样式 */
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 20px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.mb-10px {
|
||||
@@ -1311,125 +1314,180 @@ onMounted(() => {
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.stat-card {
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
height: 90px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 12px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.stat-icon {
|
||||
font-size: 24px;
|
||||
margin-right: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
|
||||
.stat-value {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
opacity: 0.7;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索卡片样式 */
|
||||
.search-card {
|
||||
.search-form {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
/* 按钮卡片样式 */
|
||||
.button-card {
|
||||
.card-header-vertical {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ff6b6b 100%);
|
||||
}
|
||||
|
||||
/* 表格卡片样式 */
|
||||
.stat-card-success {
|
||||
background: linear-gradient(135deg, #4ecdc4 0%, #44a08d 100%);
|
||||
}
|
||||
|
||||
.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
margin-right: 16px;
|
||||
font-size: 24px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-table__header-wrapper) {
|
||||
.el-table__header {
|
||||
th {
|
||||
background-color: #f8f9fa;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper) {
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 - 参考后勤管理模块 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
@@ -1439,15 +1497,6 @@ onMounted(() => {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0;
|
||||
background-color: #fff;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer-right {
|
||||
display: flex;
|
||||
@@ -1463,15 +1512,24 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
/* 描述列表样式 */
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
background-color: #fafafa;
|
||||
:deep(.el-descriptions .el-descriptions__label) {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.el-descriptions .el-descriptions__content) {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.page-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
.stat-card {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<div class="page-container">
|
||||
<!-- 统计卡片区域 -->
|
||||
<div class="mb-10px">
|
||||
<el-row :gutter="16">
|
||||
@@ -147,46 +147,52 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<el-card class="button-card mb-10px" shadow="never">
|
||||
<div class="card-header-vertical">
|
||||
<span class="toolbar-title">助学金申请审核管理</span>
|
||||
<div class="button-group">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Check"
|
||||
:disabled="multiple"
|
||||
@click="handleBatchApprove"
|
||||
v-hasPermi="['jcbt:povertyApplication:approve']"
|
||||
>
|
||||
批量通过
|
||||
</el-button>
|
||||
<el-button type="danger" plain icon="Close" :disabled="multiple" @click="handleBatchReject" v-hasPermi="['jcbt:povertyApplication:reject']">
|
||||
批量驳回
|
||||
</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['jcbt:povertyApplication:export']"> 导出 </el-button>
|
||||
<el-button type="info" plain icon="Download" @click="handleExportPending" v-hasPermi="['jcbt:povertyApplication:export']">
|
||||
导出待审核
|
||||
</el-button>
|
||||
<right-toolbar :show-search="showSearch" @show-search="showSearch = $event" @query-table="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<el-card class="table-card" shadow="never">
|
||||
<template #header>
|
||||
<el-row class="mb-[10px]">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Check"
|
||||
:disabled="multiple"
|
||||
@click="handleBatchApprove"
|
||||
v-hasPermi="['jcbt:povertyApplication:approve']"
|
||||
>
|
||||
批量通过
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Close" :disabled="multiple" @click="handleBatchReject" v-hasPermi="['jcbt:povertyApplication:reject']">
|
||||
批量驳回
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['jcbt:povertyApplication:export']">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Download" @click="handleExportPending" v-hasPermi="['jcbt:povertyApplication:export']">
|
||||
导出待审核
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar :show-search="showSearch" @show-search="showSearch = $event" @query-table="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="reviewList"
|
||||
@selection-change="handleSelectionChange"
|
||||
@sort-change="handleSortChange"
|
||||
class="scroll-table"
|
||||
max-height="650"
|
||||
:scroll-x="true"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="申请编号" align="center" prop="applicationNo" min-width="140" />
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="申请编号" align="center" prop="applicationNo" min-width="140" fixed="left" />
|
||||
<el-table-column label="学号" align="center" prop="studentNo" min-width="120" />
|
||||
<el-table-column label="学生姓名" align="center" prop="studentName" min-width="100" />
|
||||
<el-table-column label="班级" align="center" prop="className" min-width="120" />
|
||||
@@ -224,7 +230,7 @@
|
||||
<span>{{ scope.row.auditTime ? parseTime(scope.row.auditTime, '{y}-{m}-{d} {h}:{i}') : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)"></el-button>
|
||||
@@ -865,10 +871,10 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 继承后勤管理的样式 */
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 20px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.mb-10px {
|
||||
@@ -880,121 +886,170 @@ onMounted(() => {
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s ease;
|
||||
height: 90px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 12px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.stat-icon {
|
||||
font-size: 24px;
|
||||
margin-right: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
|
||||
.stat-value {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 13px;
|
||||
opacity: 0.7;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-danger {
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮卡片样式 */
|
||||
.button-card {
|
||||
.card-header-vertical {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 表格卡片样式 */
|
||||
.stat-card .stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 12px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.stat-card .stat-content .stat-icon {
|
||||
font-size: 24px;
|
||||
margin-right: 12px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.stat-card .stat-content .stat-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-card .stat-content .stat-info .stat-value {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.stat-card .stat-content .stat-info .stat-label {
|
||||
font-size: 13px;
|
||||
opacity: 0.7;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.stat-card.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.stat-card.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.stat-card.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.stat-card.stat-card-danger {
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
:deep(.el-table__header-wrapper) {
|
||||
.el-table__header {
|
||||
th {
|
||||
background-color: #f8f9fa;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper) {
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
@@ -1012,35 +1067,31 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
/* 附件预览样式 */
|
||||
.attachment-preview {
|
||||
.attachment-item {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
|
||||
h4 {
|
||||
margin-bottom: 15px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.no-attachment {
|
||||
padding: 20px;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
.attachment-preview .attachment-item {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 描述列表样式 */
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
.attachment-preview .attachment-item h4 {
|
||||
margin-bottom: 15px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
.attachment-preview .attachment-item .no-attachment {
|
||||
padding: 20px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions .el-descriptions__label) {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
:deep(.el-descriptions .el-descriptions__content) {
|
||||
color: #303133;
|
||||
}
|
||||
</style>
|
||||
@@ -1,40 +1,102 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-row :gutter="20">
|
||||
<!-- 查询面板 -->
|
||||
<el-col :span="24" class="search-container">
|
||||
<el-form :model="queryParams" ref="queryFormRef" :inline="true" v-show="showSearch" label-width="80px">
|
||||
<el-form-item label="学生姓名" prop="studentName">
|
||||
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="学号" prop="studentNo">
|
||||
<el-input v-model="queryParams.studentNo" placeholder="请输入学号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="申请状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择申请状态" clearable>
|
||||
<el-option label="草稿" value="draft" />
|
||||
<el-option label="待审核" value="waiting" />
|
||||
<el-option label="已完成" value="complete" />
|
||||
<el-option label="已拒绝" value="rejected" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<div class="page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<!-- 第一行:4个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学生姓名" prop="studentName">
|
||||
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学号" prop="studentNo">
|
||||
<el-input v-model="queryParams.studentNo" placeholder="请输入学号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="申请状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择申请状态" clearable style="width: 100%">
|
||||
<el-option label="草稿" value="draft" />
|
||||
<el-option label="待审核" value="waiting" />
|
||||
<el-option label="已完成" value="complete" />
|
||||
<el-option label="已拒绝" value="rejected" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="申请类型" prop="applicationType">
|
||||
<el-select v-model="queryParams.applicationType" placeholder="请选择申请类型" clearable style="width: 100%">
|
||||
<el-option label="教师推荐" value="RECOMMEND" />
|
||||
<el-option label="学生申请" value="STUDENT" />
|
||||
<el-option label="自动评定" value="AUTO" />
|
||||
<el-option label="直接指定" value="DIRECT" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 工具栏 -->
|
||||
<el-col :span="24">
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<!-- 第二行:2个搜索条件 + 操作按钮 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="奖学金类型" prop="scholarshipTypeId">
|
||||
<el-select v-model="queryParams.scholarshipTypeId" placeholder="请选择奖学金类型" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="type in scholarshipTypeList"
|
||||
:key="type.id"
|
||||
:label="type.typeName"
|
||||
:value="type.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="申请时间">
|
||||
<el-date-picker
|
||||
v-model="daterangeCreateTime"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
@change="handleQuery"
|
||||
style="width: 100%"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8" >
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['jcbt:scholarshipApplication:add']">班主任批量申请</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['jcbt:scholarshipApplication:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasPermi="['jcbt:scholarshipApplication:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
@@ -44,17 +106,25 @@
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasPermi="['jcbt:scholarshipApplication:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</el-col>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-col :span="24">
|
||||
<el-table v-loading="loading" :data="applicationList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
</template>
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="scholarshipApplicationTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="applicationList"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="学号" align="center" prop="studentNo" min-width="120" />
|
||||
<el-table-column label="学生姓名" align="center" prop="studentName" min-width="100" />
|
||||
<el-table-column label="学院" align="center" prop="deptName" min-width="120" />
|
||||
@@ -86,7 +156,7 @@
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
@@ -109,10 +179,13 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 班主任批量申请奖学金对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="1000px" append-to-body>
|
||||
@@ -1079,6 +1152,124 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<div class="page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
@@ -38,7 +38,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:3个搜索条件 + 操作按钮 -->
|
||||
<!-- 第二行:3个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="批次类型" prop="batchType">
|
||||
@@ -73,8 +73,10 @@
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
@@ -146,131 +148,158 @@
|
||||
<!-- 表格区域 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['jcbt:scholarshipBatch:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['jcbt:scholarshipBatch:edit']">修改</el-button>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['jcbt:scholarshipBatch:remove']">删除</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExport" v-hasPermi="['jcbt:scholarshipBatch:export']">导出</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="batchList" @selection-change="handleSelectionChange" @row-dblclick="handleView">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="批次编码" align="center" prop="batchCode" min-width="120" />
|
||||
<el-table-column label="批次名称" align="center" prop="batchName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="学年" align="center" prop="academicYear" width="120" />
|
||||
<el-table-column label="学期" align="center" prop="semester" width="80">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.semester === 1">第一学期</span>
|
||||
<span v-else-if="scope.row.semester === 2">第二学期</span>
|
||||
<span v-else-if="scope.row.semester === 3">全年</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="批次类型" align="center" prop="batchType" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.batchType === 'REGULAR'" type="primary">常规批次</el-tag>
|
||||
<el-tag v-else-if="scope.row.batchType === 'SPECIAL'" type="warning">专项批次</el-tag>
|
||||
<el-tag v-else-if="scope.row.batchType === 'SUPPLEMENTARY'" type="info">补充批次</el-tag>
|
||||
<el-tag v-else type="info">未知</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === 'DRAFT'" type="info">草稿</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'ACTIVE'" type="success">进行中</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'COMPLETED'" type="primary">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'CANCELLED'" type="danger">已取消</el-tag>
|
||||
<el-tag v-else type="info">未知</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="申请时间" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.applyStartTime && scope.row.applyEndTime">
|
||||
<div>{{ parseTime(scope.row.applyStartTime, '{y}-{m}-{d}') }}</div>
|
||||
<div style="color: #909399; font-size: 12px">至 {{ parseTime(scope.row.applyEndTime, '{y}-{m}-{d}') }}</div>
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核时间" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.reviewStartTime && scope.row.reviewEndTime">
|
||||
<div>{{ parseTime(scope.row.reviewStartTime, '{y}-{m}-{d}') }}</div>
|
||||
<div style="color: #909399; font-size: 12px">至 {{ parseTime(scope.row.reviewEndTime, '{y}-{m}-{d}') }}</div>
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="View"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px; color: blue"
|
||||
@click="handleView(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="状态变更" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
icon="Switch"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleStatusChange(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
size="default"
|
||||
style="font-size: 16px"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="batchTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="batchList"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-dblclick="handleView"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="批次编码" align="center" prop="batchCode" min-width="120" />
|
||||
<el-table-column label="批次名称" align="center" prop="batchName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="学年" align="center" prop="academicYear" width="120" />
|
||||
<el-table-column label="学期" align="center" prop="semester" width="80">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.semester === 1">第一学期</span>
|
||||
<span v-else-if="scope.row.semester === 2">第二学期</span>
|
||||
<span v-else-if="scope.row.semester === 3">全年</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="批次类型" align="center" prop="batchType" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.batchType === 'REGULAR'" type="primary">常规批次</el-tag>
|
||||
<el-tag v-else-if="scope.row.batchType === 'SPECIAL'" type="warning">专项批次</el-tag>
|
||||
<el-tag v-else-if="scope.row.batchType === 'SUPPLEMENTARY'" type="info">补充批次</el-tag>
|
||||
<el-tag v-else type="info">未知</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="状态" align="center" prop="status" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === 'DRAFT'" type="info">草稿</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'ACTIVE'" type="success">进行中</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'COMPLETED'" type="primary">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'CANCELLED'" type="danger">已取消</el-tag>
|
||||
<el-tag v-else type="info">未知</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="申请时间" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.applyStartTime && scope.row.applyEndTime">
|
||||
<div>{{ parseTime(scope.row.applyStartTime, '{y}-{m}-{d}') }}</div>
|
||||
<div style="color: #909399; font-size: 12px">至 {{ parseTime(scope.row.applyEndTime, '{y}-{m}-{d}') }}</div>
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核时间" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<div v-if="scope.row.reviewStartTime && scope.row.reviewEndTime">
|
||||
<div>{{ parseTime(scope.row.reviewStartTime, '{y}-{m}-{d}') }}</div>
|
||||
<div style="color: #909399; font-size: 12px">至 {{ parseTime(scope.row.reviewEndTime, '{y}-{m}-{d}') }}</div>
|
||||
</div>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
icon="View"
|
||||
@click="handleView(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="状态变更" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
icon="Switch"
|
||||
@click="handleStatusChange(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipBatch:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改批次对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="1200px" append-to-body>
|
||||
<el-form ref="batchFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
@@ -518,6 +547,10 @@
|
||||
</template>
|
||||
|
||||
<script setup name="ScholarshipBatch" lang="ts">
|
||||
import { reactive, ref, onMounted, getCurrentInstance, toRefs } from 'vue';
|
||||
import type { ComponentInternalInstance } from 'vue';
|
||||
import type { FormInstance, TableInstance } from 'element-plus';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import {
|
||||
listScholarshipBatch,
|
||||
getScholarshipBatch,
|
||||
@@ -533,8 +566,19 @@ import {
|
||||
} from '@/api/jcbt/scholarshipBatch';
|
||||
import { listScholarshipType, type ScholarshipTypeVO } from '@/api/jcbt/scholarshipType';
|
||||
|
||||
const { proxy } = getCurrentInstance()!;
|
||||
const { sys_normal_disable } = toRefs<any>(proxy?.useDict('sys_normal_disable'));
|
||||
// 类型定义
|
||||
interface DialogOption {
|
||||
visible: boolean;
|
||||
title: string;
|
||||
}
|
||||
|
||||
interface PageData<T, U> {
|
||||
form: T;
|
||||
queryParams: U;
|
||||
rules: any;
|
||||
}
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const batchList = ref<ScholarshipBatchVO[]>([]);
|
||||
const loading = ref(true);
|
||||
@@ -545,8 +589,10 @@ const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const buttonLoading = ref(false);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const batchFormRef = ref<ElFormInstance>();
|
||||
const queryFormRef = ref<FormInstance>();
|
||||
const batchFormRef = ref<FormInstance>();
|
||||
const toolbarRef = ref<HTMLElement>();
|
||||
const batchTableRef = ref<TableInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
@@ -612,7 +658,7 @@ const data = reactive<PageData<ScholarshipBatchForm, ScholarshipBatchQuery>>({
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
// 时间范围
|
||||
const daterangeCreateTime = ref<[DateModelType, DateModelType]>(['', '']);
|
||||
const daterangeCreateTime = ref<[string, string]>(['', '']);
|
||||
|
||||
// 状态变更表单
|
||||
const statusForm = ref({
|
||||
@@ -867,12 +913,165 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dialog-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.form-help-text {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
@@ -958,11 +1157,6 @@ onMounted(() => {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.description-cell {
|
||||
max-width: 200px;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -1,252 +1,206 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<!-- 统计卡片区域 -->
|
||||
<el-row :gutter="20" class="stats-row">
|
||||
<el-col :span="6">
|
||||
<div class="stat-card stat-card-primary">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ totalQuota }}</div>
|
||||
<div class="stat-label">总名额</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="stat-card stat-card-success">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Check /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ usedQuota }}</div>
|
||||
<div class="stat-label">已使用</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="stat-card stat-card-warning">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Opportunity /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ availableQuota }}</div>
|
||||
<div class="stat-label">可用名额</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<div class="stat-card stat-card-info">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><DataBoard /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ usageRate }}%</div>
|
||||
<div class="stat-label">使用率</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 搜索区域 -->
|
||||
<el-card class="button-card" v-show="showSearch">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="toolbar-title">名额分配查询</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="queryParams" ref="queryRef" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="奖学金批次" prop="batchId">
|
||||
<el-select v-model="queryParams.batchId" placeholder="请选择奖学金批次" clearable style="width: 100%" @change="handleBatchChange">
|
||||
<el-option v-for="batch in batchList" :key="batch.id" :label="batch.batchName" :value="batch.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="奖学金类型" prop="scholarshipTypeId">
|
||||
<el-select v-model="queryParams.scholarshipTypeId" placeholder="请选择奖学金类型" clearable style="width: 100%">
|
||||
<el-option v-for="type in scholarshipTypeList" :key="type.id" :label="type.name" :value="type.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="分配级别" prop="allocationLevel">
|
||||
<el-select v-model="queryParams.allocationLevel" placeholder="请选择分配级别" clearable style="width: 100%">
|
||||
<el-option label="全校" value="UNIVERSITY" />
|
||||
<el-option label="学院" value="COLLEGE" />
|
||||
<el-option label="专业" value="MAJOR" />
|
||||
<el-option label="班级" value="CLASS" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||
<el-option label="激活" value="ACTIVE" />
|
||||
<el-option label="停用" value="INACTIVE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="目标部门" prop="targetDeptId">
|
||||
<el-tree-select
|
||||
v-model="queryParams.targetDeptId"
|
||||
:data="deptOptions"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
value-key="id"
|
||||
placeholder="请选择目标部门"
|
||||
check-strictly
|
||||
clearable
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="锁定状态" prop="isLocked">
|
||||
<el-select v-model="queryParams.isLocked" placeholder="请选择锁定状态" clearable style="width: 100%">
|
||||
<el-option label="未锁定" :value="0" />
|
||||
<el-option label="已锁定" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryRef" :model="queryParams" label-width="100px">
|
||||
<!-- 第一行:4个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="奖学金批次" prop="batchId">
|
||||
<el-select v-model="queryParams.batchId" placeholder="请选择奖学金批次" clearable style="width: 100%" @change="handleBatchChange">
|
||||
<el-option v-for="batch in batchList" :key="batch.id" :label="batch.batchName" :value="batch.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="奖学金类型" prop="scholarshipTypeId">
|
||||
<el-select v-model="queryParams.scholarshipTypeId" placeholder="请选择奖学金类型" clearable style="width: 100%">
|
||||
<el-option v-for="type in scholarshipTypeList" :key="type.id" :label="type.name" :value="type.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="分配级别" prop="allocationLevel">
|
||||
<el-select v-model="queryParams.allocationLevel" placeholder="请选择分配级别" clearable style="width: 100%">
|
||||
<el-option label="全校" value="UNIVERSITY" />
|
||||
<el-option label="学院" value="COLLEGE" />
|
||||
<el-option label="专业" value="MAJOR" />
|
||||
<el-option label="班级" value="CLASS" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||
<el-option label="激活" value="ACTIVE" />
|
||||
<el-option label="停用" value="INACTIVE" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<el-card class="button-card">
|
||||
<!-- 第二行:2个搜索条件 + 操作按钮 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="目标部门" prop="targetDeptId">
|
||||
<el-tree-select
|
||||
v-model="queryParams.targetDeptId"
|
||||
:data="deptOptions"
|
||||
:props="{ value: 'id', label: 'label', children: 'children' }"
|
||||
value-key="id"
|
||||
placeholder="请选择目标部门"
|
||||
check-strictly
|
||||
clearable
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="锁定状态" prop="isLocked">
|
||||
<el-select v-model="queryParams.isLocked" placeholder="请选择锁定状态" clearable style="width: 100%">
|
||||
<el-option label="未锁定" :value="0" />
|
||||
<el-option label="已锁定" :value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="toolbar-title">名额分配管理</span>
|
||||
<div class="toolbar-actions">
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['jcbt:scholarshipQuota:add']">新增</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['jcbt:scholarshipQuota:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['jcbt:scholarshipQuota:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['jcbt:scholarshipQuota:export']">导出</el-button>
|
||||
<el-button type="info" plain icon="Operation" @click="handleBatchAllocate" v-hasPermi="['jcbt:scholarshipQuota:add']">批量分配</el-button>
|
||||
<el-button type="primary" plain icon="Refresh" @click="handleAutoAllocate" v-hasPermi="['jcbt:scholarshipQuota:edit']" v-if="false"
|
||||
>自动分配</el-button
|
||||
>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="info"
|
||||
plain
|
||||
icon="Operation"
|
||||
@click="handleBatchAllocate"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:add']"
|
||||
>批量分配</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-card>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-card class="table-card">
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="scholarshipQuotaTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="scholarshipQuotaList"
|
||||
@selection-change="handleSelectionChange"
|
||||
class="scroll-table"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="序号" type="index" width="50" align="center" />
|
||||
<el-table-column label="奖学金批次" align="center" prop="batchName" width="150" />
|
||||
<el-table-column label="奖学金类型" align="center" prop="scholarshipTypeName" width="150" />
|
||||
<el-table-column label="分配级别" align="center" prop="allocationLevelName" width="100" />
|
||||
<el-table-column label="目标部门" align="center" prop="targetDeptName" width="150" />
|
||||
<el-table-column label="总名额" align="center" prop="totalQuota" width="80" />
|
||||
<el-table-column label="已使用" align="center" prop="usedQuota" width="80">
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="奖学金批次" prop="batchName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="奖学金类型" prop="scholarshipTypeName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="分配级别" prop="allocationLevelName" width="100" align="center" />
|
||||
<el-table-column label="目标部门" prop="targetDeptName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="总名额" prop="totalQuota" width="80" align="center" />
|
||||
<el-table-column label="已使用" prop="usedQuota" width="80" align="center">
|
||||
<template #default="scope">
|
||||
<span :class="{ 'text-danger': scope.row.usedQuota > scope.row.totalQuota }">
|
||||
{{ scope.row.usedQuota || 0 }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="可用名额" align="center" prop="availableQuota" width="80">
|
||||
<el-table-column label="可用名额" prop="availableQuota" width="90" align="center">
|
||||
<template #default="scope">
|
||||
<span :class="{ 'text-success': scope.row.availableQuota > 0, 'text-danger': scope.row.availableQuota <= 0 }">
|
||||
{{ scope.row.availableQuota || 0 }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预留名额" align="center" prop="reservedQuota" width="80" />
|
||||
<el-table-column label="分配依据" align="center" prop="allocationBasis" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="状态" align="center" prop="statusName" width="80" />
|
||||
<el-table-column label="锁定状态" align="center" prop="isLocked" width="100">
|
||||
<el-table-column label="预留名额" prop="reservedQuota" width="90" align="center" />
|
||||
<el-table-column label="分配依据" prop="allocationBasis" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="状态" prop="statusName" width="80" align="center" />
|
||||
<el-table-column label="锁定状态" prop="isLocked" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.isLocked === 1 ? 'danger' : 'success'">
|
||||
{{ scope.row.isLocked === 1 ? '已锁定' : '未锁定' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<el-table-column label="创建时间" prop="createTime" width="180" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:edit']"
|
||||
:disabled="scope.row.isLocked === 1"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:remove']"
|
||||
:disabled="scope.row.isLocked === 1"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="锁定/解锁" placement="top">
|
||||
<el-button
|
||||
link
|
||||
:type="scope.row.isLocked === 1 ? 'warning' : 'info'"
|
||||
:icon="scope.row.isLocked === 1 ? 'Unlock' : 'Lock'"
|
||||
@click="handleLock(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="调整名额" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="Switch"
|
||||
@click="handleAdjust(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipQuota:edit']"
|
||||
:disabled="scope.row.isLocked === 1"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['jcbt:scholarshipQuota:edit']" :disabled="scope.row.isLocked === 1"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['jcbt:scholarshipQuota:remove']" :disabled="scope.row.isLocked === 1"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="锁定/解锁" placement="top">
|
||||
<el-button link :type="scope.row.isLocked === 1 ? 'warning' : 'info'" :icon="scope.row.isLocked === 1 ? 'Unlock' : 'Lock'" @click="handleLock(scope.row)" v-hasPermi="['jcbt:scholarshipQuota:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="调整名额" placement="top">
|
||||
<el-button link type="success" icon="Switch" @click="handleAdjust(scope.row)" v-hasPermi="['jcbt:scholarshipQuota:edit']" :disabled="scope.row.isLocked === 1"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改名额分配对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="600px" append-to-body>
|
||||
<el-form ref="scholarshipQuotaFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
@@ -475,7 +429,10 @@
|
||||
</template>
|
||||
|
||||
<script setup name="ScholarshipQuota" lang="ts">
|
||||
import { ref, reactive, onMounted, computed } from 'vue';
|
||||
import { ref, reactive, onMounted, computed, getCurrentInstance, toRefs } from 'vue';
|
||||
import type { ComponentInternalInstance } from 'vue';
|
||||
import type { FormRules, FormInstance, TableInstance } from 'element-plus';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import {
|
||||
listScholarshipQuota,
|
||||
getScholarshipQuota,
|
||||
@@ -495,16 +452,22 @@ import { getScholarshipTypesByBatch } from '@/api/jcbt/scholarshipApplication';
|
||||
import { deptTreeSelect } from '@/api/system/user';
|
||||
import type { ScholarshipQuotaVO, ScholarshipQuotaForm, ScholarshipQuotaQuery, BatchAllocateQuota } from '@/api/jcbt/scholarshipQuota';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
interface DialogOption {
|
||||
visible: boolean;
|
||||
title: string;
|
||||
}
|
||||
|
||||
// 表单ref定义
|
||||
const queryRef = ref();
|
||||
const scholarshipQuotaFormRef = ref();
|
||||
const batchAllocateFormRef = ref();
|
||||
const adjustFormRef = ref();
|
||||
const queryRef = ref<FormInstance>();
|
||||
const scholarshipQuotaFormRef = ref<FormInstance>();
|
||||
const batchAllocateFormRef = ref<FormInstance>();
|
||||
const adjustFormRef = ref<FormInstance>();
|
||||
const scholarshipQuotaTableRef = ref<TableInstance>();
|
||||
|
||||
// 字典数据
|
||||
const { allocation_level, quota_status } = toRefs<any>(proxy.useDict('allocation_level', 'quota_status'));
|
||||
// const { allocation_level, quota_status } = toRefs<any>(proxy.useDict('allocation_level', 'quota_status'));
|
||||
|
||||
// 遮罩层
|
||||
const loading = ref(true);
|
||||
@@ -1007,80 +970,13 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 继承后勤管理模块的样式风格 */
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.stats-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
height: 90px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 16px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
margin-right: 15px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.8;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格卡片布局 - 参考后勤管理功能 */
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -1089,105 +985,100 @@ onMounted(() => {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 20px;
|
||||
background: linear-gradient(135deg, rgb(93, 135, 255), rgb(73, 190, 255));
|
||||
border-radius: 2px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* 表格主体 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 表格样式 - 参考后勤管理功能 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-table__header-wrapper) {
|
||||
.el-table__header {
|
||||
th {
|
||||
background-color: #f8f9fa;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper) {
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 - 参考后勤管理功能 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #409eff #f0f0f0;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important;
|
||||
width: 12px !important;
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important;
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important;
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important;
|
||||
min-height: 20px !important;
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important;
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 文本颜色样式 */
|
||||
.text-danger {
|
||||
color: #f56c6c;
|
||||
}
|
||||
@@ -1195,4 +1086,13 @@ onMounted(() => {
|
||||
.text-success {
|
||||
color: #67c23a;
|
||||
}
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<div class="page-container">
|
||||
<!-- 审核统计 -->
|
||||
<div class="mb-[10px]">
|
||||
<el-row :gutter="16" class="stats-row">
|
||||
@@ -94,7 +94,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:4个搜索条件 + 操作按钮 -->
|
||||
<!-- 第二行:4个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="奖学金类型" prop="scholarshipTypeId">
|
||||
@@ -137,9 +137,9 @@
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮行 -->
|
||||
<el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
@@ -151,21 +151,22 @@
|
||||
</transition>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-card shadow="never" class="button-card">
|
||||
<div class="card-header">
|
||||
<div class="toolbar-title">审核记录管理</div>
|
||||
<div class="toolbar-actions">
|
||||
<el-button type="success" plain icon="Check" :disabled="multiple" @click="handleBatchApprove" v-hasPermi="['jcbt:review:batchApprove']">
|
||||
批量通过
|
||||
</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['jcbt:review:export']"> 导出 </el-button>
|
||||
<right-toolbar :showSearch="showSearch" @update:showSearch="showSearch = $event" @queryTable="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Check" :disabled="multiple" @click="handleBatchApprove" v-hasPermi="['jcbt:review:batchApprove']">
|
||||
批量通过
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['jcbt:review:export']"> 导出 </el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="table-card">
|
||||
<!-- 表格数据 -->
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="reviewRef"
|
||||
@@ -173,21 +174,23 @@
|
||||
:data="reviewList"
|
||||
@selection-change="handleSelectionChange"
|
||||
class="scroll-table"
|
||||
:scroll="{ x: 'max-content' }"
|
||||
border
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" fixed="left" />
|
||||
<el-table-column label="申请编号" align="center" prop="applicationNo" width="180" fixed="left">
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="申请编号" align="center" prop="applicationNo" min-width="180" fixed="left">
|
||||
<template #default="scope">
|
||||
<el-button link type="primary" @click="handleView(scope.row)">
|
||||
{{ scope.row.applicationNo }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学号" align="center" prop="studentNo" width="120" />
|
||||
<el-table-column label="学生姓名" align="center" prop="studentName" width="120" />
|
||||
<el-table-column label="班级" align="center" prop="className" width="120" />
|
||||
<el-table-column label="奖学金类型" align="center" prop="scholarshipTypeName" width="150" />
|
||||
<el-table-column label="申请类型" align="center" prop="applicationType" width="120">
|
||||
<el-table-column label="学号" align="center" prop="studentNo" min-width="120" />
|
||||
<el-table-column label="学生姓名" align="center" prop="studentName" min-width="120" />
|
||||
<el-table-column label="班级" align="center" prop="className" min-width="120" />
|
||||
<el-table-column label="奖学金类型" align="center" prop="scholarshipTypeName" min-width="150" />
|
||||
<el-table-column label="申请类型" align="center" prop="applicationType" min-width="120">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.applicationType === 'RECOMMEND'" type="primary">教师推荐</el-tag>
|
||||
<el-tag v-else-if="scope.row.applicationType === 'STUDENT'" type="success">学生申请</el-tag>
|
||||
@@ -196,7 +199,7 @@
|
||||
<el-tag v-else type="info">{{ scope.row.applicationType }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="申请状态" align="center" prop="status" width="120">
|
||||
<el-table-column label="申请状态" align="center" prop="status" min-width="120">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.status === 'DRAFT'" type="info">草稿</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === 'SUBMITTED'" type="primary">已提交</el-tag>
|
||||
@@ -208,17 +211,17 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="提交时间" align="center" prop="submitTime" width="160">
|
||||
<el-table-column label="提交时间" align="center" prop="submitTime" min-width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.submitTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220" fixed="right">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="220" fixed="right">
|
||||
<template #default="scope">
|
||||
<!-- 查看按钮,所有记录都可以查看 -->
|
||||
<el-tooltip content="查看" placement="top">
|
||||
@@ -227,7 +230,6 @@
|
||||
type="info"
|
||||
icon="View"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleView(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipApplication:query']"
|
||||
></el-button>
|
||||
@@ -241,7 +243,6 @@
|
||||
type="success"
|
||||
icon="Check"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleApprove(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipApplication:audit']"
|
||||
></el-button>
|
||||
@@ -252,7 +253,6 @@
|
||||
type="danger"
|
||||
icon="Close"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleReject(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipApplication:audit']"
|
||||
></el-button>
|
||||
@@ -263,7 +263,6 @@
|
||||
type="warning"
|
||||
icon="Document"
|
||||
size="default"
|
||||
style="font-size: 16px"
|
||||
@click="handleReview(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipApplication:audit']"
|
||||
></el-button>
|
||||
@@ -278,7 +277,6 @@
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
size="default"
|
||||
style="font-size: 16px"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['jcbt:scholarshipApplication:edit']"
|
||||
></el-button>
|
||||
@@ -288,20 +286,21 @@
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="pagination-container">
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page="queryParams.pageNum"
|
||||
:limit="queryParams.pageSize"
|
||||
@update:page="queryParams.pageNum = $event"
|
||||
@update:limit="queryParams.pageSize = $event"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page="queryParams.pageNum"
|
||||
:limit="queryParams.pageSize"
|
||||
@update:page="queryParams.pageNum = $event"
|
||||
@update:limit="queryParams.pageSize = $event"
|
||||
@pagination="getList"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 审核对话框 -->
|
||||
<el-drawer ref="drawerRef" v-model="reviewOpen" title="奖学金申请审核" direction="rtl" size="50%" :before-close="handleReviewClose">
|
||||
<template #default>
|
||||
@@ -407,7 +406,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="ScholarshipReview">
|
||||
<script setup name="ScholarshipReview" lang="ts">
|
||||
import { listScholarshipApplication, getScholarshipApplication, updateScholarshipApplication } from '@/api/jcbt/scholarshipApplication';
|
||||
import { listScholarshipType } from '@/api/jcbt/scholarshipType';
|
||||
import { listScholarshipBatch } from '@/api/jcbt/scholarshipBatch';
|
||||
@@ -783,274 +782,227 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 继承后勤管理模块的样式风格 */
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.stats-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
height: 90px;
|
||||
cursor: pointer;
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 16px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
margin-right: 15px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.8;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
&.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
&.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
&.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
&.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 搜索区域样式 */
|
||||
.search-btn-container {
|
||||
text-align: right;
|
||||
}
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 - 参考后勤管理功能 */
|
||||
.button-card {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1e293b;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
width: 4px;
|
||||
height: 20px;
|
||||
background: linear-gradient(135deg, rgb(93, 135, 255), rgb(73, 190, 255));
|
||||
border-radius: 2px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
}
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* 表格主体 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
/* 统计卡片样式 */
|
||||
.stats-row {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* 表格样式 - 参考后勤管理功能 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
.stat-card {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
:deep(.el-table__header-wrapper) {
|
||||
.el-table__header {
|
||||
th {
|
||||
background-color: #f8f9fa;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper) {
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ff6b6b 100%);
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 - 参考后勤管理功能 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #409eff #f0f0f0;
|
||||
}
|
||||
.stat-card-success {
|
||||
background: linear-gradient(135deg, #4ecdc4 0%, #44a08d 100%);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important;
|
||||
width: 12px !important;
|
||||
}
|
||||
.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important;
|
||||
}
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important;
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important;
|
||||
min-height: 20px !important;
|
||||
}
|
||||
.stat-icon {
|
||||
margin-right: 16px;
|
||||
font-size: 24px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important;
|
||||
}
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
line-height: 1.2;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
/* 操作按钮样式 - 参考后勤管理模块 */
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
/* 金额文本样式 */
|
||||
.amount-text {
|
||||
font-weight: 600;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 - 参考后勤管理模块 */
|
||||
|
||||
/* 金额文本样式 */
|
||||
.amount-text {
|
||||
font-weight: 600;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
/* 分页容器样式 - 参考后勤管理功能 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
/* 抽屉内容样式 */
|
||||
.drawer-content {
|
||||
padding: 20px;
|
||||
}
|
||||
/* 抽屉内容样式 */
|
||||
.drawer-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.page-container {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.stats-row {
|
||||
.el-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.stats-row .el-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
.card-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.toolbar-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
.card-header .toolbar-actions {
|
||||
width: 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<div class="page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
@@ -68,8 +68,10 @@
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8" >
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
@@ -80,100 +82,61 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 统计卡片区域 -->
|
||||
<div class="mb-[10px]">
|
||||
<el-row :gutter="16" class="stats-row">
|
||||
<el-col :span="6">
|
||||
<el-card shadow="hover" class="stat-card stat-card-primary">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Trophy /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ statistics.totalTypes }}</div>
|
||||
<div class="stat-label">奖学金类型总数</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="hover" class="stat-card stat-card-success">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ statistics.activeTypes }}</div>
|
||||
<div class="stat-label">启用状态</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="hover" class="stat-card stat-card-warning">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Money /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ statistics.totalAmount }}</div>
|
||||
<div class="stat-label">总奖励金额(万元)</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card shadow="hover" class="stat-card stat-card-info">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Star /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ statistics.avgAmount }}</div>
|
||||
<div class="stat-label">平均奖励金额(元)</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 操作工具栏 -->
|
||||
<el-card class="button-card">
|
||||
<div class="card-header">
|
||||
<div class="toolbar-title">
|
||||
<el-icon><Trophy /></el-icon>
|
||||
奖学金类型管理
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<el-button v-hasPermi="['jcbt:scholarshipType:add']" type="primary" plain icon="Plus" @click="handleAdd">新增</el-button>
|
||||
<el-button v-hasPermi="['jcbt:scholarshipType:edit']" type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button v-hasPermi="['jcbt:scholarshipType:remove']" type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button v-hasPermi="['jcbt:scholarshipType:export']" type="warning" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 表格数据 -->
|
||||
<el-card class="table-card">
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['jcbt:scholarshipType:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasPermi="['jcbt:scholarshipType:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasPermi="['jcbt:scholarshipType:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['jcbt:scholarshipType:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="scholarshipTypeTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="scholarshipTypeList"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="奖学金名称" prop="typeName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="类别" prop="typeCategory" width="120" align="center">
|
||||
<el-table-column label="奖学金名称" prop="typeName" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="类别" prop="typeCategory" width="140" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getCategoryTagType(scope.row.typeCategory)">
|
||||
{{ getCategoryText(scope.row.typeCategory) }}
|
||||
@@ -187,38 +150,45 @@
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="奖励金额" prop="awardAmount" width="120" align="center">
|
||||
<el-table-column label="奖励金额" prop="awardAmount" width="130" align="center">
|
||||
<template #default="scope">
|
||||
<span class="amount-text">¥{{ parseFloat(scope.row.awardAmount || '0').toLocaleString() }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="兼得类型" prop="compatibilityType" width="120" align="center">
|
||||
<el-table-column label="兼得类型" prop="compatibilityType" width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getCompatibilityTagType(scope.row.compatibilityType)">
|
||||
{{ getCompatibilityText(scope.row.compatibilityType) }}
|
||||
</el-tag>
|
||||
<div>
|
||||
<el-tag :type="getCompatibilityTagType(scope.row.compatibilityType)">
|
||||
{{ getCompatibilityText(scope.row.compatibilityType) }}
|
||||
</el-tag>
|
||||
<div v-if="scope.row.compatibilityType === 'CUSTOM'" class="compatibility-detail">
|
||||
<span class="exclusive-relation-text">{{ getExclusiveRelationText(scope.row.id) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="排序" prop="sortOrder" width="80" align="center" />
|
||||
<el-table-column label="状态" prop="status" width="80" align="center">
|
||||
<el-table-column label="状态" prop="status" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" @change="handleStatusChange(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime" width="160" align="center" />
|
||||
<el-table-column label="操作" width="180" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<el-table-column label="创建时间" prop="createTime" width="180" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<div class="action-buttons">
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button v-hasPermi="['jcbt:scholarshipType:query']" type="primary" icon="View" @click="handleView(scope.row)" />
|
||||
<el-button link type="info" icon="View" @click="handleView(scope.row)" v-hasPermi="['jcbt:scholarshipType:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button v-hasPermi="['jcbt:scholarshipType:edit']" type="success" icon="Edit" @click="handleUpdate(scope.row)" />
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['jcbt:scholarshipType:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button v-hasPermi="['jcbt:scholarshipType:remove']" type="danger" icon="Delete" @click="handleDelete(scope.row)" />
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['jcbt:scholarshipType:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@@ -227,7 +197,7 @@
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改奖学金类型对话框 -->
|
||||
@@ -496,6 +466,7 @@
|
||||
import { reactive, ref, onMounted, getCurrentInstance } from 'vue';
|
||||
import type { ComponentInternalInstance } from 'vue';
|
||||
import type { FormRules, FormInstance, TableInstance } from 'element-plus';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import {
|
||||
listScholarshipType,
|
||||
getScholarshipType,
|
||||
@@ -507,6 +478,7 @@ import {
|
||||
checkScholarshipTypeNameUnique,
|
||||
getCompatibilityConfig,
|
||||
saveCompatibilityConfig,
|
||||
getExclusiveRelationDisplay,
|
||||
type ScholarshipTypeVO,
|
||||
type ScholarshipTypeForm,
|
||||
type ScholarshipTypeQuery,
|
||||
@@ -560,6 +532,9 @@ const availableScholarshipTypes = ref<ScholarshipTypeVO[]>([]);
|
||||
// 当前奖学金的兼容性配置(用于编辑时显示原来的配置)
|
||||
const currentCompatibilityConfig = ref<CompatibilityConfig | null>(null);
|
||||
|
||||
// 互斥关系显示文本缓存
|
||||
const exclusiveRelationCache = ref<Map<string | number, string>>(new Map());
|
||||
|
||||
const dataRules = reactive<FormRules>({
|
||||
typeCode: [
|
||||
{ required: true, message: '奖学金类型编码不能为空', trigger: 'blur' },
|
||||
@@ -660,6 +635,44 @@ const getCompatibilityTagType = (value: string) => {
|
||||
return typeMap[value] || 'warning'; // 未知类型用橙色警告标签
|
||||
};
|
||||
|
||||
/** 获取互斥关系显示文本 */
|
||||
const getExclusiveRelationText = (scholarshipTypeId: string | number): string => {
|
||||
if (!scholarshipTypeId) return '';
|
||||
|
||||
// 先从缓存中获取
|
||||
const cached = exclusiveRelationCache.value.get(scholarshipTypeId);
|
||||
if (cached !== undefined) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
// 异步获取并缓存
|
||||
getExclusiveRelationDisplay(scholarshipTypeId).then(response => {
|
||||
exclusiveRelationCache.value.set(scholarshipTypeId, response.data);
|
||||
}).catch(error => {
|
||||
console.warn('获取互斥关系显示文本失败:', error);
|
||||
exclusiveRelationCache.value.set(scholarshipTypeId, '互斥(无)');
|
||||
});
|
||||
|
||||
return '加载中...';
|
||||
};
|
||||
|
||||
/** 预加载互斥关系显示文本 */
|
||||
const preloadExclusiveRelations = async () => {
|
||||
const customTypes = scholarshipTypeList.value.filter(item => item.compatibilityType === 'CUSTOM');
|
||||
|
||||
for (const type of customTypes) {
|
||||
if (type.id && !exclusiveRelationCache.value.has(type.id)) {
|
||||
try {
|
||||
const response = await getExclusiveRelationDisplay(type.id);
|
||||
exclusiveRelationCache.value.set(type.id, response.data);
|
||||
} catch (error) {
|
||||
console.warn(`获取奖学金类型 ${type.id} 的互斥关系失败:`, error);
|
||||
exclusiveRelationCache.value.set(type.id, '互斥(无)');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/** 查询奖学金类型列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
@@ -693,6 +706,9 @@ const getList = async () => {
|
||||
scholarshipTypeList.value = response.rows;
|
||||
total.value = response.total;
|
||||
|
||||
// 预加载CUSTOM类型的互斥关系显示文本
|
||||
preloadExclusiveRelations();
|
||||
|
||||
// 计算统计数据
|
||||
calculateStatistics();
|
||||
} finally {
|
||||
@@ -722,6 +738,8 @@ const resetQuery = () => {
|
||||
daterangeCreateTime.value = ['', ''];
|
||||
queryFormRef.value?.resetFields();
|
||||
queryParams.value.pageNum = 1;
|
||||
// 清空缓存
|
||||
exclusiveRelationCache.value.clear();
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
@@ -803,6 +821,8 @@ const handleDelete = async (row?: ScholarshipTypeVO) => {
|
||||
try {
|
||||
await proxy?.$modal.confirm(`是否确认删除奖学金类型"${typeNames.join('、')}"?`);
|
||||
await delScholarshipType(typeIds);
|
||||
// 清空缓存以便重新加载
|
||||
exclusiveRelationCache.value.clear();
|
||||
await getList();
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
} catch (error) {
|
||||
@@ -824,6 +844,8 @@ const handleStatusChange = async (row: ScholarshipTypeVO) => {
|
||||
await proxy?.$modal.confirm(`确认要${text}"${row.typeName}"吗?`);
|
||||
await changeScholarshipTypeStatus(row.id!, row.status!);
|
||||
proxy?.$modal.msgSuccess(`${text}成功`);
|
||||
// 清空缓存以便重新加载
|
||||
exclusiveRelationCache.value.clear();
|
||||
await getList();
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
@@ -858,6 +880,8 @@ const dialogSubmit = () => {
|
||||
}
|
||||
|
||||
dialogOpen.value = false;
|
||||
// 清空缓存以便重新加载
|
||||
exclusiveRelationCache.value.clear();
|
||||
await getList();
|
||||
} catch (error) {
|
||||
proxy?.$modal.msgError(form.value.id ? '修改失败' : '新增失败');
|
||||
@@ -936,80 +960,13 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
/* 继承后勤管理模块的样式风格 */
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.stats-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s ease;
|
||||
height: 90px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 16px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
margin-right: 15px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.8;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stat-card-primary {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-success {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-warning {
|
||||
background: linear-gradient(135deg, #ff9a56 0%, #ffad56 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格卡片布局 - 参考后勤管理功能 */
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -1018,100 +975,86 @@ onMounted(() => {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 操作工具栏样式 */
|
||||
.button-card {
|
||||
margin-bottom: 20px;
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 滚动表格样式 */
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
min-width: 1200px;
|
||||
}
|
||||
|
||||
/* 表格滚动条美化 */
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
transition: background 0.3s ease;
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important;
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important;
|
||||
}
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 27px !important;
|
||||
height: 27px !important;
|
||||
padding: 0 !important;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 金额文本样式 */
|
||||
.amount-text {
|
||||
font-weight: 600;
|
||||
color: #e74c3c;
|
||||
}
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 分页容器样式 - 参考后勤管理功能 */
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
@@ -1120,6 +1063,17 @@ onMounted(() => {
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 金额文本样式 */
|
||||
.amount-text {
|
||||
font-weight: 600;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
@@ -1137,59 +1091,6 @@ onMounted(() => {
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.page-container {
|
||||
padding: 10px;
|
||||
|
||||
.stats-row {
|
||||
.el-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
height: 80px;
|
||||
|
||||
.stat-content {
|
||||
padding: 5px 12px;
|
||||
|
||||
.stat-icon {
|
||||
font-size: 24px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
.stat-value {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
align-items: flex-start;
|
||||
|
||||
.button-group {
|
||||
width: 100%;
|
||||
justify-content: flex-end;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
min-width: 800px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1205,4 +1106,25 @@ onMounted(() => {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 兼容性详情样式 */
|
||||
.compatibility-detail {
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.exclusive-relation-text {
|
||||
color: #909399;
|
||||
line-height: 1.2;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
@@ -60,7 +60,7 @@
|
||||
<el-button icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['rs:job:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExport" v-hasPermi="['rs:job:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExport" v-hasPermi="['rs:job:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -91,7 +91,7 @@
|
||||
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="240">
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="280">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button
|
||||
@@ -113,6 +113,17 @@
|
||||
@click="handleUpdate(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="查看简历记录" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
icon="Document"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleApplications(scope.row)"
|
||||
v-if="scope.row.jobId"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
@@ -216,7 +227,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportApplications" v-hasPermi="['rs:application:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportApplications" v-hasPermi="['rs:application:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Printer" @click="handlePrintApplications">打印</el-button>
|
||||
@@ -386,7 +397,6 @@
|
||||
</el-descriptions>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="handleApplications(viewForm)" v-if="viewForm.jobId">查看简历记录</el-button>
|
||||
<el-button @click="viewOpen = false">关 闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1686,10 +1696,6 @@ function handleExportResume() {
|
||||
<p><strong>应聘职位:</strong>${selectedRecord.jobTitle || '未提供'}</p>
|
||||
<p><strong>联系电话:</strong>${selectedRecord.contactPhone || '未提供'}</p>
|
||||
<p><strong>联系邮箱:</strong>${selectedRecord.contactEmail || '未提供'}</p>
|
||||
<p><strong>申请状态:</strong>${
|
||||
selectedRecord.status === '0' ? '待处理' : selectedRecord.status === '1' ? '已通过' : selectedRecord.status === '2' ? '已拒绝' : '未知'
|
||||
}</p>
|
||||
<p><strong>申请时间:</strong>${parseTime(selectedRecord.applyTime)}</p>
|
||||
</div>
|
||||
|
||||
<div style="margin-bottom: 30px;">
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportPending" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportPending" v-hasPermi="['rs:overseas:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showPendingSearch" @queryTable="getPendingList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -219,7 +219,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:overseas:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showRecordSearch" @queryTable="getRecordList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -854,7 +854,13 @@ const handleRecordDateRangeChange = (dates: [string, string] | null) => {
|
||||
|
||||
<style scoped>
|
||||
.search-btn-container {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container :deep(.el-form-item) {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAddApplication" v-hasPermi="['rs:overseas:add']">新增申请</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportApplication" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportApplication" v-hasPermi="['rs:overseas:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showApplicationSearch" @queryTable="getApplicationList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -1055,7 +1055,13 @@ const handleViewRecord = (row: OverseasRecordVO) => {
|
||||
|
||||
<style scoped>
|
||||
.search-btn-container {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container :deep(.el-form-item) {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['rs:overseas:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -678,8 +678,13 @@ onMounted(() => {
|
||||
|
||||
/* 搜索按钮容器 */
|
||||
.search-btn-container {
|
||||
text-align: left;
|
||||
padding-top: 10px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container :deep(.el-form-item) {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* 表格卡片样式 */
|
||||
|
||||
@@ -344,9 +344,9 @@ onMounted(() => {
|
||||
min-height: 100vh;
|
||||
|
||||
.header-banner {
|
||||
background-color: #409eff;
|
||||
background: #004e48;
|
||||
color: white;
|
||||
padding: 40px 0;
|
||||
padding: 50px 0;
|
||||
text-align: center;
|
||||
|
||||
.banner-content {
|
||||
@@ -355,14 +355,20 @@ onMounted(() => {
|
||||
padding: 0 20px;
|
||||
|
||||
.apply-title {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 10px;
|
||||
font-size: 2.5rem;
|
||||
color: #ffffff;
|
||||
margin-bottom: 15px;
|
||||
font-weight: 600;
|
||||
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.apply-subtitle {
|
||||
font-size: 1rem;
|
||||
opacity: 0.8;
|
||||
font-size: 1.3rem;
|
||||
color: #ffffff;
|
||||
opacity: 0.92;
|
||||
margin: 0;
|
||||
font-weight: 300;
|
||||
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,50 +375,71 @@ onMounted(() => {
|
||||
<style scoped lang="scss">
|
||||
.recruitment-portal {
|
||||
min-height: 100vh;
|
||||
background: #f8f9fa;
|
||||
background: #f5f5f5;
|
||||
|
||||
.header-banner {
|
||||
background: linear-gradient(135deg, #2c3e50 0%, #34495e 100%);
|
||||
// 纯色背景,不要图案
|
||||
background: #004e48;
|
||||
position: relative;
|
||||
color: white;
|
||||
padding: 60px 0;
|
||||
padding: 50px 0;
|
||||
text-align: center;
|
||||
|
||||
.banner-content {
|
||||
margin: 0 auto;
|
||||
padding: 0 30px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
.portal-title {
|
||||
font-size: 3.5rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
|
||||
font-size: 3.2rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 15px;
|
||||
text-shadow: 2px 2px 6px rgba(0, 0, 0, 0.5);
|
||||
color: #ffffff;
|
||||
letter-spacing: 3px;
|
||||
}
|
||||
|
||||
.portal-subtitle {
|
||||
font-size: 1.5rem;
|
||||
opacity: 0.9;
|
||||
font-size: 1.3rem;
|
||||
color: #ffffff;
|
||||
opacity: 0.92;
|
||||
margin: 0;
|
||||
font-weight: 300;
|
||||
text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.breadcrumb-container {
|
||||
background: white;
|
||||
padding: 15px 0;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
border-bottom: 1px solid #e8ecf0;
|
||||
padding: 12px 0;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
|
||||
.el-breadcrumb {
|
||||
margin: 0 auto;
|
||||
padding: 0 30px;
|
||||
|
||||
:deep(.el-breadcrumb__item) {
|
||||
.el-breadcrumb__inner {
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
&:last-child .el-breadcrumb__inner {
|
||||
color: #2d5a3d;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.portal-container {
|
||||
margin: 0;
|
||||
padding: 30px;
|
||||
padding: 25px;
|
||||
display: flex;
|
||||
gap: 25px;
|
||||
gap: 20px;
|
||||
min-height: calc(100vh - 200px);
|
||||
}
|
||||
|
||||
@@ -427,51 +448,101 @@ onMounted(() => {
|
||||
flex-shrink: 0;
|
||||
|
||||
.nav-section {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid #e8ecf0;
|
||||
// 参考官网左侧导航的样式 - 整体深绿色背景
|
||||
background: #004e48;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 15px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
border: none;
|
||||
overflow: visible;
|
||||
|
||||
.nav-title {
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: 20px;
|
||||
color: #2c3e50;
|
||||
border-bottom: 2px solid #e3f2fd;
|
||||
padding-bottom: 10px;
|
||||
margin: 0;
|
||||
color: #ffffff;
|
||||
// 参考官网"学工在线"的深绿色背景
|
||||
background: #004e48;
|
||||
padding: 18px 20px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
.nav-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background: #004e48;
|
||||
|
||||
.nav-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 15px;
|
||||
margin-bottom: 8px;
|
||||
border-radius: 8px;
|
||||
padding: 15px 20px;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
color: #555;
|
||||
|
||||
color: #ffffff;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
border: none;
|
||||
|
||||
// 默认状态 - 普通导航项
|
||||
background: #004e48;
|
||||
|
||||
&:hover {
|
||||
background: #f8f9fa;
|
||||
color: #667eea;
|
||||
background: #006157;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: linear-gradient(135deg, #667eea, #764ba2);
|
||||
color: white;
|
||||
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
|
||||
// 参考官网"学生活动"的样式 - 更深的绿色和箭头形状
|
||||
background: #003a37;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
// 创建右箭头效果
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 15px solid #003a37;
|
||||
border-top: 15px solid transparent;
|
||||
border-bottom: 15px solid transparent;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
// 箭头阴影效果
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -17px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 17px solid rgba(0, 0, 0, 0.15);
|
||||
border-top: 17px solid transparent;
|
||||
border-bottom: 17px solid transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
margin-right: 10px;
|
||||
font-size: 1.1rem;
|
||||
color: #ffffff;
|
||||
transition: color 0.2s ease;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 1rem;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -480,11 +551,25 @@ onMounted(() => {
|
||||
|
||||
.main-content {
|
||||
flex: 1;
|
||||
min-width: 0; // 确保flex子项能够收缩
|
||||
|
||||
/* 搜索区域样式已删除 */
|
||||
min-width: 0;
|
||||
|
||||
.job-list-section {
|
||||
.el-card {
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e8e8e8;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
|
||||
:deep(.el-card__header) {
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
padding: 16px 20px;
|
||||
}
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.list-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -497,96 +582,106 @@ onMounted(() => {
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
color: #2c3e50;
|
||||
color: #2d5a3d;
|
||||
font-weight: 600;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.job-count {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
background: #e8f5e8;
|
||||
padding: 4px 8px;
|
||||
border-radius: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.view-options {
|
||||
:deep(.el-radio-group) {
|
||||
.el-radio-button__inner {
|
||||
background: #fff;
|
||||
border-color: #2d5a3d;
|
||||
color: #2d5a3d;
|
||||
|
||||
&:hover {
|
||||
color: #2d5a3d;
|
||||
}
|
||||
}
|
||||
|
||||
.el-radio-button__original-radio:checked + .el-radio-button__inner {
|
||||
background: #2d5a3d;
|
||||
border-color: #2d5a3d;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-view {
|
||||
:deep(.el-table) {
|
||||
.el-table__header {
|
||||
background: #fafafa;
|
||||
|
||||
th {
|
||||
background: #fafafa !important;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.job-title-link {
|
||||
font-weight: 600;
|
||||
font-weight: 500;
|
||||
color: #2d5a3d;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #4a7c59;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.deadline-passed {
|
||||
color: #f56c6c;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.deadline-warning {
|
||||
color: #e6a23c;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.card-view {
|
||||
.job-card-col {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.job-card {
|
||||
height: 100%;
|
||||
cursor: pointer;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 8px;
|
||||
transition: all 0.3s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-3px);
|
||||
box-shadow: 0 6px 20px rgba(45, 90, 61, 0.15);
|
||||
border-color: #2d5a3d;
|
||||
}
|
||||
|
||||
.job-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.job-card-title {
|
||||
margin: 0;
|
||||
font-size: 1.1rem;
|
||||
color: #2d5a3d;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
flex: 1;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.job-card-info {
|
||||
margin-bottom: 15px;
|
||||
flex: 1;
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
|
||||
.el-icon {
|
||||
margin-right: 8px;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.job-card-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.publish-time {
|
||||
font-size: 0.8rem;
|
||||
color: #999;
|
||||
.el-button {
|
||||
background: #2d5a3d;
|
||||
border-color: #2d5a3d;
|
||||
|
||||
&:hover {
|
||||
background: #4a7c59;
|
||||
border-color: #4a7c59;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background: #ccc;
|
||||
border-color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -594,12 +689,28 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
// 对话框样式优化
|
||||
:deep(.el-dialog) {
|
||||
border-radius: 8px;
|
||||
|
||||
.el-dialog__header {
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
|
||||
.el-dialog__title {
|
||||
color: #2d5a3d;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.job-detail {
|
||||
.detail-header {
|
||||
.job-basic-info {
|
||||
h3 {
|
||||
margin-bottom: 15px;
|
||||
color: #2c3e50;
|
||||
color: #2d5a3d;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.job-meta {
|
||||
@@ -612,6 +723,14 @@ onMounted(() => {
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.el-tag {
|
||||
&.el-tag--success {
|
||||
background: #e8f5e8;
|
||||
color: #2d5a3d;
|
||||
border-color: #2d5a3d;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,9 +740,12 @@ onMounted(() => {
|
||||
margin-bottom: 25px;
|
||||
|
||||
h4 {
|
||||
color: #2c3e50;
|
||||
color: #2d5a3d;
|
||||
margin-bottom: 15px;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
border-left: 4px solid #2d5a3d;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.content-text {
|
||||
@@ -644,9 +766,21 @@ onMounted(() => {
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
padding-top: 15px;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
|
||||
.el-button {
|
||||
margin-left: 10px;
|
||||
|
||||
&.el-button--primary {
|
||||
background: #2d5a3d;
|
||||
border-color: #2d5a3d;
|
||||
|
||||
&:hover {
|
||||
background: #4a7c59;
|
||||
border-color: #4a7c59;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,12 +57,12 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAddApplication" v-hasPermi="['rs:training:application:add']"
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAddApplication" v-hasPermi="['rs:trainingapplication:add']"
|
||||
>申请培训</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportTrainingApplication" v-hasPermi="['rs:training:application:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportTrainingApplication" v-hasPermi="['rs:trainingapplication:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showApplicationSearch" @queryTable="getApplicationList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -95,7 +95,7 @@
|
||||
type="primary"
|
||||
icon="View"
|
||||
@click="handleViewApplicant(scope.row)"
|
||||
v-hasPermi="['rs:training:application:query']"
|
||||
v-hasPermi="['rs:trainingapplication:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 待审核状态:显示撤回按钮 -->
|
||||
@@ -105,7 +105,7 @@
|
||||
type="warning"
|
||||
icon="RefreshLeft"
|
||||
@click="handleCancelApplication(scope.row)"
|
||||
v-hasPermi="['rs:training:application:cancel']"
|
||||
v-hasPermi="['rs:trainingapplication:cancel']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 已拒绝状态:显示重新提交按钮(需要修改并重新提交权限) -->
|
||||
@@ -115,7 +115,7 @@
|
||||
type="success"
|
||||
icon="RefreshRight"
|
||||
@click="handleUpdateAndResubmitApplication(scope.row)"
|
||||
v-hasPermi="['rs:training:application:edit', 'rs:training:application:submit']"
|
||||
v-hasPermi="['rs:trainingapplication:edit', 'rs:trainingapplication:submit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 已通过和已拒绝状态:显示审批历史 -->
|
||||
@@ -128,8 +128,8 @@
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDeleteApplication(scope.row)"
|
||||
v-hasPermi="['rs:training:application:remove']"
|
||||
@click="handleDeleteApplication(scope.row)"
|
||||
v-hasPermi="['rs:trainingapplication:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
@@ -161,16 +161,13 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学员姓名" prop="userName">
|
||||
<el-input v-model="recordQueryParams.userName" placeholder="请输入学员姓名" clearable @keyup.enter="handleRecordQuery" />
|
||||
<el-form-item label="培训地点" prop="location">
|
||||
<el-input v-model="recordQueryParams.location" placeholder="请输入培训地点" clearable @keyup.enter="handleRecordQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="完成状态" prop="completionStatus">
|
||||
<el-select v-model="recordQueryParams.completionStatus" placeholder="请选择完成状态" clearable style="width: 100%">
|
||||
<el-option label="未完成" value="0" />
|
||||
<el-option label="已完成" value="1" />
|
||||
</el-select>
|
||||
<el-form-item label="部门" prop="department">
|
||||
<el-input v-model="recordQueryParams.department" placeholder="请输入部门" clearable style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -193,7 +190,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:training:record:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:training:record:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showRecordSearch" @queryTable="getRecordList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -210,21 +207,17 @@
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="课程名称" align="center" prop="courseName" min-width="150" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="培训地点" align="center" prop="location" min-width="110" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="学时" align="center" prop="duration" width="80" />
|
||||
<el-table-column label="申请时间" align="center" prop="applyTime" width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.applyTime) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="申请状态" align="center" prop="status" width="100">
|
||||
<el-table-column label="部门" align="center" prop="department" min-width="110" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="完成状态" align="center" prop="completionStatus" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
:type="scope.row.status === '0' ? 'warning' : scope.row.status === '1' ? 'success' : scope.row.status === '2' ? 'danger' : 'info'"
|
||||
:type="scope.row.completionStatus === '0' ? 'warning' : scope.row.completionStatus === '1' ? 'success' : 'info'"
|
||||
>
|
||||
{{ getStatusLabel(scope.row.status) }}
|
||||
{{ scope.row.completionStatus === '0' ? '未完成' : scope.row.completionStatus === '1' ? '已完成' : '未知' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="学时" align="center" prop="duration" width="80" />
|
||||
<el-table-column label="完成时间" align="center" prop="completionTime" width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.completionTime) || '未完成' }}</span>
|
||||
@@ -355,7 +348,7 @@
|
||||
type="primary"
|
||||
@click="handleViewApplications(courseDetail)"
|
||||
v-if="courseDetail.courseId"
|
||||
v-hasPermi="['rs:training:application:list']"
|
||||
v-hasPermi="['rs:trainingapplication:list']"
|
||||
>查看申请记录</el-button
|
||||
>
|
||||
<el-button @click="courseDetailDialogVisible = false">关 闭</el-button>
|
||||
@@ -456,7 +449,12 @@
|
||||
<el-input-number v-model="applicationForm.duration" :min="0" :max="1000" :step="0.5" style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属部门" prop="department">
|
||||
<el-input v-model="applicationForm.department" placeholder="请输入所属部门" :disabled="true" />
|
||||
<el-input
|
||||
v-model="applicationForm.department"
|
||||
placeholder="请输入所属部门"
|
||||
readonly
|
||||
class="readonly-input"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="培训时间" required>
|
||||
<el-col :span="11">
|
||||
@@ -771,7 +769,8 @@ import {
|
||||
deleteTrainingApplication,
|
||||
getTrainingApprovalHistory,
|
||||
resubmitTrainingApplication,
|
||||
updateRecordAttachments
|
||||
updateRecordAttachments,
|
||||
listAllApprovalRecords
|
||||
} from '@/api/rs/training';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import request from '@/utils/request';
|
||||
@@ -787,12 +786,15 @@ import type {
|
||||
ApplicationVO,
|
||||
ApplicationForm
|
||||
} from '@/api/rs/training';
|
||||
import { listDept } from '@/api/system/dept';
|
||||
import { listDept, getDept } from '@/api/system/dept';
|
||||
import type { DeptVO } from '@/api/system/dept/types';
|
||||
import { getFilePreviewUrl } from '@/api/system/file';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { getInfo as getUserInfo } from '@/api/login';
|
||||
import { useUserStore } from '@/store/modules/user';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
const userStore = useUserStore();
|
||||
|
||||
// 环境变量
|
||||
const baseApi = import.meta.env.VITE_APP_BASE_API;
|
||||
@@ -976,17 +978,19 @@ const applicationDetail = reactive<any>({
|
||||
const approvalHistoryOpen = ref(false);
|
||||
const approvalHistoryList = ref<any[]>([]);
|
||||
|
||||
// 培训记录相关
|
||||
// 培训记录相关
|
||||
const recordLoading = ref(false);
|
||||
const recordList = ref<RecordVO[]>([]);
|
||||
const recordList = ref<RecordVO[]>([]);
|
||||
const recordTotal = ref(0);
|
||||
const showRecordSearch = ref(true);
|
||||
const recordQueryParams = reactive<RecordQuery>({
|
||||
const recordQueryParams = reactive<RecordQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
pageSize: 20,
|
||||
courseId: undefined as string | number | undefined,
|
||||
courseName: '',
|
||||
userId: undefined as string | number | undefined,
|
||||
userName: '',
|
||||
department: '',
|
||||
completionStatus: '',
|
||||
params: {}
|
||||
});
|
||||
@@ -1325,17 +1329,72 @@ function getApplicationList() {
|
||||
}
|
||||
|
||||
/** 新增培训申请 */
|
||||
function handleAddApplication() {
|
||||
async function handleAddApplication() {
|
||||
resetApplicationForm();
|
||||
applicationDialogVisible.value = true;
|
||||
applicationDialogTitle.value = '申请培训';
|
||||
|
||||
// 加载课程选项
|
||||
if (courseOptions.value.length === 0) {
|
||||
if (courseOptions.value && courseOptions.value.length === 0) {
|
||||
loadCourseOptions();
|
||||
}
|
||||
|
||||
// 模拟用户部门信息
|
||||
applicationForm.department = '计算机科学学院';
|
||||
// 自动获取登录用户的部门信息
|
||||
try {
|
||||
// 确保用户信息已加载
|
||||
if (!userStore.userId) {
|
||||
await userStore.getInfo();
|
||||
}
|
||||
|
||||
console.log('开始自动填充用户部门信息:', {
|
||||
userId: userStore.userId,
|
||||
cachedDeptName: userStore.deptName
|
||||
});
|
||||
|
||||
// 重新获取用户信息以确保获取到deptId
|
||||
await userStore.getInfo();
|
||||
const userInfo = await getUserInfo();
|
||||
const userDeptId = userInfo.data.user.deptId;
|
||||
|
||||
console.log('用户信息详情:', {
|
||||
userId: userStore.userId,
|
||||
deptId: userDeptId,
|
||||
cachedDeptName: userStore.deptName
|
||||
});
|
||||
|
||||
// 如果有deptId,从数据库sys_dept表实时获取部门名称
|
||||
if (userDeptId) {
|
||||
console.log('开始从数据库sys_dept表获取部门信息 - deptId:', userDeptId);
|
||||
|
||||
try {
|
||||
const deptResponse = await getDept(userDeptId);
|
||||
if (deptResponse.code === 200 && deptResponse.data) {
|
||||
const realDeptName = deptResponse.data.deptName;
|
||||
applicationForm.department = realDeptName;
|
||||
|
||||
console.log('培训申请部门自动匹配成功:', {
|
||||
userId: userStore.userId,
|
||||
userDeptId: userDeptId,
|
||||
deptNameFromDatabase: realDeptName,
|
||||
关联逻辑: 'sys_user.dept_id -> sys_dept.dept_name'
|
||||
});
|
||||
} else {
|
||||
console.warn('从数据库获取部门信息失败,使用缓存的部门名称');
|
||||
applicationForm.department = userStore.deptName || '';
|
||||
}
|
||||
} catch (deptError) {
|
||||
console.error('查询部门信息API调用失败:', deptError);
|
||||
applicationForm.department = userStore.deptName || '';
|
||||
}
|
||||
} else {
|
||||
console.warn('用户deptId不存在,使用缓存的部门名称');
|
||||
applicationForm.department = userStore.deptName || '';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
// 如果获取失败,使用空字符串,用户可以手动输入
|
||||
applicationForm.department = '';
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置培训申请表单 */
|
||||
@@ -1722,8 +1781,12 @@ function handleTrainingSubTabClick() {
|
||||
// 加载课程选项
|
||||
function loadCourseOptions() {
|
||||
return listTrainingCourse({ pageNum: 1, pageSize: 100, status: '0' }).then((response) => {
|
||||
courseOptions.value = response.rows;
|
||||
return response.rows;
|
||||
courseOptions.value = response.rows || [];
|
||||
return courseOptions.value;
|
||||
}).catch((error) => {
|
||||
console.error('加载课程选项失败:', error);
|
||||
courseOptions.value = [];
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1755,10 +1818,19 @@ function remoteSearchUser(query: string) {
|
||||
/** 获取培训记录列表 */
|
||||
function getRecordList() {
|
||||
recordLoading.value = true;
|
||||
listTrainingRecord(recordQueryParams).then(response => {
|
||||
// 设置当前用户ID,只查询当前用户的培训记录
|
||||
const queryParams = {
|
||||
...recordQueryParams,
|
||||
userId: userStore.userId // 设置当前用户ID
|
||||
};
|
||||
|
||||
// 调用培训记录接口,获取培训记录数据
|
||||
listTrainingRecord(queryParams).then(response => {
|
||||
recordList.value = response.rows;
|
||||
recordTotal.value = response.total;
|
||||
recordLoading.value = false;
|
||||
}).catch(() => {
|
||||
recordLoading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1768,13 +1840,14 @@ function handleAddRecord() {
|
||||
recordDialogVisible.value = true;
|
||||
recordDialogTitle.value = '添加培训记录';
|
||||
// 加载课程选项
|
||||
if (courseOptions.value.length === 0) {
|
||||
if (!courseOptions.value || courseOptions.value.length === 0) {
|
||||
loadCourseOptions();
|
||||
}
|
||||
}
|
||||
|
||||
/** 重置培训记录表单 */
|
||||
function resetRecordForm() {
|
||||
console.log('resetRecordForm 开始执行');
|
||||
recordForm.recordId = undefined;
|
||||
recordForm.courseId = '';
|
||||
recordForm.userId = '';
|
||||
@@ -1787,8 +1860,18 @@ function resetRecordForm() {
|
||||
recordForm.attachmentIds = '';
|
||||
recordForm.feedback = '';
|
||||
recordForm.remark = '';
|
||||
recordCertificateFileList.value = [];
|
||||
|
||||
console.log('开始重置附件列表,当前 recordCertificateFileList.value:', recordCertificateFileList.value);
|
||||
if (recordCertificateFileList.value) {
|
||||
recordCertificateFileList.value = [];
|
||||
} else {
|
||||
console.warn('recordCertificateFileList.value 是 undefined,创建新数组');
|
||||
recordCertificateFileList.value = [];
|
||||
}
|
||||
|
||||
console.log('开始重置表单字段');
|
||||
recordFormRef.value?.resetFields();
|
||||
console.log('resetRecordForm 执行完成');
|
||||
}
|
||||
|
||||
/** 取消培训记录对话框 */
|
||||
@@ -1808,6 +1891,10 @@ function submitRecordForm() {
|
||||
console.log('证书路径:', recordForm.certificatePath);
|
||||
console.log('证书文件名:', recordForm.certificateFileName);
|
||||
|
||||
// 在提交前确保attachmentIds字段是最新的
|
||||
updateRecordFormAttachmentIds();
|
||||
console.log('提交前的attachmentIds:', recordForm.attachmentIds);
|
||||
|
||||
if (recordForm.recordId) {
|
||||
// 修改记录时,保存证书信息到本地存储
|
||||
if (recordForm.certificatePath) {
|
||||
@@ -1873,51 +1960,108 @@ async function handleUpdateRecord(row: RecordVO) {
|
||||
console.log('=== 修改培训记录开始 ===');
|
||||
console.log('row数据:', row);
|
||||
|
||||
resetRecordForm();
|
||||
// 加载课程选项
|
||||
if (courseOptions.value.length === 0) {
|
||||
loadCourseOptions();
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await getTrainingRecord(row.recordId);
|
||||
const data = response.data || row;
|
||||
Object.assign(recordForm, data);
|
||||
|
||||
// 确保课程名称正确显示
|
||||
if (!recordForm.courseName && recordForm.courseId) {
|
||||
const course = courseOptions.value.find((c) => c.courseId === recordForm.courseId);
|
||||
if (course) {
|
||||
recordForm.courseName = course.title;
|
||||
}
|
||||
// 立即显示对话框,避免用户等待
|
||||
recordDialogVisible.value = true;
|
||||
recordDialogTitle.value = '修改培训记录';
|
||||
|
||||
// 重置表单
|
||||
try {
|
||||
console.log('开始重置表单...');
|
||||
resetRecordForm();
|
||||
console.log('表单重置完成');
|
||||
} catch (error) {
|
||||
console.error('重置表单时出错:', error);
|
||||
throw error;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('使用模拟数据,原因:', error);
|
||||
// 模拟数据,实际应使用API返回的数据
|
||||
Object.assign(recordForm, {
|
||||
recordId: row.recordId,
|
||||
courseId: row.courseId,
|
||||
courseName: row.courseName,
|
||||
userId: row.userId,
|
||||
completionStatus: row.completionStatus,
|
||||
score: row.score,
|
||||
duration: row.duration,
|
||||
completionTime: row.completionTime,
|
||||
certificatePath: row.certificatePath,
|
||||
certificateFileName: row.certificateFileName,
|
||||
remark: row.remark
|
||||
|
||||
// 先设置基础数据,确保对话框内容可见
|
||||
try {
|
||||
console.log('开始设置基础数据...');
|
||||
Object.assign(recordForm, {
|
||||
recordId: row.recordId,
|
||||
courseId: row.courseId,
|
||||
courseName: row.courseName,
|
||||
userId: row.userId,
|
||||
userName: row.userName,
|
||||
completionStatus: row.completionStatus || '0',
|
||||
score: row.score || '',
|
||||
duration: row.duration || '',
|
||||
completionTime: row.completionTime || '',
|
||||
certificatePath: row.certificatePath || '',
|
||||
certificateNumber: row.certificateNumber || '',
|
||||
certificateFileName: row.certificateFileName || '',
|
||||
attachmentIds: (row as any).attachmentIds || '',
|
||||
feedback: row.feedback || '',
|
||||
remark: row.remark || ''
|
||||
});
|
||||
console.log('基础数据设置完成,attachmentIds:', recordForm.attachmentIds);
|
||||
} catch (error) {
|
||||
console.error('设置基础数据时出错:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
console.log('设置基础数据后的recordForm:', recordForm);
|
||||
console.log('当前courseOptions.value:', courseOptions.value);
|
||||
|
||||
// 异步加载课程选项(如果还没有加载)
|
||||
try {
|
||||
console.log('开始处理课程选项,当前courseOptions:', courseOptions.value);
|
||||
if (!courseOptions.value || courseOptions.value.length === 0) {
|
||||
console.log('需要加载课程选项');
|
||||
loadCourseOptions().then(() => {
|
||||
console.log('课程选项加载完成,开始匹配课程名称');
|
||||
// 确保课程名称正确显示
|
||||
if (!recordForm.courseName && recordForm.courseId && courseOptions.value) {
|
||||
const course = courseOptions.value.find((c) => c.courseId === recordForm.courseId);
|
||||
if (course) {
|
||||
recordForm.courseName = course.title;
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
console.warn('加载课程选项失败:', error);
|
||||
});
|
||||
} else {
|
||||
console.log('使用现有课程选项');
|
||||
// 确保课程名称正确显示
|
||||
if (!recordForm.courseName && recordForm.courseId && courseOptions.value) {
|
||||
const course = courseOptions.value.find((c) => c.courseId === recordForm.courseId);
|
||||
if (course) {
|
||||
recordForm.courseName = course.title;
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('课程选项处理完成');
|
||||
} catch (error) {
|
||||
console.error('处理课程选项时出错:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
// 异步获取详细数据(可选)
|
||||
try {
|
||||
const response = await getTrainingRecord(row.recordId);
|
||||
if (response.data) {
|
||||
// 合并API返回的数据,保留已设置的基础数据
|
||||
Object.assign(recordForm, response.data);
|
||||
console.log('API返回的详细数据:', response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('获取详细数据失败,使用基础数据:', error);
|
||||
// 使用基础数据继续,不影响对话框显示
|
||||
}
|
||||
|
||||
// 异步处理证书附件数据
|
||||
handleRecordAttachmentData().catch(error => {
|
||||
console.warn('处理附件数据失败:', error);
|
||||
// 不影响对话框显示
|
||||
});
|
||||
|
||||
console.log('=== 修改培训记录完成 ===');
|
||||
} catch (error) {
|
||||
console.error('修改培训记录过程中发生错误:', error);
|
||||
// 即使出错也要显示对话框,让用户看到基础数据
|
||||
proxy?.$modal.msgError('加载培训记录数据时发生错误,请重试');
|
||||
}
|
||||
|
||||
console.log('设置后的recordForm:', recordForm);
|
||||
|
||||
// 处理证书附件数据
|
||||
await handleRecordAttachmentData();
|
||||
|
||||
recordDialogVisible.value = true;
|
||||
recordDialogTitle.value = '修改培训记录';
|
||||
|
||||
console.log('=== 修改培训记录完成 ===');
|
||||
}
|
||||
|
||||
/** 查看培训记录详情 */
|
||||
@@ -1960,7 +2104,7 @@ function handleDeleteRecord(row?: RecordVO) {
|
||||
if (row) {
|
||||
confirmMessage = `是否确认删除学员"${row.userName}"的培训记录?`;
|
||||
} else {
|
||||
const selectedItems = recordList.value.filter((item) => recordIds.value.includes(item.recordId as number | string));
|
||||
const selectedItems = recordList.value.filter((item) => recordIds.value.includes(item.applicationId as number | string));
|
||||
if (selectedItems.length === 1) {
|
||||
confirmMessage = `是否确认删除学员"${selectedItems[0].userName}"的培训记录?`;
|
||||
} else {
|
||||
@@ -2090,7 +2234,7 @@ function handleRecordCertificateSuccess(response: any, file: any) {
|
||||
file.url = response.data.url;
|
||||
file.ossId = response.data.ossId;
|
||||
|
||||
proxy?.$modal.msgSuccess('证书上传成功!');
|
||||
proxy?.$modal.msgSuccess('证书上传成功!');
|
||||
console.log('证书上传成功:', response.data);
|
||||
|
||||
// 更新文件状态为成功
|
||||
@@ -2099,6 +2243,9 @@ function handleRecordCertificateSuccess(response: any, file: any) {
|
||||
|
||||
// 自动保存附件ID到后端
|
||||
saveRecordAttachments();
|
||||
|
||||
// 同时更新recordForm中的attachmentIds字段,确保提交时包含附件信息
|
||||
updateRecordFormAttachmentIds();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2147,6 +2294,25 @@ async function saveRecordAttachments() {
|
||||
}
|
||||
}
|
||||
|
||||
/** 更新recordForm中的attachmentIds字段 */
|
||||
function updateRecordFormAttachmentIds() {
|
||||
if (!recordForm.recordId) {
|
||||
console.warn('记录ID为空,无法更新附件ID');
|
||||
return;
|
||||
}
|
||||
|
||||
// 提取所有成功上传的ossId
|
||||
const attachmentOssIds = recordCertificateFileList.value
|
||||
.filter(file => file.status === 'success' && file.ossId)
|
||||
.map(file => file.ossId);
|
||||
|
||||
// 转换为逗号分隔的字符串并更新recordForm
|
||||
const attachmentIds = attachmentOssIds.join(',');
|
||||
recordForm.attachmentIds = attachmentIds;
|
||||
|
||||
console.log('更新recordForm.attachmentIds:', attachmentIds);
|
||||
}
|
||||
|
||||
/** 处理培训记录附件数据 */
|
||||
async function handleRecordAttachmentData() {
|
||||
try {
|
||||
@@ -2761,6 +2927,9 @@ function handleRemoveCertificate(file: any) {
|
||||
// 自动保存附件ID到后端
|
||||
saveRecordAttachments();
|
||||
|
||||
// 同时更新recordForm中的attachmentIds字段
|
||||
updateRecordFormAttachmentIds();
|
||||
|
||||
proxy?.$modal.msgSuccess('证书文件已删除');
|
||||
}
|
||||
|
||||
@@ -2774,8 +2943,8 @@ function handleRecordQuery() {
|
||||
function resetRecordQuery() {
|
||||
recordQueryForm.value?.resetFields();
|
||||
recordQueryParams.courseName = '';
|
||||
recordQueryParams.userName = '';
|
||||
recordQueryParams.completionStatus = '';
|
||||
recordQueryParams.location = '';
|
||||
recordQueryParams.department = '';
|
||||
handleRecordQuery();
|
||||
}
|
||||
|
||||
@@ -3115,6 +3284,19 @@ onMounted(() => {
|
||||
color: #909399 !important;
|
||||
line-height: 1.4 !important;
|
||||
}
|
||||
|
||||
/* 只读输入框样式 */
|
||||
.readonly-input :deep(.el-input__inner) {
|
||||
background-color: #f5f7fa !important;
|
||||
color: #606266 !important;
|
||||
border-color: #dcdfe6 !important;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
.readonly-input :deep(.el-input__inner:focus) {
|
||||
border-color: #dcdfe6 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportTrainingApplication" v-hasPermi="['rs:trainingApproval:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportTrainingApplication" v-hasPermi="['rs:trainingapproval:export']" style="display: none">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showApplicationSearch" @queryTable="getApplicationList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -120,7 +120,7 @@
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 审批记录选项卡 -->
|
||||
<el-tab-pane label="审批记录" name="approvalRecord" v-hasPermi="['rs:trainingApproval:query']">
|
||||
<el-tab-pane label="审批记录" name="approvalRecord" v-hasPermi="['rs:trainingapproval:query']">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="animate.searchAnimate.enter" :leave-active-class="animate.searchAnimate.leave">
|
||||
<div v-show="showApprovalRecordSearch" class="mb-[10px]">
|
||||
@@ -175,7 +175,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportApprovalRecord" v-hasPermi="['rs:trainingApproval:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportApprovalRecord" v-hasPermi="['rs:trainingapproval:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showApprovalRecordSearch" @queryTable="getApprovalRecordList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -351,12 +351,12 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="申请时间">
|
||||
<el-input v-model="approvalRecordDetail.applyTime" readonly />
|
||||
<el-input :value="parseTime(approvalRecordDetail.applyTime)" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="审批时间">
|
||||
<el-input v-model="approvalRecordDetail.approvalTime" readonly />
|
||||
<el-input :value="parseTime(approvalRecordDetail.approvalTime)" readonly />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -822,8 +822,26 @@ const handleApprovalRecordSelectionChange = (selection: any[]) => {
|
||||
// 查看审批记录详情
|
||||
const handleViewApprovalRecord = async (row: any) => {
|
||||
try {
|
||||
const response = await getTrainingApplication(row.applicationId);
|
||||
Object.assign(approvalRecordDetail, response.data);
|
||||
// 获取原始申请数据,以获取完整的申请信息(申请时间、部门、申请理由等)
|
||||
const applicationResponse = await getTrainingApplication(row.applicationId);
|
||||
const applicationData = applicationResponse.data;
|
||||
|
||||
// 合并申请数据和审批数据
|
||||
Object.assign(approvalRecordDetail, {
|
||||
applicationId: row.applicationId,
|
||||
courseId: applicationData.courseId,
|
||||
courseName: applicationData.courseName,
|
||||
userId: applicationData.userId,
|
||||
userName: applicationData.userName,
|
||||
department: applicationData.department, // 从申请数据获取部门
|
||||
status: row.status, // 使用审批记录的状态
|
||||
applyTime: applicationData.applyTime, // 从申请数据获取申请时间
|
||||
approvalTime: row.approvalTime, // 从审批记录获取审批时间
|
||||
reason: applicationData.reason, // 从申请数据获取申请理由
|
||||
remark: applicationData.remark,
|
||||
adminRemark: row.opinion, // 从审批记录获取审批意见
|
||||
certificatePath: applicationData.certificatePath
|
||||
});
|
||||
|
||||
// 获取审批历史记录
|
||||
const historyResponse = await getTrainingApprovalHistory(row.applicationId);
|
||||
@@ -1007,7 +1025,13 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.search-btn-container {
|
||||
text-align: right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container :deep(.el-form-item) {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
|
||||
@@ -2,125 +2,133 @@
|
||||
<div class="page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<el-card v-show="showSearch" class="search-card">
|
||||
<el-form :model="queryParams" ref="queryFormRef" label-width="80px">
|
||||
<el-row :gutter="20">
|
||||
<!-- 第一行:4个条件 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input v-model="queryParams.idCard" placeholder="请输入身份证号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="准考证号" prop="examNumber">
|
||||
<el-input v-model="queryParams.examNumber" placeholder="请输入准考证号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-select v-model="queryParams.gender" placeholder="请选择性别" clearable class="w-100">
|
||||
<el-option v-for="dict in zsjy_gender" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<!-- 第一行:4个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="身份证号" prop="idCard">
|
||||
<el-input v-model="queryParams.idCard" placeholder="请输入身份证号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="准考证号" prop="examNumber">
|
||||
<el-input v-model="queryParams.examNumber" placeholder="请输入准考证号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-select v-model="queryParams.gender" placeholder="请选择性别" clearable style="width: 100%">
|
||||
<el-option v-for="dict in zsjy_gender" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<!-- 第二行:4个条件 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item label="所属学院" prop="collegeId">
|
||||
<el-select v-model="queryParams.collegeId" placeholder="请选择学院" clearable class="w-100" @change="onSearchCollegeChange">
|
||||
<el-option v-for="college in collegeOptions" :key="college.deptId" :label="college.deptName" :value="college.deptCategory" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="报考专业" prop="appliedMajor">
|
||||
<el-select v-model="queryParams.appliedMajor" placeholder="请选择报考专业" clearable class="w-100">
|
||||
<el-option v-for="major in searchMajorOptions" :key="major.value" :label="major.label" :value="major.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="联系电话" prop="phone1">
|
||||
<el-input v-model="queryParams.phone1" placeholder="请输入联系电话" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="中考地区" prop="examRegion">
|
||||
<el-input v-model="queryParams.examRegion" placeholder="请输入中考地区" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 第二行:4个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="所属学院" prop="collegeId">
|
||||
<el-select v-model="queryParams.collegeId" placeholder="请选择学院" clearable style="width: 100%" @change="onSearchCollegeChange">
|
||||
<el-option v-for="college in collegeOptions" :key="college.deptId" :label="college.deptName" :value="college.deptCategory" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="报考专业" prop="appliedMajor">
|
||||
<el-select v-model="queryParams.appliedMajor" placeholder="请选择报考专业" clearable style="width: 100%">
|
||||
<el-option v-for="major in searchMajorOptions" :key="major.value" :label="major.label" :value="major.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="联系电话" prop="phone1">
|
||||
<el-input v-model="queryParams.phone1" placeholder="请输入联系电话" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="中考地区" prop="examRegion">
|
||||
<el-input v-model="queryParams.examRegion" placeholder="请输入中考地区" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<!-- 第三行:1个条件 + 操作按钮 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item label="报名状态" prop="enrollmentStatus">
|
||||
<el-select v-model="queryParams.enrollmentStatus" placeholder="请选择报名状态" clearable class="w-100">
|
||||
<el-option :value="ENROLLMENT_STATUS.PENDING" label="待审核" />
|
||||
<el-option :value="ENROLLMENT_STATUS.AUDITING" label="信息审核中" />
|
||||
<el-option :value="ENROLLMENT_STATUS.PROCESSING" label="录取处理中" />
|
||||
<el-option :value="ENROLLMENT_STATUS.CONFIRMING" label="待最终确认" />
|
||||
<el-option :value="ENROLLMENT_STATUS.COMPLETED" label="录取完成" />
|
||||
<el-option :value="ENROLLMENT_STATUS.REJECTED" label="已驳回" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="18" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
<!-- 第三行:1个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="报名状态" prop="enrollmentStatus">
|
||||
<el-select v-model="queryParams.enrollmentStatus" placeholder="请选择报名状态" clearable style="width: 100%">
|
||||
<el-option :value="ENROLLMENT_STATUS.PENDING" label="待审核" />
|
||||
<el-option :value="ENROLLMENT_STATUS.AUDITING" label="信息审核中" />
|
||||
<el-option :value="ENROLLMENT_STATUS.PROCESSING" label="录取处理中" />
|
||||
<el-option :value="ENROLLMENT_STATUS.CONFIRMING" label="待最终确认" />
|
||||
<el-option :value="ENROLLMENT_STATUS.COMPLETED" label="录取完成" />
|
||||
<el-option :value="ENROLLMENT_STATUS.REJECTED" label="已驳回" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮行 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<el-card class="button-card">
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<div class="card-header-vertical">
|
||||
<span class="toolbar-title">招生信息管理</span>
|
||||
<div class="search-toggle">
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:enrollment:info:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['zsjy:enrollment:info:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['zsjy:enrollment:info:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:enrollment:info:export']">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Check" :disabled="multiple" @click="handleBatchAudit()" v-hasPermi="['zsjy:enrollment:info:edit']">批量审核</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
<div class="button-group">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:enrollment:info:add']">新增</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['zsjy:enrollment:info:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['zsjy:enrollment:info:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:enrollment:info:export']">导出</el-button>
|
||||
<el-button type="success" plain icon="Check" :disabled="multiple" @click="handleBatchAudit()" v-hasPermi="['zsjy:enrollment:info:edit']"
|
||||
>批量审核</el-button
|
||||
>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<el-card class="table-card">
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" :data="enrollmentInfoList" class="scroll-table" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="主键ID" align="center" prop="id" v-if="false" />
|
||||
<el-table-column label="姓名" align="center" prop="name" :show-overflow-tooltip="true" />
|
||||
<el-table
|
||||
ref="enrollmentTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="enrollmentInfoList"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="姓名" align="center" prop="name" :show-overflow-tooltip="true" min-width="100" />
|
||||
<el-table-column label="身份证号" align="center" prop="idCard" :show-overflow-tooltip="true" width="180" />
|
||||
<el-table-column label="性别" align="center" prop="gender">
|
||||
<el-table-column label="性别" align="center" prop="gender" width="80">
|
||||
<template #default="scope">
|
||||
<!-- 直接显示性别文字 -->
|
||||
<span class="gender-text-direct">
|
||||
{{ scope.row.gender === 'M' ? '男' : scope.row.gender === 'F' ? '女' : getGenderDisplay(scope.row.gender, scope.row.idCard) }}
|
||||
</span>
|
||||
@@ -128,7 +136,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="联系电话" align="center" prop="phone1" :show-overflow-tooltip="true" width="130" />
|
||||
<el-table-column label="准考证号" align="center" prop="examNumber" :show-overflow-tooltip="true" width="130" />
|
||||
<el-table-column label="中考地区" align="center" prop="examRegion" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="中考地区" align="center" prop="examRegion" :show-overflow-tooltip="true" min-width="120" />
|
||||
<el-table-column label="中考成绩" align="center" prop="totalScore" width="100" />
|
||||
<el-table-column label="报考专业" align="center" prop="appliedMajor" :show-overflow-tooltip="true" width="120" />
|
||||
<el-table-column label="所属学院" align="center" prop="collegeName" :show-overflow-tooltip="true" width="120" />
|
||||
@@ -142,39 +150,31 @@
|
||||
<span>{{ parseTime(scope.row.applicationTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="220" fixed="right">
|
||||
<el-table-column label="操作" align="center" width="280" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<div class="action-buttons">
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['zsjy:enrollment:info:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:enrollment:info:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="审核" placement="top">
|
||||
<el-button link type="success" icon="Check" @click="handleAudit(scope.row)" v-hasPermi="['zsjy:enrollment:info:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['zsjy:enrollment:info:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button link type="info" icon="View" @click="handleView(scope.row)" v-hasPermi="['zsjy:enrollment:info:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:enrollment:info:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="审核" placement="top">
|
||||
<el-button link type="success" icon="Check" @click="handleAudit(scope.row)" v-hasPermi="['zsjy:enrollment:info:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:enrollment:info:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改招生报名信息对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="1000px" append-to-body>
|
||||
<el-form ref="enrollmentInfoFormRef" :model="form" :rules="rules" label-width="120px">
|
||||
@@ -892,6 +892,7 @@ const handleBatchCurrentChange = (val: number) => {
|
||||
|
||||
const queryFormRef = ref<FormInstance>();
|
||||
const enrollmentInfoFormRef = ref<FormInstance>();
|
||||
const enrollmentTableRef = ref();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
@@ -1594,6 +1595,33 @@ const handleExport = () => {
|
||||
);
|
||||
};
|
||||
|
||||
/** 批量更新按钮操作 */
|
||||
const handleBatchUpdate = async () => {
|
||||
if (ids.value.length === 0) {
|
||||
proxy?.$modal.msgError('请选择要修改的招生报名信息');
|
||||
return;
|
||||
}
|
||||
if (ids.value.length > 1) {
|
||||
proxy?.$modal.msgError('批量修改功能暂不支持,请选择单条记录进行修改');
|
||||
return;
|
||||
}
|
||||
// 如果只选择了一条记录,调用单个修改方法
|
||||
const row = enrollmentInfoList.value.find(item => item.id === ids.value[0]);
|
||||
if (row) {
|
||||
handleUpdate(row);
|
||||
}
|
||||
};
|
||||
|
||||
/** 批量删除按钮操作 */
|
||||
const handleBatchDelete = async () => {
|
||||
if (ids.value.length === 0) {
|
||||
proxy?.$modal.msgError('请选择要删除的招生报名信息');
|
||||
return;
|
||||
}
|
||||
// 调用现有的删除方法,它已经支持批量删除
|
||||
handleDelete();
|
||||
};
|
||||
|
||||
/** 批量审核按钮操作 */
|
||||
const handleBatchAudit = async () => {
|
||||
if (ids.value.length === 0) {
|
||||
@@ -1920,77 +1948,157 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 20px;
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.search-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.search-btn-container {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header-vertical {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.search-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
text-align: right;
|
||||
padding-top: 20px;
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dialog-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表单区域样式 */
|
||||
.form-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
@@ -2004,6 +2112,7 @@ onMounted(() => {
|
||||
border-bottom: 2px solid #409eff;
|
||||
}
|
||||
|
||||
/* 查看文本样式 */
|
||||
.view-text {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
@@ -2015,16 +2124,43 @@ onMounted(() => {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100% !important;
|
||||
/* 性别文本样式 */
|
||||
.gender-text-direct {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
/* 住宿文本样式 */
|
||||
.boarding-text {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/* 学院和专业名称样式 */
|
||||
.college-name {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.college-code {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.major-name {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.major-code {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
/* 学生信息区域样式 */
|
||||
.student-info-section {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
@@ -2041,6 +2177,7 @@ onMounted(() => {
|
||||
border-bottom: 2px solid #409eff;
|
||||
}
|
||||
|
||||
/* 批量审核相关样式 */
|
||||
.batch-audit-info {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
@@ -2069,6 +2206,17 @@ onMounted(() => {
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 其他辅助样式 */
|
||||
.w-100 {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.selected-gender {
|
||||
margin-top: 5px;
|
||||
font-size: 12px;
|
||||
@@ -2095,37 +2243,4 @@ onMounted(() => {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.gender-text-direct {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.boarding-text {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.college-name {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.college-code {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.major-name {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.major-code {
|
||||
font-size: 14px;
|
||||
color: #303133;
|
||||
}
|
||||
</style>
|
||||
@@ -504,4 +504,13 @@ onMounted(() => {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -65,13 +65,7 @@
|
||||
|
||||
<!-- 第三行:搜索条件 + 操作按钮 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="审核状态" prop="auditStatus">
|
||||
<el-select v-model="queryParams.auditStatus" placeholder="请选择审核状态" clearable style="width: 100%">
|
||||
<el-option v-for="dict in zsjy_graduate_audit_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- 审核状态搜索条件已隐藏 -->
|
||||
<el-col :span="6">
|
||||
<el-form-item label="手机号码" prop="phoneNumber">
|
||||
<el-input v-model="queryParams.phoneNumber" placeholder="请输入手机号码" clearable @keyup.enter="handleQuery" />
|
||||
@@ -184,19 +178,7 @@
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-card shadow="hover" class="stat-card stat-card-warning">
|
||||
<div class="stat-content">
|
||||
<div class="stat-icon">
|
||||
<el-icon><DocumentChecked /></el-icon>
|
||||
</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ pendingAuditCount || 0 }}</div>
|
||||
<div class="stat-label">待审核</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<!-- 待审核统计卡片已隐藏 -->
|
||||
<el-col :span="3">
|
||||
<el-card shadow="hover" class="stat-card stat-card-primary" @click="handleStatistics">
|
||||
<div class="stat-content">
|
||||
@@ -229,12 +211,7 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExport" v-hasPermi="['zsjy:graduate:export']">导出</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Check" :disabled="multiple" @click="handleBatchAudit('1')" v-hasPermi="['zsjy:graduate:audit']">批量通过</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Close" :disabled="multiple" @click="handleBatchAudit('2')" v-hasPermi="['zsjy:graduate:audit']">批量拒绝</el-button>
|
||||
</el-col>
|
||||
<!-- 批量审核按钮已隐藏 -->
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
@@ -274,19 +251,8 @@
|
||||
<el-table-column label="工作地点" align="center" prop="workLocation" width="140" show-overflow-tooltip />
|
||||
<el-table-column label="薪资范围" align="center" prop="salaryRangeName" width="120" />
|
||||
<el-table-column label="升学院校" align="center" prop="furtherSchool" width="160" show-overflow-tooltip />
|
||||
<el-table-column label="审核状态" align="center" prop="auditStatus" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getAuditStatusTagType(scope.row.auditStatus)" size="small">
|
||||
{{ scope.row.auditStatusName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核时间" align="center" prop="auditTime" width="160">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.auditTime">{{ proxy.parseTime(scope.row.auditTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 审核状态列已隐藏 -->
|
||||
<!-- 审核时间列已隐藏 -->
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160">
|
||||
<template #default="scope">
|
||||
<span>{{ proxy.parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
@@ -300,9 +266,7 @@
|
||||
<el-tooltip content="编辑" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:graduate:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="审核" placement="top" v-if="scope.row.auditStatus === '0'">
|
||||
<el-button link type="success" icon="Check" @click="handleAudit(scope.row)" v-hasPermi="['zsjy:graduate:audit']"></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 审核按钮已隐藏 -->
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:graduate:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
@@ -483,39 +447,20 @@
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 审核信息 -->
|
||||
<el-card class="detail-card" shadow="never">
|
||||
<!-- 审核信息已隐藏 -->
|
||||
<!-- 备注信息 -->
|
||||
<el-card class="detail-card" shadow="never" v-if="detailData.remark">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<el-icon><DocumentChecked /></el-icon>
|
||||
<span>审核信息</span>
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>备注信息</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="detail-grid">
|
||||
<div class="detail-item">
|
||||
<label>审核状态:</label>
|
||||
<div class="detail-value">
|
||||
<el-tag :type="getAuditStatusTagType(detailData.auditStatus)" size="small">
|
||||
{{ detailData.auditStatusName }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>审核人:</label>
|
||||
<div class="detail-value">{{ detailData.auditByName || '-' }}</div>
|
||||
</div>
|
||||
<div class="detail-item">
|
||||
<label>审核时间:</label>
|
||||
<div class="detail-value">{{ detailData.auditTime ? proxy.parseTime(detailData.auditTime, '{y}-{m}-{d} {h}:{i}:{s}') : '-' }}</div>
|
||||
</div>
|
||||
<div class="detail-item full-width">
|
||||
<label>审核意见:</label>
|
||||
<div class="detail-value description">{{ detailData.auditRemark || '-' }}</div>
|
||||
</div>
|
||||
<div class="detail-item full-width">
|
||||
<label>备注信息:</label>
|
||||
<label>备注:</label>
|
||||
<div class="detail-value description">{{ detailData.remark || '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -523,26 +468,7 @@
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 审核弹窗 -->
|
||||
<el-dialog title="审核毕业生信息" v-model="auditVisible" width="500px" :before-close="closeAudit">
|
||||
<el-form ref="auditFormRef" :model="auditForm" label-width="100px">
|
||||
<el-form-item label="审核状态" prop="auditStatus" required>
|
||||
<el-radio-group v-model="auditForm.auditStatus">
|
||||
<el-radio value="1">通过</el-radio>
|
||||
<el-radio value="2">拒绝</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="审核意见" prop="auditRemark">
|
||||
<el-input v-model="auditForm.auditRemark" type="textarea" :rows="4" placeholder="请输入审核意见(选填)" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeAudit">取消</el-button>
|
||||
<el-button type="primary" @click="submitAudit">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!-- 审核弹窗已隐藏 -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -553,18 +479,17 @@ import {
|
||||
getGraduateInfo,
|
||||
delGraduateInfo,
|
||||
exportGraduateInfo,
|
||||
auditGraduateInfo,
|
||||
batchAuditGraduateInfo,
|
||||
getOverallStatistics,
|
||||
getPendingAuditCount
|
||||
getOverallStatistics
|
||||
} from '@/api/zsjy/graduateInfo';
|
||||
import { GraduateInfoVO, GraduateInfoQuery, GraduateStatisticsVO } from '@/api/zsjy/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const { sys_user_sex, zsjy_graduate_employment_status, zsjy_graduate_audit_status } = proxy.useDict(
|
||||
const { sys_user_sex, zsjy_education_level, zsjy_graduate_employment_status, zsjy_graduate_company_type, zsjy_graduate_salary_range } = proxy.useDict(
|
||||
'sys_user_sex',
|
||||
'zsjy_education_level',
|
||||
'zsjy_graduate_employment_status',
|
||||
'zsjy_graduate_audit_status'
|
||||
'zsjy_graduate_company_type',
|
||||
'zsjy_graduate_salary_range'
|
||||
);
|
||||
|
||||
// 响应式数据
|
||||
@@ -576,15 +501,8 @@ const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const statistics = ref<GraduateStatisticsVO>({});
|
||||
const pendingAuditCount = ref(0);
|
||||
const detailVisible = ref(false);
|
||||
const detailData = ref<GraduateInfoVO>();
|
||||
const auditVisible = ref(false);
|
||||
const auditForm = reactive({
|
||||
id: '',
|
||||
auditStatus: '1',
|
||||
auditRemark: ''
|
||||
});
|
||||
const daterangeCreateTime = ref<[string, string]>(['', '']);
|
||||
|
||||
// 查询参数
|
||||
@@ -599,7 +517,6 @@ const queryParams = reactive<GraduateInfoQuery>({
|
||||
collegeName: '',
|
||||
majorName: '',
|
||||
employmentStatus: '',
|
||||
auditStatus: '',
|
||||
phoneNumber: '',
|
||||
params: {}
|
||||
});
|
||||
@@ -616,26 +533,46 @@ const getList = async () => {
|
||||
|
||||
try {
|
||||
const response = await listGraduateInfo(queryParams);
|
||||
console.log('API响应完整结构:', response); // 调试日志
|
||||
console.log('响应类型:', typeof response); // 调试日志
|
||||
|
||||
// 检查响应数据格式并设置列表数据
|
||||
if (response && response.rows !== undefined) {
|
||||
// 处理 TableDataInfo 格式的数据 (直接从response获取)
|
||||
graduateInfoList.value = response.rows || [];
|
||||
total.value = response.total || 0;
|
||||
} else if (response && response.data && response.data.rows !== undefined) {
|
||||
// 处理嵌套在data中的 TableDataInfo 格式
|
||||
graduateInfoList.value = response.data.rows || [];
|
||||
total.value = response.data.total || 0;
|
||||
} else if (response && Array.isArray(response)) {
|
||||
// 处理直接返回的数组格式
|
||||
graduateInfoList.value = response;
|
||||
total.value = response.length;
|
||||
} else if (response && response.data && Array.isArray(response.data)) {
|
||||
// 处理嵌套的数组格式
|
||||
graduateInfoList.value = response.data;
|
||||
total.value = response.data.length;
|
||||
// 根据request.ts的响应拦截器,response直接是TableDataInfo格式
|
||||
if (response && typeof response === 'object') {
|
||||
// 使用类型断言处理不同的响应格式
|
||||
const responseData = response as any;
|
||||
|
||||
// 检查是否是TableDataInfo格式(直接有rows和total)
|
||||
if (responseData.rows !== undefined) {
|
||||
console.log('响应数据是TableDataInfo格式');
|
||||
graduateInfoList.value = responseData.rows || [];
|
||||
total.value = responseData.total || 0;
|
||||
}
|
||||
// 如果是R<TableDataInfo>格式(有data字段)
|
||||
else if (responseData.data && responseData.data.rows !== undefined) {
|
||||
console.log('响应数据是R<TableDataInfo>格式');
|
||||
graduateInfoList.value = responseData.data.rows || [];
|
||||
total.value = responseData.data.total || 0;
|
||||
}
|
||||
// 如果直接是数组
|
||||
else if (Array.isArray(responseData)) {
|
||||
console.log('响应数据是直接数组格式');
|
||||
graduateInfoList.value = responseData;
|
||||
total.value = responseData.length;
|
||||
}
|
||||
// 其他格式
|
||||
else {
|
||||
console.error('未知的响应数据格式:', responseData);
|
||||
console.error('响应对象的属性:', Object.keys(responseData)); // 调试日志
|
||||
graduateInfoList.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
console.log('设置列表数据:', graduateInfoList.value.length, '条记录'); // 调试日志
|
||||
if (graduateInfoList.value.length > 0) {
|
||||
console.log('第一条数据示例:', graduateInfoList.value[0]);
|
||||
console.log('第一条数据的employmentCompany:', graduateInfoList.value[0]?.employmentCompany);
|
||||
}
|
||||
} else {
|
||||
console.error('未知的响应数据格式:', response);
|
||||
console.error('响应数据格式异常:', response);
|
||||
graduateInfoList.value = [];
|
||||
total.value = 0;
|
||||
}
|
||||
@@ -652,11 +589,31 @@ const getList = async () => {
|
||||
/** 获取统计数据 */
|
||||
const getStatistics = async () => {
|
||||
try {
|
||||
const [statsResponse, pendingResponse] = await Promise.all([getOverallStatistics(), getPendingAuditCount()]);
|
||||
statistics.value = statsResponse.data;
|
||||
pendingAuditCount.value = pendingResponse.data;
|
||||
const statsResponse = await getOverallStatistics();
|
||||
console.log('统计数据响应:', statsResponse); // 调试日志
|
||||
|
||||
// 根据后端Controller,统计接口返回R<GraduateStatisticsVO>格式
|
||||
if (statsResponse && typeof statsResponse === 'object') {
|
||||
// 使用类型断言处理响应格式
|
||||
const statsData = statsResponse as any;
|
||||
|
||||
// 如果响应有data字段(R格式)
|
||||
if (statsData.data !== undefined) {
|
||||
console.log('统计数据是R格式');
|
||||
statistics.value = statsData.data || {};
|
||||
}
|
||||
// 如果响应直接是统计对象
|
||||
else {
|
||||
console.log('统计数据是直接对象格式');
|
||||
statistics.value = statsData;
|
||||
}
|
||||
} else {
|
||||
statistics.value = {};
|
||||
}
|
||||
console.log('设置统计数据:', statistics.value); // 调试日志
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error);
|
||||
statistics.value = {};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -709,53 +666,7 @@ const closeDetail = () => {
|
||||
detailData.value = undefined;
|
||||
};
|
||||
|
||||
/** 审核按钮操作 */
|
||||
const handleAudit = (row: GraduateInfoVO) => {
|
||||
auditForm.id = row.id as string;
|
||||
auditForm.auditStatus = '1';
|
||||
auditForm.auditRemark = '';
|
||||
auditVisible.value = true;
|
||||
};
|
||||
|
||||
/** 提交审核 */
|
||||
const submitAudit = async () => {
|
||||
try {
|
||||
await auditGraduateInfo(auditForm.id, auditForm.auditStatus, auditForm.auditRemark);
|
||||
proxy.$modal.msgSuccess('审核成功');
|
||||
closeAudit();
|
||||
getList();
|
||||
getStatistics();
|
||||
} catch (error) {
|
||||
proxy.$modal.msgError('审核失败');
|
||||
}
|
||||
};
|
||||
|
||||
/** 关闭审核弹窗 */
|
||||
const closeAudit = () => {
|
||||
auditVisible.value = false;
|
||||
auditForm.id = '';
|
||||
auditForm.auditStatus = '1';
|
||||
auditForm.auditRemark = '';
|
||||
};
|
||||
|
||||
/** 批量审核操作 */
|
||||
const handleBatchAudit = async (auditStatus: string) => {
|
||||
if (ids.value.length === 0) {
|
||||
proxy.$modal.msgWarning('请选择要审核的数据');
|
||||
return;
|
||||
}
|
||||
|
||||
const statusText = auditStatus === '1' ? '通过' : '拒绝';
|
||||
try {
|
||||
await proxy.$modal.confirm(`确认要批量${statusText}选中的毕业生信息吗?`);
|
||||
await batchAuditGraduateInfo(ids.value, auditStatus);
|
||||
proxy.$modal.msgSuccess(`批量${statusText}成功`);
|
||||
getList();
|
||||
getStatistics();
|
||||
} catch (error) {
|
||||
// 用户取消操作
|
||||
}
|
||||
};
|
||||
/** 审核相关功能已隐藏 */
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: GraduateInfoVO) => {
|
||||
@@ -809,19 +720,7 @@ const getEmploymentStatusTagType = (status: string) => {
|
||||
}
|
||||
};
|
||||
|
||||
/** 获取审核状态标签类型 */
|
||||
const getAuditStatusTagType = (status: string) => {
|
||||
switch (status) {
|
||||
case '0':
|
||||
return 'warning';
|
||||
case '1':
|
||||
return 'success';
|
||||
case '2':
|
||||
return 'danger';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
/** 审核状态标签类型函数已移除 */
|
||||
|
||||
// 页面初始化
|
||||
onMounted(() => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<div class="page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
@@ -34,7 +34,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:日期筛选 + 操作按钮 -->
|
||||
<!-- 第二行:日期筛选 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="签到日期">
|
||||
@@ -50,8 +50,12 @@
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" class="search-btn-container">
|
||||
<el-form-item>
|
||||
</el-row>
|
||||
|
||||
<!-- 第三行:搜索按钮 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
@@ -120,35 +124,38 @@
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<!-- 操作工具栏 -->
|
||||
<el-card shadow="never" class="button-card">
|
||||
<div class="card-header-vertical">
|
||||
<div class="toolbar-title">实习日常管理</div>
|
||||
<div class="button-group">
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:internshipdaily:add']">新增签到</el-button>
|
||||
<el-button plain icon="Search" @click="showSearch = !showSearch">搜索</el-button>
|
||||
<el-button type="primary" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:internshipdaily:export']">导出</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:internshipdaily:add']">新增签到</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:internshipdaily:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-card shadow="never" class="table-card">
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="internshipDailyTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="internshipDailyList"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
|
||||
<el-table-column label="学生信息" min-width="180" align="left">
|
||||
<template #default="scope">
|
||||
<div class=":liststudent-info">
|
||||
<div class="student-info">
|
||||
<div class="student-name">{{ scope.row.studentName }}</div>
|
||||
<div class="student-number">学号:{{ scope.row.studentNumber }}</div>
|
||||
<!-- <div class="student-class">班级:{{ scope.row.className }}</div> -->
|
||||
@@ -176,27 +183,35 @@
|
||||
|
||||
<el-table-column label="签到地点" prop="checkInLocation" min-width="150" align="left" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="操作" width="120" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" width="160" align="center" class-name="small-padding fixed-width" fixed="right">
|
||||
<template #default="scope">
|
||||
<div class="action-buttons">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="查看日历" placement="top">
|
||||
<el-button link type="success" icon="Calendar" @click="handleCalendar(scope.row)" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
icon="View"
|
||||
@click="handleView(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="查看日历" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="Calendar"
|
||||
@click="handleCalendar(scope.row)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog title="考勤详情" v-model="viewDialogVisible" width="600px" append-to-body>
|
||||
<div v-if="currentRecord" class="detail-container">
|
||||
@@ -615,47 +630,114 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 继承后勤管理的样式
|
||||
/* 页面容器 */
|
||||
.page-container {
|
||||
.search-btn-container {
|
||||
text-align: right;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.button-card {
|
||||
margin-bottom: 20px;
|
||||
/* 表格卡片 */
|
||||
.button-card {
|
||||
:deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
padding: 18px 20px 0 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header-vertical {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
/* 表格容器和滚动样式 */
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
|
||||
.scroll-table {
|
||||
min-width: 100%;
|
||||
|
||||
/* 滚动条样式 */
|
||||
:deep(.el-table__body-wrapper) {
|
||||
&::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: #c1c1c1;
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: #a8a8a8;
|
||||
}
|
||||
}
|
||||
|
||||
/* Firefox 滚动条 */
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #c1c1c1 #f1f1f1;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
/* 固定列阴影效果 */
|
||||
:deep(.el-table__fixed) {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: -1px;
|
||||
width: 30px;
|
||||
pointer-events: none;
|
||||
transition: box-shadow 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
:deep(.el-table__fixed-right) {
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: -1px;
|
||||
width: 30px;
|
||||
pointer-events: none;
|
||||
transition: box-shadow 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格行悬停效果 */
|
||||
:deep(.el-table__row) {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
|
||||
.el-table__fixed .el-table__cell {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.el-table__fixed-right .el-table__cell {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.table-card {
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
}
|
||||
/* 分页容器 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
@@ -721,27 +803,6 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 表格样式 */
|
||||
.scroll-table {
|
||||
:deep(.el-table__header-wrapper) {
|
||||
.el-table__header {
|
||||
th {
|
||||
background-color: #f8f9fa;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper) {
|
||||
.el-table__row {
|
||||
&:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 学生信息样式 */
|
||||
.student-info {
|
||||
.student-name {
|
||||
@@ -772,14 +833,6 @@ onMounted(() => {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer-right {
|
||||
display: flex;
|
||||
@@ -831,15 +884,28 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮栏样式 */
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.stat-card {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,9 +1,11 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<div class="page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="120px">
|
||||
<!-- 第一行:4个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学生姓名" prop="studentName">
|
||||
@@ -30,13 +32,14 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 第二行:2个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="实习公司" prop="companyName">
|
||||
<el-input v-model="queryParams.companyName" placeholder="请输入实习公司名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="实习开始时间">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
@@ -50,10 +53,10 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<!-- 搜索按钮行 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
@@ -115,82 +118,95 @@
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExport" v-hasPermi="['zsjy:internship:export']">导出</el-button>
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:internship:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" border :data="internshipList" @row-dblclick="handleView">
|
||||
<el-table-column label="学号" align="center" prop="studentNo" width="120" />
|
||||
<el-table-column label="姓名" align="center" prop="studentName" width="100" />
|
||||
<el-table-column label="性别" align="center" prop="gender" width="80">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_user_sex" :value="scope.row.gender" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="班级" align="center" prop="className" width="180" />
|
||||
<el-table-column label="班主任" align="center" prop="classTeacherName" width="100" />
|
||||
<el-table-column label="实习状态" align="center" prop="internshipStatus" width="100">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.internshipStatus === 'null' || !scope.row.internshipStatus" class="status-tag not-started">未实习</span>
|
||||
<dict-tag v-else :options="internship_status" :value="scope.row.internshipStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实习公司" align="center" prop="companyName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="实习岗位" align="center" prop="internshipPosition" width="120" show-overflow-tooltip />
|
||||
<el-table-column label="实习开始时间" align="center" prop="internshipStartDate" width="120">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.internshipStartDate">{{ parseTime(scope.row.internshipStartDate, '{y}-{m}-{d}') }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实习地点" align="center" prop="companyAddress" width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="View"
|
||||
size="default"
|
||||
@click="handleView(scope.row)"
|
||||
v-hasPermi="['zsjy:internship:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="新增实习信息" placement="top" v-if="!scope.row.internshipId">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="Plus"
|
||||
size="default"
|
||||
@click="handleAdd(scope.row)"
|
||||
v-hasPermi="['zsjy:internship:add']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="编辑实习信息" placement="top" v-if="scope.row.internshipId">
|
||||
<el-button
|
||||
link
|
||||
type="warning"
|
||||
icon="Edit"
|
||||
size="default"
|
||||
@click="handleEdit(scope.row)"
|
||||
v-hasPermi="['zsjy:internship:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="internshipTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="internshipList"
|
||||
row-key="studentId"
|
||||
class="scroll-table"
|
||||
@row-dblclick="handleView"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="学号" align="center" prop="studentNo" width="120" />
|
||||
<el-table-column label="姓名" align="center" prop="studentName" width="100" />
|
||||
<el-table-column label="性别" align="center" prop="gender" width="80">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="sys_user_sex" :value="scope.row.gender" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="班级" align="center" prop="className" width="180" />
|
||||
<el-table-column label="班主任" align="center" prop="classTeacherName" width="100" />
|
||||
<el-table-column label="实习状态" align="center" prop="internshipStatus" width="100">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.internshipStatus === 'null' || !scope.row.internshipStatus" class="status-tag not-started">未实习</span>
|
||||
<dict-tag v-else :options="internship_status" :value="scope.row.internshipStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实习公司" align="center" prop="companyName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="实习岗位" align="center" prop="internshipPosition" width="120" show-overflow-tooltip />
|
||||
<el-table-column label="实习开始时间" align="center" prop="internshipStartDate" width="120">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.internshipStartDate">{{ parseTime(scope.row.internshipStartDate, '{y}-{m}-{d}') }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="实习地点" align="center" prop="companyAddress" width="120" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
icon="View"
|
||||
@click="handleView(scope.row)"
|
||||
v-hasPermi="['zsjy:internship:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="新增实习信息" placement="top" v-if="!scope.row.internshipId">
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
icon="Plus"
|
||||
@click="handleAdd(scope.row)"
|
||||
v-hasPermi="['zsjy:internship:add']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="编辑实习信息" placement="top" v-if="scope.row.internshipId">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleEdit(scope.row)"
|
||||
v-hasPermi="['zsjy:internship:edit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 学生实习详情对话框 -->
|
||||
<el-dialog title="学生实习详情" v-model="dialog.visible" width="900px" append-to-body>
|
||||
<div v-if="studentDetail" class="student-detail">
|
||||
@@ -460,110 +476,234 @@ const cancel = () => {
|
||||
})();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
<style scoped>
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
.search-btn-container {
|
||||
text-align: right;
|
||||
margin-top: 10px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dialog-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.statistics-row {
|
||||
.statistics-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
color: white;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100px; /* 设置固定高度,确保所有卡片高度一致 */
|
||||
|
||||
.statistics-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center; /* 内容垂直居中 */
|
||||
|
||||
.statistics-number {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.statistics-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.statistics-rate {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.statistics-description {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.statistics-icon {
|
||||
font-size: 40px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&.total-students {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
&.not-internship {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
}
|
||||
|
||||
&.internshiping {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
}
|
||||
|
||||
&.completed {
|
||||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.button-card {
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.table-card {
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.student-detail {
|
||||
.mt-4 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
.form-tip {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
&.not-started {
|
||||
background-color: #f56c6c;
|
||||
color: white;
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.statistics-row {
|
||||
.statistics-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
color: white;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100px; /* 设置固定高度,确保所有卡片高度一致 */
|
||||
|
||||
.statistics-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center; /* 内容垂直居中 */
|
||||
|
||||
.statistics-number {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.statistics-label {
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.statistics-description {
|
||||
font-size: 12px;
|
||||
opacity: 0.8;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.statistics-icon {
|
||||
font-size: 40px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&.total-students {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
}
|
||||
|
||||
&.not-internship {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
}
|
||||
|
||||
&.internshiping {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
}
|
||||
|
||||
&.completed {
|
||||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 状态标签样式 */
|
||||
.status-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
|
||||
&.not-started {
|
||||
background-color: #f56c6c;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
/* 按钮栏样式 */
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -34,8 +34,10 @@
|
||||
<el-input-number v-model="queryParams.professionalSkills" :min="1" :max="10" placeholder="请输入专业技能评分" style="width: 100%" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item>
|
||||
</el-row>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
@@ -46,95 +48,119 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
<el-card shadow="never">
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:internshipmonthly:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['zsjy:internshipmonthly:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate()"
|
||||
v-hasPermi="['zsjy:internshipmonthly:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['zsjy:internshipmonthly:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete()"
|
||||
v-hasPermi="['zsjy:internshipmonthly:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:internshipmonthly:export']">导出</el-button>
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['zsjy:internshipmonthly:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table v-loading="loading" :data="monthlyList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="总结月份" align="center" prop="summaryMonth" width="120" />
|
||||
<el-table-column label="工作内容" align="center" prop="workContent" :show-overflow-tooltip="true" min-width="200" />
|
||||
<el-table-column label="综合评分" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="专业/沟通/团队/学习/态度" placement="top">
|
||||
<el-tag :type="getScoreTagType(getAverageScore(scope.row))"> {{ getAverageScore(scope.row).toFixed(1) }}分 </el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="字数统计" align="center" width="100">
|
||||
<template #default="scope"> {{ scope.row.wordCount || 0 }}字 </template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" align="center" prop="reviewStatus" width="100">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="internship_monthly_status" :value="scope.row.reviewStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否逾期" align="center" prop="isOverdue" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.isOverdue === 1" type="danger">逾期</el-tag>
|
||||
<el-tag v-else type="success">正常</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交时间" align="center" prop="submitTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.submitTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="200" fixed="right">
|
||||
<template #default="scope">
|
||||
<!-- 查看详情 -->
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['zsjy:internshipmonthly:list']"></el-button>
|
||||
</el-tooltip>
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="monthlyTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="monthlyList"
|
||||
row-key="id"
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="总结月份" prop="summaryMonth" width="120" align="center" />
|
||||
<el-table-column label="工作内容" prop="workContent" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="综合评分" width="120" align="center">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="专业/沟通/团队/学习/态度" placement="top">
|
||||
<el-tag :type="getScoreTagType(getAverageScore(scope.row))"> {{ getAverageScore(scope.row).toFixed(1) }}分 </el-tag>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="字数统计" width="100" align="center">
|
||||
<template #default="scope"> {{ scope.row.wordCount || 0 }}字 </template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审核状态" prop="reviewStatus" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="internship_monthly_status" :value="scope.row.reviewStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否逾期" prop="isOverdue" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.isOverdue === 1" type="danger">逾期</el-tag>
|
||||
<el-tag v-else type="success">正常</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="提交时间" prop="submitTime" width="180" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.submitTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" prop="createTime" width="180" align="center">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="280" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button link type="info" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['zsjy:internshipmonthly:list']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top" v-if="scope.row.reviewStatus === 3">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:internshipmonthly:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="提交" placement="top" v-if="scope.row.reviewStatus === 3">
|
||||
<el-button link type="success" icon="Check" @click="handleSubmit(scope.row)" v-hasPermi="['zsjy:internshipmonthly:submit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top" v-if="scope.row.reviewStatus === 3">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:internshipmonthly:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 编辑(只有草稿状态才能编辑) -->
|
||||
<el-tooltip content="编辑" placement="top" v-if="scope.row.reviewStatus === 3">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:internshipmonthly:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<!-- 提交(只有草稿状态才能提交) -->
|
||||
<el-tooltip content="提交" placement="top" v-if="scope.row.reviewStatus === 3">
|
||||
<el-button link type="success" icon="Check" @click="handleSubmit(scope.row)" v-hasPermi="['zsjy:internshipmonthly:submit']"></el-button>
|
||||
</el-tooltip>
|
||||
|
||||
<!-- 删除(只有草稿状态才能删除) -->
|
||||
<el-tooltip content="删除" placement="top" v-if="scope.row.reviewStatus === 3">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:internshipmonthly:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</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>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 添加或修改月度总结对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="1000px" append-to-body>
|
||||
<MonthlyForm ref="monthlyFormRef" @success="getList" />
|
||||
@@ -148,6 +174,9 @@
|
||||
</template>
|
||||
|
||||
<script setup name="InternshipMonthly" lang="ts">
|
||||
import { reactive, ref, toRefs, getCurrentInstance, nextTick, onMounted, type ComponentInternalInstance } from 'vue';
|
||||
// import type { ElFormInstance, ComponentRef, DialogOption, PageData } from '@/types';
|
||||
// import { parseTime } from '@/utils/ruoyi';
|
||||
import {
|
||||
listInternshipMonthly,
|
||||
getInternshipMonthly,
|
||||
@@ -169,12 +198,12 @@ const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
const dialog = reactive({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const detailDialog = reactive<DialogOption>({
|
||||
const detailDialog = reactive({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
@@ -186,7 +215,7 @@ const initFormData: any = {
|
||||
reviewStatus: undefined,
|
||||
professionalSkills: undefined
|
||||
};
|
||||
const data = reactive<PageData<any, any>>({
|
||||
const data = reactive({
|
||||
form: {},
|
||||
queryParams: { ...initFormData },
|
||||
rules: {}
|
||||
@@ -194,9 +223,9 @@ const data = reactive<PageData<any, any>>({
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const monthlyFormRef = ref<ComponentRef<typeof MonthlyForm>>();
|
||||
const monthlyDetailRef = ref<ComponentRef<typeof MonthlyDetail>>();
|
||||
const queryFormRef = ref();
|
||||
const monthlyFormRef = ref();
|
||||
const monthlyDetailRef = ref();
|
||||
|
||||
/** 查询月度总结列表 */
|
||||
const getList = async () => {
|
||||
@@ -307,44 +336,101 @@ const getScoreTagType = (score: number) => {
|
||||
return 'danger';
|
||||
};
|
||||
|
||||
/** 时间格式化函数 */
|
||||
const parseTime = (time: any, pattern: string) => {
|
||||
if (!time) return '';
|
||||
const date = new Date(time);
|
||||
const format = {
|
||||
y: date.getFullYear(),
|
||||
m: String(date.getMonth() + 1).padStart(2, '0'),
|
||||
d: String(date.getDate()).padStart(2, '0'),
|
||||
h: String(date.getHours()).padStart(2, '0'),
|
||||
i: String(date.getMinutes()).padStart(2, '0'),
|
||||
s: String(date.getSeconds()).padStart(2, '0')
|
||||
};
|
||||
|
||||
return pattern.replace(/{([ymdhis])+}/g, (result, key) => {
|
||||
return format[key as keyof typeof format] || result;
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 操作按钮样式优化 - 参考后勤管理页面 */
|
||||
:deep(.el-table__fixed-right) {
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 20px;
|
||||
background-color: #f4f4f5;
|
||||
min-height: calc(100vh - 84px);
|
||||
}
|
||||
|
||||
/* 表格容器样式 */
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* 表格滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
:deep(.el-table__fixed-right .el-table__cell) {
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
:deep(.el-table__row:hover .el-table__cell) {
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 操作列按钮间距优化 */
|
||||
.small-padding .el-button + .el-button {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* 确保操作按钮在固定列中居中对齐 */
|
||||
.small-padding {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.small-padding .el-tooltip {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.small-padding .el-tooltip:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
@@ -353,4 +439,49 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.search-btn-container .el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dialog-form .el-form-item {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.dialog-form .form-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions .el-descriptions__label) {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
:deep(.el-descriptions .el-descriptions__content) {
|
||||
color: #303133;
|
||||
}
|
||||
</style>
|
||||
@@ -1,91 +1,25 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 统计卡片 -->
|
||||
<el-row :gutter="16" class="stats-row">
|
||||
<el-col :xl="6" :lg="12" :md="12" :sm="12" :xs="24">
|
||||
<div class="stat-card total">
|
||||
<div class="stat-icon">
|
||||
<el-icon><User /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-number">{{ statistics.total }}</div>
|
||||
<div class="stat-label">走访总数</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="6" :lg="12" :md="12" :sm="12" :xs="24">
|
||||
<div class="stat-card month">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Calendar /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-number">{{ statistics.monthCount }}</div>
|
||||
<div class="stat-label">本月走访</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="6" :lg="12" :md="12" :sm="12" :xs="24">
|
||||
<div class="stat-card completed">
|
||||
<div class="stat-icon">
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-number">{{ statistics.completedCount }}</div>
|
||||
<div class="stat-label">已完成</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xl="6" :lg="12" :md="12" :sm="12" :xs="24">
|
||||
<div class="stat-card pending">
|
||||
<div class="stat-icon">
|
||||
<el-icon><Clock /></el-icon>
|
||||
</div>
|
||||
<div class="stat-content">
|
||||
<div class="stat-number">{{ statistics.pendingCount }}</div>
|
||||
<div class="stat-label">待走访</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<!-- 搜索条件 -->
|
||||
<!-- 第一行:4个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学生信息" prop="studentName">
|
||||
<el-input
|
||||
v-model="queryParams.studentName"
|
||||
placeholder="请输入学生姓名或学号"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名或学号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="实习单位" prop="companyName">
|
||||
<el-input
|
||||
v-model="queryParams.companyName"
|
||||
placeholder="请输入实习单位名称"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.companyName" placeholder="请输入实习单位名称" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="走访人" prop="visitorName">
|
||||
<el-input
|
||||
v-model="queryParams.visitorName"
|
||||
placeholder="请输入走访人姓名"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
<el-input v-model="queryParams.visitorName" placeholder="请输入走访人姓名" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
@@ -97,30 +31,31 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 第二行:日期范围 + 操作按钮 -->
|
||||
<!-- 第二行:1个搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="走访日期" prop="visitDateRange">
|
||||
<el-form-item label="走访日期">
|
||||
<el-date-picker
|
||||
v-model="queryParams.visitDateRange"
|
||||
value-format="YYYY-MM-DD"
|
||||
type="daterange"
|
||||
range-separator="至"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
@change="handleQuery"
|
||||
style="width: 100%"
|
||||
/>
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-row>
|
||||
|
||||
<el-button type="info" plain icon="Search" @click="showSearch = !showSearch"> {{ showSearch ? '隐藏' : '显示' }}搜索 </el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<!-- 第三行:搜索按钮 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item style="margin-bottom: 0;">
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
@@ -128,37 +63,59 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 操作按钮栏 -->
|
||||
<el-card shadow="hover" class="button-card">
|
||||
<!-- 表格数据 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<div class="card-header-vertical">
|
||||
<div class="toolbar-title">班主任走访列表</div>
|
||||
<div class="button-group">
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:internshipVisit:add']">新增走访</el-button>
|
||||
<el-button type="success" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:internshipVisit:export']">导出</el-button>
|
||||
<el-button type="info" plain icon="Search" @click="showSearch = !showSearch"> {{ showSearch ? '隐藏' : '显示' }}搜索 </el-button>
|
||||
<el-tooltip content="刷新" placement="top">
|
||||
<el-button icon="Refresh" circle @click="getList" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleBatchUpdate"
|
||||
v-hasPermi="['zsjy:internshipVisit:edit']"
|
||||
>修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleBatchDelete"
|
||||
v-hasPermi="['zsjy:internshipVisit:remove']"
|
||||
>删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['zsjy:internshipVisit:export']"
|
||||
>导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-card>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-card shadow="hover" class="table-card">
|
||||
<div class="table-container">
|
||||
<el-table
|
||||
ref="visitTableRef"
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="visitList"
|
||||
row-key="visitId"
|
||||
border
|
||||
stripe
|
||||
highlight-current-row
|
||||
class="scroll-table"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||
<el-table-column label="学生信息" min-width="150" align="left">
|
||||
<template #default="scope">
|
||||
<div class="student-info">
|
||||
@@ -168,53 +125,45 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="实习单位" prop="companyName" min-width="150" align="left" show-overflow-tooltip />
|
||||
|
||||
<el-table-column label="走访人" prop="visitorName" min-width="100" align="center" />
|
||||
|
||||
<el-table-column label="走访日期" prop="visitDate" min-width="120" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.visitDate, '{y}-{m}-{d}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="走访状态" prop="status" min-width="100" align="center">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="visitStatusOptions" :value="scope.row.status || ''" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="创建时间" prop="createTime" min-width="160" align="center">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.createTime) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
|
||||
<el-table-column label="操作" width="180" align="center" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<div class="action-buttons">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['zsjy:internshipVisit:query']" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="编辑" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:internshipVisit:edit']" />
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:internshipVisit:remove']" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button link type="info" icon="View" @click="handleView(scope.row)" v-hasPermi="['zsjy:internshipVisit:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:internshipVisit:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:internshipVisit:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页组件 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" :page="queryParams.pageNum" :limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :page="queryParams.pageNum" :limit="queryParams.pageSize" :total="total" @pagination="getList" />
|
||||
</div>
|
||||
|
||||
<!-- 详情对话框 -->
|
||||
<el-dialog title="走访详情" v-model="viewDialogVisible" width="800px" append-to-body>
|
||||
<div v-if="currentRecord" class="detail-container">
|
||||
@@ -386,13 +335,7 @@ const viewDialogVisible = ref(false);
|
||||
const formDialogVisible = ref(false);
|
||||
const currentRecord = ref(null);
|
||||
|
||||
// 统计数据
|
||||
const statistics = ref({
|
||||
total: 0,
|
||||
monthCount: 0,
|
||||
completedCount: 0,
|
||||
pendingCount: 0
|
||||
});
|
||||
|
||||
|
||||
// 字典数据
|
||||
const visitStatusOptions = ref([]);
|
||||
@@ -495,8 +438,6 @@ function getList() {
|
||||
}
|
||||
|
||||
loading.value = false;
|
||||
// 计算统计数据
|
||||
calculateStatistics();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取走访记录列表失败:', error);
|
||||
@@ -508,18 +449,7 @@ function getList() {
|
||||
});
|
||||
}
|
||||
|
||||
/** 计算统计数据 */
|
||||
function calculateStatistics() {
|
||||
const now = new Date();
|
||||
const currentMonth = now.getFullYear() + '-' + String(now.getMonth() + 1).padStart(2, '0');
|
||||
|
||||
statistics.value = {
|
||||
total: visitList.value.length,
|
||||
monthCount: visitList.value.filter((item) => item.visitDate && item.visitDate.startsWith(currentMonth)).length,
|
||||
completedCount: visitList.value.filter((item) => item.status === '2').length, // 2-已审核
|
||||
pendingCount: visitList.value.filter((item) => item.status === '0').length // 0-草稿
|
||||
};
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
@@ -605,6 +535,34 @@ function submitForm() {
|
||||
});
|
||||
}
|
||||
|
||||
/** 批量修改按钮操作 */
|
||||
function handleBatchUpdate() {
|
||||
if (ids.value.length === 1) {
|
||||
// 单个修改,直接调用修改方法
|
||||
const visitId = ids.value[0];
|
||||
const row = visitList.value.find(item => item.visitId === visitId);
|
||||
if (row) {
|
||||
handleUpdate(row);
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning('请选择一条记录进行修改');
|
||||
}
|
||||
}
|
||||
|
||||
/** 批量删除按钮操作 */
|
||||
function handleBatchDelete() {
|
||||
const visitIds = ids.value;
|
||||
ElMessageBox.confirm('是否确认删除选中的' + visitIds.length + '条走访记录?')
|
||||
.then(function () {
|
||||
return delInternshipVisit(visitIds);
|
||||
})
|
||||
.then(() => {
|
||||
getList();
|
||||
ElMessage.success('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const visitIds = row.visitId || ids.value;
|
||||
@@ -819,177 +777,124 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
/* 页面容器样式 */
|
||||
.page-container {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 按钮卡片样式 */
|
||||
.button-card {
|
||||
margin-bottom: 16px;
|
||||
|
||||
|
||||
/* 表格卡片布局 */
|
||||
.table-card {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.form-item-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 1.4;
|
||||
margin-top: 4px;
|
||||
.table-card :deep(.el-card__body) {
|
||||
padding: 0px 20px 20px 20px !important;
|
||||
}
|
||||
|
||||
.card-header-vertical {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
/* 表格容器 - 支持横向滚动 */
|
||||
.table-container {
|
||||
width: 100%;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 横向滚动表格样式 */
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
/* 表格横向滚动条样式优化 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto !important; /* 自动显示横向滚动条 */
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
.scroll-table :deep(.el-table__header-wrapper) {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
margin-bottom: 16px;
|
||||
/* 强制显示表格横向滚动条 - 适用于所有浏览器 */
|
||||
.scroll-table :deep(.el-table__body-wrapper) {
|
||||
scrollbar-width: thin; /* Firefox */
|
||||
scrollbar-color: #409eff #f0f0f0; /* Firefox - thumb track */
|
||||
}
|
||||
|
||||
/* 统计卡片样式 */
|
||||
.stats-row {
|
||||
margin-bottom: 20px;
|
||||
/* Webkit 浏览器的横向滚动条样式 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar {
|
||||
height: 12px !important; /* 增加滚动条高度 */
|
||||
width: 12px !important;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
margin-bottom: 16px;
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-track {
|
||||
background: #f0f0f0 !important;
|
||||
border-radius: 6px !important;
|
||||
border: 1px solid #e4e7ed !important; /* 添加边框使其更明显 */
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb {
|
||||
background: #409eff !important; /* 使用主题色,更明显 */
|
||||
border-radius: 6px !important;
|
||||
border: 2px solid #f0f0f0 !important; /* 添加白色边框 */
|
||||
min-height: 20px !important; /* 确保最小高度 */
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 16px;
|
||||
font-size: 24px;
|
||||
color: white;
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:hover {
|
||||
background: #337ecc !important; /* 悬停时更深的蓝色 */
|
||||
}
|
||||
|
||||
.stat-card.total .stat-icon {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-thumb:active {
|
||||
background: #2b6cb0 !important; /* 点击时的颜色 */
|
||||
}
|
||||
|
||||
.stat-card.month .stat-icon {
|
||||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
/* 确保滚动条始终可见的额外设置 */
|
||||
.scroll-table :deep(.el-table__body-wrapper)::-webkit-scrollbar-corner {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.stat-card.completed .stat-icon {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
/* 固定列样式优化 */
|
||||
.scroll-table :deep(.el-table__fixed-right) {
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stat-card.pending .stat-icon {
|
||||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||||
.scroll-table :deep(.el-table__fixed-left) {
|
||||
box-shadow: 2px 0 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
flex: 1;
|
||||
/* 确保固定列在滚动时有正确的背景色 */
|
||||
.scroll-table :deep(.el-table__fixed-right .el-table__cell),
|
||||
.scroll-table :deep(.el-table__fixed-left .el-table__cell) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 主卡片样式 */
|
||||
.main-card {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.main-card .el-card__body {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
/* 搜索容器样式 */
|
||||
.search-container {
|
||||
background: #f8f9fa;
|
||||
padding: 16px;
|
||||
border-radius: 6px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* 工具栏样式 */
|
||||
.toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.toolbar-left {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.toolbar-right {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 表格容器样式 */
|
||||
.table-container {
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.el-table {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.el-table th {
|
||||
background-color: #f5f7fa;
|
||||
color: #606266;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.el-table .el-table__row:hover {
|
||||
background-color: #f5f7fa;
|
||||
/* 表格行悬停效果在固定列上的同步 */
|
||||
.scroll-table :deep(.el-table__row:hover .el-table__cell) {
|
||||
background-color: #f5f7fa !important;
|
||||
}
|
||||
|
||||
/* 分页容器样式 */
|
||||
.pagination-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20px;
|
||||
padding: 16px 0;
|
||||
justify-content: flex-end;
|
||||
padding: 16px 20px 0 0 !important;
|
||||
background-color: #fff;
|
||||
margin-top: 0px !important;
|
||||
}
|
||||
|
||||
/* 移除按钮栏底部边框 */
|
||||
.button-card :deep(.el-card__header) {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器样式 */
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* 学生信息样式 */
|
||||
@@ -1008,12 +913,12 @@ onMounted(() => {
|
||||
}
|
||||
}
|
||||
|
||||
/* 操作按钮样式 */
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
/* 表单提示样式 */
|
||||
.form-item-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
line-height: 1.4;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* 对话框样式 */
|
||||
@@ -1023,6 +928,32 @@ onMounted(() => {
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dialog-form {
|
||||
.el-form-item {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.form-tip {
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
margin-top: 4px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
}
|
||||
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
/* 详情容器样式 */
|
||||
.detail-container {
|
||||
padding: 8px 0;
|
||||
@@ -1030,21 +961,6 @@ onMounted(() => {
|
||||
|
||||
/* 响应式设计 */
|
||||
@media (max-width: 768px) {
|
||||
.stat-card {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.toolbar-left,
|
||||
.toolbar-right {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
<template>
|
||||
<div class="p-2 page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<!-- 搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="所属企业" prop="enterpriseId">
|
||||
<el-select v-model="queryParams.enterpriseId" placeholder="请选择所属企业" clearable style="width: 100%" @change="handleQuery">
|
||||
<el-select v-model="queryParams.enterpriseId" placeholder="请选择所属企业" clearable>
|
||||
<el-option v-for="item in enterpriseOptions" :key="item.id" :label="item.enterpriseName" :value="item.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -26,14 +24,46 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable style="width: 100%">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||||
<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮行 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="是否永久" prop="isPermanent">
|
||||
<el-select v-model="queryParams.isPermanent" placeholder="请选择是否永久" clearable>
|
||||
<el-option label="是" :value="1" />
|
||||
<el-option label="否" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="开始时间" prop="startDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.startDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择开始时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="结束时间" prop="endDate">
|
||||
<el-date-picker
|
||||
clearable
|
||||
v-model="queryParams.endDate"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择结束时间"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
@@ -47,39 +77,42 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 操作按钮栏 -->
|
||||
<el-card shadow="hover" class="button-card">
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<div class="card-header-vertical">
|
||||
<div class="toolbar-title">招聘岗位列表</div>
|
||||
<div class="button-group">
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:position:add']">新增</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['zsjy:position:edit']">修改</el-button>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['zsjy:position:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['zsjy:position:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['zsjy:position:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:position:export']">导出</el-button>
|
||||
<el-button type="info" plain icon="Fold" @click="toggleSearch">
|
||||
<span v-if="showSearch">隐藏</span>
|
||||
<span v-else>展开</span>
|
||||
搜索
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-card>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<el-card shadow="hover" class="table-card">
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" :data="jobPositionList" @selection-change="handleSelectionChange" class="scroll-table" stripe border>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="jobPositionList"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
class="scroll-table"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="企业名称" align="center" prop="enterpriseName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="所属企业" align="center" prop="enterpriseName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="岗位名称" align="center" prop="positionName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="工作地址" align="center" prop="workAddress" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="工作时间" align="center" prop="workTime" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="薪资" align="center" prop="salary" min-width="120" />
|
||||
<el-table-column label="有效期" align="center" min-width="180">
|
||||
<el-table-column label="工作地址" align="center" prop="workAddress" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="工作时间" align="center" prop="workTime" width="180" show-overflow-tooltip />
|
||||
<el-table-column label="薪资" align="center" prop="salary" width="150" show-overflow-tooltip />
|
||||
<el-table-column label="有效期" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.isPermanent === 1">永久有效</span>
|
||||
<span v-else>{{ scope.row.startDate }} ~ {{ scope.row.endDate }}</span>
|
||||
@@ -91,54 +124,28 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
|
||||
<el-table-column label="操作" align="center" width="280" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="View"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px; color: blue"
|
||||
@click="handleDetail(scope.row)"
|
||||
v-hasPermi="['zsjy:position:query']"
|
||||
></el-button>
|
||||
<el-button link type="info" icon="View" @click="handleDetail(scope.row)" v-hasPermi="['zsjy:position:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['zsjy:position:edit']"
|
||||
></el-button>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:position:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
size="default"
|
||||
style="font-size: 16px"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['zsjy:position:remove']"
|
||||
></el-button>
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:position:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 新增/修改对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="800px" append-to-body>
|
||||
<!-- 添加或修改招聘岗位对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="800px" append-to-body>
|
||||
<el-form ref="jobPositionFormRef" :model="form" :rules="rules" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
@@ -217,7 +224,7 @@
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -253,58 +260,30 @@
|
||||
</template>
|
||||
|
||||
<script setup name="JobPosition" lang="ts">
|
||||
import { getCurrentInstance, ComponentInternalInstance, ref, reactive, toRefs, onMounted } from 'vue';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import {
|
||||
listJobPosition,
|
||||
getJobPosition,
|
||||
delJobPosition,
|
||||
addJobPosition,
|
||||
updateJobPosition,
|
||||
exportJobPosition,
|
||||
listEnterpriseOptions
|
||||
} from '@/api/zsjy/jobPosition';
|
||||
import { listJobPosition, getJobPosition, delJobPosition, addJobPosition, updateJobPosition, exportJobPosition, listEnterpriseOptions } from '@/api/zsjy/jobPosition';
|
||||
import { JobPositionVO, JobPositionForm, JobPositionQuery } from '@/api/zsjy/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
// 字典数据
|
||||
const { sys_normal_disable } = toRefs<any>(proxy?.useDict('sys_normal_disable'));
|
||||
|
||||
// 表格数据
|
||||
const jobPositionList = ref<JobPositionVO[]>([]);
|
||||
const total = ref(0);
|
||||
const loading = ref(false);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
// 表单相关
|
||||
const open = ref(false);
|
||||
const title = ref('');
|
||||
const jobPositionFormRef = ref<FormInstance>();
|
||||
const queryFormRef = ref<FormInstance>();
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const jobPositionFormRef = ref<ElFormInstance>();
|
||||
|
||||
// 企业选项
|
||||
const enterpriseOptions = ref<any[]>([]);
|
||||
|
||||
// 日期范围
|
||||
const dateRange = ref<[string, string]>([]);
|
||||
|
||||
// 查询参数
|
||||
const queryParams = ref<JobPositionQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
enterpriseId: undefined,
|
||||
positionName: undefined,
|
||||
workAddress: undefined,
|
||||
status: undefined,
|
||||
isPermanent: undefined
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
// 表单参数
|
||||
const form = ref<JobPositionForm>({
|
||||
const initFormData: JobPositionForm = {
|
||||
id: undefined,
|
||||
enterpriseId: '',
|
||||
positionName: '',
|
||||
@@ -317,17 +296,37 @@ const form = ref<JobPositionForm>({
|
||||
isPermanent: 0,
|
||||
status: '0',
|
||||
remark: ''
|
||||
};
|
||||
|
||||
const data = reactive<PageData<JobPositionForm, JobPositionQuery>>({
|
||||
form: { ...initFormData },
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
enterpriseId: undefined,
|
||||
positionName: undefined,
|
||||
workAddress: undefined,
|
||||
status: undefined,
|
||||
isPermanent: undefined,
|
||||
params: {}
|
||||
},
|
||||
rules: {
|
||||
enterpriseId: [{ required: true, message: '请选择所属企业', trigger: 'change' }],
|
||||
positionName: [{ required: true, message: '岗位名称不能为空', trigger: 'blur' }],
|
||||
workAddress: [{ required: true, message: '工作地址不能为空', trigger: 'blur' }],
|
||||
workTime: [{ required: true, message: '工作时间不能为空', trigger: 'blur' }],
|
||||
salary: [{ required: true, message: '薪资不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
}
|
||||
});
|
||||
|
||||
// 表单校验规则
|
||||
const rules = {
|
||||
enterpriseId: [{ required: true, message: '请选择所属企业', trigger: 'change' }],
|
||||
positionName: [{ required: true, message: '岗位名称不能为空', trigger: 'blur' }],
|
||||
workAddress: [{ required: true, message: '工作地址不能为空', trigger: 'blur' }],
|
||||
workTime: [{ required: true, message: '工作时间不能为空', trigger: 'blur' }],
|
||||
salary: [{ required: true, message: '薪资不能为空', trigger: 'blur' }],
|
||||
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
|
||||
};
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
// 企业选项
|
||||
const enterpriseOptions = ref<any[]>([]);
|
||||
|
||||
// 日期范围
|
||||
const dateRange = ref<[string, string] | []>([]);
|
||||
|
||||
// 详情数据
|
||||
const detailOpen = ref(false);
|
||||
@@ -360,11 +359,6 @@ const resetQuery = () => {
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 切换搜索显示 */
|
||||
const toggleSearch = () => {
|
||||
showSearch.value = !showSearch.value;
|
||||
};
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: JobPositionVO[]) => {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
@@ -374,22 +368,22 @@ const handleSelectionChange = (selection: JobPositionVO[]) => {
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
resetForm();
|
||||
open.value = true;
|
||||
title.value = '添加招聘岗位';
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = '添加招聘岗位';
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: JobPositionVO) => {
|
||||
resetForm();
|
||||
reset();
|
||||
const id = row?.id || ids.value[0];
|
||||
const res = await getJobPosition(id);
|
||||
Object.assign(form.value, res.data);
|
||||
if (!form.value.isPermanent) {
|
||||
dateRange.value = [form.value.startDate, form.value.endDate];
|
||||
}
|
||||
open.value = true;
|
||||
title.value = '修改招聘岗位';
|
||||
dialog.visible = true;
|
||||
dialog.title = '修改招聘岗位';
|
||||
};
|
||||
|
||||
/** 详情按钮操作 */
|
||||
@@ -412,6 +406,8 @@ const handlePermanentChange = (val: number) => {
|
||||
const submitForm = () => {
|
||||
jobPositionFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
|
||||
// 处理日期范围
|
||||
if (form.value.isPermanent === 0 && dateRange.value && dateRange.value.length === 2) {
|
||||
form.value.startDate = dateRange.value[0];
|
||||
@@ -419,14 +415,13 @@ const submitForm = () => {
|
||||
}
|
||||
|
||||
if (form.value.id) {
|
||||
await updateJobPosition(form.value);
|
||||
proxy?.$modal.msgSuccess('修改成功');
|
||||
await updateJobPosition(form.value).finally(() => (buttonLoading.value = false));
|
||||
} else {
|
||||
await addJobPosition(form.value);
|
||||
proxy?.$modal.msgSuccess('新增成功');
|
||||
await addJobPosition(form.value).finally(() => (buttonLoading.value = false));
|
||||
}
|
||||
open.value = false;
|
||||
getList();
|
||||
proxy?.$modal.msgSuccess('操作成功');
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -434,27 +429,31 @@ const submitForm = () => {
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: JobPositionVO) => {
|
||||
const jobIds = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除选中的招聘岗位?');
|
||||
await proxy?.$modal.confirm('是否确认删除选中的招聘岗位?').finally(() => (loading.value = false));
|
||||
await delJobPosition(jobIds);
|
||||
proxy?.$modal.msgSuccess('删除成功');
|
||||
getList();
|
||||
await getList();
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = async () => {
|
||||
await proxy?.$modal.confirm('是否确认导出所有招聘岗位数据?');
|
||||
await exportJobPosition(queryParams.value);
|
||||
proxy?.$modal.msgSuccess('导出成功');
|
||||
const handleExport = () => {
|
||||
proxy?.download(
|
||||
'zsjy/position/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`jobPosition_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
open.value = false;
|
||||
resetForm();
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
};
|
||||
|
||||
/** 表单重置 */
|
||||
const resetForm = () => {
|
||||
const reset = () => {
|
||||
form.value = {
|
||||
id: undefined,
|
||||
enterpriseId: '',
|
||||
@@ -480,102 +479,107 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 继承后勤管理的样式
|
||||
<style scoped>
|
||||
.page-container {
|
||||
.search-btn-container {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header-vertical {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
text-align: right;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// 表格适应性样式
|
||||
:deep(.el-table) {
|
||||
.el-table__cell {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式表格
|
||||
:deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
// 表格列宽自适应
|
||||
.el-table {
|
||||
width: 100%;
|
||||
table-layout: auto;
|
||||
}
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 操作按钮样式
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
.search-btn-container {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
// 描述列表样式优化
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
.button-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
.table-card {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:deep(.el-card__header) {
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.el-table) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-table th) {
|
||||
background-color: #fafafa;
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.el-button--plain) {
|
||||
border-color: #dcdfe6;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
:deep(.el-button--plain:hover) {
|
||||
border-color: #409eff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-button--primary.is-plain) {
|
||||
border-color: #409eff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-button--success.is-plain) {
|
||||
border-color: #67c23a;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
:deep(.el-button--danger.is-plain) {
|
||||
border-color: #f56c6c;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
:deep(.el-button--warning.is-plain) {
|
||||
border-color: #e6a23c;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-select .el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-date-editor .el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
.exclusive-relation-text {
|
||||
color: #909399;
|
||||
line-height: 1.2;
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
@@ -2,10 +2,9 @@
|
||||
<div class="p-2 page-container">
|
||||
<!-- 搜索区域 -->
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<div ref="searchRef" v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" label-width="100px">
|
||||
<!-- 搜索条件 -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="所属企业" prop="enterpriseId">
|
||||
@@ -40,7 +39,9 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24" class="search-btn-container">
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
@@ -52,32 +53,35 @@
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<!-- 操作按钮栏 -->
|
||||
<el-card shadow="hover" class="button-card">
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<template #header>
|
||||
<div class="card-header-vertical">
|
||||
<div class="toolbar-title">招聘海报列表</div>
|
||||
<div class="button-group">
|
||||
<el-row ref="toolbarRef" :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['zsjy:poster:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['zsjy:poster:edit']">修改</el-button>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['zsjy:poster:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['zsjy:poster:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['zsjy:poster:export']">导出</el-button>
|
||||
<el-button type="info" plain icon="Fold" @click="toggleSearch">
|
||||
<span v-if="showSearch">隐藏</span>
|
||||
<span v-else>展开</span>
|
||||
搜索
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
</el-card>
|
||||
|
||||
<!-- 表格区域 -->
|
||||
<el-card shadow="hover" class="table-card">
|
||||
<div class="table-container">
|
||||
<el-table v-loading="loading" :data="posterList" @selection-change="handleSelectionChange" class="scroll-table" stripe border>
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="posterList"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
:scroll-x="true"
|
||||
class="scroll-table"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" fixed="left" />
|
||||
<el-table-column label="企业名称" align="center" prop="enterpriseName" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="海报类型" align="center" prop="posterType" width="120">
|
||||
@@ -92,76 +96,45 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="海报预览" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-image
|
||||
<!-- 使用 ImagePreview 组件,支持 OSS ID 格式 -->
|
||||
<image-preview
|
||||
v-if="scope.row.posterPath"
|
||||
:src="scope.row.posterPath"
|
||||
:preview-src-list="[scope.row.posterPath]"
|
||||
:preview-teleported="true"
|
||||
fit="cover"
|
||||
style="width: 80px; height: 80px; cursor: pointer"
|
||||
>
|
||||
<template #error>
|
||||
<div
|
||||
style="
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #f5f7fa;
|
||||
color: #909399;
|
||||
font-size: 12px;
|
||||
"
|
||||
>
|
||||
加载失败
|
||||
</div>
|
||||
</template>
|
||||
</el-image>
|
||||
<span v-else>-</span>
|
||||
:width="80"
|
||||
:height="80"
|
||||
:preview="true"
|
||||
style="cursor: pointer"
|
||||
/>
|
||||
<div v-else style="width: 80px; height: 80px; background: #fafafa; display: flex; align-items: center; justify-content: center; font-size: 12px; color: #ccc; border: 1px dashed #d9d9d9; border-radius: 4px;">
|
||||
<div style="text-align: center;">
|
||||
<el-icon><Picture /></el-icon>
|
||||
<div>未上传</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="海报状态" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag v-if="scope.row.posterPath" type="success" size="small">已上传</el-tag>
|
||||
<el-tag v-else type="warning" size="small">待上传</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" width="160" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
|
||||
<el-table-column label="操作" align="center" width="280" fixed="right" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="预览" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="View"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px; color: blue"
|
||||
@click="handlePreview(scope.row)"
|
||||
v-hasPermi="['zsjy:poster:query']"
|
||||
></el-button>
|
||||
<el-button link type="info" icon="View" @click="handlePreview(scope.row)" v-hasPermi="['zsjy:poster:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
size="default"
|
||||
style="font-size: 16px; margin-right: 8px"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['zsjy:poster:edit']"
|
||||
></el-button>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['zsjy:poster:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
size="default"
|
||||
style="font-size: 16px"
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['zsjy:poster:remove']"
|
||||
></el-button>
|
||||
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['zsjy:poster:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</div>
|
||||
@@ -209,12 +182,44 @@
|
||||
|
||||
<!-- 预览对话框 -->
|
||||
<el-dialog title="海报预览" v-model="previewOpen" width="900px" append-to-body>
|
||||
<PosterPreview
|
||||
v-if="previewOpen && previewData.posterPath"
|
||||
:poster-data="previewData"
|
||||
:enterprise-detail="enterpriseDetail"
|
||||
:position-detail="positionDetail"
|
||||
/>
|
||||
<div v-if="previewOpen && previewData.posterPath" class="poster-preview-container">
|
||||
<!-- 海报图片预览 -->
|
||||
<div class="poster-image-section">
|
||||
<image-preview
|
||||
:src="previewData.posterPath"
|
||||
:width="400"
|
||||
:height="600"
|
||||
:preview="true"
|
||||
style="margin: 0 auto;"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 海报详情信息 -->
|
||||
<div class="poster-info-section">
|
||||
<el-descriptions title="海报详情" :column="2" border>
|
||||
<el-descriptions-item label="海报类型">
|
||||
<dict-tag :options="zsjy_poster_type" :value="previewData.posterType" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="所属企业">
|
||||
{{ enterpriseDetail.enterpriseName || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="关联岗位" v-if="previewData.posterType === '2'">
|
||||
{{ positionDetail.positionName || '-' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">
|
||||
{{ previewData.createTime || '-' }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 无海报图片提示 -->
|
||||
<div v-else-if="previewOpen && !previewData.posterPath" class="no-poster-tip">
|
||||
<el-empty description="暂无海报图片,请先上传海报模板">
|
||||
<el-button type="primary" @click="handleUpdate(previewData)">立即上传</el-button>
|
||||
</el-empty>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="previewOpen = false">关 闭</el-button>
|
||||
@@ -225,8 +230,9 @@
|
||||
</template>
|
||||
|
||||
<script setup name="RecruitmentPoster" lang="ts">
|
||||
import { getCurrentInstance, ComponentInternalInstance, ref, reactive, toRefs } from 'vue';
|
||||
import { getCurrentInstance, ComponentInternalInstance, ref, reactive, toRefs, onMounted } from 'vue';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { Picture } from '@element-plus/icons-vue';
|
||||
import {
|
||||
listRecruitmentPoster,
|
||||
getRecruitmentPoster,
|
||||
@@ -240,7 +246,6 @@ import { listEnterpriseOptions } from '@/api/zsjy/jobPosition';
|
||||
import { getEnterprise } from '@/api/zsjy/enterprise';
|
||||
import { getJobPosition } from '@/api/zsjy/jobPosition';
|
||||
import { RecruitmentPosterVO, RecruitmentPosterForm, RecruitmentPosterQuery } from '@/api/zsjy/types';
|
||||
import PosterPreview from '@/components/PosterPreview/index.vue';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
@@ -349,11 +354,6 @@ const resetQuery = () => {
|
||||
handleQuery();
|
||||
};
|
||||
|
||||
/** 切换搜索显示 */
|
||||
const toggleSearch = () => {
|
||||
showSearch.value = !showSearch.value;
|
||||
};
|
||||
|
||||
/** 企业选择改变 */
|
||||
const handleEnterpriseChange = (val: number | string) => {
|
||||
queryParams.value.positionId = undefined;
|
||||
@@ -506,102 +506,148 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
// 继承后勤管理的样式
|
||||
<style scoped>
|
||||
.page-container {
|
||||
.search-btn-container {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header-vertical {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.toolbar-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
text-align: right;
|
||||
padding-top: 20px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
// 表格适应性样式
|
||||
:deep(.el-table) {
|
||||
.el-table__cell {
|
||||
padding: 8px 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 响应式表格
|
||||
:deep(.el-table__body-wrapper) {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
// 表格列宽自适应
|
||||
.el-table {
|
||||
width: 100%;
|
||||
table-layout: auto;
|
||||
}
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
// 操作按钮样式
|
||||
.action-buttons {
|
||||
.search-btn-container {
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.table-card {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.scroll-table {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
:deep(.el-card__header) {
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
:deep(.el-table) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-table th) {
|
||||
background-color: #fafafa;
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.el-button--plain) {
|
||||
border-color: #dcdfe6;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
:deep(.el-button--plain:hover) {
|
||||
border-color: #409eff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-button--primary.is-plain) {
|
||||
border-color: #409eff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
:deep(.el-button--success.is-plain) {
|
||||
border-color: #67c23a;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
:deep(.el-button--danger.is-plain) {
|
||||
border-color: #f56c6c;
|
||||
color: #f56c6c;
|
||||
}
|
||||
|
||||
:deep(.el-button--warning.is-plain) {
|
||||
border-color: #e6a23c;
|
||||
color: #e6a23c;
|
||||
}
|
||||
|
||||
:deep(.el-form-item__label) {
|
||||
color: #606266;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-select .el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
:deep(.el-date-editor .el-input__wrapper) {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* 海报预览样式 */
|
||||
.poster-preview-container {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
white-space: nowrap;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
// 描述列表样式优化
|
||||
:deep(.el-descriptions) {
|
||||
.el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
.poster-image-section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 20px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.el-descriptions__content {
|
||||
color: #303133;
|
||||
.poster-info-section {
|
||||
width: 100%;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.no-poster-tip {
|
||||
padding: 40px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 描述列表样式优化 */
|
||||
:deep(.el-descriptions) .el-descriptions__label {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
:deep(.el-descriptions) .el-descriptions__content {
|
||||
color: #303133;
|
||||
}
|
||||
.search-btn-container {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in new issue
Block a user