Merge branch 'master' of http://47.99.164.66:3000/hzdyjs-xg/all-project
This commit is contained in:
commit
d9f760fe1c
159 files changed
+7742
-9254
No files matched your search
+49
-15
@@ -33,6 +33,8 @@ import org.dromara.rs.domain.query.RsOverseasApplicationQuery;
|
||||
import org.dromara.rs.service.IRsOverseasApplicationService;
|
||||
import org.dromara.rs.service.IRsOverseasApprovalService;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 出国申请Controller
|
||||
@@ -54,40 +56,72 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 查询出国申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<RsOverseasApplicationVo> list(RsOverseasApplicationQuery query) {
|
||||
query.setTenantId(LoginHelper.getTenantId()); // 设置租户ID
|
||||
return applicationService.queryPageList(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询我的出国申请列表(排除已通过的申请,已通过的申请显示在出国记录中)
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/my/list")
|
||||
public TableDataInfo<RsOverseasApplicationVo> myList(RsOverseasApplicationQuery query) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
query.setApplicantId(userId);
|
||||
query.setTenantId(LoginHelper.getTenantId()); // 设置租户ID
|
||||
return applicationService.queryMyApplicationList(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询待审批的申请列表(有审批权限的用户可以看到所有待审批申请)
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:approve")
|
||||
@SaCheckPermission("rs:overseas:approve")
|
||||
@GetMapping("/pending/list")
|
||||
public TableDataInfo<RsOverseasApplicationVo> pendingList(RsOverseasApplicationQuery query) {
|
||||
// 不限制currentApprover,让有审批权限的用户看到所有待审批申请
|
||||
// String currentUser = LoginHelper.getUsername();
|
||||
// query.setCurrentApprover(currentUser);
|
||||
query.setStatus("0"); // 只查询待审核状态
|
||||
query.setTenantId(LoginHelper.getTenantId()); // 设置租户ID
|
||||
return applicationService.queryPageList(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 临时测试API - 查询待审批的申请列表(调试用)
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approve")
|
||||
@GetMapping("/pending/debug")
|
||||
public R<Object> pendingDebug(RsOverseasApplicationQuery query) {
|
||||
// 获取当前用户信息
|
||||
String currentUser = LoginHelper.getUsername();
|
||||
Long userId = LoginHelper.getUserId();
|
||||
String tenantId = LoginHelper.getTenantId();
|
||||
|
||||
// 设置查询条件
|
||||
query.setStatus("0"); // 只查询待审核状态
|
||||
query.setTenantId(tenantId); // 设置租户ID
|
||||
|
||||
// 执行查询
|
||||
TableDataInfo<RsOverseasApplicationVo> result = applicationService.queryPageList(query);
|
||||
|
||||
// 返回调试信息
|
||||
Map<String, Object> debugInfo = new HashMap<>();
|
||||
debugInfo.put("currentUser", currentUser);
|
||||
debugInfo.put("userId", userId);
|
||||
debugInfo.put("tenantId", tenantId);
|
||||
debugInfo.put("queryParams", query);
|
||||
debugInfo.put("result", result);
|
||||
|
||||
return R.ok(debugInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据状态查询申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/status/{status}")
|
||||
public R<List<RsOverseasApplicationVo>> listByStatus(@PathVariable String status) {
|
||||
List<RsOverseasApplicationVo> list = applicationService.queryByStatus(status);
|
||||
@@ -97,7 +131,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 导出出国申请列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:export")
|
||||
@SaCheckPermission("rs:overseas:export")
|
||||
@Log(title = "出国申请", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(RsOverseasApplicationQuery query, HttpServletResponse response) {
|
||||
@@ -108,7 +142,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 获取出国申请详细信息
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:query")
|
||||
@SaCheckPermission("rs:overseas:query")
|
||||
@GetMapping("/{applicationId}")
|
||||
public R<RsOverseasApplicationVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long applicationId) {
|
||||
return R.ok(applicationService.queryById(applicationId));
|
||||
@@ -117,7 +151,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 新增出国申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:add")
|
||||
@SaCheckPermission("rs:overseas:add")
|
||||
@Log(title = "出国申请", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody RsOverseasApplicationBo bo) {
|
||||
@@ -144,7 +178,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 修改出国申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:edit")
|
||||
@SaCheckPermission("rs:overseas:edit")
|
||||
@Log(title = "出国申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody RsOverseasApplicationBo bo) {
|
||||
@@ -154,7 +188,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 提交出国申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:submit")
|
||||
@SaCheckPermission("rs:overseas:submit")
|
||||
@Log(title = "提交出国申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/submit/{applicationId}")
|
||||
public R<Void> submit(@NotNull(message = "申请ID不能为空") @PathVariable Long applicationId) {
|
||||
@@ -164,7 +198,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 重新提交被拒绝的出国申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:edit")
|
||||
@SaCheckPermission("rs:overseas:edit")
|
||||
@Log(title = "重新提交出国申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/resubmit/{applicationId}")
|
||||
public R<Void> resubmit(@NotNull(message = "申请ID不能为空") @PathVariable Long applicationId,
|
||||
@@ -175,7 +209,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 取消出国申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:cancel")
|
||||
@SaCheckPermission("rs:overseas:cancel")
|
||||
@Log(title = "取消出国申请", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/cancel/{applicationId}")
|
||||
public R<Void> cancel(@NotNull(message = "申请ID不能为空") @PathVariable Long applicationId,
|
||||
@@ -186,7 +220,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 审批出国申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:approve")
|
||||
@SaCheckPermission("rs:overseas:approve")
|
||||
@Log(title = "审批出国申请", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/approve")
|
||||
public R<Void> approve(@RequestBody ApprovalRequest request) {
|
||||
@@ -200,7 +234,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 批量删除出国申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:remove")
|
||||
@SaCheckPermission("rs:overseas:remove")
|
||||
@Log(title = "出国申请", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{applicationIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键集合不能为空") @PathVariable List<Long> applicationIds) {
|
||||
@@ -210,7 +244,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 查询出国申请审批历史
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:query")
|
||||
@SaCheckPermission("rs:overseas:query")
|
||||
@GetMapping("/approval/history/{applicationId}")
|
||||
public R<List<RsOverseasApprovalVo>> getApprovalHistory(@PathVariable("applicationId") Long applicationId) {
|
||||
List<RsOverseasApprovalVo> approvalList = overseasApprovalService.selectApprovalHistoryByApplicationId(applicationId);
|
||||
@@ -220,7 +254,7 @@ public class RsOverseasApplicationController extends BaseController {
|
||||
/**
|
||||
* 修复已审批通过但未创建记录的申请
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:application:approve")
|
||||
@SaCheckPermission("rs:overseas:approve")
|
||||
@Log(title = "修复出国记录", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/fix/records")
|
||||
public R<String> fixApprovedRecords() {
|
||||
|
||||
+10
-10
@@ -49,7 +49,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 查询出国审批记录列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<RsOverseasApprovalVo> list(RsOverseasApprovalQuery query) {
|
||||
return approvalService.queryPageList(query);
|
||||
@@ -58,7 +58,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 查询我的审批记录列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/my/list")
|
||||
public TableDataInfo<RsOverseasApprovalVo> myList(RsOverseasApprovalQuery query) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
@@ -69,7 +69,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 联合查询出国审批记录列表(包含待审批申请和已审批记录)
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/combined/list")
|
||||
public TableDataInfo<RsOverseasApprovalVo> combinedList(RsOverseasApprovalQuery query) {
|
||||
return approvalService.queryCombinedPageList(query);
|
||||
@@ -78,7 +78,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 根据申请ID查询审批记录列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:query")
|
||||
@SaCheckPermission("rs:overseas:query")
|
||||
@GetMapping("/application/{applicationId}")
|
||||
public R<List<RsOverseasApprovalVo>> getByApplicationId(@PathVariable Long applicationId) {
|
||||
List<RsOverseasApprovalVo> list = approvalService.queryByApplicationId(applicationId);
|
||||
@@ -88,7 +88,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 导出出国审批记录列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:export")
|
||||
@SaCheckPermission("rs:overseas:export")
|
||||
@Log(title = "出国审批记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(RsOverseasApprovalQuery query, HttpServletResponse response) {
|
||||
@@ -99,7 +99,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 获取出国审批记录详细信息
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:query")
|
||||
@SaCheckPermission("rs:overseas:query")
|
||||
@GetMapping("/{approvalId}")
|
||||
public R<RsOverseasApprovalVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long approvalId) {
|
||||
return R.ok(approvalService.queryById(approvalId));
|
||||
@@ -108,7 +108,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 新增出国审批记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:add")
|
||||
@SaCheckPermission("rs:overseas:add")
|
||||
@Log(title = "出国审批记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody RsOverseasApprovalBo bo) {
|
||||
@@ -121,7 +121,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 修改出国审批记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:edit")
|
||||
@SaCheckPermission("rs:overseas:edit")
|
||||
@Log(title = "出国审批记录", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody RsOverseasApprovalBo bo) {
|
||||
@@ -131,7 +131,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 批量删除出国审批记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:remove")
|
||||
@SaCheckPermission("rs:overseas:remove")
|
||||
@Log(title = "出国审批记录", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{approvalIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键集合不能为空") @PathVariable List<Long> approvalIds) {
|
||||
@@ -141,7 +141,7 @@ public class RsOverseasApprovalController extends BaseController {
|
||||
/**
|
||||
* 修复审批记录测试数据
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:approval:edit")
|
||||
@SaCheckPermission("rs:overseas:edit")
|
||||
@Log(title = "出国审批记录", businessType = BusinessType.UPDATE)
|
||||
@PostMapping("/fixData")
|
||||
public R<String> fixApprovalData() {
|
||||
|
||||
+11
-11
@@ -48,7 +48,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 查询出国记录列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo<RsOverseasRecordVo> list(RsOverseasRecordQuery query) {
|
||||
return recordService.queryPageList(query);
|
||||
@@ -57,7 +57,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 查询我的出国记录列表(联合查询:记录+已通过申请)
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:list")
|
||||
@SaCheckPermission("rs:overseas:list")
|
||||
@GetMapping("/my/list")
|
||||
public TableDataInfo<RsOverseasRecordVo> myList(RsOverseasRecordQuery query) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
@@ -68,7 +68,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 根据申请ID查询出国记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:query")
|
||||
@SaCheckPermission("rs:overseas:query")
|
||||
@GetMapping("/application/{applicationId}")
|
||||
public R<RsOverseasRecordVo> getByApplicationId(@PathVariable Long applicationId) {
|
||||
RsOverseasRecordVo record = recordService.queryByApplicationId(applicationId);
|
||||
@@ -78,7 +78,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 导出出国记录列表
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:export")
|
||||
@SaCheckPermission("rs:overseas:export")
|
||||
@Log(title = "出国记录", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(RsOverseasRecordQuery query, HttpServletResponse response) {
|
||||
@@ -89,7 +89,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 获取出国记录详细信息
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:query")
|
||||
@SaCheckPermission("rs:overseas:query")
|
||||
@GetMapping("/{recordId}")
|
||||
public R<RsOverseasRecordVo> getInfo(@NotNull(message = "主键不能为空") @PathVariable Long recordId) {
|
||||
return R.ok(recordService.queryById(recordId));
|
||||
@@ -98,7 +98,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 新增出国记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:add")
|
||||
@SaCheckPermission("rs:overseas:add")
|
||||
@Log(title = "出国记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody RsOverseasRecordBo bo) {
|
||||
@@ -108,7 +108,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 修改出国记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:edit")
|
||||
@SaCheckPermission("rs:overseas:edit")
|
||||
@Log(title = "出国记录", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody RsOverseasRecordBo bo) {
|
||||
@@ -118,7 +118,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 基于申请信息创建出国记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:create")
|
||||
@SaCheckPermission("rs:overseas:create")
|
||||
@Log(title = "创建出国记录", businessType = BusinessType.INSERT)
|
||||
@PostMapping("/create/{applicationId}")
|
||||
public R<Void> createFromApplication(@NotNull(message = "申请ID不能为空") @PathVariable Long applicationId) {
|
||||
@@ -128,7 +128,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 更新出国记录完成状态
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:complete")
|
||||
@SaCheckPermission("rs:overseas:complete")
|
||||
@Log(title = "更新出国记录完成状态", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/complete")
|
||||
public R<Void> updateCompletion(@RequestBody CompletionRequest request) {
|
||||
@@ -140,7 +140,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 批量删除出国记录
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:remove")
|
||||
@SaCheckPermission("rs:overseas:remove")
|
||||
@Log(title = "出国记录", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{recordIds}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键集合不能为空") @PathVariable List<Long> recordIds) {
|
||||
@@ -150,7 +150,7 @@ public class RsOverseasRecordController extends BaseController {
|
||||
/**
|
||||
* 初始化测试数据(临时接口,用于解决出国记录列表显示问题)
|
||||
*/
|
||||
@SaCheckPermission("rs:overseas:record:add")
|
||||
@SaCheckPermission("rs:overseas:add")
|
||||
@PostMapping("/initTestData")
|
||||
public R<Void> initTestData() {
|
||||
try {
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ public class RsOverseasRecord extends BaseEntity {
|
||||
private String transportationPlan;
|
||||
|
||||
/**
|
||||
* 完成状态:0-进行中,1-已完成,2-提前结束
|
||||
* 完成状态:1-已完成,2-已拒绝
|
||||
*/
|
||||
@ExcelProperty(value = "完成状态")
|
||||
private String completionStatus;
|
||||
|
||||
+31
@@ -52,6 +52,37 @@ public class RsTrainingRecord extends BaseEntity {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* 完成状态:0=进行中,1=已完成,2=未完成
|
||||
*/
|
||||
private String completionStatus;
|
||||
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date completionTime;
|
||||
|
||||
/**
|
||||
* 成绩/分数
|
||||
*/
|
||||
private BigDecimal score;
|
||||
|
||||
/**
|
||||
* 证书路径
|
||||
*/
|
||||
private String certificatePath;
|
||||
|
||||
/**
|
||||
* 证书编号
|
||||
*/
|
||||
private String certificateNumber;
|
||||
|
||||
/**
|
||||
* 反馈意见
|
||||
*/
|
||||
private String feedback;
|
||||
|
||||
private String tenantId;
|
||||
private Long createDept;
|
||||
private String courseName;
|
||||
|
||||
+1
-3
@@ -226,12 +226,10 @@ public class RsOverseasRecordVo implements Serializable {
|
||||
return "未知状态";
|
||||
}
|
||||
switch (this.completionStatus) {
|
||||
case "0":
|
||||
return "进行中";
|
||||
case "1":
|
||||
return "已完成";
|
||||
case "2":
|
||||
return "提前结束";
|
||||
return "已拒绝";
|
||||
default:
|
||||
return "未知状态";
|
||||
}
|
||||
|
||||
+5
-2
@@ -183,9 +183,12 @@ public class RsOverseasRecordServiceImpl implements IRsOverseasRecordService {
|
||||
record.setItinerary(application.getItinerary());
|
||||
record.setAccommodationPlan(application.getAccommodationPlan());
|
||||
record.setTransportationPlan(application.getTransportationPlan());
|
||||
record.setCompletionStatus("0"); // 设置为进行中
|
||||
|
||||
log.info("准备插入出国记录,申请ID: {}, 申请人: {}, 目的地: {}",
|
||||
// 修复:审批通过的申请创建记录时应该设置为已完成状态
|
||||
// 因为审批通过意味着出国活动已经完成
|
||||
record.setCompletionStatus("1"); // 设置为已完成
|
||||
|
||||
log.info("准备插入出国记录,申请ID: {}, 申请人: {}, 目的地: {}, 状态: 已完成",
|
||||
applicationId, application.getApplicantName(), application.getDestination());
|
||||
|
||||
boolean insertResult = baseMapper.insert(record) > 0;
|
||||
|
||||
+10
@@ -131,6 +131,13 @@ public class RsTrainingRecordServiceImpl implements IRsTrainingRecordService {
|
||||
public int updateCompletionStatus(Long recordId, String completionStatus) {
|
||||
RsTrainingRecord record = trainingRecordMapper.selectById(recordId);
|
||||
if (record != null) {
|
||||
record.setCompletionStatus(completionStatus);
|
||||
|
||||
// 如果状态改为已完成,自动设置完成时间
|
||||
if ("1".equals(completionStatus)) {
|
||||
record.setCompletionTime(DateUtils.getNowDate());
|
||||
}
|
||||
|
||||
record.setUpdateTime(DateUtils.getNowDate());
|
||||
return trainingRecordMapper.updateById(record);
|
||||
}
|
||||
@@ -149,6 +156,8 @@ public class RsTrainingRecordServiceImpl implements IRsTrainingRecordService {
|
||||
public int uploadCertificate(Long recordId, String certificatePath, String certificateNumber) {
|
||||
RsTrainingRecord record = trainingRecordMapper.selectById(recordId);
|
||||
if (record != null) {
|
||||
record.setCertificatePath(certificatePath);
|
||||
record.setCertificateNumber(certificateNumber);
|
||||
record.setUpdateTime(DateUtils.getNowDate());
|
||||
return trainingRecordMapper.updateById(record);
|
||||
}
|
||||
@@ -164,6 +173,7 @@ public class RsTrainingRecordServiceImpl implements IRsTrainingRecordService {
|
||||
lqw.like(record.getCourseName() != null, RsTrainingRecord::getCourseName, record.getCourseName());
|
||||
lqw.eq(record.getUserId() != null, RsTrainingRecord::getUserId, record.getUserId());
|
||||
lqw.like(record.getUserName() != null, RsTrainingRecord::getUserName, record.getUserName());
|
||||
lqw.eq(record.getCompletionStatus() != null, RsTrainingRecord::getCompletionStatus, record.getCompletionStatus());
|
||||
lqw.eq(record.getStatus() != null, RsTrainingRecord::getStatus, record.getStatus());
|
||||
return lqw;
|
||||
}
|
||||
|
||||
+4
-9
@@ -94,15 +94,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="approvalLevel != null and approvalLevel != ''">
|
||||
AND oa.approval_level = #{approvalLevel}
|
||||
</if>
|
||||
<!-- 审批状态过滤:如果指定了状态则使用指定的,否则只查询已完成审批的记录 -->
|
||||
<choose>
|
||||
<when test="approvalStatus != null and approvalStatus != ''">
|
||||
AND oa.approval_status = #{approvalStatus}
|
||||
</when>
|
||||
<otherwise>
|
||||
AND oa.approval_status IN ('1', '2')
|
||||
</otherwise>
|
||||
</choose>
|
||||
<!-- 审批状态过滤:如果指定了状态则使用指定的,否则显示所有状态 -->
|
||||
<if test="approvalStatus != null and approvalStatus != ''">
|
||||
AND oa.approval_status = #{approvalStatus}
|
||||
</if>
|
||||
<if test="approvalTimeBegin != null">
|
||||
AND oa.approval_time >= #{approvalTimeBegin}
|
||||
</if>
|
||||
|
||||
+17
-6
@@ -20,6 +20,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="duration" column="duration"/>
|
||||
<result property="startTime" column="start_time"/>
|
||||
<result property="endTime" column="end_time"/>
|
||||
<result property="completionStatus" column="completion_status"/>
|
||||
<result property="completionTime" column="completion_time"/>
|
||||
<result property="score" column="score"/>
|
||||
<result property="certificatePath" column="certificate_path"/>
|
||||
<result property="certificateNumber" column="certificate_number"/>
|
||||
<result property="feedback" column="feedback"/>
|
||||
<result property="tenantId" column="tenant_id"/>
|
||||
<result property="createDept" column="create_dept"/>
|
||||
<result property="courseName" column="course_name"/>
|
||||
@@ -37,14 +43,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</sql>
|
||||
|
||||
<select id="selectRsTrainingRecordList" parameterType="RsTrainingRecord" resultMap="RsTrainingRecordResult">
|
||||
SELECT record_id, application_id, course_id, user_id, user_name, department, position, reason, status,
|
||||
apply_time, current_approver, location, duration, start_time, end_time, tenant_id, create_dept, course_name
|
||||
FROM rs_training_record
|
||||
<include refid="selectRsTrainingRecordVo"/>
|
||||
<where>
|
||||
deleted = '0'
|
||||
<!-- 其他条件 -->
|
||||
r.deleted = '0'
|
||||
<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>
|
||||
<if test="userName != null and userName != ''">and r.user_name like concat('%', #{userName}, '%')</if>
|
||||
<if test="completionStatus != null and completionStatus != ''">and r.completion_status = #{completionStatus}</if>
|
||||
<if test="status != null and status != ''">and r.status = #{status}</if>
|
||||
<if test="params.beginTime != null and params.beginTime != ''">and date_format(r.create_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')</if>
|
||||
<if test="params.endTime != null and params.endTime != ''">and date_format(r.create_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')</if>
|
||||
</where>
|
||||
ORDER BY create_time DESC
|
||||
ORDER BY r.create_time DESC
|
||||
</select>
|
||||
|
||||
<insert id="insertRsTrainingRecord" parameterType="org.dromara.rs.domain.RsTrainingRecord">
|
||||
|
||||
@@ -1,233 +1,123 @@
|
||||
# 代码调整记录 - 2025-01-07 - weizzzz
|
||||
|
||||
## 📊 出国记录选项卡显示已完成审批数据实现
|
||||
## 📋 变更概述
|
||||
- **变更时间**: 2025-01-07 15:30:00
|
||||
- **变更人员**: weizzzz
|
||||
- **变更类型**: 前端路由修复
|
||||
- **影响模块**: 人事系统 - 出国审批管理
|
||||
|
||||
### 🎯 调整目标
|
||||
实现出国记录选项卡显示已完成审批的申请数据,使其与申请记录选项卡形成完整的数据流转机制。
|
||||
## 🔍 问题描述
|
||||
|
||||
### 📋 问题分析
|
||||
### 发现的问题
|
||||
用户反馈出国审批页面显示标题错误:
|
||||
- **期望显示**: "待审批申请"
|
||||
- **实际显示**: "出国审批"
|
||||
|
||||
#### 申请记录选项卡现有机制
|
||||
1. **状态过滤**:`AND oa.status != '1'` 排除已通过的申请
|
||||
2. **数据范围**:显示草稿、待审核、已拒绝、已取消等状态
|
||||
3. **业务逻辑**:已通过的申请不在申请记录中重复显示
|
||||
### 问题分析
|
||||
通过深入分析发现系统中存在**双重路径问题**:
|
||||
|
||||
#### 出国记录选项卡原有限制
|
||||
1. **数据源单一**:仅查询 `rs_overseas_record` 表
|
||||
2. **数据缺失**:已通过审批但未创建记录的申请无法显示
|
||||
3. **用户体验问题**:用户无法看到已通过的申请数据
|
||||
1. **错误路径**(当前菜单指向):
|
||||
- 组件路径: `web/src/views/rs/overseasApproval/index.vue`
|
||||
- 菜单配置: menu_id `2140` → `rs/overseasApproval/index`
|
||||
- 页面标题: "出国审批" ❌
|
||||
|
||||
### 🔧 技术实现方案
|
||||
2. **正确路径**(应该使用的):
|
||||
- 组件路径: `web/src/views/rs/overseas/approval.vue`
|
||||
- 菜单配置: menu_id `2220` → `rs/overseas/approval`
|
||||
- 页面标题: "待审批申请" ✅
|
||||
|
||||
#### 1. 数据库层面 - 联合查询 (RsOverseasRecordMapper.xml)
|
||||
### 根本原因
|
||||
开发过程中创建了两套出国审批系统,导致菜单配置指向了错误的组件。
|
||||
|
||||
```xml
|
||||
<!-- 新增联合查询SQL片段 -->
|
||||
<sql id="selectOverseasRecordWithApprovedApplicationsVo">
|
||||
-- 查询已创建的出国记录
|
||||
select ors.*, 'record' as data_source
|
||||
from rs_overseas_record ors
|
||||
where ors.deleted = '0'
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- 查询已通过审批但未创建记录的申请
|
||||
select
|
||||
NULL as record_id,
|
||||
oa.application_id, oa.applicant_id, oa.applicant_name, ...
|
||||
oa.start_date as actual_start_date, oa.end_date as actual_end_date,
|
||||
'approved_application' as data_source
|
||||
from rs_overseas_application oa
|
||||
where oa.deleted = '0'
|
||||
AND oa.status = '1' -- 已通过审批
|
||||
AND NOT EXISTS (
|
||||
SELECT 1 FROM rs_overseas_record ors
|
||||
WHERE ors.application_id = oa.application_id
|
||||
)
|
||||
</sql>
|
||||
## 🔧 解决方案
|
||||
|
||||
<!-- 新增我的出国记录联合查询方法 -->
|
||||
<select id="selectMyOverseasRecordList">
|
||||
SELECT * FROM (
|
||||
<include refid="selectOverseasRecordWithApprovedApplicationsVo"/>
|
||||
) combined_data
|
||||
WHERE combined_data.applicant_id = #{applicantId}
|
||||
ORDER BY combined_data.actual_start_date DESC
|
||||
</select>
|
||||
### 采用方案1: 修改菜单配置
|
||||
将错误的菜单配置修改为指向正确的组件路径。
|
||||
|
||||
### 具体修改内容
|
||||
|
||||
#### 数据库变更
|
||||
```sql
|
||||
-- 修改前
|
||||
menu_id: 2140
|
||||
menu_name: "出国审批"
|
||||
path: "overseasApproval"
|
||||
component: "rs/overseasApproval/index"
|
||||
|
||||
-- 修改后
|
||||
menu_id: 2140
|
||||
menu_name: "待审批申请"
|
||||
path: "overseas/approval"
|
||||
component: "rs/overseas/approval"
|
||||
```
|
||||
|
||||
#### 2. 实体层面 - 扩展VO类 (RsOverseasRecordVo.java)
|
||||
|
||||
```java
|
||||
/**
|
||||
* 数据来源标识
|
||||
*/
|
||||
private String dataSource;
|
||||
|
||||
/**
|
||||
* 获取数据来源说明
|
||||
*/
|
||||
public String getDataSourceText() {
|
||||
switch (this.dataSource) {
|
||||
case "record": return "出国记录";
|
||||
case "approved_application": return "已通过申请";
|
||||
default: return "出国记录";
|
||||
}
|
||||
}
|
||||
#### 执行的SQL语句
|
||||
```sql
|
||||
UPDATE sys_menu
|
||||
SET component = 'rs/overseas/approval',
|
||||
path = 'overseas/approval',
|
||||
menu_name = '待审批申请'
|
||||
WHERE menu_id = 2140;
|
||||
```
|
||||
|
||||
#### 3. 数据访问层面 - Mapper接口扩展
|
||||
## ✅ 验证结果
|
||||
|
||||
```java
|
||||
/**
|
||||
* 查询我的出国记录列表(联合查询:记录+已通过申请)
|
||||
*/
|
||||
List<RsOverseasRecordVo> selectMyOverseasRecordList(RsOverseasRecordQuery query);
|
||||
### 修改验证
|
||||
- ✅ 菜单配置成功更新
|
||||
- ✅ 组件路径指向正确
|
||||
- ✅ 页面标题将显示"待审批申请"
|
||||
|
||||
### 修改后的菜单配置
|
||||
```
|
||||
+---------+-----------------+-------------------+----------------------+-----------+---------+--------+
|
||||
| menu_id | menu_name | path | component | menu_type | visible | status |
|
||||
+---------+-----------------+-------------------+----------------------+-----------+---------+--------+
|
||||
| 2140 | 待审批申请 | overseas/approval | rs/overseas/approval | M | 0 | 0 |
|
||||
+---------+-----------------+-------------------+----------------------+-----------+---------+--------+
|
||||
```
|
||||
|
||||
#### 4. 业务逻辑层面 - Service实现
|
||||
## 📂 相关文件
|
||||
|
||||
```java
|
||||
/**
|
||||
* 查询我的出国记录分页列表(联合查询:记录+已通过申请)
|
||||
*/
|
||||
@Override
|
||||
public TableDataInfo<RsOverseasRecordVo> queryMyRecordPageList(RsOverseasRecordQuery query) {
|
||||
List<RsOverseasRecordVo> list = baseMapper.selectMyOverseasRecordList(query);
|
||||
// 手动分页处理...
|
||||
return TableDataInfo.build(page);
|
||||
}
|
||||
### 涉及的组件文件
|
||||
- **正确组件**: `web/src/views/rs/overseas/approval.vue` (现在使用)
|
||||
- **错误组件**: `web/src/views/rs/overseasApproval/index.vue` (已停用)
|
||||
|
||||
### 目录结构对比
|
||||
```
|
||||
web/src/views/rs/
|
||||
├── overseasApproval/ ❌ 旧版本(已停用)
|
||||
│ └── index.vue → 显示"出国审批"
|
||||
├── overseas/ ✅ 新版本(当前使用)
|
||||
│ ├── index.vue → 出国申请管理
|
||||
│ └── approval.vue → 显示"待审批申请"
|
||||
```
|
||||
|
||||
#### 5. 控制器层面 - Controller调整
|
||||
## 🔍 后续建议
|
||||
|
||||
```java
|
||||
/**
|
||||
* 查询我的出国记录列表(联合查询:记录+已通过申请)
|
||||
*/
|
||||
@GetMapping("/my/list")
|
||||
public TableDataInfo<RsOverseasRecordVo> myList(RsOverseasRecordQuery query) {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
query.setApplicantId(userId);
|
||||
return recordService.queryMyRecordPageList(query); // 使用新的联合查询方法
|
||||
}
|
||||
```
|
||||
### 代码清理
|
||||
1. 可考虑删除不再使用的 `web/src/views/rs/overseasApproval/` 目录
|
||||
2. 检查是否有其他重复的菜单配置需要清理
|
||||
|
||||
### 📊 数据流转逻辑
|
||||
### 质量保证
|
||||
1. 需要在前端测试菜单导航是否正常
|
||||
2. 确认页面功能完整性
|
||||
3. 验证用户权限是否正确
|
||||
|
||||
#### 完整的申请→记录流程
|
||||
```
|
||||
1. 用户提交申请 → 申请记录选项卡显示(status='0' 待审核)
|
||||
2. 审批通过 → 申请状态更新(status='1' 已通过)
|
||||
3. 数据分流:
|
||||
- 申请记录选项卡:不再显示(status != '1')
|
||||
- 出国记录选项卡:开始显示(联合查询包含已通过申请)
|
||||
4. 创建正式记录 → 出国记录选项卡显示正式记录
|
||||
5. 用户完成任务 → 更新完成状态
|
||||
```
|
||||
## 📝 注意事项
|
||||
|
||||
#### 状态码映射关系
|
||||
```
|
||||
申请状态码:
|
||||
- NULL/'': 草稿
|
||||
- '0': 待审核
|
||||
- '1': 已通过 ✅ 新增显示在出国记录中
|
||||
- '2': 已拒绝
|
||||
- '3': 已取消
|
||||
- '4': 已完成
|
||||
### 影响范围
|
||||
- **前端路由**: 出国审批菜单现在指向正确的组件
|
||||
- **用户体验**: 页面标题将正确显示为"待审批申请"
|
||||
- **功能完整性**: 使用功能更完善的approval.vue组件
|
||||
|
||||
记录状态码:
|
||||
- '0': 进行中
|
||||
- '1': 已完成
|
||||
- '2': 提前结束
|
||||
```
|
||||
|
||||
### ✅ 实现效果
|
||||
|
||||
#### 申请记录选项卡
|
||||
- ✅ 排除已通过申请:`status != '1'`
|
||||
- ✅ 显示范围:草稿、待审核、已拒绝、已取消
|
||||
- ✅ 用户体验:进行中的申请管理
|
||||
|
||||
#### 出国记录选项卡(新增功能)
|
||||
- ✅ 联合查询:正式记录 + 已通过申请
|
||||
- ✅ 数据完整性:无缝显示已通过的申请
|
||||
- ✅ 标识区分:`dataSource` 字段区分数据来源
|
||||
- ✅ 用户体验:完整的出国历史记录
|
||||
|
||||
### 🔍 技术特点
|
||||
|
||||
#### 性能优化
|
||||
- ✅ 联合查询一次性获取所有相关数据
|
||||
- ✅ 手动分页处理,避免复杂的子查询分页
|
||||
- ✅ 索引优化:基于 `applicant_id` 和 `status` 字段
|
||||
|
||||
#### 数据一致性
|
||||
- ✅ 避免重复显示:`NOT EXISTS` 排除已创建记录的申请
|
||||
- ✅ 状态同步:基于申请状态 `'1'` 进行联合查询
|
||||
- ✅ 字段映射:申请字段映射到记录字段(如 `start_date` → `actual_start_date`)
|
||||
|
||||
#### 扩展性设计
|
||||
- ✅ 数据源标识:支持未来更多数据源的集成
|
||||
- ✅ 查询条件:保持与原有查询条件的完全兼容
|
||||
- ✅ 接口一致性:前端无需修改,后端透明升级
|
||||
|
||||
### 📋 影响的文件
|
||||
|
||||
#### 后端文件 (6个)
|
||||
1. **RsOverseasRecordMapper.xml** - 新增联合查询SQL
|
||||
2. **RsOverseasRecordVo.java** - 新增dataSource字段
|
||||
3. **RsOverseasRecordMapper.java** - 新增selectMyOverseasRecordList方法
|
||||
4. **IRsOverseasRecordService.java** - 新增queryMyRecordPageList接口
|
||||
5. **RsOverseasRecordServiceImpl.java** - 实现联合查询业务逻辑
|
||||
6. **RsOverseasRecordController.java** - 更新myList方法调用
|
||||
|
||||
#### 数据库影响
|
||||
- ✅ 无结构变更:纯查询逻辑优化
|
||||
- ✅ 向下兼容:不影响现有数据和功能
|
||||
- ✅ 性能影响:联合查询对性能影响可控
|
||||
|
||||
### 🎯 验证标准
|
||||
|
||||
#### 功能验证
|
||||
1. **申请记录选项卡**:已通过的申请不显示
|
||||
2. **出国记录选项卡**:已通过的申请正常显示
|
||||
3. **数据源标识**:能够区分记录来源
|
||||
4. **分页功能**:联合查询结果正确分页
|
||||
5. **筛选功能**:各种查询条件正常工作
|
||||
|
||||
#### 性能验证
|
||||
1. **查询效率**:联合查询响应时间在可接受范围
|
||||
2. **内存使用**:大数据量下内存占用稳定
|
||||
3. **并发处理**:多用户同时查询无异常
|
||||
|
||||
### 📈 业务价值
|
||||
|
||||
#### 用户体验提升
|
||||
- ✅ **数据完整性**:用户能看到完整的出国申请历史
|
||||
- ✅ **状态透明**:清楚了解申请的处理进度
|
||||
- ✅ **操作便利**:已通过申请可直接在记录中管理
|
||||
|
||||
#### 管理效率提升
|
||||
- ✅ **数据统一**:避免数据分散在不同入口
|
||||
- ✅ **流程闭环**:申请→审批→记录形成完整闭环
|
||||
- ✅ **追踪便利**:便于管理员和用户追踪申请状态
|
||||
|
||||
### 🔄 后续优化建议
|
||||
|
||||
#### 短期优化
|
||||
1. **前端提示**:在记录列表中增加数据来源的视觉标识
|
||||
2. **状态同步**:考虑在申请通过时自动创建记录
|
||||
3. **权限细化**:不同来源数据的操作权限管理
|
||||
|
||||
#### 长期规划
|
||||
1. **工作流集成**:与Warm-Flow工作流引擎深度集成
|
||||
2. **通知机制**:申请状态变更的实时通知
|
||||
3. **数据分析**:基于完整数据的统计分析功能
|
||||
### 风险评估
|
||||
- **风险等级**: 低
|
||||
- **影响用户**: 所有使用出国审批功能的用户
|
||||
- **回滚方案**: 可通过SQL语句快速回滚菜单配置
|
||||
|
||||
---
|
||||
|
||||
**调整时间**: 2025-01-07 17:30:00
|
||||
**调整人员**: weizzzz
|
||||
**测试状态**: 待验证
|
||||
**影响范围**: 出国记录查询功能增强,无破坏性变更
|
||||
**📊 变更状态**: ✅ 已完成
|
||||
**🕐 完成时间**: 2025-01-07 15:30:00
|
||||
**👤 验证人员**: weizzzz
|
||||
**📋 测试状态**: 待前端验证
|
||||
@@ -68,7 +68,7 @@ CREATE TABLE `rs_overseas_record` (
|
||||
`actual_end_date` date DEFAULT NULL COMMENT '实际结束日期',
|
||||
`actual_duration` int(11) DEFAULT NULL COMMENT '实际出国天数',
|
||||
`actual_budget` decimal(12,2) DEFAULT NULL COMMENT '实际花费金额',
|
||||
`completion_status` char(1) NOT NULL DEFAULT '0' COMMENT '完成状态(0-进行中,1-已完成,2-提前结束)',
|
||||
`completion_status` char(1) NOT NULL DEFAULT '1' COMMENT '完成状态(1-已完成,2-已拒绝)',
|
||||
`achievement` text DEFAULT NULL COMMENT '出国成果',
|
||||
`report_content` text DEFAULT NULL COMMENT '总结报告内容',
|
||||
`certificate_path` varchar(500) DEFAULT NULL COMMENT '证书文件路径',
|
||||
|
||||
@@ -98,7 +98,7 @@ export const approveApplication = (data: CwApprovalForm) => {
|
||||
params.append('approveOpinion', data.approvalComment || '');
|
||||
|
||||
return request({
|
||||
url: '/cw/approval/dept', // 🔧 修复:使用部门审批接口
|
||||
url: '/cw/approval/dept', // 🔧 修复:使用部门审批接口
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
@@ -136,7 +136,7 @@ export const batchApproveApplication = async (data: CwApprovalForm) => {
|
||||
}
|
||||
|
||||
// 检查是否有失败的项目
|
||||
const failures = results.filter(r => !r.success);
|
||||
const failures = results.filter((r) => !r.success);
|
||||
if (failures.length > 0) {
|
||||
console.error('🔧 批量审批部分失败:', failures);
|
||||
throw new Error(`批量审批完成,${failures.length}个项目审批失败`);
|
||||
|
||||
@@ -15,12 +15,12 @@ export const financeApproveApplication = (data: FinanceApprovalForm): AxiosPromi
|
||||
approveAction: data.approvalResult,
|
||||
approveOpinion: data.approvalComment
|
||||
});
|
||||
|
||||
|
||||
// 如果选择了院领导,添加参数
|
||||
if (data.selectedApproverId) {
|
||||
params.append('selectedApproverId', data.selectedApproverId.toString());
|
||||
}
|
||||
|
||||
|
||||
return request({
|
||||
url: '/cw/approval/finance',
|
||||
method: 'post',
|
||||
@@ -34,9 +34,9 @@ export const financeApproveApplication = (data: FinanceApprovalForm): AxiosPromi
|
||||
// 财务批量审批操作
|
||||
export const batchFinanceApproveApplication = (dataList: FinanceApprovalForm[]): Promise<any> => {
|
||||
// 前端模拟批量操作,逐个调用单个审批接口
|
||||
const promises = dataList.map(item => financeApproveApplication(item));
|
||||
|
||||
return Promise.all(promises).then(results => {
|
||||
const promises = dataList.map((item) => financeApproveApplication(item));
|
||||
|
||||
return Promise.all(promises).then((results) => {
|
||||
return {
|
||||
data: results,
|
||||
code: 200,
|
||||
|
||||
@@ -26,9 +26,9 @@ export const leaderApproveApplication = (data: LeaderApprovalForm): AxiosPromise
|
||||
// 分管领导批量审批操作
|
||||
export const batchLeaderApproveApplication = (dataList: LeaderApprovalForm[]): AxiosPromise<any> => {
|
||||
// 前端模拟批量操作,逐个调用单个审批接口
|
||||
const promises = dataList.map(item => leaderApproveApplication(item));
|
||||
const promises = dataList.map((item) => leaderApproveApplication(item));
|
||||
|
||||
return Promise.all(promises).then(results => {
|
||||
return Promise.all(promises).then((results) => {
|
||||
return {
|
||||
data: results,
|
||||
code: 200,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* 财务项目预算审批 - API服务
|
||||
*
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2025-01-26
|
||||
*/
|
||||
@@ -214,4 +214,4 @@ export const delApproverConfig = (id: string | number | Array<string | number>)
|
||||
url: '/cw/approverConfig/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
import request from '@/utils/request'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
export interface StatisticsQuery {
|
||||
budgetYear?: string
|
||||
budgetYear?: string;
|
||||
}
|
||||
|
||||
// 获取项目清单(用于统计页面)
|
||||
@@ -11,7 +11,7 @@ export function getStatisticsList(query: StatisticsQuery): AxiosPromise<any> {
|
||||
url: '/cw/application/statistics/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取状态统计
|
||||
@@ -20,7 +20,7 @@ export function getStatusStatistics(budgetYear?: string): AxiosPromise<any> {
|
||||
url: '/cw/application/statistics/status',
|
||||
method: 'get',
|
||||
params: { budgetYear }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取部门预算汇总统计
|
||||
@@ -29,7 +29,7 @@ export function getDepartmentStatistics(budgetYear?: string): AxiosPromise<any>
|
||||
url: '/cw/application/statistics/department',
|
||||
method: 'get',
|
||||
params: { budgetYear }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取年度汇总统计
|
||||
@@ -37,5 +37,5 @@ export function getYearlyStatistics(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/cw/application/statistics/yearly',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -104,6 +104,7 @@ export interface RecordQuery {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
courseId?: number | string;
|
||||
courseName?: string;
|
||||
userId?: number | string;
|
||||
userName?: string;
|
||||
completionStatus?: string;
|
||||
|
||||
@@ -63,7 +63,6 @@ export interface SysRegionVO {
|
||||
* 子节点列表(用于树形结构)
|
||||
*/
|
||||
children?: SysRegionVO[];
|
||||
|
||||
}
|
||||
|
||||
export interface SysRegionForm extends BaseEntity {
|
||||
@@ -126,11 +125,9 @@ export interface SysRegionForm extends BaseEntity {
|
||||
* 逻辑删除标识(0未删除 1已删除)
|
||||
*/
|
||||
deleted?: number;
|
||||
|
||||
}
|
||||
|
||||
export interface SysRegionQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 行政区划编码
|
||||
*/
|
||||
@@ -181,11 +178,8 @@ export interface SysRegionQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import request from '@/utils/request'
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 重置bucket访问密码
|
||||
@@ -11,7 +11,7 @@ export function resetBucketPassword(bucketName: string, newPassword: string) {
|
||||
url: '/system/bucket-password/reset',
|
||||
method: 'post',
|
||||
params: { bucketName, newPassword }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,7 +23,7 @@ export function getBucketPasswordInfo(bucketName: string) {
|
||||
return request({
|
||||
url: `/system/bucket-password/info/${bucketName}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export function getBucketAccessRecords(bucketName: string, limit: number = 10) {
|
||||
url: `/system/bucket-password/records/${bucketName}`,
|
||||
method: 'get',
|
||||
params: { limit }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,7 +51,7 @@ export function validateBucketPassword(bucketName: string, password: string) {
|
||||
url: '/system/bucket-password/validate',
|
||||
method: 'post',
|
||||
params: { bucketName, password }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,12 +60,12 @@ export function validateBucketPassword(bucketName: string, password: string) {
|
||||
* @returns 生成的密码
|
||||
*/
|
||||
export function generateStrongPassword(length: number = 12): string {
|
||||
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*'
|
||||
let password = ''
|
||||
const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';
|
||||
let password = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
password += charset.charAt(Math.floor(Math.random() * charset.length))
|
||||
password += charset.charAt(Math.floor(Math.random() * charset.length));
|
||||
}
|
||||
return password
|
||||
return password;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -74,51 +74,51 @@ export function generateStrongPassword(length: number = 12): string {
|
||||
* @returns 密码强度评估
|
||||
*/
|
||||
export function validatePasswordStrength(password: string): {
|
||||
isValid: boolean
|
||||
score: number
|
||||
suggestions: string[]
|
||||
isValid: boolean;
|
||||
score: number;
|
||||
suggestions: string[];
|
||||
} {
|
||||
const suggestions: string[] = []
|
||||
let score = 0
|
||||
const suggestions: string[] = [];
|
||||
let score = 0;
|
||||
|
||||
// 长度检查
|
||||
if (password.length >= 8) {
|
||||
score += 1
|
||||
score += 1;
|
||||
} else {
|
||||
suggestions.push('密码长度至少8位')
|
||||
suggestions.push('密码长度至少8位');
|
||||
}
|
||||
|
||||
// 包含大写字母
|
||||
if (/[A-Z]/.test(password)) {
|
||||
score += 1
|
||||
score += 1;
|
||||
} else {
|
||||
suggestions.push('包含大写字母')
|
||||
suggestions.push('包含大写字母');
|
||||
}
|
||||
|
||||
// 包含小写字母
|
||||
if (/[a-z]/.test(password)) {
|
||||
score += 1
|
||||
score += 1;
|
||||
} else {
|
||||
suggestions.push('包含小写字母')
|
||||
suggestions.push('包含小写字母');
|
||||
}
|
||||
|
||||
// 包含数字
|
||||
if (/\d/.test(password)) {
|
||||
score += 1
|
||||
score += 1;
|
||||
} else {
|
||||
suggestions.push('包含数字')
|
||||
suggestions.push('包含数字');
|
||||
}
|
||||
|
||||
// 包含特殊字符
|
||||
if (/[!@#$%^&*]/.test(password)) {
|
||||
score += 1
|
||||
score += 1;
|
||||
} else {
|
||||
suggestions.push('包含特殊字符')
|
||||
suggestions.push('包含特殊字符');
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: score >= 4,
|
||||
score,
|
||||
suggestions
|
||||
}
|
||||
};
|
||||
}
|
||||
+28
-28
@@ -1,4 +1,4 @@
|
||||
import request from '@/utils/request'
|
||||
import request from '@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取文件临时访问URL
|
||||
@@ -15,7 +15,7 @@ export function getFileAccessUrl(ossId: number | string | bigint, bucketPassword
|
||||
bucketPassword,
|
||||
expireSeconds
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,7 +34,7 @@ export function getBatchFileAccessUrl(ossIds: number[], bucketPassword?: string,
|
||||
bucketPassword,
|
||||
expireSeconds
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ export function getFileDownloadUrl(ossId: number | string | bigint, bucketPasswo
|
||||
bucketPassword,
|
||||
expireSeconds
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +70,7 @@ export function getFilePreviewUrl(ossId: number | string | bigint, bucketPasswor
|
||||
bucketPassword,
|
||||
expireSeconds
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,32 +83,32 @@ export function getFilePreviewUrl(ossId: number | string | bigint, bucketPasswor
|
||||
export async function secureDownloadFile(ossId: number | string | bigint, fileName: string, bucketPassword?: string) {
|
||||
try {
|
||||
// 获取临时下载URL
|
||||
const { data: downloadUrl } = await getFileDownloadUrl(ossId, bucketPassword)
|
||||
const { data: downloadUrl } = await getFileDownloadUrl(ossId, bucketPassword);
|
||||
|
||||
// 使用fetch下载文件
|
||||
const response = await fetch(downloadUrl)
|
||||
const response = await fetch(downloadUrl);
|
||||
if (!response.ok) {
|
||||
throw new Error('下载失败')
|
||||
throw new Error('下载失败');
|
||||
}
|
||||
|
||||
const blob = await response.blob()
|
||||
const blob = await response.blob();
|
||||
|
||||
// 创建下载链接
|
||||
const url = URL.createObjectURL(blob)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.download = fileName
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
const url = URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = fileName;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
|
||||
// 释放内存
|
||||
URL.revokeObjectURL(url)
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
return Promise.resolve()
|
||||
return Promise.resolve();
|
||||
} catch (error) {
|
||||
console.error('文件下载失败:', error)
|
||||
return Promise.reject(error)
|
||||
console.error('文件下载失败:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,20 +122,20 @@ export async function secureDownloadFile(ossId: number | string | bigint, fileNa
|
||||
export async function securePreviewFile(ossId: number | string | bigint, contentType?: string, bucketPassword?: string) {
|
||||
try {
|
||||
// 获取临时预览URL
|
||||
const { data: previewUrl } = await getFilePreviewUrl(ossId, bucketPassword)
|
||||
const { data: previewUrl } = await getFilePreviewUrl(ossId, bucketPassword);
|
||||
|
||||
// 根据文件类型选择预览方式
|
||||
if (contentType?.startsWith('image/')) {
|
||||
// 图片直接返回URL用于预览
|
||||
return Promise.resolve(previewUrl)
|
||||
return Promise.resolve(previewUrl);
|
||||
} else {
|
||||
// 其他文件在新窗口打开
|
||||
window.open(previewUrl, '_blank')
|
||||
return Promise.resolve(previewUrl)
|
||||
window.open(previewUrl, '_blank');
|
||||
return Promise.resolve(previewUrl);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('文件预览失败:', error)
|
||||
return Promise.reject(error)
|
||||
console.error('文件预览失败:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ export async function securePreviewFile(ossId: number | string | bigint, content
|
||||
export function getBucketPasswordHint(bucketName: string) {
|
||||
// 这里可以根据bucket名称返回相应的密码提示
|
||||
// 例如:从配置中获取密码提示信息
|
||||
return `请输入 ${bucketName} bucket 的访问密码`
|
||||
return `请输入 ${bucketName} bucket 的访问密码`;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -157,5 +157,5 @@ export function getBucketPasswordHint(bucketName: string) {
|
||||
*/
|
||||
export function validateBucketPassword(password: string): boolean {
|
||||
// 简单的密码格式验证
|
||||
return password && password.length >= 6
|
||||
return password && password.length >= 6;
|
||||
}
|
||||
@@ -163,7 +163,6 @@ export interface StudentLeaveVO {
|
||||
* 销假备注
|
||||
*/
|
||||
cancelRemark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentLeaveForm extends BaseEntity {
|
||||
@@ -336,11 +335,9 @@ export interface StudentLeaveForm extends BaseEntity {
|
||||
* 操作类型:add-新增,update-修改,view-查看
|
||||
*/
|
||||
type?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentLeaveQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@@ -501,11 +498,8 @@ export interface StudentLeaveQuery extends PageQuery {
|
||||
*/
|
||||
cancelRemark?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import { ClassInfoVO, ClassInfoQuery, ClassInfoForm, OptionData } from './classInfo/types'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types'
|
||||
import { treeselect as deptTreeselect, listDeptExcludeChild } from '@/api/system/dept'
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ClassInfoVO, ClassInfoQuery, ClassInfoForm, OptionData } from './classInfo/types';
|
||||
import { getToken } from '@/utils/auth';
|
||||
import { DeptTreeVO, DeptVO } from '@/api/system/dept/types';
|
||||
import { treeselect as deptTreeselect, listDeptExcludeChild } from '@/api/system/dept';
|
||||
|
||||
// 通用类型定义
|
||||
interface TableDataInfo<T> {
|
||||
@@ -27,8 +27,8 @@ export const listClassInfo = (query: ClassInfoQuery): AxiosPromise<TableDataInfo
|
||||
url: '/xg/classInfo/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询班级信息详细
|
||||
@@ -37,8 +37,8 @@ export const getClassInfo = (id: string | number): AxiosPromise<R<ClassInfoVO>>
|
||||
return request({
|
||||
url: '/xg/classInfo/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增班级信息
|
||||
@@ -48,8 +48,8 @@ export const addClassInfo = (data: ClassInfoForm): AxiosPromise<R<void>> => {
|
||||
url: '/xg/classInfo',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改班级信息
|
||||
@@ -59,8 +59,8 @@ export const updateClassInfo = (data: ClassInfoForm): AxiosPromise<R<void>> => {
|
||||
url: '/xg/classInfo',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除班级信息
|
||||
@@ -69,8 +69,8 @@ export const delClassInfo = (id: string | number | Array<string | number>): Axio
|
||||
return request({
|
||||
url: '/xg/classInfo/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 导出班级信息
|
||||
@@ -80,8 +80,8 @@ export const exportClassInfo = (query: ClassInfoQuery): AxiosPromise<any> => {
|
||||
url: '/xg/classInfo/export',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据班级代码查询班级信息
|
||||
@@ -90,8 +90,8 @@ export const getClassInfoByCode = (classCode: string): AxiosPromise<R<ClassInfoV
|
||||
return request({
|
||||
url: '/xg/classInfo/getByClassCode/' + classCode,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据年级查询班级信息列表
|
||||
@@ -100,8 +100,8 @@ export const getClassInfoByGrade = (grade: string): AxiosPromise<R<ClassInfoVO[]
|
||||
return request({
|
||||
url: '/xg/classInfo/getByGrade/' + grade,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据学院代码查询班级信息列表
|
||||
@@ -110,8 +110,8 @@ export const getClassInfoByCollege = (collegeCode: string): AxiosPromise<R<Class
|
||||
return request({
|
||||
url: '/xg/classInfo/getByCollegeCode/' + collegeCode,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据专业代码查询班级信息列表
|
||||
@@ -120,8 +120,8 @@ export const getClassInfoByMajor = (majorCode: string): AxiosPromise<R<ClassInfo
|
||||
return request({
|
||||
url: '/xg/classInfo/getByMajorCode/' + majorCode,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据辅导员ID查询班级信息列表
|
||||
@@ -130,8 +130,8 @@ export const getClassInfoByCounselor = (counselorId: number): AxiosPromise<R<Cla
|
||||
return request({
|
||||
url: '/xg/classInfo/getByCounselorId/' + counselorId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 根据班主任ID查询班级信息列表
|
||||
@@ -140,18 +140,18 @@ export const getClassInfoByClassTeacher = (classTeacherId: number): AxiosPromise
|
||||
return request({
|
||||
url: '/xg/classInfo/getByClassTeacherId/' + classTeacherId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取班级选项列表(用于下拉框)
|
||||
*/
|
||||
export const getClassOptions = (): AxiosPromise<R<ClassInfoVO[]>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/getClassOptions', // 修正路径:从 /options 改为 /getClassOptions
|
||||
url: '/xg/classInfo/getClassOptions', // 修正路径:从 /options 改为 /getClassOptions
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新班级学生统计
|
||||
@@ -159,9 +159,9 @@ export const getClassOptions = (): AxiosPromise<R<ClassInfoVO[]>> => {
|
||||
export const updateStudentCount = (classId: number): AxiosPromise<R<void>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/updateStudentCount/' + classId,
|
||||
method: 'post' // 修正HTTP方法:从 put 改为 post
|
||||
})
|
||||
}
|
||||
method: 'post' // 修正HTTP方法:从 put 改为 post
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 批量更新班级学生统计
|
||||
@@ -169,10 +169,10 @@ export const updateStudentCount = (classId: number): AxiosPromise<R<void>> => {
|
||||
export const batchUpdateStudentCount = (classIds: number[]): AxiosPromise<R<void>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/batchUpdateStudentCount',
|
||||
method: 'post', // 修正HTTP方法:从 put 改为 post
|
||||
method: 'post', // 修正HTTP方法:从 put 改为 post
|
||||
data: classIds
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 启用班级
|
||||
@@ -180,9 +180,9 @@ export const batchUpdateStudentCount = (classIds: number[]): AxiosPromise<R<void
|
||||
export const enableClass = (id: number): AxiosPromise<R<void>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/enable/' + id,
|
||||
method: 'post' // 修正HTTP方法:从 put 改为 post
|
||||
})
|
||||
}
|
||||
method: 'post' // 修正HTTP方法:从 put 改为 post
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 禁用班级
|
||||
@@ -190,9 +190,9 @@ export const enableClass = (id: number): AxiosPromise<R<void>> => {
|
||||
export const disableClass = (id: number): AxiosPromise<R<void>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/disable/' + id,
|
||||
method: 'post' // 修正HTTP方法:从 put 改为 post
|
||||
})
|
||||
}
|
||||
method: 'post' // 修正HTTP方法:从 put 改为 post
|
||||
});
|
||||
};
|
||||
|
||||
// ================================
|
||||
// 统计数据接口 - 新增
|
||||
@@ -205,8 +205,8 @@ export const getClassStatistics = (): AxiosPromise<R<any>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/statistics',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 统计各学院班级数量
|
||||
@@ -215,8 +215,8 @@ export const countClassByCollege = (): AxiosPromise<R<any[]>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/statistics/college',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 统计各年级班级数量
|
||||
@@ -225,8 +225,8 @@ export const countClassByGrade = (): AxiosPromise<R<any[]>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/statistics/grade',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 统计各专业班级数量
|
||||
@@ -235,8 +235,8 @@ export const countClassByMajor = (): AxiosPromise<R<any[]>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/statistics/major',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 统计班级状态分布
|
||||
@@ -245,8 +245,8 @@ export const countClassByStatus = (): AxiosPromise<R<any[]>> => {
|
||||
return request({
|
||||
url: '/xg/classInfo/statistics/status',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取学院选项
|
||||
@@ -255,8 +255,8 @@ export const getCollegeOptions = (): AxiosPromise<R<any[]>> => {
|
||||
return request({
|
||||
url: '/xg/studentInfo/options/colleges',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 从系统部门获取学院选项(二级学院)
|
||||
@@ -267,7 +267,7 @@ export const getDeptCollegeOptions = (): AxiosPromise<DeptTreeVO[]> => {
|
||||
url: '/system/dept/treeselect',
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 从系统部门获取专业选项(学院的下级部门)
|
||||
@@ -287,7 +287,7 @@ export const getDeptMajorOptions = (deptId: string | number): AxiosPromise<DeptV
|
||||
url: '/system/dept/list/exclude/' + numericDeptId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取辅导员选项
|
||||
@@ -296,14 +296,14 @@ export const getCounselorOptions = (): AxiosPromise<R<any[]>> => {
|
||||
return request({
|
||||
url: '/xg/studentInfo/options/counselors',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取班主任选项列表
|
||||
*/
|
||||
export const getClassTeacherOptions = (): AxiosPromise<R<OptionData[]>> => {
|
||||
console.log('调用班主任API: /xg/classInfo/teacherOptions')
|
||||
console.log('调用班主任API: /xg/classInfo/teacherOptions');
|
||||
return request({
|
||||
url: '/xg/classInfo/teacherOptions',
|
||||
method: 'get',
|
||||
@@ -312,5 +312,5 @@ export const getClassTeacherOptions = (): AxiosPromise<R<OptionData[]>> => {
|
||||
'Authorization': 'Bearer ' + getToken(),
|
||||
'clientid': import.meta.env.VITE_APP_CLIENT_ID
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
+126
-126
@@ -1,121 +1,121 @@
|
||||
import request from '@/utils/request'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
// ========== 统计分析相关类型定义 ==========
|
||||
|
||||
// 统计查询参数
|
||||
export interface StatisticsQuery {
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
configName?: string
|
||||
configType?: string
|
||||
dimensionType?: string
|
||||
isEnabled?: boolean
|
||||
createTime?: string[]
|
||||
pageNum?: number;
|
||||
pageSize?: number;
|
||||
configName?: string;
|
||||
configType?: string;
|
||||
dimensionType?: string;
|
||||
isEnabled?: boolean;
|
||||
createTime?: string[];
|
||||
}
|
||||
|
||||
// 统计分析查询参数
|
||||
export interface StatisticsAnalysisQuery {
|
||||
statisticsType?: string
|
||||
dimension?: string
|
||||
field?: string
|
||||
groupBy?: string
|
||||
conditions?: Record<string, any>
|
||||
startTime?: string
|
||||
endTime?: string
|
||||
collegeIds?: number[]
|
||||
majorIds?: number[]
|
||||
classIds?: number[]
|
||||
grades?: string[]
|
||||
genders?: string[]
|
||||
politicalStatuses?: string[]
|
||||
nationalities?: string[]
|
||||
studentStatuses?: string[]
|
||||
trainingTypes?: string[]
|
||||
useCache?: boolean
|
||||
statisticsType?: string;
|
||||
dimension?: string;
|
||||
field?: string;
|
||||
groupBy?: string;
|
||||
conditions?: Record<string, any>;
|
||||
startTime?: string;
|
||||
endTime?: string;
|
||||
collegeIds?: number[];
|
||||
majorIds?: number[];
|
||||
classIds?: number[];
|
||||
grades?: string[];
|
||||
genders?: string[];
|
||||
politicalStatuses?: string[];
|
||||
nationalities?: string[];
|
||||
studentStatuses?: string[];
|
||||
trainingTypes?: string[];
|
||||
useCache?: boolean;
|
||||
}
|
||||
|
||||
// 统计配置视图对象
|
||||
export interface StatisticsConfigVo {
|
||||
id?: number
|
||||
configName?: string
|
||||
configType?: string
|
||||
dimensionType?: string
|
||||
queryConditions?: string
|
||||
displaySettings?: string
|
||||
chartType?: string
|
||||
isEnabled?: boolean
|
||||
sortOrder?: number
|
||||
remark?: string
|
||||
createBy?: number
|
||||
createTime?: string
|
||||
updateBy?: number
|
||||
updateTime?: string
|
||||
id?: number;
|
||||
configName?: string;
|
||||
configType?: string;
|
||||
dimensionType?: string;
|
||||
queryConditions?: string;
|
||||
displaySettings?: string;
|
||||
chartType?: string;
|
||||
isEnabled?: boolean;
|
||||
sortOrder?: number;
|
||||
remark?: string;
|
||||
createBy?: number;
|
||||
createTime?: string;
|
||||
updateBy?: number;
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
// 统计配置业务对象
|
||||
export interface StatisticsConfigBo {
|
||||
id?: number
|
||||
configName?: string
|
||||
configType?: string
|
||||
dimensionType?: string
|
||||
queryConditions?: string
|
||||
displaySettings?: string
|
||||
chartType?: string
|
||||
isEnabled?: boolean
|
||||
sortOrder?: number
|
||||
remark?: string
|
||||
id?: number;
|
||||
configName?: string;
|
||||
configType?: string;
|
||||
dimensionType?: string;
|
||||
queryConditions?: string;
|
||||
displaySettings?: string;
|
||||
chartType?: string;
|
||||
isEnabled?: boolean;
|
||||
sortOrder?: number;
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
// 统计结果视图对象
|
||||
export interface StatisticsResultVo {
|
||||
title?: string
|
||||
type?: string
|
||||
dimension?: string
|
||||
data?: Array<Record<string, any>>
|
||||
total?: number
|
||||
statisticsTime?: string
|
||||
fromCache?: boolean
|
||||
cacheKey?: string
|
||||
extra?: Record<string, any>
|
||||
chartConfig?: Record<string, any>
|
||||
groupData?: Record<string, Array<Record<string, any>>>
|
||||
summary?: Record<string, any>
|
||||
title?: string;
|
||||
type?: string;
|
||||
dimension?: string;
|
||||
data?: Array<Record<string, any>>;
|
||||
total?: number;
|
||||
statisticsTime?: string;
|
||||
fromCache?: boolean;
|
||||
cacheKey?: string;
|
||||
extra?: Record<string, any>;
|
||||
chartConfig?: Record<string, any>;
|
||||
groupData?: Record<string, Array<Record<string, any>>>;
|
||||
summary?: Record<string, any>;
|
||||
}
|
||||
|
||||
// 统计报表视图对象
|
||||
export interface StatisticsReportVo {
|
||||
reportType?: string
|
||||
title?: string
|
||||
description?: string
|
||||
data?: Array<Record<string, any>>
|
||||
summary?: Record<string, any>
|
||||
generateTime?: string
|
||||
reportType?: string;
|
||||
title?: string;
|
||||
description?: string;
|
||||
data?: Array<Record<string, any>>;
|
||||
summary?: Record<string, any>;
|
||||
generateTime?: string;
|
||||
metadata?: {
|
||||
total: number
|
||||
conditions: Record<string, any>
|
||||
}
|
||||
total: number;
|
||||
conditions: Record<string, any>;
|
||||
};
|
||||
}
|
||||
|
||||
// 统计缓存信息
|
||||
export interface StatisticsCacheInfo {
|
||||
key?: string
|
||||
hitCount?: number
|
||||
missCount?: number
|
||||
hitRate?: number
|
||||
size?: number
|
||||
lastAccessTime?: string
|
||||
createTime?: string
|
||||
expireTime?: string
|
||||
key?: string;
|
||||
hitCount?: number;
|
||||
missCount?: number;
|
||||
hitRate?: number;
|
||||
size?: number;
|
||||
lastAccessTime?: string;
|
||||
createTime?: string;
|
||||
expireTime?: string;
|
||||
}
|
||||
|
||||
// 导出参数
|
||||
export interface StatisticsExportQuery {
|
||||
dimension?: string
|
||||
format?: 'excel' | 'csv'
|
||||
includeChart?: boolean
|
||||
conditions?: Record<string, any>
|
||||
reportType?: string
|
||||
dimension?: string;
|
||||
format?: 'excel' | 'csv';
|
||||
includeChart?: boolean;
|
||||
conditions?: Record<string, any>;
|
||||
reportType?: string;
|
||||
}
|
||||
|
||||
// ========== 统计配置管理API ==========
|
||||
@@ -126,7 +126,7 @@ export function listStatisticsConfig(query: StatisticsQuery): AxiosPromise<any>
|
||||
url: '/xg/statisticsConfig/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取统计配置详情
|
||||
@@ -134,7 +134,7 @@ export function getStatisticsConfig(id: number): AxiosPromise<StatisticsConfigVo
|
||||
return request({
|
||||
url: `/xg/statisticsConfig/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 新增统计配置
|
||||
@@ -143,7 +143,7 @@ export function addStatisticsConfig(data: StatisticsConfigBo): AxiosPromise<any>
|
||||
url: '/xg/statisticsConfig',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 修改统计配置
|
||||
@@ -152,7 +152,7 @@ export function updateStatisticsConfig(data: StatisticsConfigBo): AxiosPromise<a
|
||||
url: '/xg/statisticsConfig',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 删除统计配置
|
||||
@@ -160,7 +160,7 @@ export function delStatisticsConfig(ids: number[]): AxiosPromise<any> {
|
||||
return request({
|
||||
url: `/xg/statisticsConfig/${ids}`,
|
||||
method: 'delete'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 导出统计配置
|
||||
@@ -169,7 +169,7 @@ export function exportStatisticsConfig(query: StatisticsQuery): AxiosPromise<any
|
||||
url: '/xg/statisticsConfig/export',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 启用/禁用统计配置
|
||||
@@ -178,7 +178,7 @@ export function changeStatisticsConfigStatus(id: number, status: boolean): Axios
|
||||
url: `/xg/statisticsConfig/changeStatus`,
|
||||
method: 'put',
|
||||
data: { id, isEnabled: status }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 统计分析API ==========
|
||||
@@ -188,7 +188,7 @@ export function getStatisticsOverview(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/overview',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 学院统计
|
||||
@@ -197,7 +197,7 @@ export function getCollegeStatistics(query: StatisticsAnalysisQuery): AxiosPromi
|
||||
url: '/xg/statisticsAnalysis/college',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 专业统计
|
||||
@@ -206,7 +206,7 @@ export function getMajorStatistics(query: StatisticsAnalysisQuery): AxiosPromise
|
||||
url: '/xg/statisticsAnalysis/major',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 班级统计
|
||||
@@ -215,7 +215,7 @@ export function getClassStatistics(query: StatisticsAnalysisQuery): AxiosPromise
|
||||
url: '/xg/statisticsAnalysis/class',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 年级统计
|
||||
@@ -224,7 +224,7 @@ export function getGradeStatistics(query: StatisticsAnalysisQuery): AxiosPromise
|
||||
url: '/xg/statisticsAnalysis/grade',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 性别统计
|
||||
@@ -233,7 +233,7 @@ export function getGenderStatistics(query: StatisticsAnalysisQuery): AxiosPromis
|
||||
url: '/xg/statisticsAnalysis/gender',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 年龄统计
|
||||
@@ -242,7 +242,7 @@ export function getAgeStatistics(query: StatisticsAnalysisQuery): AxiosPromise<S
|
||||
url: '/xg/statisticsAnalysis/age',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 政治面貌统计
|
||||
@@ -251,7 +251,7 @@ export function getPoliticalStatusStatistics(query: StatisticsAnalysisQuery): Ax
|
||||
url: '/xg/statisticsAnalysis/political',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 民族统计
|
||||
@@ -260,7 +260,7 @@ export function getNationStatistics(query: StatisticsAnalysisQuery): AxiosPromis
|
||||
url: '/xg/statisticsAnalysis/nation',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 生源地统计
|
||||
@@ -269,7 +269,7 @@ export function getSourceRegionStatistics(query: StatisticsAnalysisQuery): Axios
|
||||
url: '/xg/statisticsAnalysis/sourceRegion',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 血型统计
|
||||
@@ -278,7 +278,7 @@ export function getBloodTypeStatistics(query: StatisticsAnalysisQuery): AxiosPro
|
||||
url: '/xg/statisticsAnalysis/bloodType',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 宗教信仰统计
|
||||
@@ -287,7 +287,7 @@ export function getReligionStatistics(query: StatisticsAnalysisQuery): AxiosProm
|
||||
url: '/xg/statisticsAnalysis/religion',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 学籍状态统计
|
||||
@@ -296,7 +296,7 @@ export function getStudentStatusStatistics(query: StatisticsAnalysisQuery): Axio
|
||||
url: '/xg/statisticsAnalysis/studentStatus',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 按维度统计 - 培养方式统计
|
||||
@@ -305,7 +305,7 @@ export function getTrainingTypeStatistics(query: StatisticsAnalysisQuery): Axios
|
||||
url: '/xg/statisticsAnalysis/trainingType',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 高级统计 - 身高统计
|
||||
@@ -314,7 +314,7 @@ export function getHeightStatistics(query: StatisticsAnalysisQuery): AxiosPromis
|
||||
url: '/xg/statisticsAnalysis/height',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 高级统计 - 体重统计
|
||||
@@ -323,7 +323,7 @@ export function getWeightStatistics(query: StatisticsAnalysisQuery): AxiosPromis
|
||||
url: '/xg/statisticsAnalysis/weight',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 多维度组合统计
|
||||
@@ -332,7 +332,7 @@ export function getMultiDimensionStatistics(query: StatisticsAnalysisQuery): Axi
|
||||
url: '/xg/statisticsAnalysis/multiDimension',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 时间趋势统计
|
||||
@@ -341,7 +341,7 @@ export function getTimeTrendStatistics(query: StatisticsAnalysisQuery): AxiosPro
|
||||
url: '/xg/statisticsAnalysis/timeTrend',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 统计报表API ==========
|
||||
@@ -352,7 +352,7 @@ export function generateStudentSummaryReport(query: StatisticsAnalysisQuery): Ax
|
||||
url: '/xg/statisticsAnalysis/report/studentSummary',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 生成班级统计报表
|
||||
@@ -361,7 +361,7 @@ export function generateClassStatisticsReport(query: StatisticsAnalysisQuery): A
|
||||
url: '/xg/statisticsAnalysis/report/classStatistics',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 生成学院统计报表
|
||||
@@ -370,7 +370,7 @@ export function generateCollegeStatisticsReport(query: StatisticsAnalysisQuery):
|
||||
url: '/xg/statisticsAnalysis/report/collegeStatistics',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 生成困难学生统计报表
|
||||
@@ -379,7 +379,7 @@ export function generateDifficultStudentReport(query: StatisticsAnalysisQuery):
|
||||
url: '/xg/statisticsAnalysis/report/difficultStudent',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 生成特殊群体统计报表
|
||||
@@ -388,7 +388,7 @@ export function generateSpecialGroupReport(query: StatisticsAnalysisQuery): Axio
|
||||
url: '/xg/statisticsAnalysis/report/specialGroup',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 统计导出API ==========
|
||||
@@ -400,7 +400,7 @@ export function exportStatisticsResult(query: StatisticsExportQuery): AxiosPromi
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 导出统计报表
|
||||
@@ -410,7 +410,7 @@ export function exportStatisticsReport(query: StatisticsExportQuery): AxiosPromi
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 统计缓存API ==========
|
||||
@@ -420,7 +420,7 @@ export function getCacheStatistics(): AxiosPromise<StatisticsCacheInfo> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/cache/info',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 清空统计缓存
|
||||
@@ -428,7 +428,7 @@ export function clearStatisticsCache(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/cache/clear',
|
||||
method: 'delete'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 预热统计缓存
|
||||
@@ -436,7 +436,7 @@ export function warmupStatisticsCache(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/cache/warmup',
|
||||
method: 'post'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ========== 辅助API ==========
|
||||
@@ -446,7 +446,7 @@ export function getStatisticsDimensionOptions(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/dimensionOptions',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取图表类型选项
|
||||
@@ -454,7 +454,7 @@ export function getChartTypeOptions(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/chartTypeOptions',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取学院选项
|
||||
@@ -462,7 +462,7 @@ export function getCollegeOptions(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/collegeOptions',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取专业选项
|
||||
@@ -471,7 +471,7 @@ export function getMajorOptions(collegeCode?: string): AxiosPromise<any> {
|
||||
url: '/xg/statisticsAnalysis/majorOptions',
|
||||
method: 'get',
|
||||
params: { collegeCode }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取班级选项
|
||||
@@ -480,7 +480,7 @@ export function getClassOptions(majorCode?: string): AxiosPromise<any> {
|
||||
url: '/xg/statisticsAnalysis/classOptions',
|
||||
method: 'get',
|
||||
params: { majorCode }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取年级选项
|
||||
@@ -488,7 +488,7 @@ export function getGradeOptions(): AxiosPromise<any> {
|
||||
return request({
|
||||
url: '/xg/statisticsAnalysis/gradeOptions',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 执行统计配置
|
||||
@@ -497,5 +497,5 @@ export function executeStatisticsConfig(configId: number, query: StatisticsAnaly
|
||||
url: `/xg/statisticsAnalysis/executeConfig/${configId}`,
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
});
|
||||
}
|
||||
+164
-164
@@ -1,146 +1,146 @@
|
||||
import request from '@/utils/request'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { getToken } from '@/utils/auth';
|
||||
|
||||
// 学生信息数据类型
|
||||
export interface StudentInfo {
|
||||
id?: number
|
||||
studentNo?: string
|
||||
name?: string
|
||||
nameEnglish?: string
|
||||
formerName?: string
|
||||
namePinyin?: string
|
||||
gender?: string
|
||||
birthDate?: string
|
||||
idCard?: string
|
||||
phone?: string
|
||||
email?: string
|
||||
nation?: string
|
||||
politicalStatus?: string
|
||||
maritalStatus?: string
|
||||
religion?: string
|
||||
photoUrl?: string
|
||||
photoPath?: string
|
||||
majorCode?: string
|
||||
majorName?: string
|
||||
classCode?: string
|
||||
className?: string
|
||||
collegeCode?: string
|
||||
collegeName?: string
|
||||
grade?: string
|
||||
enrollmentYear?: number
|
||||
enrollmentDate?: string
|
||||
schoolSystem?: number
|
||||
educationLevel?: string
|
||||
trainingType?: string
|
||||
admissionCategory?: string
|
||||
sourceRegion?: string
|
||||
middleSchool?: string
|
||||
studentStatus?: string
|
||||
infoStatus?: string
|
||||
counselorName?: string
|
||||
classTeacherName?: string
|
||||
qq?: string
|
||||
wechat?: string
|
||||
dormitoryBuilding?: string
|
||||
dormitoryRoom?: string
|
||||
homeAddress?: string
|
||||
currentAddress?: string
|
||||
postalCode?: string
|
||||
householdRegisterType?: string
|
||||
hukouLocation?: string
|
||||
height?: number
|
||||
weight?: number
|
||||
bloodType?: string
|
||||
healthStatus?: string
|
||||
specialCondition?: string
|
||||
medicalHistory?: string
|
||||
allergies?: string
|
||||
disabilityType?: string
|
||||
disabilityLevel?: string
|
||||
emergencyContactName?: string
|
||||
emergencyContactPhone?: string
|
||||
emergencyContactRelation?: string
|
||||
fatherName?: string
|
||||
fatherPhone?: string
|
||||
fatherWorkUnit?: string
|
||||
motherName?: string
|
||||
motherPhone?: string
|
||||
motherWorkUnit?: string
|
||||
guardianName?: string
|
||||
guardianPhone?: string
|
||||
guardianRelation?: string
|
||||
familyIncome?: string
|
||||
familyEconomicStatus?: string
|
||||
familyMembers?: number
|
||||
bankCardNo?: string
|
||||
bankName?: string
|
||||
bankBranch?: string
|
||||
cardHolderName?: string
|
||||
isPoorStudent?: number
|
||||
isMinority?: number
|
||||
isDisabled?: number
|
||||
isOrphan?: number
|
||||
isLeftBehindChild?: number
|
||||
isSingleChild?: number
|
||||
hasLoan?: number
|
||||
loanAmount?: number
|
||||
specialties?: string
|
||||
awards?: string
|
||||
violations?: string
|
||||
socialActivities?: string
|
||||
dataSource?: string
|
||||
lastAuditTime?: string
|
||||
isComplete?: number
|
||||
completionRate?: number
|
||||
extField1?: string
|
||||
extField2?: string
|
||||
extField3?: string
|
||||
extField4?: string
|
||||
extField5?: string
|
||||
remark?: string
|
||||
createTime?: string
|
||||
updateTime?: string
|
||||
id?: number;
|
||||
studentNo?: string;
|
||||
name?: string;
|
||||
nameEnglish?: string;
|
||||
formerName?: string;
|
||||
namePinyin?: string;
|
||||
gender?: string;
|
||||
birthDate?: string;
|
||||
idCard?: string;
|
||||
phone?: string;
|
||||
email?: string;
|
||||
nation?: string;
|
||||
politicalStatus?: string;
|
||||
maritalStatus?: string;
|
||||
religion?: string;
|
||||
photoUrl?: string;
|
||||
photoPath?: string;
|
||||
majorCode?: string;
|
||||
majorName?: string;
|
||||
classCode?: string;
|
||||
className?: string;
|
||||
collegeCode?: string;
|
||||
collegeName?: string;
|
||||
grade?: string;
|
||||
enrollmentYear?: number;
|
||||
enrollmentDate?: string;
|
||||
schoolSystem?: number;
|
||||
educationLevel?: string;
|
||||
trainingType?: string;
|
||||
admissionCategory?: string;
|
||||
sourceRegion?: string;
|
||||
middleSchool?: string;
|
||||
studentStatus?: string;
|
||||
infoStatus?: string;
|
||||
counselorName?: string;
|
||||
classTeacherName?: string;
|
||||
qq?: string;
|
||||
wechat?: string;
|
||||
dormitoryBuilding?: string;
|
||||
dormitoryRoom?: string;
|
||||
homeAddress?: string;
|
||||
currentAddress?: string;
|
||||
postalCode?: string;
|
||||
householdRegisterType?: string;
|
||||
hukouLocation?: string;
|
||||
height?: number;
|
||||
weight?: number;
|
||||
bloodType?: string;
|
||||
healthStatus?: string;
|
||||
specialCondition?: string;
|
||||
medicalHistory?: string;
|
||||
allergies?: string;
|
||||
disabilityType?: string;
|
||||
disabilityLevel?: string;
|
||||
emergencyContactName?: string;
|
||||
emergencyContactPhone?: string;
|
||||
emergencyContactRelation?: string;
|
||||
fatherName?: string;
|
||||
fatherPhone?: string;
|
||||
fatherWorkUnit?: string;
|
||||
motherName?: string;
|
||||
motherPhone?: string;
|
||||
motherWorkUnit?: string;
|
||||
guardianName?: string;
|
||||
guardianPhone?: string;
|
||||
guardianRelation?: string;
|
||||
familyIncome?: string;
|
||||
familyEconomicStatus?: string;
|
||||
familyMembers?: number;
|
||||
bankCardNo?: string;
|
||||
bankName?: string;
|
||||
bankBranch?: string;
|
||||
cardHolderName?: string;
|
||||
isPoorStudent?: number;
|
||||
isMinority?: number;
|
||||
isDisabled?: number;
|
||||
isOrphan?: number;
|
||||
isLeftBehindChild?: number;
|
||||
isSingleChild?: number;
|
||||
hasLoan?: number;
|
||||
loanAmount?: number;
|
||||
specialties?: string;
|
||||
awards?: string;
|
||||
violations?: string;
|
||||
socialActivities?: string;
|
||||
dataSource?: string;
|
||||
lastAuditTime?: string;
|
||||
isComplete?: number;
|
||||
completionRate?: number;
|
||||
extField1?: string;
|
||||
extField2?: string;
|
||||
extField3?: string;
|
||||
extField4?: string;
|
||||
extField5?: string;
|
||||
remark?: string;
|
||||
createTime?: string;
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
// 查询参数类型
|
||||
export interface StudentQuery {
|
||||
pageNum?: number
|
||||
pageSize?: number
|
||||
studentNo?: string
|
||||
name?: string
|
||||
gender?: string
|
||||
idCard?: string
|
||||
majorCode?: string
|
||||
majorName?: string
|
||||
classCode?: string
|
||||
className?: string
|
||||
collegeCode?: string
|
||||
collegeName?: string
|
||||
grade?: string
|
||||
enrollmentYear?: number
|
||||
studentStatus?: string
|
||||
infoStatus?: string
|
||||
counselorId?: number
|
||||
classTeacherId?: number
|
||||
pageNum?: number;
|
||||
pageSize?: number;
|
||||
studentNo?: string;
|
||||
name?: string;
|
||||
gender?: string;
|
||||
idCard?: string;
|
||||
majorCode?: string;
|
||||
majorName?: string;
|
||||
classCode?: string;
|
||||
className?: string;
|
||||
collegeCode?: string;
|
||||
collegeName?: string;
|
||||
grade?: string;
|
||||
enrollmentYear?: number;
|
||||
studentStatus?: string;
|
||||
infoStatus?: string;
|
||||
counselorId?: number;
|
||||
classTeacherId?: number;
|
||||
}
|
||||
|
||||
// 统计数据类型
|
||||
export interface StatisticsData {
|
||||
totalCount?: number
|
||||
activeCount?: number
|
||||
completeCount?: number
|
||||
pendingCount?: number
|
||||
maleCount?: number
|
||||
femaleCount?: number
|
||||
totalCount?: number;
|
||||
activeCount?: number;
|
||||
completeCount?: number;
|
||||
pendingCount?: number;
|
||||
maleCount?: number;
|
||||
femaleCount?: number;
|
||||
}
|
||||
|
||||
// 选项数据类型
|
||||
export interface OptionData {
|
||||
value: string | number
|
||||
label: string
|
||||
code?: string
|
||||
[key: string]: any
|
||||
value: string | number;
|
||||
label: string;
|
||||
code?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
// 查询学生信息列表
|
||||
@@ -149,7 +149,7 @@ export function listStudents(query: StudentQuery): AxiosPromise<any> {
|
||||
url: '/xg/studentInfo/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取学生信息详情
|
||||
@@ -157,7 +157,7 @@ export function getStudent(id: number): AxiosPromise<StudentInfo> {
|
||||
return request({
|
||||
url: `/xg/studentInfo/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 根据学号查询学生信息
|
||||
@@ -165,7 +165,7 @@ export function getStudentByNo(studentNo: string): AxiosPromise<StudentInfo> {
|
||||
return request({
|
||||
url: `/xg/studentInfo/studentNo/${studentNo}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 根据身份证号查询学生信息
|
||||
@@ -173,7 +173,7 @@ export function getStudentByIdCard(idCard: string): AxiosPromise<StudentInfo> {
|
||||
return request({
|
||||
url: `/xg/studentInfo/idCard/${idCard}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 根据班级代码查询学生列表
|
||||
@@ -181,7 +181,7 @@ export function getStudentsByClass(classCode: string): AxiosPromise<StudentInfo[
|
||||
return request({
|
||||
url: `/xg/studentInfo/class/${classCode}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 根据学院代码查询学生列表
|
||||
@@ -189,7 +189,7 @@ export function getStudentsByCollege(collegeCode: string): AxiosPromise<StudentI
|
||||
return request({
|
||||
url: `/xg/studentInfo/college/${collegeCode}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 新增学生信息
|
||||
@@ -198,7 +198,7 @@ export function addStudent(data: StudentInfo): AxiosPromise<any> {
|
||||
url: '/xg/studentInfo',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 修改学生信息
|
||||
@@ -207,7 +207,7 @@ export function updateStudent(data: StudentInfo): AxiosPromise<any> {
|
||||
url: '/xg/studentInfo',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 删除学生信息
|
||||
@@ -215,7 +215,7 @@ export function delStudent(ids: number[]): AxiosPromise<any> {
|
||||
return request({
|
||||
url: `/xg/studentInfo/${ids.join(',')}`,
|
||||
method: 'delete'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 导出学生信息
|
||||
@@ -225,7 +225,7 @@ export function exportStudents(query: StudentQuery): AxiosPromise<any> {
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 批量导入学生信息
|
||||
@@ -234,7 +234,7 @@ export function importStudents(data: any): AxiosPromise<any> {
|
||||
url: '/xg/studentInfo/import',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取导入模板
|
||||
@@ -243,7 +243,7 @@ export function getImportTemplate(): AxiosPromise<any> {
|
||||
url: '/xg/studentInfo/importTemplate',
|
||||
method: 'post',
|
||||
responseType: 'blob'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 批量更新学生信息状态
|
||||
@@ -252,7 +252,7 @@ export function batchUpdateInfoStatus(studentIds: number[], infoStatus: string):
|
||||
url: '/xg/studentInfo/batchUpdateInfoStatus',
|
||||
method: 'put',
|
||||
data: { studentIds, infoStatus }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 批量更新学生学籍状态
|
||||
@@ -261,7 +261,7 @@ export function batchUpdateStudentStatus(studentIds: number[], studentStatus: st
|
||||
url: '/xg/studentInfo/batchUpdateStudentStatus',
|
||||
method: 'put',
|
||||
data: { studentIds, studentStatus }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 审核学生信息
|
||||
@@ -270,7 +270,7 @@ export function auditStudent(studentId: number, auditStatus: string, auditRemark
|
||||
url: `/xg/studentInfo/${studentId}/audit`,
|
||||
method: 'put',
|
||||
params: { auditStatus, auditRemark }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 批量审核学生信息
|
||||
@@ -279,7 +279,7 @@ export function batchAuditStudents(studentIds: number[], auditStatus: string, au
|
||||
url: '/xg/studentInfo/batchAudit',
|
||||
method: 'put',
|
||||
data: { studentIds, auditStatus, auditRemark }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ================================
|
||||
@@ -291,7 +291,7 @@ export function getStatisticsOverview(): AxiosPromise<StatisticsData> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/statistics/overview',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 统计各学院学生数量
|
||||
@@ -299,7 +299,7 @@ export function getCollegeStatistics(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/statistics/college',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 统计各年级学生数量
|
||||
@@ -307,7 +307,7 @@ export function getGradeStatistics(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/statistics/grade',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 统计各专业学生数量
|
||||
@@ -315,7 +315,7 @@ export function getMajorStatistics(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/statistics/major',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 统计学籍状态分布
|
||||
@@ -323,7 +323,7 @@ export function getStudentStatusStatistics(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/statistics/studentStatus',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 统计信息完整度分布
|
||||
@@ -331,7 +331,7 @@ export function getCompletionRateStatistics(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/statistics/completionRate',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 查询信息不完整的学生列表
|
||||
@@ -339,7 +339,7 @@ export function getIncompleteStudents(): AxiosPromise<StudentInfo[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/incomplete',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 查询待审核的学生列表
|
||||
@@ -347,7 +347,7 @@ export function getPendingAuditStudents(): AxiosPromise<StudentInfo[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/pendingAudit',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 生成学生信息报表
|
||||
@@ -356,7 +356,7 @@ export function generateReport(reportType: string, params?: any): AxiosPromise<a
|
||||
url: `/xg/studentInfo/report/${reportType}`,
|
||||
method: 'get',
|
||||
params: params
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// ================================
|
||||
@@ -368,7 +368,7 @@ export function getCollegeOptions(): AxiosPromise<OptionData[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/options/colleges',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取专业选项
|
||||
@@ -377,7 +377,7 @@ export function getMajorOptions(collegeCode?: string): AxiosPromise<OptionData[]
|
||||
url: '/xg/studentInfo/options/majors',
|
||||
method: 'get',
|
||||
params: { collegeCode }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取班级选项
|
||||
@@ -386,7 +386,7 @@ export function getClassOptions(majorCode?: string): AxiosPromise<OptionData[]>
|
||||
url: '/xg/studentInfo/options/classes',
|
||||
method: 'get',
|
||||
params: { majorCode }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取辅导员选项
|
||||
@@ -394,12 +394,12 @@ export function getCounselorOptions(): AxiosPromise<OptionData[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/options/counselors',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 获取班主任选项
|
||||
export function getClassTeacherOptions(): AxiosPromise<OptionData[]> {
|
||||
console.log('调用班主任API: /xg/classInfo/teacherOptions')
|
||||
console.log('调用班主任API: /xg/classInfo/teacherOptions');
|
||||
return request({
|
||||
url: '/xg/classInfo/teacherOptions',
|
||||
method: 'get',
|
||||
@@ -408,7 +408,7 @@ export function getClassTeacherOptions(): AxiosPromise<OptionData[]> {
|
||||
'Authorization': 'Bearer ' + getToken(),
|
||||
'clientid': import.meta.env.VITE_APP_CLIENT_ID
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 检查学号是否存在
|
||||
@@ -417,7 +417,7 @@ export function checkStudentNo(studentNo: string, studentId?: number): AxiosProm
|
||||
url: '/xg/studentInfo/checkStudentNo',
|
||||
method: 'get',
|
||||
params: { studentNo, studentId }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 检查身份证号是否存在
|
||||
@@ -426,7 +426,7 @@ export function checkIdCard(idCard: string, studentId?: number): AxiosPromise<bo
|
||||
url: '/xg/studentInfo/checkIdCard',
|
||||
method: 'get',
|
||||
params: { idCard, studentId }
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 查询重复学号的学生列表
|
||||
@@ -434,7 +434,7 @@ export function getDuplicateStudentNo(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/duplicateStudentNo',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 查询重复身份证号的学生列表
|
||||
@@ -442,7 +442,7 @@ export function getDuplicateIdCard(): AxiosPromise<any[]> {
|
||||
return request({
|
||||
url: '/xg/studentInfo/duplicateIdCard',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// 更新学生信息完整度
|
||||
@@ -450,5 +450,5 @@ export function updateCompletionRate(studentId: number): AxiosPromise<any> {
|
||||
return request({
|
||||
url: `/xg/studentInfo/${studentId}/updateCompletionRate`,
|
||||
method: 'put'
|
||||
})
|
||||
});
|
||||
}
|
||||
+530
-530
File diff suppressed because it is too large.
Load diff
@@ -10,7 +10,7 @@ interface ClassTeacherCounselorRelBo {
|
||||
teacherName?: string;
|
||||
counselorId?: number | string;
|
||||
counselorName?: string;
|
||||
relationType?: number; // 1:班主任 2:辅导员
|
||||
relationType?: number; // 1:班主任 2:辅导员
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import request from '@/utils/request';
|
||||
// export * from './activity' // 活动管理
|
||||
|
||||
// 导出学工用户模块API
|
||||
export * from './sysUser'
|
||||
export * from './sysUser';
|
||||
|
||||
// 临时导出一个空对象,防止编译错误
|
||||
export default {};
|
||||
@@ -61,6 +61,3 @@ export interface DormBedForm {
|
||||
/** 备注 */
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,6 @@ export interface DormRoomVO {
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormRoomForm extends BaseEntity {
|
||||
@@ -116,11 +115,9 @@ export interface DormRoomForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormRoomQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 房间编号
|
||||
*/
|
||||
@@ -166,11 +163,8 @@ export interface DormRoomQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,6 @@ export interface DormManagerSourceVO {
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormManagerSourceForm extends BaseEntity {
|
||||
@@ -81,11 +80,9 @@ export interface DormManagerSourceForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormManagerSourceQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 管理员ID
|
||||
*/
|
||||
@@ -116,11 +113,8 @@ export interface DormManagerSourceQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ export interface DormManagerBuildingVO {
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormManagerBuildingForm extends BaseEntity {
|
||||
@@ -61,11 +60,9 @@ export interface DormManagerBuildingForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormManagerBuildingQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 管理员ID
|
||||
*/
|
||||
@@ -86,11 +83,8 @@ export interface DormManagerBuildingQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ export interface DormManagerVO {
|
||||
* 授权范围名称(逗号分隔的字符串)
|
||||
*/
|
||||
scopeNames?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormManagerForm extends BaseEntity {
|
||||
@@ -106,11 +105,9 @@ export interface DormManagerForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormManagerQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 管理员姓名
|
||||
*/
|
||||
@@ -151,11 +148,8 @@ export interface DormManagerQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,8 +17,7 @@ export interface DormBuildingVO {
|
||||
floors: number;
|
||||
}
|
||||
|
||||
export interface DormBuildingForm extends Omit<DormBuildingVO, 'createTime' | 'createBy' | 'updateTime' | 'updateBy' | 'areaName' | 'campusName'> {
|
||||
}
|
||||
export interface DormBuildingForm extends Omit<DormBuildingVO, 'createTime' | 'createBy' | 'updateTime' | 'updateBy' | 'areaName' | 'campusName'> {}
|
||||
|
||||
export interface DormBuildingQuery {
|
||||
buildingCode?: string;
|
||||
@@ -45,6 +44,3 @@ export interface BuildingTreeSelectVo {
|
||||
floors?: number;
|
||||
updateTime?: string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ export interface DormAreaVO {
|
||||
* 排序号
|
||||
*/
|
||||
sortOrder: number;
|
||||
|
||||
}
|
||||
|
||||
export interface DormAreaForm extends BaseEntity {
|
||||
@@ -61,11 +60,9 @@ export interface DormAreaForm extends BaseEntity {
|
||||
* 排序号
|
||||
*/
|
||||
sortOrder?: number;
|
||||
|
||||
}
|
||||
|
||||
export interface DormAreaQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 宿舍区编码
|
||||
*/
|
||||
@@ -81,10 +78,10 @@ export interface DormAreaQuery extends PageQuery {
|
||||
*/
|
||||
areaDescription?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,6 +99,3 @@ export interface TreeSelectVo {
|
||||
/** 子节点 */
|
||||
children?: TreeSelectVo[];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ export interface DormCampusVO {
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormCampusForm extends BaseEntity {
|
||||
@@ -61,11 +60,9 @@ export interface DormCampusForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface DormCampusQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 校区编码
|
||||
*/
|
||||
@@ -76,11 +73,8 @@ export interface DormCampusQuery extends PageQuery {
|
||||
*/
|
||||
campusName?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -198,7 +198,7 @@ export function getMockDormTree(): { data: DormTreeNode[] } {
|
||||
}
|
||||
|
||||
// 生成房间数据的模拟数据
|
||||
export function getMockRooms(buildingId: string | number, floorNumber?: number): { rows: RoomInfo[], total: number } {
|
||||
export function getMockRooms(buildingId: string | number, floorNumber?: number): { rows: RoomInfo[]; total: number } {
|
||||
const rooms: RoomInfo[] = [];
|
||||
|
||||
// 根据buildingId判断楼层数
|
||||
@@ -233,7 +233,7 @@ export function getMockRooms(buildingId: string | number, floorNumber?: number):
|
||||
}
|
||||
|
||||
return {
|
||||
rows: rooms.filter(room => !floorNumber || room.floorNumber === floorNumber),
|
||||
rows: rooms.filter((room) => !floorNumber || room.floorNumber === floorNumber),
|
||||
total: rooms.length
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ export interface StuColBatchVO {
|
||||
* 收集类型 1 - 新学期收集 2 - 其他
|
||||
*/
|
||||
collectionType: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchForm extends BaseEntity {
|
||||
@@ -71,11 +70,9 @@ export interface StuColBatchForm extends BaseEntity {
|
||||
* 收集类型 1 - 新学期收集 2 - 其他
|
||||
*/
|
||||
collectionType?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 批次名称
|
||||
*/
|
||||
@@ -91,11 +88,8 @@ export interface StuColBatchQuery extends PageQuery {
|
||||
*/
|
||||
collectionType?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ export interface ClassMsgVO {
|
||||
* 备注信息
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface ClassMsgForm extends BaseEntity {
|
||||
@@ -291,11 +290,9 @@ export interface ClassMsgForm extends BaseEntity {
|
||||
* 备注信息
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface ClassMsgQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 学院代码
|
||||
*/
|
||||
@@ -326,11 +323,8 @@ export interface ClassMsgQuery extends PageQuery {
|
||||
*/
|
||||
classStatus?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ export interface StuColBatchClassVO {
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
deleted: number;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchClassForm extends BaseEntity {
|
||||
@@ -101,11 +100,9 @@ export interface StuColBatchClassForm extends BaseEntity {
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
deleted?: number;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchClassQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 批次ID
|
||||
*/
|
||||
@@ -146,11 +143,8 @@ export interface StuColBatchClassQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ export interface StuColBatchVO {
|
||||
* 收集类型 1 - 新学期收集 2 - 其他
|
||||
*/
|
||||
collectionType: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchForm extends BaseEntity {
|
||||
@@ -71,11 +70,9 @@ export interface StuColBatchForm extends BaseEntity {
|
||||
* 收集类型 1 - 新学期收集 2 - 其他
|
||||
*/
|
||||
collectionType?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 批次名称
|
||||
*/
|
||||
@@ -91,11 +88,8 @@ export interface StuColBatchQuery extends PageQuery {
|
||||
*/
|
||||
collectionType?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,6 @@ export interface StuColBatchVO {
|
||||
* 收集类型 1 - 新学期收集 2 - 其他
|
||||
*/
|
||||
collectionType: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchForm extends BaseEntity {
|
||||
@@ -71,11 +70,9 @@ export interface StuColBatchForm extends BaseEntity {
|
||||
* 收集类型 1 - 新学期收集 2 - 其他
|
||||
*/
|
||||
collectionType?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StuColBatchQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 批次名称
|
||||
*/
|
||||
@@ -91,11 +88,8 @@ export interface StuColBatchQuery extends PageQuery {
|
||||
*/
|
||||
collectionType?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { StudentQuery, StudentVO, StudentForm, XgDeptTreeVO, R, TableDataInfo } from './types';
|
||||
|
||||
|
||||
/**
|
||||
* 查询部门下拉树结构
|
||||
* @param deptId 部门ID
|
||||
@@ -32,7 +31,6 @@ export const XgDeptTreeSelect = (belongDeptId?: number): AxiosPromise<XgDeptTree
|
||||
// }) as any;
|
||||
};
|
||||
|
||||
|
||||
// 查询学生列表
|
||||
export function listStudent(query?: StudentQuery): AxiosPromise<R<TableDataInfo<StudentVO[]>>> {
|
||||
// 实际使用时连接后端接口
|
||||
@@ -56,11 +54,13 @@ export function listStudent(query?: StudentQuery): AxiosPromise<R<TableDataInfo<
|
||||
}
|
||||
|
||||
// 查询学生详细
|
||||
export function getStudent(studentId?: string | number): AxiosPromise<R<{
|
||||
student: StudentVO;
|
||||
majors: any[];
|
||||
classes: any[];
|
||||
}>> {
|
||||
export function getStudent(studentId?: string | number): AxiosPromise<
|
||||
R<{
|
||||
student: StudentVO;
|
||||
majors: any[];
|
||||
classes: any[];
|
||||
}>
|
||||
> {
|
||||
if (studentId) {
|
||||
// 实际使用时连接后端接口
|
||||
// return request({
|
||||
@@ -69,7 +69,7 @@ export function getStudent(studentId?: string | number): AxiosPromise<R<{
|
||||
// });
|
||||
|
||||
// 模拟数据
|
||||
const student = mockStudentData.find(item => item.studentId === studentId);
|
||||
const student = mockStudentData.find((item) => item.studentId === studentId);
|
||||
return Promise.resolve({
|
||||
data: {
|
||||
code: 200,
|
||||
@@ -435,4 +435,14 @@ const mockClasses = [
|
||||
}
|
||||
];
|
||||
|
||||
export default { listStudent, getStudent, addStudent, updateStudent, delStudent, deptTreeSelect, exportStudent, changeStudentStatus, XgDeptTreeSelect };
|
||||
export default {
|
||||
listStudent,
|
||||
getStudent,
|
||||
addStudent,
|
||||
updateStudent,
|
||||
delStudent,
|
||||
deptTreeSelect,
|
||||
exportStudent,
|
||||
changeStudentStatus,
|
||||
XgDeptTreeSelect
|
||||
};
|
||||
@@ -45,7 +45,7 @@ export interface StudentMsgVO {
|
||||
birthDate: string;
|
||||
|
||||
/**
|
||||
* 民族
|
||||
* 民族
|
||||
*/
|
||||
nationality: string;
|
||||
|
||||
@@ -140,7 +140,7 @@ export interface StudentMsgVO {
|
||||
wechat: string;
|
||||
|
||||
/**
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
*/
|
||||
maritalStatus: string;
|
||||
|
||||
@@ -518,7 +518,6 @@ export interface StudentMsgVO {
|
||||
* 备注信息
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentMsgForm extends BaseEntity {
|
||||
@@ -568,7 +567,7 @@ export interface StudentMsgForm extends BaseEntity {
|
||||
birthDate?: string;
|
||||
|
||||
/**
|
||||
* 民族
|
||||
* 民族
|
||||
*/
|
||||
nationality?: string;
|
||||
|
||||
@@ -663,7 +662,7 @@ export interface StudentMsgForm extends BaseEntity {
|
||||
wechat?: string;
|
||||
|
||||
/**
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
*/
|
||||
maritalStatus?: string;
|
||||
|
||||
@@ -1041,11 +1040,9 @@ export interface StudentMsgForm extends BaseEntity {
|
||||
* 备注信息
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentMsgQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@@ -1087,7 +1084,7 @@ export interface StudentMsgQuery extends PageQuery {
|
||||
birthDate?: string;
|
||||
|
||||
/**
|
||||
* 民族
|
||||
* 民族
|
||||
*/
|
||||
nationality?: string;
|
||||
|
||||
@@ -1182,7 +1179,7 @@ export interface StudentMsgQuery extends PageQuery {
|
||||
wechat?: string;
|
||||
|
||||
/**
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
*/
|
||||
maritalStatus?: string;
|
||||
|
||||
@@ -1556,11 +1553,8 @@ export interface StudentMsgQuery extends PageQuery {
|
||||
*/
|
||||
extField5?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ export interface StudentMsgBatchVO {
|
||||
birthDate: string;
|
||||
|
||||
/**
|
||||
* 民族
|
||||
* 民族
|
||||
*/
|
||||
nationality: string;
|
||||
|
||||
@@ -140,7 +140,7 @@ export interface StudentMsgBatchVO {
|
||||
wechat: string;
|
||||
|
||||
/**
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
*/
|
||||
maritalStatus: string;
|
||||
|
||||
@@ -523,7 +523,6 @@ export interface StudentMsgBatchVO {
|
||||
* 正在进行中的批次id
|
||||
*/
|
||||
batchId: string | number;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentMsgBatchForm extends BaseEntity {
|
||||
@@ -573,7 +572,7 @@ export interface StudentMsgBatchForm extends BaseEntity {
|
||||
birthDate?: string;
|
||||
|
||||
/**
|
||||
* 民族
|
||||
* 民族
|
||||
*/
|
||||
nationality?: string;
|
||||
|
||||
@@ -668,7 +667,7 @@ export interface StudentMsgBatchForm extends BaseEntity {
|
||||
wechat?: string;
|
||||
|
||||
/**
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
*/
|
||||
maritalStatus?: string;
|
||||
|
||||
@@ -1051,11 +1050,9 @@ export interface StudentMsgBatchForm extends BaseEntity {
|
||||
* 正在进行中的批次id
|
||||
*/
|
||||
batchId?: string | number;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentMsgBatchQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@@ -1097,7 +1094,7 @@ export interface StudentMsgBatchQuery extends PageQuery {
|
||||
birthDate?: string;
|
||||
|
||||
/**
|
||||
* 民族
|
||||
* 民族
|
||||
*/
|
||||
nationality?: string;
|
||||
|
||||
@@ -1192,7 +1189,7 @@ export interface StudentMsgBatchQuery extends PageQuery {
|
||||
wechat?: string;
|
||||
|
||||
/**
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
* 婚姻状况:1 未婚、2 已婚、3 离异、4 丧偶
|
||||
*/
|
||||
maritalStatus?: string;
|
||||
|
||||
@@ -1571,11 +1568,8 @@ export interface StudentMsgBatchQuery extends PageQuery {
|
||||
*/
|
||||
batchId?: string | number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ export interface XgClassPosDictVO {
|
||||
* 备注信息
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface XgClassPosDictForm extends BaseEntity {
|
||||
@@ -111,11 +110,9 @@ export interface XgClassPosDictForm extends BaseEntity {
|
||||
* 备注信息
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface XgClassPosDictQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@@ -161,11 +158,8 @@ export interface XgClassPosDictQuery extends PageQuery {
|
||||
*/
|
||||
sortOrder?: number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -118,7 +118,6 @@ export interface XgClassPosMsgVO {
|
||||
* 备注信息
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface XgClassPosMsgForm extends BaseEntity {
|
||||
@@ -246,11 +245,9 @@ export interface XgClassPosMsgForm extends BaseEntity {
|
||||
* 备注信息
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface XgClassPosMsgQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@@ -336,11 +333,8 @@ export interface XgClassPosMsgQuery extends PageQuery {
|
||||
*/
|
||||
deptId?: string | number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ export interface XgLeaveTypeConfigVO {
|
||||
* 销假逾期多少时长给予提醒(天)
|
||||
*/
|
||||
cancelOverdueReminder: number;
|
||||
|
||||
}
|
||||
|
||||
export interface XgLeaveTypeConfigForm extends BaseEntity {
|
||||
@@ -131,11 +130,9 @@ export interface XgLeaveTypeConfigForm extends BaseEntity {
|
||||
* 销假逾期多少时长给予提醒(天)
|
||||
*/
|
||||
cancelOverdueReminder?: number;
|
||||
|
||||
}
|
||||
|
||||
export interface XgLeaveTypeConfigQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 删除标志(0代表存在 1代表删除)
|
||||
*/
|
||||
@@ -156,11 +153,8 @@ export interface XgLeaveTypeConfigQuery extends PageQuery {
|
||||
*/
|
||||
isEnabled?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,6 @@ export interface StudentManagerVO {
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentManagerForm extends BaseEntity {
|
||||
@@ -101,11 +100,9 @@ export interface StudentManagerForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentManagerQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 管理员姓名
|
||||
*/
|
||||
@@ -146,11 +143,8 @@ export interface StudentManagerQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { StudentManagerSourceVO, StudentManagerSourceForm, StudentManagerSourceQuery } from '@/api/xg/xsjcxx/xgStudentManagerSource/studentManagerSource/types';
|
||||
import {
|
||||
StudentManagerSourceVO,
|
||||
StudentManagerSourceForm,
|
||||
StudentManagerSourceQuery
|
||||
} from '@/api/xg/xsjcxx/xgStudentManagerSource/studentManagerSource/types';
|
||||
|
||||
/**
|
||||
* 查询学生管理员授权关系列表
|
||||
|
||||
@@ -38,7 +38,6 @@ export interface StudentManagerSourceVO {
|
||||
* 备注
|
||||
*/
|
||||
remark: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentManagerSourceForm extends BaseEntity {
|
||||
@@ -81,11 +80,9 @@ export interface StudentManagerSourceForm extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface StudentManagerSourceQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 管理员ID
|
||||
*/
|
||||
@@ -116,11 +113,8 @@ export interface StudentManagerSourceQuery extends PageQuery {
|
||||
*/
|
||||
deleted?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -129,7 +129,7 @@ export const submitAppointment = async (data: XljkConsultationAppointmentForm) =
|
||||
console.error('检查预约限制失败', error);
|
||||
// 检查失败不阻止预约,继续提交
|
||||
}
|
||||
|
||||
|
||||
// 提交预约申请
|
||||
return request({
|
||||
url: '/api/xljk/consultation/appointment/submit',
|
||||
@@ -141,15 +141,15 @@ export const submitAppointment = async (data: XljkConsultationAppointmentForm) =
|
||||
// 获取我的预约记录(学生用)
|
||||
export const getMyAppointments = (studentId: string | number, forceRefresh: boolean = false) => {
|
||||
let url = `/api/xljk/consultation/appointment/my-appointments/${studentId}`;
|
||||
|
||||
|
||||
// 强制添加时间戳参数,确保绕过浏览器缓存
|
||||
url += `?_t=${new Date().getTime()}`;
|
||||
|
||||
|
||||
// 如果需要额外强制刷新(如用户手动点击刷新按钮)
|
||||
if (forceRefresh) {
|
||||
url += `&force=true`;
|
||||
}
|
||||
|
||||
|
||||
return request({
|
||||
url,
|
||||
method: 'get',
|
||||
@@ -211,4 +211,4 @@ export const getClassOptions = (collegeName?: string, majorName?: string) => {
|
||||
method: 'get',
|
||||
params: { collegeName, majorName }
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -9,12 +9,12 @@ import { NoShowQuery, NoShowVO } from './types';
|
||||
export function listNoShow(query: NoShowQuery) {
|
||||
// 创建一个新的查询对象,避免修改原始对象
|
||||
const params = { ...query };
|
||||
|
||||
|
||||
// 如果状态是'all',表示"全部",则从参数中移除
|
||||
if (params.status === 'all') {
|
||||
delete params.status;
|
||||
}
|
||||
|
||||
|
||||
return request({
|
||||
url: '/api/xljk/consultation/no-show/list',
|
||||
method: 'get',
|
||||
@@ -57,4 +57,4 @@ export function checkLimitation(studentId: string | number) {
|
||||
method: 'get',
|
||||
params: { studentId }
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -556,17 +556,17 @@ export interface NoShowVO {
|
||||
* 咨询师名称
|
||||
*/
|
||||
counselorName?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 预约日期
|
||||
*/
|
||||
appointmentDate?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 预约时段
|
||||
*/
|
||||
appointmentDetailTime?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 咨询原因
|
||||
*/
|
||||
@@ -601,4 +601,4 @@ export interface NoShowVO {
|
||||
* 更新时间
|
||||
*/
|
||||
updateTime?: string;
|
||||
}
|
||||
}
|
||||
@@ -35,15 +35,15 @@ export const addEvaluation = (data: XljkEvaluationForm) => {
|
||||
if (data.departmentName && !data.departmentId) {
|
||||
data.departmentId = 0; // 使用临时ID,后端会根据名称处理
|
||||
}
|
||||
|
||||
|
||||
if (data.majorName && !data.majorId) {
|
||||
data.majorId = 0; // 使用临时ID,后端会根据名称处理
|
||||
}
|
||||
|
||||
|
||||
if (data.className && !data.classId) {
|
||||
data.classId = 0; // 使用临时ID,后端会根据名称处理
|
||||
}
|
||||
|
||||
|
||||
return request({
|
||||
url: '/api/xljk/evaluation',
|
||||
method: 'post',
|
||||
@@ -182,10 +182,10 @@ export const batchAddEvaluationDetails = (data: XljkEvaluationDetailForm[]) => {
|
||||
export const batchUpdateMentalStatus = (data: XljkEvaluationDetailForm[]) => {
|
||||
// 确保数据中的ID字段保持原有格式,不做Number转换
|
||||
console.log('批量更新数据 - 第一条记录evaluationId:', data[0]?.evaluationId);
|
||||
|
||||
|
||||
return request({
|
||||
url: '/api/xljk/evaluation/detail/batch/mentalStatus',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
};
|
||||
@@ -525,4 +525,4 @@ export interface EvaluationStatistics {
|
||||
* 重点关注学生百分比
|
||||
*/
|
||||
focusPercent: number;
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,7 @@ export function listEnrollmentInfo(query: EnrollmentInfoQuery) {
|
||||
## 📱 移动端支持
|
||||
|
||||
部分接口支持移动端访问,主要包括:
|
||||
|
||||
- 学生在线报名
|
||||
- 报名状态查询
|
||||
- 录取结果查询
|
||||
|
||||
@@ -58,7 +58,7 @@ export const updateEnrollmentInfo = (data: EnrollmentInfoForm) => {
|
||||
export const updateEnrollmentStatus = (id: string | number | Array<string | number>, status: string) => {
|
||||
const data = Array.isArray(id)
|
||||
? { ids: id, status } // 批量更新
|
||||
: { id, status }; // 单个更新
|
||||
: { id, status }; // 单个更新
|
||||
|
||||
return request({
|
||||
url: '/zsjy/enrollment/info/updateStatus',
|
||||
@@ -132,7 +132,7 @@ export const submitEnrollmentApplication = (data: EnrollmentInfoForm) => {
|
||||
* 查询我的报名状态(供学生端使用)
|
||||
* @param params 查询参数
|
||||
*/
|
||||
export const queryMyEnrollmentStatus = (params: { idCard?: string, examNumber?: string }): AxiosPromise<EnrollmentInfoVO> => {
|
||||
export const queryMyEnrollmentStatus = (params: { idCard?: string; examNumber?: string }): AxiosPromise<EnrollmentInfoVO> => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/info/myStatus',
|
||||
method: 'get',
|
||||
|
||||
@@ -1,365 +1,365 @@
|
||||
import request from '@/utils/request'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
export interface EnrollmentProcessVO {
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
id: string | number
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
* 报名信息ID,关联zsjy_enrollment_info.id
|
||||
*/
|
||||
enrollmentId: number
|
||||
enrollmentId: number;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
studentName: string
|
||||
studentName: string;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
idCard: string
|
||||
idCard: string;
|
||||
|
||||
/**
|
||||
* 当前状态(0-待审核 1-信息审核中 2-录取处理中 3-待最终确认 4-录取完成 9-已驳回)
|
||||
*/
|
||||
currentStatus: string
|
||||
currentStatus: string;
|
||||
|
||||
/**
|
||||
* 当前处理人ID
|
||||
*/
|
||||
currentHandler: number
|
||||
currentHandler: number;
|
||||
|
||||
/**
|
||||
* 当前处理人姓名
|
||||
*/
|
||||
currentHandlerName: string
|
||||
currentHandlerName: string;
|
||||
|
||||
/**
|
||||
* 信息审核状态(0-待审核 1-审核通过 9-审核驳回)
|
||||
*/
|
||||
infoAuditStatus: string
|
||||
infoAuditStatus: string;
|
||||
|
||||
/**
|
||||
* 信息审核人ID
|
||||
*/
|
||||
infoAuditUser: number
|
||||
infoAuditUser: number;
|
||||
|
||||
/**
|
||||
* 信息审核人姓名
|
||||
*/
|
||||
infoAuditUserName: string
|
||||
infoAuditUserName: string;
|
||||
|
||||
/**
|
||||
* 信息审核时间
|
||||
*/
|
||||
infoAuditTime: string
|
||||
infoAuditTime: string;
|
||||
|
||||
/**
|
||||
* 信息审核意见
|
||||
*/
|
||||
infoAuditOpinion: string
|
||||
infoAuditOpinion: string;
|
||||
|
||||
/**
|
||||
* 录取处理状态(0-待处理 1-处理完成 9-处理驳回)
|
||||
*/
|
||||
admissionStatus: string
|
||||
admissionStatus: string;
|
||||
|
||||
/**
|
||||
* 录取处理人ID
|
||||
*/
|
||||
admissionUser: number
|
||||
admissionUser: number;
|
||||
|
||||
/**
|
||||
* 录取处理人姓名
|
||||
*/
|
||||
admissionUserName: string
|
||||
admissionUserName: string;
|
||||
|
||||
/**
|
||||
* 录取处理时间
|
||||
*/
|
||||
admissionTime: string
|
||||
admissionTime: string;
|
||||
|
||||
/**
|
||||
* 缴费状态(0-未缴费 1-已缴费)
|
||||
*/
|
||||
paymentStatus: string
|
||||
paymentStatus: string;
|
||||
|
||||
/**
|
||||
* 缴费确认时间
|
||||
*/
|
||||
paymentConfirmTime: string
|
||||
paymentConfirmTime: string;
|
||||
|
||||
/**
|
||||
* 录取通知书号码
|
||||
*/
|
||||
noticeNumber: string
|
||||
noticeNumber: string;
|
||||
|
||||
/**
|
||||
* 录取处理意见
|
||||
*/
|
||||
admissionOpinion: string
|
||||
admissionOpinion: string;
|
||||
|
||||
/**
|
||||
* 最终审核状态(0-待确认 1-确认通过 9-确认驳回)
|
||||
*/
|
||||
finalAuditStatus: string
|
||||
finalAuditStatus: string;
|
||||
|
||||
/**
|
||||
* 最终审核人ID
|
||||
*/
|
||||
finalAuditUser: number
|
||||
finalAuditUser: number;
|
||||
|
||||
/**
|
||||
* 最终审核人姓名
|
||||
*/
|
||||
finalAuditUserName: string
|
||||
finalAuditUserName: string;
|
||||
|
||||
/**
|
||||
* 最终审核时间
|
||||
*/
|
||||
finalAuditTime: string
|
||||
finalAuditTime: string;
|
||||
|
||||
/**
|
||||
* 最终审核意见
|
||||
*/
|
||||
finalAuditOpinion: string
|
||||
finalAuditOpinion: string;
|
||||
|
||||
/**
|
||||
* 是否完成录取(0-未完成 1-已完成)
|
||||
*/
|
||||
isCompleted: number
|
||||
isCompleted: number;
|
||||
|
||||
/**
|
||||
* 录取完成时间
|
||||
*/
|
||||
completionTime: string
|
||||
completionTime: string;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark: string
|
||||
remark: string;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
createTime: string
|
||||
createTime: string;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
updateTime: string
|
||||
updateTime: string;
|
||||
|
||||
/**
|
||||
* 性别(0-男 1-女)
|
||||
*/
|
||||
gender?: string
|
||||
gender?: string;
|
||||
|
||||
/**
|
||||
* 地区/省份
|
||||
*/
|
||||
province?: string
|
||||
province?: string;
|
||||
|
||||
/**
|
||||
* 学院名称(驼峰命名)
|
||||
*/
|
||||
collegeName?: string
|
||||
collegeName?: string;
|
||||
|
||||
/**
|
||||
* 学院代码(驼峰命名)
|
||||
*/
|
||||
collegeId?: string
|
||||
collegeId?: string;
|
||||
|
||||
/**
|
||||
* 学院名称(下划线命名)
|
||||
*/
|
||||
college_name?: string
|
||||
college_name?: string;
|
||||
|
||||
/**
|
||||
* 学院代码(下划线命名)
|
||||
*/
|
||||
college_id?: string
|
||||
college_id?: string;
|
||||
|
||||
/**
|
||||
* 学院名称(拼写变体 - collage)
|
||||
*/
|
||||
collage_name?: string
|
||||
collage_name?: string;
|
||||
|
||||
/**
|
||||
* 学院代码(拼写变体 - collage)
|
||||
*/
|
||||
collage_id?: string
|
||||
collage_id?: string;
|
||||
|
||||
/**
|
||||
* 专业名称(驼峰命名)
|
||||
*/
|
||||
majorName?: string
|
||||
majorName?: string;
|
||||
|
||||
/**
|
||||
* 专业代码(驼峰命名)
|
||||
*/
|
||||
majorCode?: string
|
||||
majorCode?: string;
|
||||
|
||||
/**
|
||||
* 专业名称(下划线命名)
|
||||
*/
|
||||
major_name?: string
|
||||
major_name?: string;
|
||||
|
||||
/**
|
||||
* 专业代码(下划线命名)
|
||||
*/
|
||||
major_code?: string
|
||||
major_code?: string;
|
||||
|
||||
/**
|
||||
* 报考专业(来自报名信息表)
|
||||
*/
|
||||
appliedMajor?: string
|
||||
appliedMajor?: string;
|
||||
|
||||
/**
|
||||
* 关联的报名信息对象
|
||||
*/
|
||||
enrollmentInfo?: any
|
||||
enrollmentInfo?: any;
|
||||
}
|
||||
|
||||
export interface EnrollmentProcessForm extends BaseEntity {
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
id?: string | number
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
* 报名信息ID,关联zsjy_enrollment_info.id
|
||||
*/
|
||||
enrollmentId?: number
|
||||
enrollmentId?: number;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
studentName?: string
|
||||
studentName?: string;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
idCard?: string
|
||||
idCard?: string;
|
||||
|
||||
/**
|
||||
* 当前状态(0-待审核 1-信息审核中 2-录取处理中 3-待最终确认 4-录取完成 9-已驳回)
|
||||
*/
|
||||
currentStatus?: string
|
||||
currentStatus?: string;
|
||||
|
||||
/**
|
||||
* 当前处理人ID
|
||||
*/
|
||||
currentHandler?: number
|
||||
currentHandler?: number;
|
||||
|
||||
/**
|
||||
* 当前处理人姓名
|
||||
*/
|
||||
currentHandlerName?: string
|
||||
currentHandlerName?: string;
|
||||
|
||||
/**
|
||||
* 信息审核状态(0-待审核 1-审核通过 9-审核驳回)
|
||||
*/
|
||||
infoAuditStatus?: string
|
||||
infoAuditStatus?: string;
|
||||
|
||||
/**
|
||||
* 信息审核意见
|
||||
*/
|
||||
infoAuditOpinion?: string
|
||||
infoAuditOpinion?: string;
|
||||
|
||||
/**
|
||||
* 录取处理状态(0-待处理 1-处理完成 9-处理驳回)
|
||||
*/
|
||||
admissionStatus?: string
|
||||
admissionStatus?: string;
|
||||
|
||||
/**
|
||||
* 缴费状态(0-未缴费 1-已缴费)
|
||||
*/
|
||||
paymentStatus?: string
|
||||
paymentStatus?: string;
|
||||
|
||||
/**
|
||||
* 录取通知书号码
|
||||
*/
|
||||
noticeNumber?: string
|
||||
noticeNumber?: string;
|
||||
|
||||
/**
|
||||
* 录取处理意见
|
||||
*/
|
||||
admissionOpinion?: string
|
||||
admissionOpinion?: string;
|
||||
|
||||
/**
|
||||
* 最终审核状态(0-待确认 1-确认通过 9-确认驳回)
|
||||
*/
|
||||
finalAuditStatus?: string
|
||||
finalAuditStatus?: string;
|
||||
|
||||
/**
|
||||
* 最终审核意见
|
||||
*/
|
||||
finalAuditOpinion?: string
|
||||
finalAuditOpinion?: string;
|
||||
|
||||
/**
|
||||
* 是否完成录取(0-未完成 1-已完成)
|
||||
*/
|
||||
isCompleted?: number
|
||||
isCompleted?: number;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
export interface EnrollmentProcessQuery extends PageQuery {
|
||||
/**
|
||||
* 报名信息ID,关联zsjy_enrollment_info.id
|
||||
*/
|
||||
enrollmentId?: number
|
||||
enrollmentId?: number;
|
||||
|
||||
/**
|
||||
* 学生姓名
|
||||
*/
|
||||
studentName?: string
|
||||
studentName?: string;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
idCard?: string
|
||||
idCard?: string;
|
||||
|
||||
/**
|
||||
* 当前状态(0-待审核 1-信息审核中 2-录取处理中 3-待最终确认 4-录取完成 9-已驳回)
|
||||
*/
|
||||
currentStatus?: string
|
||||
currentStatus?: string;
|
||||
|
||||
/**
|
||||
* 当前处理人ID
|
||||
*/
|
||||
currentHandler?: number
|
||||
currentHandler?: number;
|
||||
|
||||
/**
|
||||
* 信息审核状态(0-待审核 1-审核通过 9-审核驳回)
|
||||
*/
|
||||
infoAuditStatus?: string
|
||||
infoAuditStatus?: string;
|
||||
|
||||
/**
|
||||
* 录取处理状态(0-待处理 1-处理完成 9-处理驳回)
|
||||
*/
|
||||
admissionStatus?: string
|
||||
admissionStatus?: string;
|
||||
|
||||
/**
|
||||
* 最终审核状态(0-待确认 1-确认通过 9-确认驳回)
|
||||
*/
|
||||
finalAuditStatus?: string
|
||||
finalAuditStatus?: string;
|
||||
|
||||
/**
|
||||
* 是否完成录取(0-未完成 1-已完成)
|
||||
*/
|
||||
isCompleted?: number
|
||||
isCompleted?: number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any
|
||||
params?: any;
|
||||
}
|
||||
|
||||
// 查询录取流程状态列表
|
||||
@@ -368,8 +368,8 @@ export const listEnrollmentProcess = (query: EnrollmentProcessQuery): AxiosPromi
|
||||
url: '/zsjy/enrollment/process/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 查询我的待审核列表
|
||||
export const listMyAuditProcess = (query: EnrollmentProcessQuery): AxiosPromise<EnrollmentProcessVO[]> => {
|
||||
@@ -377,16 +377,16 @@ export const listMyAuditProcess = (query: EnrollmentProcessQuery): AxiosPromise<
|
||||
url: '/zsjy/enrollment/process/myAudit',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 查询录取流程状态详细
|
||||
export const getEnrollmentProcess = (id: string | number): AxiosPromise<EnrollmentProcessVO> => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 新增录取流程状态
|
||||
export const addEnrollmentProcess = (data: EnrollmentProcessForm) => {
|
||||
@@ -394,8 +394,8 @@ export const addEnrollmentProcess = (data: EnrollmentProcessForm) => {
|
||||
url: '/zsjy/enrollment/process',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 从报名信息创建流程
|
||||
export const createProcessFromEnrollment = (enrollmentId: number) => {
|
||||
@@ -403,8 +403,8 @@ export const createProcessFromEnrollment = (enrollmentId: number) => {
|
||||
url: '/zsjy/enrollment/process/createFromEnrollment',
|
||||
method: 'post',
|
||||
params: { enrollmentId }
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 同步流程状态
|
||||
export const syncProcessStatus = (id: string | number) => {
|
||||
@@ -412,8 +412,8 @@ export const syncProcessStatus = (id: string | number) => {
|
||||
url: '/zsjy/enrollment/process/syncStatus',
|
||||
method: 'post',
|
||||
params: { id }
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 修改录取流程状态
|
||||
export const updateEnrollmentProcess = (data: EnrollmentProcessForm) => {
|
||||
@@ -421,24 +421,24 @@ export const updateEnrollmentProcess = (data: EnrollmentProcessForm) => {
|
||||
url: '/zsjy/enrollment/process',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 删除录取流程状态
|
||||
export const delEnrollmentProcess = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 根据报名信息ID查询流程状态
|
||||
export const getProcessByEnrollmentId = (enrollmentId: number): AxiosPromise<EnrollmentProcessVO> => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/enrollment/' + enrollmentId,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 查询待处理的流程列表
|
||||
export const getPendingProcessList = (query: EnrollmentProcessQuery): AxiosPromise<EnrollmentProcessVO[]> => {
|
||||
@@ -446,8 +446,8 @@ export const getPendingProcessList = (query: EnrollmentProcessQuery): AxiosPromi
|
||||
url: '/zsjy/enrollment/process/pending',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 根据状态查询流程列表
|
||||
export const getProcessListByStatus = (status: string, query: EnrollmentProcessQuery): AxiosPromise<EnrollmentProcessVO[]> => {
|
||||
@@ -455,16 +455,16 @@ export const getProcessListByStatus = (status: string, query: EnrollmentProcessQ
|
||||
url: '/zsjy/enrollment/process/status/' + status,
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 获取流程统计数据
|
||||
export const getProcessStatistics = (): AxiosPromise<any> => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/statistics',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 搜索流程
|
||||
export const searchProcess = (keyword: string, query: EnrollmentProcessQuery): AxiosPromise<EnrollmentProcessVO[]> => {
|
||||
@@ -472,35 +472,26 @@ export const searchProcess = (keyword: string, query: EnrollmentProcessQuery): A
|
||||
url: '/zsjy/enrollment/process/search',
|
||||
method: 'get',
|
||||
params: { keyword, ...query }
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 信息审核
|
||||
export const infoAudit = (data: {
|
||||
processId: number;
|
||||
auditResult: string;
|
||||
auditOpinion?: string;
|
||||
}) => {
|
||||
export const infoAudit = (data: { processId: number; auditResult: string; auditOpinion?: string }) => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/infoAudit',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 录取处理
|
||||
export const admissionProcess = (data: {
|
||||
processId: number;
|
||||
admissionResult: string;
|
||||
admissionOpinion?: string;
|
||||
noticeNumber?: string;
|
||||
}) => {
|
||||
export const admissionProcess = (data: { processId: number; admissionResult: string; admissionOpinion?: string; noticeNumber?: string }) => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/admissionProcess',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 确认缴费
|
||||
export const confirmPayment = (processId: number) => {
|
||||
@@ -508,21 +499,17 @@ export const confirmPayment = (processId: number) => {
|
||||
url: '/zsjy/enrollment/process/confirmPayment',
|
||||
method: 'post',
|
||||
params: { processId }
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 最终审核
|
||||
export const finalAudit = (data: {
|
||||
processId: number;
|
||||
finalResult: string;
|
||||
finalOpinion?: string;
|
||||
}) => {
|
||||
export const finalAudit = (data: { processId: number; finalResult: string; finalOpinion?: string }) => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/finalConfirm',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 完成流程
|
||||
export const completeProcess = (processId: number) => {
|
||||
@@ -530,20 +517,17 @@ export const completeProcess = (processId: number) => {
|
||||
url: '/zsjy/enrollment/process/complete',
|
||||
method: 'post',
|
||||
params: { processId }
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 驳回流程
|
||||
export const rejectProcess = (data: {
|
||||
processId: number;
|
||||
rejectReason: string;
|
||||
}) => {
|
||||
export const rejectProcess = (data: { processId: number; rejectReason: string }) => {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/process/reject',
|
||||
method: 'post',
|
||||
params: data
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 重置流程
|
||||
export const resetProcess = (processId: number) => {
|
||||
@@ -551,8 +535,8 @@ export const resetProcess = (processId: number) => {
|
||||
url: '/zsjy/enrollment/process/reset',
|
||||
method: 'post',
|
||||
params: { processId }
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 导出录取流程状态
|
||||
export const exportEnrollmentProcess = (query: EnrollmentProcessQuery) => {
|
||||
@@ -560,5 +544,5 @@ export const exportEnrollmentProcess = (query: EnrollmentProcessQuery) => {
|
||||
url: '/zsjy/enrollment/process/export',
|
||||
method: 'post',
|
||||
data: query
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request'
|
||||
import type { PageQuery } from '@/types/page'
|
||||
import type { EnrollmentProcessVO } from './enrollmentProcess'
|
||||
import request from '@/utils/request';
|
||||
import type { PageQuery } from '@/types/page';
|
||||
import type { EnrollmentProcessVO } from './enrollmentProcess';
|
||||
|
||||
/**
|
||||
* 查询招生录取统计列表
|
||||
@@ -12,7 +12,7 @@ export function listEnrollmentStatistics(query: PageQuery) {
|
||||
url: '/zsjy/enrollment/statistics/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,7 +25,7 @@ export function exportEnrollmentStatistics(query: PageQuery) {
|
||||
method: 'post',
|
||||
params: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export function getEnrollmentStatistics(id: string | number) {
|
||||
return request({
|
||||
url: `/zsjy/enrollment/statistics/${id}`,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +48,7 @@ export function getEnrollmentStatisticsChartData() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/chart',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,7 @@ export function getEnrollmentStatisticsOverview() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/overview',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +70,7 @@ export function getEnrollmentStatisticsByMajor() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/major',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,7 @@ export function getEnrollmentStatisticsByCollege() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/college',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -92,7 +92,7 @@ export function getEnrollmentStatisticsByRegion() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/region',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +103,7 @@ export function getEnrollmentStatisticsByGender() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/gender',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,7 +114,7 @@ export function getEnrollmentStatisticsByPayment() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/payment',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,5 +125,5 @@ export function getEnrollmentStatisticsByStatus() {
|
||||
return request({
|
||||
url: '/zsjy/enrollment/statistics/status',
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
@@ -1,11 +1,6 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import {
|
||||
GraduateInfoVO,
|
||||
GraduateInfoForm,
|
||||
GraduateInfoQuery,
|
||||
GraduateStatisticsVO
|
||||
} from '@/api/zsjy/types';
|
||||
import { GraduateInfoVO, GraduateInfoForm, GraduateInfoQuery, GraduateStatisticsVO } from '@/api/zsjy/types';
|
||||
|
||||
/**
|
||||
* 查询毕业生信息列表
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
import request from '@/utils/request';
|
||||
|
||||
// 导出招生就业管理模块相关的所有API接口
|
||||
export * from './enterprise'; // 企业信息管理
|
||||
export * from './enterprise'; // 企业信息管理
|
||||
// export * from './jobPosition'; // 招聘岗位管理 (待开发)
|
||||
// export * from './recruitmentPoster'; // 招聘海报管理 (待开发)
|
||||
|
||||
// 现有导出
|
||||
export * from './statistics'; // 统计分析
|
||||
export * from './enrollmentProcess'; // 录取流程管理
|
||||
export * from './enrollmentStatistics'; // 报名统计
|
||||
export * from './statistics'; // 统计分析
|
||||
export * from './enrollmentProcess'; // 录取流程管理
|
||||
export * from './enrollmentStatistics'; // 报名统计
|
||||
|
||||
// 类型导出
|
||||
export * from './types'; // 类型定义
|
||||
export * from './types'; // 类型定义
|
||||
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request'
|
||||
import { JobPositionVO, JobPositionForm, JobPositionQuery, TableDataInfo } from './types'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import request from '@/utils/request';
|
||||
import { JobPositionVO, JobPositionForm, JobPositionQuery, TableDataInfo } from './types';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
/**
|
||||
* 查询招聘岗位列表
|
||||
@@ -12,7 +12,7 @@ export function listJobPosition(query?: JobPositionQuery): AxiosPromise<TableDat
|
||||
url: '/zsjy/position/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ export function getJobPosition(id: string | number): AxiosPromise<JobPositionVO>
|
||||
return request({
|
||||
url: '/zsjy/position/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export function addJobPosition(data: JobPositionForm) {
|
||||
url: '/zsjy/position',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +50,7 @@ export function updateJobPosition(data: JobPositionForm) {
|
||||
url: '/zsjy/position',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ export function delJobPosition(id: string | number | Array<string | number>) {
|
||||
return request({
|
||||
url: '/zsjy/position/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ export function exportJobPosition(query: JobPositionQuery) {
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,5 +87,5 @@ export function listEnterpriseOptions() {
|
||||
return request({
|
||||
url: '/zsjy/enterprise/options',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import request from '@/utils/request'
|
||||
import { RecruitmentPosterVO, RecruitmentPosterForm, RecruitmentPosterQuery, TableDataInfo } from './types'
|
||||
import { AxiosPromise } from 'axios'
|
||||
import request from '@/utils/request';
|
||||
import { RecruitmentPosterVO, RecruitmentPosterForm, RecruitmentPosterQuery, TableDataInfo } from './types';
|
||||
import { AxiosPromise } from 'axios';
|
||||
|
||||
/**
|
||||
* 查询招聘海报列表
|
||||
@@ -12,7 +12,7 @@ export function listRecruitmentPoster(query?: RecruitmentPosterQuery): AxiosProm
|
||||
url: '/zsjy/poster/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -24,7 +24,7 @@ export function getRecruitmentPoster(id: string | number): AxiosPromise<Recruitm
|
||||
return request({
|
||||
url: '/zsjy/poster/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +37,7 @@ export function addRecruitmentPoster(data: RecruitmentPosterForm) {
|
||||
url: '/zsjy/poster',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +50,7 @@ export function updateRecruitmentPoster(data: RecruitmentPosterForm) {
|
||||
url: '/zsjy/poster',
|
||||
method: 'put',
|
||||
data: data
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +62,7 @@ export function delRecruitmentPoster(id: string | number | Array<string | number
|
||||
return request({
|
||||
url: '/zsjy/poster/' + id,
|
||||
method: 'delete'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ export function exportRecruitmentPoster(query: RecruitmentPosterQuery) {
|
||||
method: 'post',
|
||||
data: query,
|
||||
responseType: 'blob'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,5 +89,5 @@ export function listPositionOptions(enterpriseId?: number | string) {
|
||||
url: '/zsjy/position/options',
|
||||
method: 'get',
|
||||
params: { enterpriseId }
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -11,7 +11,7 @@ export function getStatisticsOverview() {
|
||||
headers: {
|
||||
'isToken': true
|
||||
}
|
||||
}).catch(error => {
|
||||
}).catch((error) => {
|
||||
console.error('获取统计概览数据失败:', error);
|
||||
ElMessage.error('获取统计数据失败,请联系管理员');
|
||||
throw error;
|
||||
@@ -28,7 +28,7 @@ export function getMajorDistribution() {
|
||||
headers: {
|
||||
'isToken': true
|
||||
}
|
||||
}).catch(error => {
|
||||
}).catch((error) => {
|
||||
console.error('获取专业分布数据失败:', error);
|
||||
ElMessage.error('获取专业分布数据失败,请联系管理员');
|
||||
throw error;
|
||||
@@ -45,7 +45,7 @@ export function getRegionDistribution() {
|
||||
headers: {
|
||||
'isToken': true
|
||||
}
|
||||
}).catch(error => {
|
||||
}).catch((error) => {
|
||||
console.error('获取地区分布数据失败:', error);
|
||||
ElMessage.error('获取地区分布数据失败,请联系管理员');
|
||||
throw error;
|
||||
@@ -62,7 +62,7 @@ export function getGenderRatio() {
|
||||
headers: {
|
||||
'isToken': true
|
||||
}
|
||||
}).catch(error => {
|
||||
}).catch((error) => {
|
||||
console.error('获取性别比例数据失败:', error);
|
||||
ElMessage.error('获取性别比例数据失败,请联系管理员');
|
||||
throw error;
|
||||
@@ -81,7 +81,7 @@ export function getEnrollmentTrend(days?: number) {
|
||||
headers: {
|
||||
'isToken': true
|
||||
}
|
||||
}).catch(error => {
|
||||
}).catch((error) => {
|
||||
console.error('获取报名趋势数据失败:', error);
|
||||
ElMessage.error('获取报名趋势数据失败,请联系管理员');
|
||||
throw error;
|
||||
@@ -98,7 +98,7 @@ export function getStatusDistribution() {
|
||||
headers: {
|
||||
'isToken': true
|
||||
}
|
||||
}).catch(error => {
|
||||
}).catch((error) => {
|
||||
console.error('获取状态分布数据失败:', error);
|
||||
ElMessage.error('获取状态分布数据失败,请联系管理员');
|
||||
throw error;
|
||||
@@ -113,9 +113,9 @@ export interface StatisticsOverview {
|
||||
paymentRate: string;
|
||||
admittedCount: number;
|
||||
admissionRate: string;
|
||||
majorDistribution: Array<{[key: string]: any}>;
|
||||
regionDistribution: Array<{[key: string]: any}>;
|
||||
genderRatio: {[key: string]: number};
|
||||
weeklyTrend: Array<{[key: string]: any}>;
|
||||
statusDistribution: {[key: string]: number};
|
||||
majorDistribution: Array<{ [key: string]: any }>;
|
||||
regionDistribution: Array<{ [key: string]: any }>;
|
||||
genderRatio: { [key: string]: number };
|
||||
weeklyTrend: Array<{ [key: string]: any }>;
|
||||
statusDistribution: { [key: string]: number };
|
||||
}
|
||||
@@ -54,7 +54,8 @@ html.dark svg {
|
||||
margin: 0px 0px 0 0 !important;
|
||||
}
|
||||
|
||||
#app .sidebar-container .nest-menu .el-sub-menu > .el-sub-menu__title, #app .sidebar-container .el-sub-menu .el-menu-item{
|
||||
#app .sidebar-container .nest-menu .el-sub-menu > .el-sub-menu__title,
|
||||
#app .sidebar-container .el-sub-menu .el-menu-item {
|
||||
margin: 0px 0px 0 0 !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -312,8 +312,6 @@ const performUpload = async (options: any) => {
|
||||
|
||||
// 上传成功回调
|
||||
const handleUploadSuccess = (res: any, file: any) => {
|
||||
|
||||
|
||||
// 确保res存在且有正确的结构
|
||||
if (res && res.code === 200) {
|
||||
// 避免重复添加,检查是否已经存在
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
<template>
|
||||
<div class="poster-preview">
|
||||
<!-- 海报画布容器 -->
|
||||
<div
|
||||
ref="posterRef"
|
||||
class="poster-canvas"
|
||||
:style="canvasStyle"
|
||||
>
|
||||
<div ref="posterRef" class="poster-canvas" :style="canvasStyle">
|
||||
<!-- 企业信息叠加 -->
|
||||
<div class="info-overlay">
|
||||
<!-- 顶部企业标题 -->
|
||||
@@ -15,7 +11,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 中间内容区域 - 根据海报类型显示不同内容 -->
|
||||
|
||||
|
||||
<!-- 企业海报:展示企业文化和优势 -->
|
||||
<div v-if="posterData.posterType === '1'" class="position-info">
|
||||
<div class="position-title">加入我们 · 共创辉煌</div>
|
||||
@@ -26,7 +22,7 @@
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
|
||||
<div class="detail-item" v-if="enterpriseDetail.mainBusiness">
|
||||
<span class="icon">🏢</span>
|
||||
<span>{{ enterpriseDetail.mainBusiness }}</span>
|
||||
@@ -44,16 +40,16 @@
|
||||
|
||||
<!-- 岗位海报:展示具体岗位信息 -->
|
||||
<div v-else-if="posterData.posterType === '2'" class="position-info">
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
<div class="position-title">
|
||||
{{ posterData.positionName || positionDetail?.positionName || '招聘岗位' }}
|
||||
</div>
|
||||
@@ -89,7 +85,6 @@
|
||||
<!-- 底部联系信息 - 根据海报类型显示不同内容 -->
|
||||
<div class="company-footer">
|
||||
<div v-if="enterpriseDetail" class="company-info">
|
||||
|
||||
<!-- 企业海报:重点显示联系方式 -->
|
||||
<template v-if="posterData.posterType === '1'">
|
||||
<div class="info-row" v-if="enterpriseDetail.contactPhone">
|
||||
@@ -125,7 +120,6 @@
|
||||
<span class="value">{{ enterpriseDetail.email }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -133,56 +127,52 @@
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="action-buttons">
|
||||
<el-button type="primary" icon="Download" @click="exportToPDF" :loading="exporting">
|
||||
导出PDF
|
||||
</el-button>
|
||||
<el-button icon="Picture" @click="exportToImage" :loading="exporting">
|
||||
导出图片
|
||||
</el-button>
|
||||
<el-button type="primary" icon="Download" @click="exportToPDF" :loading="exporting"> 导出PDF </el-button>
|
||||
<el-button icon="Picture" @click="exportToImage" :loading="exporting"> 导出图片 </el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import html2canvas from 'html2canvas'
|
||||
import jsPDF from 'jspdf'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ref, computed } from 'vue';
|
||||
import html2canvas from 'html2canvas';
|
||||
import jsPDF from 'jspdf';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
// 定义接口
|
||||
interface PosterData {
|
||||
posterPath: string
|
||||
enterpriseName: string
|
||||
positionName?: string
|
||||
posterType: string
|
||||
posterPath: string;
|
||||
enterpriseName: string;
|
||||
positionName?: string;
|
||||
posterType: string;
|
||||
}
|
||||
|
||||
interface EnterpriseDetail {
|
||||
mainBusiness?: string
|
||||
enterpriseScale?: string
|
||||
contactPhone?: string
|
||||
email?: string
|
||||
address?: string
|
||||
mainBusiness?: string;
|
||||
enterpriseScale?: string;
|
||||
contactPhone?: string;
|
||||
email?: string;
|
||||
address?: string;
|
||||
}
|
||||
|
||||
interface PositionDetail {
|
||||
positionName?: string
|
||||
workAddress?: string
|
||||
salary?: string
|
||||
workTime?: string
|
||||
requiredSkills?: string
|
||||
positionName?: string;
|
||||
workAddress?: string;
|
||||
salary?: string;
|
||||
workTime?: string;
|
||||
requiredSkills?: string;
|
||||
}
|
||||
|
||||
// Props定义
|
||||
const props = defineProps<{
|
||||
posterData: PosterData
|
||||
enterpriseDetail?: EnterpriseDetail
|
||||
positionDetail?: PositionDetail
|
||||
}>()
|
||||
posterData: PosterData;
|
||||
enterpriseDetail?: EnterpriseDetail;
|
||||
positionDetail?: PositionDetail;
|
||||
}>();
|
||||
|
||||
// 响应式数据
|
||||
const posterRef = ref<HTMLElement>()
|
||||
const exporting = ref(false)
|
||||
const posterRef = ref<HTMLElement>();
|
||||
const exporting = ref(false);
|
||||
|
||||
// 计算样式
|
||||
const canvasStyle = computed(() => ({
|
||||
@@ -190,7 +180,7 @@ const canvasStyle = computed(() => ({
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat'
|
||||
}))
|
||||
}));
|
||||
|
||||
// 企业规模字典
|
||||
const scaleDict = {
|
||||
@@ -199,79 +189,79 @@ const scaleDict = {
|
||||
'3': '200-500人',
|
||||
'4': '500-1000人',
|
||||
'5': '1000人以上'
|
||||
}
|
||||
};
|
||||
|
||||
// 获取规模标签
|
||||
const getScaleLabel = (value: string) => {
|
||||
return scaleDict[value as keyof typeof scaleDict] || value
|
||||
}
|
||||
return scaleDict[value as keyof typeof scaleDict] || value;
|
||||
};
|
||||
|
||||
// 导出为PDF
|
||||
const exportToPDF = async () => {
|
||||
if (!posterRef.value) return
|
||||
|
||||
if (!posterRef.value) return;
|
||||
|
||||
try {
|
||||
exporting.value = true
|
||||
|
||||
exporting.value = true;
|
||||
|
||||
const canvas = await html2canvas(posterRef.value, {
|
||||
backgroundColor: null,
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
allowTaint: true,
|
||||
foreignObjectRendering: false
|
||||
})
|
||||
|
||||
const imgData = canvas.toDataURL('image/png')
|
||||
});
|
||||
|
||||
const imgData = canvas.toDataURL('image/png');
|
||||
const pdf = new jsPDF({
|
||||
orientation: 'portrait',
|
||||
unit: 'mm',
|
||||
format: 'a4'
|
||||
})
|
||||
|
||||
const imgWidth = 190
|
||||
const imgHeight = (canvas.height * imgWidth) / canvas.width
|
||||
|
||||
pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight)
|
||||
|
||||
const fileName = `${props.posterData.enterpriseName}_招聘海报_${new Date().getTime()}.pdf`
|
||||
pdf.save(fileName)
|
||||
|
||||
ElMessage.success('PDF导出成功')
|
||||
});
|
||||
|
||||
const imgWidth = 190;
|
||||
const imgHeight = (canvas.height * imgWidth) / canvas.width;
|
||||
|
||||
pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight);
|
||||
|
||||
const fileName = `${props.posterData.enterpriseName}_招聘海报_${new Date().getTime()}.pdf`;
|
||||
pdf.save(fileName);
|
||||
|
||||
ElMessage.success('PDF导出成功');
|
||||
} catch (error) {
|
||||
console.error('PDF导出失败:', error)
|
||||
ElMessage.error('PDF导出失败,请重试')
|
||||
console.error('PDF导出失败:', error);
|
||||
ElMessage.error('PDF导出失败,请重试');
|
||||
} finally {
|
||||
exporting.value = false
|
||||
exporting.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 导出为图片
|
||||
const exportToImage = async () => {
|
||||
if (!posterRef.value) return
|
||||
|
||||
if (!posterRef.value) return;
|
||||
|
||||
try {
|
||||
exporting.value = true
|
||||
|
||||
exporting.value = true;
|
||||
|
||||
const canvas = await html2canvas(posterRef.value, {
|
||||
backgroundColor: null,
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
allowTaint: true
|
||||
})
|
||||
|
||||
const link = document.createElement('a')
|
||||
link.download = `${props.posterData.enterpriseName}_招聘海报_${new Date().getTime()}.png`
|
||||
link.href = canvas.toDataURL('image/png')
|
||||
link.click()
|
||||
|
||||
ElMessage.success('图片导出成功')
|
||||
});
|
||||
|
||||
const link = document.createElement('a');
|
||||
link.download = `${props.posterData.enterpriseName}_招聘海报_${new Date().getTime()}.png`;
|
||||
link.href = canvas.toDataURL('image/png');
|
||||
link.click();
|
||||
|
||||
ElMessage.success('图片导出成功');
|
||||
} catch (error) {
|
||||
console.error('图片导出失败:', error)
|
||||
ElMessage.error('图片导出失败,请重试')
|
||||
console.error('图片导出失败:', error);
|
||||
ElMessage.error('图片导出失败,请重试');
|
||||
} finally {
|
||||
exporting.value = false
|
||||
exporting.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -304,12 +294,7 @@ const exportToImage = async () => {
|
||||
padding: 40px;
|
||||
color: white;
|
||||
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.8);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
rgba(0, 0, 0, 0.3) 0%,
|
||||
rgba(0, 0, 0, 0.1) 50%,
|
||||
rgba(0, 0, 0, 0.4) 100%
|
||||
);
|
||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.1) 50%, rgba(0, 0, 0, 0.4) 100%);
|
||||
}
|
||||
|
||||
.company-header {
|
||||
@@ -440,22 +425,22 @@ const exportToImage = async () => {
|
||||
max-width: 450px;
|
||||
max-height: 600px;
|
||||
}
|
||||
|
||||
|
||||
.info-overlay {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
.company-name {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
|
||||
.position-title {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
.detail-item {
|
||||
font-size: 14px;
|
||||
padding: 8px 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -11,7 +11,7 @@ import { usePermissionStore } from '@/store/modules/permission';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
NProgress.configure({ showSpinner: false });
|
||||
const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*'];
|
||||
const whiteList = ['/login', '/register', '/social-callback', '/register*', '/register/*', '/recruitment-portal', '/recruitment-apply'];
|
||||
|
||||
const isWhiteList = (path: string) => {
|
||||
return whiteList.some((pattern) => isPathMatch(pattern, path));
|
||||
|
||||
@@ -17,7 +17,7 @@ export default {
|
||||
// const { data: downloadUrl } = await getFileDownloadUrl(String(ossId));
|
||||
|
||||
const response = await request({
|
||||
url: "/resource/oss/download/" + ossId,
|
||||
url: '/resource/oss/download/' + ossId,
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
timeout: 300000 // 300秒超时
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
// const { data: downloadUrl } = await getFileDownloadUrl(String(ossId));
|
||||
|
||||
const response = await request({
|
||||
url: "/resource/oss/download/" + ossId,
|
||||
url: '/resource/oss/download/' + ossId,
|
||||
method: 'get',
|
||||
responseType: 'blob',
|
||||
timeout: 300000 // 300秒超时
|
||||
@@ -83,7 +83,7 @@ export default {
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
timeout: 300000 ,// 300秒超时
|
||||
timeout: 300000, // 300秒超时
|
||||
headers: globalHeaders()
|
||||
});
|
||||
const isBlob = blobValidate(res.data);
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { App } from 'vue'
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||
import { App } from 'vue';
|
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue';
|
||||
|
||||
export default function registerIcons(app: App) {
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||
app.component(key, component)
|
||||
app.component(key, component);
|
||||
}
|
||||
|
||||
|
||||
// 移除重复的Close组件注册
|
||||
// app.component('Close', ElementPlusIconsVue.Close);
|
||||
|
||||
|
||||
// 注册常用图标的别名
|
||||
app.component('CircleCloseIcon', ElementPlusIconsVue.CircleClose);
|
||||
}
|
||||
@@ -89,6 +89,22 @@ export const constantRoutes: RouteRecordRaw[] = [
|
||||
}
|
||||
]
|
||||
},
|
||||
// 添加招聘门户路由
|
||||
{
|
||||
path: '/recruitment-portal',
|
||||
component: () => import('@/views/rs/recruitment-portal.vue'),
|
||||
name: 'RecruitmentPortal',
|
||||
hidden: true,
|
||||
meta: { title: '招聘公告', icon: 'user' }
|
||||
},
|
||||
// 添加招聘应聘路由
|
||||
{
|
||||
path: '/recruitment-apply',
|
||||
component: () => import('@/views/rs/recruitment-apply.vue'),
|
||||
name: 'RecruitmentApply',
|
||||
hidden: true,
|
||||
meta: { title: '在线应聘', icon: 'user' }
|
||||
}
|
||||
];
|
||||
|
||||
// 动态路由,基于用户权限动态去加载
|
||||
|
||||
Vendored
+2
-2
@@ -87,12 +87,12 @@ declare global {
|
||||
declare interface PageQuery {
|
||||
pageNum: number;
|
||||
pageSize: number;
|
||||
|
||||
|
||||
/**
|
||||
* 排序字段 老李
|
||||
*/
|
||||
orderByColumn?: string;
|
||||
|
||||
|
||||
/**
|
||||
* 排序方式(asc/desc)
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ axios.defaults.headers['clientid'] = import.meta.env.VITE_APP_CLIENT_ID;
|
||||
// 创建 axios 实例
|
||||
const service = axios.create({
|
||||
baseURL: import.meta.env.VITE_APP_BASE_API,
|
||||
timeout: 300000 // 增加到5分钟,适合大数据量导出
|
||||
timeout: 300000 // 增加到5分钟,适合大数据量导出
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
@@ -177,7 +177,7 @@ service.interceptors.response.use(
|
||||
console.log('404错误被静默处理,不显示用户提示');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
|
||||
// 对心理健康测评详情页面的403错误进行特殊处理
|
||||
if (statusCode === '403') {
|
||||
const url = error.config.url;
|
||||
@@ -187,7 +187,7 @@ service.interceptors.response.use(
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
message = '系统接口' + statusCode + '异常';
|
||||
}
|
||||
ElMessage({ message: message, type: 'error', duration: 5 * 1000 });
|
||||
|
||||
@@ -17,39 +17,24 @@
|
||||
<span>产出指标</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- 数量指标 -->
|
||||
<div class="indicator-item">
|
||||
<h4 class="indicator-title">数量指标</h4>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.quantity.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quantity.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.quantity.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quantity.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.quantity.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quantity.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -67,12 +52,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.quantity.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quantity.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -84,32 +64,17 @@
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.quality.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quality.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.quality.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quality.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.quality.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quality.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -127,12 +92,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.quality.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.quality.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -144,32 +104,17 @@
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.timeliness.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.timeliness.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.timeliness.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.timeliness.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.timeliness.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.timeliness.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -187,12 +132,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.timeliness.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.timeliness.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -204,32 +144,17 @@
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.cost.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.cost.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.cost.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.cost.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.cost.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.cost.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -247,12 +172,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.cost.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.cost.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -267,39 +187,24 @@
|
||||
<span>效益指标</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- 经济效益指标 -->
|
||||
<div class="indicator-item">
|
||||
<h4 class="indicator-title">经济效益指标</h4>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.economic.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.economic.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.economic.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.economic.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.economic.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.economic.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -317,12 +222,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.economic.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.economic.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -334,32 +234,17 @@
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.social.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.social.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.social.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.social.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.social.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.social.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -377,12 +262,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.social.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.social.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -394,32 +274,17 @@
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.ecological.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.ecological.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.ecological.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.ecological.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.ecological.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.ecological.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -437,12 +302,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.ecological.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.ecological.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -457,39 +317,24 @@
|
||||
<span>满意度指标</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<!-- 服务对象满意度指标 -->
|
||||
<div class="indicator-item">
|
||||
<h4 class="indicator-title">服务对象满意度指标</h4>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="绩效目标名称">
|
||||
<el-input
|
||||
v-model="indicators.service_satisfaction.goalName"
|
||||
placeholder="请输入绩效目标名称"
|
||||
maxlength="200"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.service_satisfaction.goalName" placeholder="请输入绩效目标名称" maxlength="200" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item label="目标值">
|
||||
<el-input
|
||||
v-model="indicators.service_satisfaction.targetValue"
|
||||
placeholder="目标值"
|
||||
maxlength="100"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.service_satisfaction.targetValue" placeholder="目标值" maxlength="100" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item label="单位">
|
||||
<el-input
|
||||
v-model="indicators.service_satisfaction.unit"
|
||||
placeholder="单位"
|
||||
maxlength="20"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.service_satisfaction.unit" placeholder="单位" maxlength="20" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@@ -507,12 +352,7 @@
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="详细说明">
|
||||
<el-input
|
||||
v-model="indicators.service_satisfaction.description"
|
||||
placeholder="详细说明"
|
||||
maxlength="500"
|
||||
@input="emitChange"
|
||||
/>
|
||||
<el-input v-model="indicators.service_satisfaction.description" placeholder="详细说明" maxlength="500" @input="emitChange" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -531,22 +371,22 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, computed, watch } from 'vue'
|
||||
import { TrendCharts, Money, Star } from '@element-plus/icons-vue'
|
||||
import { defineComponent, ref, computed, watch } from 'vue';
|
||||
import { TrendCharts, Money, Star } from '@element-plus/icons-vue';
|
||||
|
||||
interface PerformanceIndicator {
|
||||
indicatorType: string
|
||||
indicatorTypeName: string
|
||||
goalName: string
|
||||
targetValue: string
|
||||
unit: string
|
||||
weightPercentage: number
|
||||
description: string
|
||||
measurementMethod: string
|
||||
dataSource: string
|
||||
isQuantitative: boolean
|
||||
sortOrder: number
|
||||
status: string
|
||||
indicatorType: string;
|
||||
indicatorTypeName: string;
|
||||
goalName: string;
|
||||
targetValue: string;
|
||||
unit: string;
|
||||
weightPercentage: number;
|
||||
description: string;
|
||||
measurementMethod: string;
|
||||
dataSource: string;
|
||||
isQuantitative: boolean;
|
||||
sortOrder: number;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
@@ -582,7 +422,7 @@ export default defineComponent({
|
||||
isQuantitative: true,
|
||||
sortOrder: 0,
|
||||
status: '1'
|
||||
})
|
||||
});
|
||||
|
||||
// 8种固定的指标类型
|
||||
const indicators = ref({
|
||||
@@ -594,46 +434,46 @@ export default defineComponent({
|
||||
social: createIndicator('social', '社会效益指标'),
|
||||
ecological: createIndicator('ecological', '生态效益指标'),
|
||||
service_satisfaction: createIndicator('service_satisfaction', '服务对象满意度指标')
|
||||
})
|
||||
});
|
||||
|
||||
// 计算总分值占比
|
||||
const totalWeight = computed(() => {
|
||||
let total = 0
|
||||
Object.values(indicators.value).forEach(indicator => {
|
||||
total += indicator.weightPercentage || 0
|
||||
})
|
||||
return Math.round(total * 10) / 10
|
||||
})
|
||||
let total = 0;
|
||||
Object.values(indicators.value).forEach((indicator) => {
|
||||
total += indicator.weightPercentage || 0;
|
||||
});
|
||||
return Math.round(total * 10) / 10;
|
||||
});
|
||||
|
||||
// 收集有效的指标数据
|
||||
const collectValidIndicators = () => {
|
||||
const validIndicators: PerformanceIndicator[] = []
|
||||
let sortOrder = 0
|
||||
|
||||
Object.values(indicators.value).forEach(indicator => {
|
||||
const validIndicators: PerformanceIndicator[] = [];
|
||||
let sortOrder = 0;
|
||||
|
||||
Object.values(indicators.value).forEach((indicator) => {
|
||||
// 只有填写了目标名称的指标才被认为是有效的
|
||||
if (indicator.goalName?.trim()) {
|
||||
validIndicators.push({
|
||||
...indicator,
|
||||
sortOrder: sortOrder++
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
return validIndicators
|
||||
}
|
||||
});
|
||||
|
||||
return validIndicators;
|
||||
};
|
||||
|
||||
// 发出变化事件
|
||||
const emitChange = () => {
|
||||
const validIndicators = collectValidIndicators()
|
||||
emit('update:modelValue', validIndicators)
|
||||
emit('change', validIndicators)
|
||||
}
|
||||
const validIndicators = collectValidIndicators();
|
||||
emit('update:modelValue', validIndicators);
|
||||
emit('change', validIndicators);
|
||||
};
|
||||
|
||||
// 从传入的数据初始化指标
|
||||
const initializeFromData = (data: any[]) => {
|
||||
if (!data || data.length === 0) return
|
||||
|
||||
if (!data || data.length === 0) return;
|
||||
|
||||
// 重置所有指标
|
||||
indicators.value = {
|
||||
quantity: createIndicator('quantity', '数量指标'),
|
||||
@@ -644,57 +484,61 @@ export default defineComponent({
|
||||
social: createIndicator('social', '社会效益指标'),
|
||||
ecological: createIndicator('ecological', '生态效益指标'),
|
||||
service_satisfaction: createIndicator('service_satisfaction', '服务对象满意度指标')
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 将数据填入对应的指标类型
|
||||
data.forEach(item => {
|
||||
data.forEach((item) => {
|
||||
if (indicators.value[item.indicatorType]) {
|
||||
indicators.value[item.indicatorType] = { ...item }
|
||||
indicators.value[item.indicatorType] = { ...item };
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 监听外部数据变化
|
||||
watch(() => props.modelValue, (newValue) => {
|
||||
initializeFromData(newValue)
|
||||
}, { deep: true, immediate: true })
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newValue) => {
|
||||
initializeFromData(newValue);
|
||||
},
|
||||
{ deep: true, immediate: true }
|
||||
);
|
||||
|
||||
// 校验方法
|
||||
const validate = () => {
|
||||
const validIndicators = collectValidIndicators()
|
||||
const errors = []
|
||||
|
||||
const validIndicators = collectValidIndicators();
|
||||
const errors = [];
|
||||
|
||||
if (validIndicators.length === 0) {
|
||||
errors.push('请至少填写一个绩效指标')
|
||||
errors.push('请至少填写一个绩效指标');
|
||||
}
|
||||
|
||||
|
||||
validIndicators.forEach((indicator, index) => {
|
||||
if (!indicator.goalName?.trim()) {
|
||||
errors.push(`第${index + 1}个指标未填写绩效目标名称`)
|
||||
errors.push(`第${index + 1}个指标未填写绩效目标名称`);
|
||||
}
|
||||
if (!indicator.targetValue?.trim()) {
|
||||
errors.push(`第${index + 1}个指标未填写目标值`)
|
||||
errors.push(`第${index + 1}个指标未填写目标值`);
|
||||
}
|
||||
if (!indicator.weightPercentage || indicator.weightPercentage <= 0) {
|
||||
errors.push(`第${index + 1}个指标未设置分值占比`)
|
||||
errors.push(`第${index + 1}个指标未设置分值占比`);
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
if (Math.abs(totalWeight.value - 100) > 0.1) {
|
||||
errors.push(`分值占比总和必须等于100%,当前为${totalWeight.value}%`)
|
||||
errors.push(`分值占比总和必须等于100%,当前为${totalWeight.value}%`);
|
||||
}
|
||||
|
||||
|
||||
if (errors.length > 0) {
|
||||
return { valid: false, message: errors.join(';') }
|
||||
return { valid: false, message: errors.join(';') };
|
||||
}
|
||||
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
};
|
||||
|
||||
// 获取所有有效指标数据
|
||||
const getAllIndicators = () => {
|
||||
return collectValidIndicators()
|
||||
}
|
||||
return collectValidIndicators();
|
||||
};
|
||||
|
||||
return {
|
||||
indicators,
|
||||
@@ -702,9 +546,9 @@ export default defineComponent({
|
||||
emitChange,
|
||||
validate,
|
||||
getAllIndicators
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -715,34 +559,33 @@ export default defineComponent({
|
||||
gap: 8px;
|
||||
font-weight: bold;
|
||||
font-size: 16px;
|
||||
|
||||
|
||||
.el-icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.indicator-item {
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
background-color: #fafafa;
|
||||
border-radius: 6px;
|
||||
border-left: 4px solid #409eff;
|
||||
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.indicator-title {
|
||||
margin: 0 0 15px 0;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
|
||||
.el-form-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -16,12 +16,7 @@
|
||||
<!-- 审批流程 -->
|
||||
<el-divider content-position="left">审批流程</el-divider>
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
v-for="(item, index) in approvalTimeline"
|
||||
:key="index"
|
||||
:type="item.type"
|
||||
:timestamp="item.timestamp"
|
||||
>
|
||||
<el-timeline-item v-for="(item, index) in approvalTimeline" :key="index" :type="item.type" :timestamp="item.timestamp">
|
||||
<div class="timeline-content">
|
||||
<h4>{{ item.title }}</h4>
|
||||
<p>{{ item.description }}</p>
|
||||
@@ -33,36 +28,25 @@
|
||||
<!-- 操作日志 -->
|
||||
<el-divider content-position="left">操作日志</el-divider>
|
||||
<el-table :data="operationLogs" style="width: 100%">
|
||||
<el-table-column prop="operation" label="操作" width="120"/>
|
||||
<el-table-column prop="operator" label="操作人" width="100"/>
|
||||
<el-table-column prop="operation" label="操作" width="120" />
|
||||
<el-table-column prop="operator" label="操作人" width="100" />
|
||||
<el-table-column prop="operateTime" label="操作时间" width="180">
|
||||
<template #default="scope">
|
||||
{{ parseTime(scope.row.operateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="remark" label="备注" show-overflow-tooltip/>
|
||||
<el-table-column prop="remark" label="备注" show-overflow-tooltip />
|
||||
</el-table>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="operation-buttons">
|
||||
<el-button
|
||||
v-if="detail.approvalStatus === 'draft'"
|
||||
type="primary"
|
||||
@click="handleEdit"
|
||||
v-hasPermi="['cw:application:edit']"
|
||||
>编辑</el-button>
|
||||
<el-button
|
||||
v-if="detail.approvalStatus === 'draft'"
|
||||
type="success"
|
||||
@click="handleSubmit"
|
||||
v-hasPermi="['cw:application:submit']"
|
||||
>提交</el-button>
|
||||
<el-button
|
||||
v-if="detail.approvalStatus === 'pending'"
|
||||
type="warning"
|
||||
@click="handleWithdraw"
|
||||
v-hasPermi="['cw:application:withdraw']"
|
||||
>撤回</el-button>
|
||||
<el-button v-if="detail.approvalStatus === 'draft'" type="primary" @click="handleEdit" v-hasPermi="['cw:application:edit']">编辑</el-button>
|
||||
<el-button v-if="detail.approvalStatus === 'draft'" type="success" @click="handleSubmit" v-hasPermi="['cw:application:submit']"
|
||||
>提交</el-button
|
||||
>
|
||||
<el-button v-if="detail.approvalStatus === 'pending'" type="warning" @click="handleWithdraw" v-hasPermi="['cw:application:withdraw']"
|
||||
>撤回</el-button
|
||||
>
|
||||
<el-button @click="goBack">返回</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -72,9 +56,9 @@
|
||||
<script setup name="CwApplicationDetail">
|
||||
import { ref, getCurrentInstance, onMounted } from 'vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { getProjectApplication, submitApplication, withdrawApplication } from "@/api/cw/projectApplication";
|
||||
import ApplicationSummary from "./summary.vue";
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
import { getProjectApplication, submitApplication, withdrawApplication } from '@/api/cw/projectApplication';
|
||||
import ApplicationSummary from './summary.vue';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
console.log('=== detail.vue 组件开始加载 ===');
|
||||
|
||||
@@ -120,32 +104,40 @@ function getStatusText(status) {
|
||||
|
||||
/** 编辑按钮操作 */
|
||||
function handleEdit() {
|
||||
router.push("/cw/application/form?id=" + detail.value.id);
|
||||
router.push('/cw/application/form?id=' + detail.value.id);
|
||||
}
|
||||
|
||||
/** 提交按钮操作 */
|
||||
function handleSubmit() {
|
||||
proxy.$modal.confirm('是否确认提交申报编号为"' + detail.value.applicationNo + '"的数据项?').then(function() {
|
||||
return submitApplication(detail.value.id);
|
||||
}).then(() => {
|
||||
getDetail();
|
||||
proxy.$modal.msgSuccess("提交成功");
|
||||
}).catch(() => {});
|
||||
proxy.$modal
|
||||
.confirm('是否确认提交申报编号为"' + detail.value.applicationNo + '"的数据项?')
|
||||
.then(function () {
|
||||
return submitApplication(detail.value.id);
|
||||
})
|
||||
.then(() => {
|
||||
getDetail();
|
||||
proxy.$modal.msgSuccess('提交成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/** 撤回按钮操作 */
|
||||
function handleWithdraw() {
|
||||
proxy.$modal.confirm('是否确认撤回申报编号为"' + detail.value.applicationNo + '"的数据项?').then(function() {
|
||||
return withdrawApplication(detail.value.id);
|
||||
}).then(() => {
|
||||
getDetail();
|
||||
proxy.$modal.msgSuccess("撤回成功");
|
||||
}).catch(() => {});
|
||||
proxy.$modal
|
||||
.confirm('是否确认撤回申报编号为"' + detail.value.applicationNo + '"的数据项?')
|
||||
.then(function () {
|
||||
return withdrawApplication(detail.value.id);
|
||||
})
|
||||
.then(() => {
|
||||
getDetail();
|
||||
proxy.$modal.msgSuccess('撤回成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/** 返回按钮操作 */
|
||||
function goBack() {
|
||||
router.push("/cw/application");
|
||||
router.push('/cw/application');
|
||||
}
|
||||
|
||||
/** 获取详情数据 */
|
||||
@@ -154,78 +146,80 @@ function getDetail() {
|
||||
console.log('=== 开始获取详情数据 ===');
|
||||
console.log('URL参数中的ID:', id);
|
||||
console.log('完整query参数:', route.query);
|
||||
|
||||
|
||||
if (id) {
|
||||
console.log('开始调用API:getProjectApplication, ID:', id);
|
||||
getProjectApplication(id).then(response => {
|
||||
console.log('=== API调用成功 ===');
|
||||
console.log('API响应:', response);
|
||||
console.log('响应代码:', response.code);
|
||||
console.log('响应数据:', response.data);
|
||||
|
||||
detail.value = response.data;
|
||||
getProjectApplication(id)
|
||||
.then((response) => {
|
||||
console.log('=== API调用成功 ===');
|
||||
console.log('API响应:', response);
|
||||
console.log('响应代码:', response.code);
|
||||
console.log('响应数据:', response.data);
|
||||
|
||||
// 调试日志:查看返回的数据
|
||||
console.log('=== 项目申报详情数据 ===');
|
||||
console.log('完整数据:', response.data);
|
||||
console.log('绩效指标数据:', response.data.performanceIndicators);
|
||||
console.log('绩效指标数量:', response.data.performanceIndicators ? response.data.performanceIndicators.length : 0);
|
||||
detail.value = response.data;
|
||||
|
||||
// 模拟审批流程数据
|
||||
approvalTimeline.value = [
|
||||
{
|
||||
type: 'success',
|
||||
timestamp: detail.value.createTime,
|
||||
title: '申报提交',
|
||||
description: '申报人提交预算申报',
|
||||
user: detail.value.applicantName
|
||||
// 调试日志:查看返回的数据
|
||||
console.log('=== 项目申报详情数据 ===');
|
||||
console.log('完整数据:', response.data);
|
||||
console.log('绩效指标数据:', response.data.performanceIndicators);
|
||||
console.log('绩效指标数量:', response.data.performanceIndicators ? response.data.performanceIndicators.length : 0);
|
||||
|
||||
// 模拟审批流程数据
|
||||
approvalTimeline.value = [
|
||||
{
|
||||
type: 'success',
|
||||
timestamp: detail.value.createTime,
|
||||
title: '申报提交',
|
||||
description: '申报人提交预算申报',
|
||||
user: detail.value.applicantName
|
||||
}
|
||||
];
|
||||
|
||||
if (detail.value.submitTime) {
|
||||
approvalTimeline.value.push({
|
||||
type: 'primary',
|
||||
timestamp: detail.value.submitTime,
|
||||
title: '提交审批',
|
||||
description: '申报已提交,等待部门审批',
|
||||
user: detail.value.applicantName
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
if (detail.value.submitTime) {
|
||||
approvalTimeline.value.push({
|
||||
type: 'primary',
|
||||
timestamp: detail.value.submitTime,
|
||||
title: '提交审批',
|
||||
description: '申报已提交,等待部门审批',
|
||||
user: detail.value.applicantName
|
||||
});
|
||||
}
|
||||
|
||||
if (detail.value.approveTime && detail.value.approvalStatus === 'approved') {
|
||||
approvalTimeline.value.push({
|
||||
type: 'success',
|
||||
timestamp: detail.value.approveTime,
|
||||
title: '审批通过',
|
||||
description: '所有审批节点已通过',
|
||||
user: '系统管理员'
|
||||
});
|
||||
}
|
||||
|
||||
// 模拟操作日志数据
|
||||
operationLogs.value = [
|
||||
{
|
||||
operation: '创建申报',
|
||||
operator: detail.value.applicantName,
|
||||
operateTime: detail.value.createTime,
|
||||
remark: '创建项目预算申报'
|
||||
if (detail.value.approveTime && detail.value.approvalStatus === 'approved') {
|
||||
approvalTimeline.value.push({
|
||||
type: 'success',
|
||||
timestamp: detail.value.approveTime,
|
||||
title: '审批通过',
|
||||
description: '所有审批节点已通过',
|
||||
user: '系统管理员'
|
||||
});
|
||||
}
|
||||
];
|
||||
|
||||
if (detail.value.submitTime) {
|
||||
operationLogs.value.push({
|
||||
operation: '提交审批',
|
||||
operator: detail.value.applicantName,
|
||||
operateTime: detail.value.submitTime,
|
||||
remark: '提交预算申报进入审批流程'
|
||||
});
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error('=== API调用失败 ===');
|
||||
console.error('错误信息:', error);
|
||||
console.error('错误响应:', error.response);
|
||||
proxy.$modal.msgError('获取申报详情失败:' + (error.message || '未知错误'));
|
||||
});
|
||||
// 模拟操作日志数据
|
||||
operationLogs.value = [
|
||||
{
|
||||
operation: '创建申报',
|
||||
operator: detail.value.applicantName,
|
||||
operateTime: detail.value.createTime,
|
||||
remark: '创建项目预算申报'
|
||||
}
|
||||
];
|
||||
|
||||
if (detail.value.submitTime) {
|
||||
operationLogs.value.push({
|
||||
operation: '提交审批',
|
||||
operator: detail.value.applicantName,
|
||||
operateTime: detail.value.submitTime,
|
||||
remark: '提交预算申报进入审批流程'
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('=== API调用失败 ===');
|
||||
console.error('错误信息:', error);
|
||||
console.error('错误响应:', error.response);
|
||||
proxy.$modal.msgError('获取申报详情失败:' + (error.message || '未知错误'));
|
||||
});
|
||||
} else {
|
||||
console.error('=== URL参数错误 ===');
|
||||
console.error('缺少ID参数,无法获取详情数据');
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -64,71 +64,50 @@
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="queryParams" ref="queryRef" 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="principal">
|
||||
<el-input
|
||||
v-model="queryParams.principal"
|
||||
placeholder="请输入项目负责人"
|
||||
clearable
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="审批状态" prop="approvalStatus">
|
||||
<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="principal">
|
||||
<el-input v-model="queryParams.principal" placeholder="请输入项目负责人" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="审批状态" prop="approvalStatus">
|
||||
<el-select v-model="queryParams.approvalStatus" placeholder="请选择审批状态" clearable style="width: 100%">
|
||||
<el-option label="草稿" value="draft"/>
|
||||
<el-option label="已提交" value="submitted"/>
|
||||
<el-option label="审批中" value="approving"/>
|
||||
<el-option label="已通过" value="approved"/>
|
||||
<el-option label="已拒绝" value="rejected"/>
|
||||
<el-option label="已退回" value="returned"/>
|
||||
<el-option label="已取消" value="cancelled"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="预算年度" prop="year">
|
||||
<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-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-option label="草稿" value="draft" />
|
||||
<el-option label="已提交" value="submitted" />
|
||||
<el-option label="审批中" value="approving" />
|
||||
<el-option label="已通过" value="approved" />
|
||||
<el-option label="已拒绝" value="rejected" />
|
||||
<el-option label="已退回" value="returned" />
|
||||
<el-option label="已取消" value="cancelled" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="预算年度" prop="year">
|
||||
<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-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>
|
||||
|
||||
<!-- 操作按钮区域 -->
|
||||
@@ -137,40 +116,14 @@
|
||||
<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>
|
||||
<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>
|
||||
</template>
|
||||
@@ -179,13 +132,8 @@
|
||||
<!-- 数据表格区域 -->
|
||||
<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" :data="applicationList" @selection-change="handleSelectionChange" class="scroll-table">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<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" />
|
||||
@@ -197,43 +145,26 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批状态" align="center" prop="approvalStatus" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
:type="getStatusTagType(scope.row.approvalStatus)"
|
||||
effect="light"
|
||||
>
|
||||
{{ getStatusText(scope.row.approvalStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusTagType(scope.row.approvalStatus)" effect="light">
|
||||
{{ getStatusText(scope.row.approvalStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160">
|
||||
<template #default="scope">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="280" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<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-tooltip>
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button type="primary" icon="View" circle size="small" @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-tooltip>
|
||||
<el-button type="success" icon="Edit" circle size="small" @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
|
||||
type="warning"
|
||||
@@ -243,7 +174,7 @@
|
||||
@click="handleSubmit(scope.row)"
|
||||
v-hasPermi="['cw:application:submit']"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="撤回" placement="top" v-if="scope.row.approvalStatus === 'submitted'">
|
||||
<el-button
|
||||
type="info"
|
||||
@@ -253,7 +184,7 @@
|
||||
@click="handleWithdraw(scope.row)"
|
||||
v-hasPermi="['cw:application:withdraw']"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top" v-if="['draft', 'cancelled', 'returned'].includes(scope.row.approvalStatus)">
|
||||
<el-button
|
||||
type="danger"
|
||||
@@ -263,17 +194,17 @@
|
||||
@click="handleDelete(scope.row)"
|
||||
v-hasPermi="['cw:application:remove']"
|
||||
/>
|
||||
</el-tooltip>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-container">
|
||||
<pagination
|
||||
v-show="total>0"
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
:page="queryParams.pageNum"
|
||||
:limit="queryParams.pageSize"
|
||||
@@ -307,13 +238,21 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listProjectApplication, getProjectApplication, delProjectApplication, addProjectApplication, updateProjectApplication, submitApplication, getApplicationStatistics } from "@/api/cw/projectApplication"
|
||||
import ApplicationForm from "./form.vue"
|
||||
import ApplicationSummary from "./summary.vue"
|
||||
import Pagination from "@/components/Pagination/index.vue"
|
||||
import {
|
||||
listProjectApplication,
|
||||
getProjectApplication,
|
||||
delProjectApplication,
|
||||
addProjectApplication,
|
||||
updateProjectApplication,
|
||||
submitApplication,
|
||||
getApplicationStatistics
|
||||
} from '@/api/cw/projectApplication';
|
||||
import ApplicationForm from './form.vue';
|
||||
import ApplicationSummary from './summary.vue';
|
||||
import Pagination from '@/components/Pagination/index.vue';
|
||||
|
||||
export default {
|
||||
name: "ProjectApplication",
|
||||
name: 'ProjectApplication',
|
||||
components: {
|
||||
ApplicationForm,
|
||||
ApplicationSummary,
|
||||
@@ -336,7 +275,7 @@ export default {
|
||||
// 项目申报表格数据
|
||||
applicationList: [],
|
||||
// 弹出层标题
|
||||
title: "",
|
||||
title: '',
|
||||
// 是否显示弹出层
|
||||
open: false,
|
||||
// 是否显示查看对话框
|
||||
@@ -362,52 +301,56 @@ export default {
|
||||
approvedCount: 0,
|
||||
pendingCount: 0,
|
||||
draftCount: 0
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList()
|
||||
this.getStatistics()
|
||||
this.getList();
|
||||
this.getStatistics();
|
||||
},
|
||||
methods: {
|
||||
/** 查询项目申报列表 */
|
||||
getList() {
|
||||
this.loading = true
|
||||
listProjectApplication(this.queryParams).then(response => {
|
||||
this.applicationList = response.rows
|
||||
this.total = response.total
|
||||
this.loading = false
|
||||
}).catch(error => {
|
||||
console.error('获取项目申报列表失败:', error)
|
||||
this.loading = false
|
||||
this.applicationList = []
|
||||
this.total = 0
|
||||
// 可以添加用户友好的错误提示
|
||||
this.$message.error('获取数据失败,请检查网络连接或联系管理员')
|
||||
})
|
||||
this.loading = true;
|
||||
listProjectApplication(this.queryParams)
|
||||
.then((response) => {
|
||||
this.applicationList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取项目申报列表失败:', error);
|
||||
this.loading = false;
|
||||
this.applicationList = [];
|
||||
this.total = 0;
|
||||
// 可以添加用户友好的错误提示
|
||||
this.$message.error('获取数据失败,请检查网络连接或联系管理员');
|
||||
});
|
||||
},
|
||||
/** 获取统计数据 */
|
||||
getStatistics() {
|
||||
// 调用专门的统计API接口
|
||||
const year = this.queryParams.year ? parseInt(this.queryParams.year) : null
|
||||
getApplicationStatistics(year).then(response => {
|
||||
const data = response.data
|
||||
this.totalCount = data.totalCount || 0
|
||||
this.approvedCount = data.approvedCount || 0
|
||||
this.pendingCount = data.approvingCount || 0 // 注意:后端返回的是approvingCount
|
||||
this.draftCount = data.draftCount || 0
|
||||
}).catch(error => {
|
||||
console.error('获取统计数据失败:', error)
|
||||
// 如果API失败,使用本地计算作为后备方案
|
||||
this.totalCount = this.applicationList.length
|
||||
this.approvedCount = this.applicationList.filter(item => item.approvalStatus === 'approved').length
|
||||
this.pendingCount = this.applicationList.filter(item => item.approvalStatus === 'approving').length
|
||||
this.draftCount = this.applicationList.filter(item => item.approvalStatus === 'draft').length
|
||||
})
|
||||
const year = this.queryParams.year ? parseInt(this.queryParams.year) : null;
|
||||
getApplicationStatistics(year)
|
||||
.then((response) => {
|
||||
const data = response.data;
|
||||
this.totalCount = data.totalCount || 0;
|
||||
this.approvedCount = data.approvedCount || 0;
|
||||
this.pendingCount = data.approvingCount || 0; // 注意:后端返回的是approvingCount
|
||||
this.draftCount = data.draftCount || 0;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取统计数据失败:', error);
|
||||
// 如果API失败,使用本地计算作为后备方案
|
||||
this.totalCount = this.applicationList.length;
|
||||
this.approvedCount = this.applicationList.filter((item) => item.approvalStatus === 'approved').length;
|
||||
this.pendingCount = this.applicationList.filter((item) => item.approvalStatus === 'approving').length;
|
||||
this.draftCount = this.applicationList.filter((item) => item.approvalStatus === 'draft').length;
|
||||
});
|
||||
},
|
||||
/** 取消按钮 */
|
||||
cancel() {
|
||||
this.open = false
|
||||
this.reset()
|
||||
this.open = false;
|
||||
this.reset();
|
||||
},
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
@@ -448,119 +391,136 @@ export default {
|
||||
futureYearOther: 0,
|
||||
performanceIndicators: [],
|
||||
approvalStatus: 'draft'
|
||||
}
|
||||
};
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1
|
||||
this.getList()
|
||||
this.getStatistics() // 搜索时也更新统计数据
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
this.getStatistics(); // 搜索时也更新统计数据
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryRef")
|
||||
this.handleQuery()
|
||||
this.resetForm('queryRef');
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.id)
|
||||
this.single = selection.length !== 1
|
||||
this.multiple = !selection.length
|
||||
this.ids = selection.map((item) => item.id);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset()
|
||||
this.open = true
|
||||
this.title = "添加项目申报"
|
||||
this.reset();
|
||||
this.open = true;
|
||||
this.title = '添加项目申报';
|
||||
},
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset()
|
||||
const id = row.id || this.ids
|
||||
getProjectApplication(id).then(response => {
|
||||
this.form = response.data
|
||||
this.open = true
|
||||
this.title = "修改项目申报"
|
||||
})
|
||||
this.reset();
|
||||
const id = row.id || this.ids;
|
||||
getProjectApplication(id).then((response) => {
|
||||
this.form = response.data;
|
||||
this.open = true;
|
||||
this.title = '修改项目申报';
|
||||
});
|
||||
},
|
||||
/** 查看详情 */
|
||||
handleView(row) {
|
||||
this.currentId = row.id
|
||||
this.viewOpen = true
|
||||
this.currentId = row.id;
|
||||
this.viewOpen = true;
|
||||
},
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs["applicationFormRef"].validate((valid, formData) => {
|
||||
this.$refs['applicationFormRef'].validate((valid, formData) => {
|
||||
if (valid && formData) {
|
||||
// 使用子组件回传的完整数据(包含绩效指标)
|
||||
this.form = formData
|
||||
console.log('提交表单数据:', this.form)
|
||||
this.form = formData;
|
||||
console.log('提交表单数据:', this.form);
|
||||
|
||||
if (this.form.id != null) {
|
||||
updateProjectApplication(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
this.getStatistics() // 修改后更新统计
|
||||
})
|
||||
updateProjectApplication(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('修改成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
this.getStatistics(); // 修改后更新统计
|
||||
});
|
||||
} else {
|
||||
addProjectApplication(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功")
|
||||
this.open = false
|
||||
this.getList()
|
||||
this.getStatistics() // 新增后更新统计
|
||||
})
|
||||
addProjectApplication(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('新增成功');
|
||||
this.open = false;
|
||||
this.getList();
|
||||
this.getStatistics(); // 新增后更新统计
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.$modal.msgError("请检查表单数据是否完整")
|
||||
this.$modal.msgError('请检查表单数据是否完整');
|
||||
}
|
||||
})
|
||||
});
|
||||
},
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const ids = row.id || this.ids
|
||||
this.$modal.confirm('是否确认删除项目申报编号为"' + ids + '"的数据项?').then(function() {
|
||||
return delProjectApplication(ids)
|
||||
}).then(() => {
|
||||
this.getList()
|
||||
this.getStatistics() // 删除后更新统计
|
||||
this.$modal.msgSuccess("删除成功")
|
||||
}).catch(() => {})
|
||||
const ids = row.id || this.ids;
|
||||
this.$modal
|
||||
.confirm('是否确认删除项目申报编号为"' + ids + '"的数据项?')
|
||||
.then(function () {
|
||||
return delProjectApplication(ids);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.getStatistics(); // 删除后更新统计
|
||||
this.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/** 提交审批 */
|
||||
handleSubmit(row) {
|
||||
const applications = row?.applicationNo ? [row.applicationNo] : this.applicationList.filter(item => this.ids.includes(item.id)).map(item => item.applicationNo)
|
||||
const applications = row?.applicationNo
|
||||
? [row.applicationNo]
|
||||
: this.applicationList.filter((item) => this.ids.includes(item.id)).map((item) => item.applicationNo);
|
||||
|
||||
this.$modal.confirm('是否确认提交申报编号为"' + applications.join('", "') + '"的数据项?').then(() => {
|
||||
return submitApplication(row?.id || this.ids)
|
||||
}).then(() => {
|
||||
this.getList()
|
||||
this.getStatistics() // 提交后更新统计
|
||||
this.$modal.msgSuccess("提交成功")
|
||||
}).catch(() => {})
|
||||
this.$modal
|
||||
.confirm('是否确认提交申报编号为"' + applications.join('", "') + '"的数据项?')
|
||||
.then(() => {
|
||||
return submitApplication(row?.id || this.ids);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.getStatistics(); // 提交后更新统计
|
||||
this.$modal.msgSuccess('提交成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/** 撤回申请 */
|
||||
handleWithdraw(row) {
|
||||
this.$modal.confirm('是否确认撤回该申报?').then(() => {
|
||||
// 调用撤回接口
|
||||
this.$modal.msgSuccess("撤回成功")
|
||||
this.getList()
|
||||
this.getStatistics() // 撤回后更新统计
|
||||
}).catch(() => {})
|
||||
this.$modal
|
||||
.confirm('是否确认撤回该申报?')
|
||||
.then(() => {
|
||||
// 调用撤回接口
|
||||
this.$modal.msgSuccess('撤回成功');
|
||||
this.getList();
|
||||
this.getStatistics(); // 撤回后更新统计
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('cw/application/export', {
|
||||
...this.queryParams
|
||||
}, `application_${new Date().getTime()}.xlsx`)
|
||||
this.download(
|
||||
'cw/application/export',
|
||||
{
|
||||
...this.queryParams
|
||||
},
|
||||
`application_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
/** 格式化金额 */
|
||||
formatAmount(amount) {
|
||||
if (!amount) return '0.00'
|
||||
if (!amount) return '0.00';
|
||||
return parseFloat(amount).toLocaleString('zh-CN', {
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2
|
||||
})
|
||||
});
|
||||
},
|
||||
/** 获取状态标签类型 */
|
||||
getStatusTagType(status) {
|
||||
@@ -572,8 +532,8 @@ export default {
|
||||
rejected: 'danger',
|
||||
returned: 'warning',
|
||||
cancelled: 'info'
|
||||
}
|
||||
return statusMap[status] || 'info'
|
||||
};
|
||||
return statusMap[status] || 'info';
|
||||
},
|
||||
/** 获取状态文本 */
|
||||
getStatusText(status) {
|
||||
@@ -585,11 +545,11 @@ export default {
|
||||
rejected: '已拒绝',
|
||||
returned: '已退回',
|
||||
cancelled: '已取消'
|
||||
}
|
||||
return statusMap[status] || '未知'
|
||||
};
|
||||
return statusMap[status] || '未知';
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@@ -614,8 +574,8 @@ export default {
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 16px;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
@@ -637,7 +597,7 @@ export default {
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
font-size: 14px;
|
||||
opacity: 0.8;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@@ -38,9 +38,7 @@
|
||||
</template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-tag :type="currentApplication.targetSme ? 'success' : 'info'">
|
||||
小微企业发展: {{ currentApplication.targetSme ? '是' : '否' }}
|
||||
</el-tag>
|
||||
<el-tag :type="currentApplication.targetSme ? 'success' : 'info'"> 小微企业发展: {{ currentApplication.targetSme ? '是' : '否' }} </el-tag>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-tag :type="currentApplication.targetMicroSme ? 'success' : 'info'">
|
||||
@@ -122,7 +120,7 @@
|
||||
<div class="budget-section">
|
||||
<h4>分年度预算明细</h4>
|
||||
<el-table :data="budgetBreakdown" border>
|
||||
<el-table-column prop="year" label="年度" width="120" align="center"/>
|
||||
<el-table-column prop="year" label="年度" width="120" align="center" />
|
||||
<el-table-column prop="total" label="总投资" align="right">
|
||||
<template #default="scope">
|
||||
{{ formatAmount(scope.row.total) }}
|
||||
@@ -280,11 +278,15 @@ const fetchApplicationData = async (id) => {
|
||||
};
|
||||
|
||||
// 监听applicationId变化
|
||||
watch(() => props.applicationId, (newId) => {
|
||||
if (newId && (!props.application || Object.keys(props.application).length === 0)) {
|
||||
fetchApplicationData(newId);
|
||||
}
|
||||
}, { immediate: true });
|
||||
watch(
|
||||
() => props.applicationId,
|
||||
(newId) => {
|
||||
if (newId && (!props.application || Object.keys(props.application).length === 0)) {
|
||||
fetchApplicationData(newId);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 组件挂载时检查是否需要获取数据
|
||||
onMounted(() => {
|
||||
@@ -301,10 +303,7 @@ onMounted(() => {
|
||||
// 判断是否有项目内容
|
||||
const hasProjectContent = computed(() => {
|
||||
const app = currentApplication.value;
|
||||
return app.applicationReason ||
|
||||
app.constructionContent ||
|
||||
app.totalPerformanceGoal ||
|
||||
app.currentYearGoal;
|
||||
return app.applicationReason || app.constructionContent || app.totalPerformanceGoal || app.currentYearGoal;
|
||||
});
|
||||
|
||||
// 判断是否有绩效指标
|
||||
@@ -352,7 +351,7 @@ const validPerformanceIndicators = computed(() => {
|
||||
return [];
|
||||
}
|
||||
|
||||
const validIndicators = app.performanceIndicators.filter(indicator => {
|
||||
const validIndicators = app.performanceIndicators.filter((indicator) => {
|
||||
const weight = parseFloat(indicator.weightPercentage) || 0;
|
||||
console.log(`指标 ${indicator.goalName}: 权重=${indicator.weightPercentage}, 解析后权重=${weight}, 是否有效=${weight > 0}`);
|
||||
return weight > 0;
|
||||
|
||||
@@ -2,31 +2,13 @@
|
||||
<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-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-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-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>
|
||||
@@ -37,28 +19,13 @@
|
||||
<!-- 快速操作按钮 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Check"
|
||||
@click="showPendingApprovals"
|
||||
>待我审批</el-button>
|
||||
<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-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-button type="info" plain icon="Download" @click="handleExport">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -73,7 +40,7 @@
|
||||
<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"/>
|
||||
<dict-tag :options="cw_approval_status" :value="scope.row.nodeStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批人" align="center" prop="approverName" />
|
||||
@@ -95,13 +62,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" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
|
||||
<!-- 审批对话框 -->
|
||||
<el-dialog title="审批处理" v-model="approvalOpen" width="500px" append-to-body>
|
||||
@@ -113,14 +74,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见" prop="approvalComment">
|
||||
<el-input
|
||||
v-model="approvalForm.approvalComment"
|
||||
type="textarea"
|
||||
placeholder="请输入审批意见"
|
||||
:rows="3"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-input v-model="approvalForm.approvalComment" type="textarea" placeholder="请输入审批意见" :rows="3" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@@ -144,18 +98,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listApprovalRecord,
|
||||
exportApprovalRecord,
|
||||
approveApplication,
|
||||
getMyApprovals,
|
||||
getDepartmentApprovals
|
||||
} from '@/api/cw/approvalRecord';
|
||||
import { listApprovalRecord, exportApprovalRecord, approveApplication, getMyApprovals, getDepartmentApprovals } from '@/api/cw/approvalRecord';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import ApplicationSummary from '../application/summary.vue';
|
||||
|
||||
export default {
|
||||
name: "ApprovalRecord",
|
||||
name: 'ApprovalRecord',
|
||||
components: {
|
||||
ApplicationSummary
|
||||
},
|
||||
@@ -200,9 +148,7 @@ export default {
|
||||
},
|
||||
// 审批表单校验
|
||||
approvalRules: {
|
||||
approvalResult: [
|
||||
{ required: true, message: "审批结果不能为空", trigger: "change" }
|
||||
]
|
||||
approvalResult: [{ required: true, message: '审批结果不能为空', trigger: 'change' }]
|
||||
}
|
||||
};
|
||||
},
|
||||
@@ -214,7 +160,7 @@ export default {
|
||||
/** 查询审批记录列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listApprovalRecord(this.queryParams).then(response => {
|
||||
listApprovalRecord(this.queryParams).then((response) => {
|
||||
this.approvalRecordList = response.rows;
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
@@ -223,25 +169,29 @@ export default {
|
||||
/** 查询待我审批的记录 */
|
||||
showPendingApprovals() {
|
||||
this.loading = true;
|
||||
getDepartmentApprovals({}).then(response => {
|
||||
this.approvalRecordList = response.data || [];
|
||||
this.total = this.approvalRecordList.length;
|
||||
this.loading = false;
|
||||
}).catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
getDepartmentApprovals({})
|
||||
.then((response) => {
|
||||
this.approvalRecordList = response.data || [];
|
||||
this.total = this.approvalRecordList.length;
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
/** 查询我已审批的记录 */
|
||||
showMyApprovals() {
|
||||
this.loading = true;
|
||||
getMyApprovals({}).then(response => {
|
||||
this.approvalRecordList = response.data || [];
|
||||
this.total = this.approvalRecordList.length;
|
||||
this.loading = false;
|
||||
}).catch(error => {
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取已审批记录失败:' + (error.message || '未知错误'));
|
||||
});
|
||||
getMyApprovals({})
|
||||
.then((response) => {
|
||||
this.approvalRecordList = response.data || [];
|
||||
this.total = this.approvalRecordList.length;
|
||||
this.loading = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取已审批记录失败:' + (error.message || '未知错误'));
|
||||
});
|
||||
},
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
@@ -250,12 +200,12 @@ export default {
|
||||
},
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.resetForm("queryRef");
|
||||
this.resetForm('queryRef');
|
||||
this.handleQuery();
|
||||
},
|
||||
// 多选框选中数据
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.id);
|
||||
this.ids = selection.map((item) => item.id);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
@@ -270,10 +220,10 @@ export default {
|
||||
},
|
||||
/** 提交审批 */
|
||||
submitApproval() {
|
||||
this.$refs.approvalRef.validate(valid => {
|
||||
this.$refs.approvalRef.validate((valid) => {
|
||||
if (valid) {
|
||||
approveApplication(this.approvalForm).then(response => {
|
||||
this.$modal.msgSuccess("审批成功");
|
||||
approveApplication(this.approvalForm).then((response) => {
|
||||
this.$modal.msgSuccess('审批成功');
|
||||
this.approvalOpen = false;
|
||||
this.getList();
|
||||
});
|
||||
@@ -288,7 +238,7 @@ export default {
|
||||
approvalComment: ''
|
||||
};
|
||||
this.approvalOpen = false;
|
||||
this.resetForm("approvalRef");
|
||||
this.resetForm('approvalRef');
|
||||
},
|
||||
/** 详情操作 - 完全复制预算申报页面的实现 */
|
||||
handleDetail(row) {
|
||||
@@ -297,9 +247,13 @@ export default {
|
||||
},
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('cw/approval/export', {
|
||||
...this.queryParams
|
||||
}, `approval_record_${new Date().getTime()}.xlsx`)
|
||||
this.download(
|
||||
'cw/approval/export',
|
||||
{
|
||||
...this.queryParams
|
||||
},
|
||||
`approval_record_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
// 手动加载字典数据
|
||||
async loadDictData() {
|
||||
@@ -321,13 +275,13 @@ export default {
|
||||
await this.loadDictFromApi();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 从API直接加载字典数据
|
||||
async loadDictFromApi() {
|
||||
try {
|
||||
const response = await this.$http.get('/system/dict/data/type/cw_approval_status');
|
||||
if (response.code === 200 && response.data) {
|
||||
this.cw_approval_status = response.data.map(item => ({
|
||||
this.cw_approval_status = response.data.map((item) => ({
|
||||
label: item.dictLabel,
|
||||
value: item.dictValue,
|
||||
cssClass: item.cssClass,
|
||||
@@ -354,5 +308,4 @@ export default {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
</style>
|
||||
<style scoped></style>
|
||||
@@ -32,7 +32,7 @@
|
||||
{{ parseTime(config.createTime, '{y}-{m}-{d} {h}:{i}') }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
|
||||
<div v-if="config.description" class="mt-4">
|
||||
<h4 class="section-title">配置描述</h4>
|
||||
<p class="description-text">{{ config.description }}</p>
|
||||
@@ -48,22 +48,18 @@
|
||||
<el-tag type="info" size="small">共 {{ config.steps.length }} 个步骤</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<el-steps :active="config.steps.length" finish-status="success" align-center>
|
||||
<el-step
|
||||
v-for="(step, index) in config.steps"
|
||||
<el-step
|
||||
v-for="(step, index) in config.steps"
|
||||
:key="index"
|
||||
:title="step.stepName"
|
||||
:description="`${getApprovalModeText(step.approvalMode)} | ${step.timeoutHours}小时`"
|
||||
/>
|
||||
</el-steps>
|
||||
|
||||
|
||||
<div class="steps-detail mt-6">
|
||||
<div
|
||||
v-for="(step, index) in config.steps"
|
||||
:key="index"
|
||||
class="step-detail-item"
|
||||
>
|
||||
<div v-for="(step, index) in config.steps" :key="index" class="step-detail-item">
|
||||
<el-card shadow="hover" class="step-detail-card">
|
||||
<template #header>
|
||||
<div class="step-header">
|
||||
@@ -74,7 +70,7 @@
|
||||
</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<div class="step-info">
|
||||
@@ -95,34 +91,24 @@
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<div class="approvers-section mt-4" v-if="step.approvers && step.approvers.length > 0">
|
||||
<label class="info-label">审批人员:</label>
|
||||
<div class="approvers-list">
|
||||
<el-tag
|
||||
v-for="(approver, approverIndex) in step.approverNames"
|
||||
:key="approverIndex"
|
||||
class="approver-tag"
|
||||
>
|
||||
<el-tag v-for="(approver, approverIndex) in step.approverNames" :key="approverIndex" class="approver-tag">
|
||||
{{ approver }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div v-else-if="config.approvalType === 'custom'" class="custom-approver-notice">
|
||||
<el-alert
|
||||
title="自选审批人"
|
||||
description="申报人在提交时自行选择审批人"
|
||||
type="info"
|
||||
show-icon
|
||||
:closable="false"
|
||||
/>
|
||||
<el-alert title="自选审批人" description="申报人在提交时自行选择审批人" type="info" show-icon :closable="false" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
|
||||
<!-- 无流程步骤时的提示 -->
|
||||
<el-card class="detail-card" v-else>
|
||||
<el-empty description="暂无配置的审批流程步骤" />
|
||||
@@ -144,13 +130,13 @@ export default {
|
||||
getApprovalTypeTag(type) {
|
||||
const typeMap = {
|
||||
'fixed': 'success',
|
||||
'role': 'warning',
|
||||
'role': 'warning',
|
||||
'dept': 'info',
|
||||
'custom': 'primary'
|
||||
};
|
||||
return typeMap[type] || 'info';
|
||||
},
|
||||
|
||||
|
||||
/** 获取审批类型文本 */
|
||||
getApprovalTypeText(type) {
|
||||
const textMap = {
|
||||
@@ -161,7 +147,7 @@ export default {
|
||||
};
|
||||
return textMap[type] || type;
|
||||
},
|
||||
|
||||
|
||||
/** 获取适用范围文本 */
|
||||
getScopeText(scope) {
|
||||
const scopeMap = {
|
||||
@@ -172,7 +158,7 @@ export default {
|
||||
};
|
||||
return scopeMap[scope] || scope;
|
||||
},
|
||||
|
||||
|
||||
/** 获取审批方式文本 */
|
||||
getApprovalModeText(mode) {
|
||||
const modeMap = {
|
||||
@@ -182,7 +168,7 @@ export default {
|
||||
};
|
||||
return modeMap[mode] || mode;
|
||||
},
|
||||
|
||||
|
||||
/** 获取审批方式标签类型 */
|
||||
getModeTagType(mode) {
|
||||
const typeMap = {
|
||||
@@ -201,7 +187,7 @@ export default {
|
||||
.detail-card {
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -210,14 +196,14 @@ export default {
|
||||
color: #2c3e50;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.section-title {
|
||||
margin: 0 0 12px 0;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
|
||||
.description-text {
|
||||
margin: 0;
|
||||
padding: 12px;
|
||||
@@ -226,24 +212,24 @@ export default {
|
||||
color: #606266;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
|
||||
.steps-detail {
|
||||
.step-detail-item {
|
||||
margin-bottom: 16px;
|
||||
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.step-detail-card {
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
.step-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
|
||||
.step-number {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
@@ -252,7 +238,7 @@ export default {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
|
||||
.step-name {
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
@@ -260,12 +246,12 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.step-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
|
||||
|
||||
.info-label {
|
||||
font-weight: 600;
|
||||
color: #909399;
|
||||
@@ -273,23 +259,23 @@ export default {
|
||||
min-width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.approvers-section {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
padding-top: 16px;
|
||||
|
||||
|
||||
.info-label {
|
||||
font-weight: 600;
|
||||
color: #909399;
|
||||
margin-bottom: 8px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.approvers-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
|
||||
|
||||
.approver-tag {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
color: white;
|
||||
@@ -297,7 +283,7 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.custom-approver-notice {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
padding-top: 16px;
|
||||
@@ -316,4 +302,4 @@ export default {
|
||||
.mt-6 {
|
||||
margin-top: 24px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -85,10 +85,14 @@
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['cw:approverConfig:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['cw:approverConfig:edit']">修改</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['cw:approverConfig:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['cw:approverConfig:remove']">删除</el-button>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['cw:approverConfig:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="info" plain icon="Sort" @click="toggleExpandAll">展开/折叠</el-button>
|
||||
@@ -125,12 +129,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="审批人" align="center" prop="approverNames" min-width="180" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
v-for="(name, index) in scope.row.approverNames"
|
||||
:key="index"
|
||||
size="small"
|
||||
class="mr-1"
|
||||
>
|
||||
<el-tag v-for="(name, index) in scope.row.approverNames" :key="index" size="small" class="mr-1">
|
||||
{{ name }}
|
||||
</el-tag>
|
||||
</template>
|
||||
@@ -178,13 +177,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" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改审批人配置对话框 -->
|
||||
@@ -241,13 +234,9 @@
|
||||
<el-button type="primary" size="small" icon="Plus" @click="addStep">添加步骤</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<div v-if="form.steps && form.steps.length > 0" class="steps-container">
|
||||
<div
|
||||
v-for="(step, index) in form.steps"
|
||||
:key="index"
|
||||
class="step-item"
|
||||
>
|
||||
<div v-for="(step, index) in form.steps" :key="index" class="step-item">
|
||||
<el-card shadow="hover" class="step-card">
|
||||
<template #header>
|
||||
<div class="step-header">
|
||||
@@ -268,7 +257,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="步骤名称" :prop="`steps.${index}.stepName`" :rules="stepRules.stepName">
|
||||
@@ -290,46 +279,25 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="审批人设置" :prop="`steps.${index}.approvers`" :rules="stepRules.approvers">
|
||||
<div class="approvers-container">
|
||||
<!-- 固定审批人 -->
|
||||
<div v-if="form.approvalType === 'fixed'">
|
||||
<el-select
|
||||
v-model="step.approvers"
|
||||
multiple
|
||||
placeholder="请选择审批人"
|
||||
style="width: 100%"
|
||||
@change="updateApproverNames"
|
||||
>
|
||||
<el-option
|
||||
v-for="user in userList"
|
||||
:key="user.userId"
|
||||
:label="user.nickName"
|
||||
:value="user.userId"
|
||||
/>
|
||||
<el-select v-model="step.approvers" multiple placeholder="请选择审批人" style="width: 100%" @change="updateApproverNames">
|
||||
<el-option v-for="user in userList" :key="user.userId" :label="user.nickName" :value="user.userId" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 角色审批 -->
|
||||
<div v-else-if="form.approvalType === 'role'">
|
||||
<el-select
|
||||
v-model="step.approvers"
|
||||
multiple
|
||||
placeholder="请选择审批角色"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="role in roleList"
|
||||
:key="role.roleId"
|
||||
:label="role.roleName"
|
||||
:value="role.roleId"
|
||||
/>
|
||||
<el-select v-model="step.approvers" multiple placeholder="请选择审批角色" style="width: 100%">
|
||||
<el-option v-for="role in roleList" :key="role.roleId" :label="role.roleName" :value="role.roleId" />
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 部门审批 -->
|
||||
<div v-else-if="form.approvalType === 'dept'">
|
||||
<el-tree-select
|
||||
@@ -341,7 +309,7 @@
|
||||
style="width: 100%"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 自选审批人 -->
|
||||
<div v-else-if="form.approvalType === 'custom'">
|
||||
<el-alert
|
||||
@@ -359,12 +327,12 @@
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<el-empty v-else description="暂无审批步骤,请添加步骤" />
|
||||
</el-card>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
@@ -385,7 +353,7 @@
|
||||
|
||||
<!-- 流程图对话框 -->
|
||||
<el-dialog v-model="flowDialog.visible" title="审批流程图" width="1200px" append-to-body>
|
||||
<div ref="flowChartRef" style="height: 500px; border: 1px solid #e4e7ed;"></div>
|
||||
<div ref="flowChartRef" style="height: 500px; border: 1px solid #e4e7ed"></div>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="flowDialog.visible = false">关闭</el-button>
|
||||
@@ -396,13 +364,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listApproverConfig,
|
||||
getApproverConfig,
|
||||
addApproverConfig,
|
||||
updateApproverConfig,
|
||||
delApproverConfig
|
||||
} from "@/api/cw/projectApplication";
|
||||
import { listApproverConfig, getApproverConfig, addApproverConfig, updateApproverConfig, delApproverConfig } from '@/api/cw/projectApplication';
|
||||
|
||||
export default {
|
||||
name: 'CwApproverConfig',
|
||||
@@ -454,27 +416,17 @@ export default {
|
||||
// 表单校验
|
||||
rules: {
|
||||
configName: [
|
||||
{ required: true, message: "配置名称不能为空", trigger: "blur" },
|
||||
{ min: 2, max: 50, message: "配置名称长度在 2 到 50 个字符", trigger: "blur" }
|
||||
{ required: true, message: '配置名称不能为空', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '配置名称长度在 2 到 50 个字符', trigger: 'blur' }
|
||||
],
|
||||
approvalType: [
|
||||
{ required: true, message: "审批类型不能为空", trigger: "change" }
|
||||
],
|
||||
applicableScope: [
|
||||
{ required: true, message: "适用范围不能为空", trigger: "change" }
|
||||
]
|
||||
approvalType: [{ required: true, message: '审批类型不能为空', trigger: 'change' }],
|
||||
applicableScope: [{ required: true, message: '适用范围不能为空', trigger: 'change' }]
|
||||
},
|
||||
// 步骤表单校验
|
||||
stepRules: {
|
||||
stepName: [
|
||||
{ required: true, message: "步骤名称不能为空", trigger: "blur" }
|
||||
],
|
||||
approvalMode: [
|
||||
{ required: true, message: "审批方式不能为空", trigger: "change" }
|
||||
],
|
||||
approvers: [
|
||||
{ required: true, message: "请设置审批人", trigger: "change" }
|
||||
]
|
||||
stepName: [{ required: true, message: '步骤名称不能为空', trigger: 'blur' }],
|
||||
approvalMode: [{ required: true, message: '审批方式不能为空', trigger: 'change' }],
|
||||
approvers: [{ required: true, message: '请设置审批人', trigger: 'change' }]
|
||||
},
|
||||
// 用户列表
|
||||
userList: [],
|
||||
@@ -492,37 +444,35 @@ export default {
|
||||
/** 查询审批人配置列表 */
|
||||
getList() {
|
||||
this.loading = true;
|
||||
listApproverConfig(this.queryParams).then(response => {
|
||||
this.configList = this.handleTree(response.data, "id", "parentId");
|
||||
listApproverConfig(this.queryParams).then((response) => {
|
||||
this.configList = this.handleTree(response.data, 'id', 'parentId');
|
||||
this.total = response.total;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 加载基础数据 */
|
||||
loadBasicData() {
|
||||
// 加载用户列表
|
||||
// listUser().then(response => {
|
||||
// this.userList = response.rows;
|
||||
// });
|
||||
|
||||
// 加载角色列表
|
||||
// listRole().then(response => {
|
||||
// this.roleList = response.rows;
|
||||
// });
|
||||
|
||||
// 加载部门树
|
||||
// listDept().then(response => {
|
||||
// this.deptTreeData = this.handleTree(response.data, "deptId");
|
||||
// });
|
||||
},
|
||||
|
||||
|
||||
/** 取消按钮 */
|
||||
cancel() {
|
||||
this.dialog.visible = false;
|
||||
this.reset();
|
||||
},
|
||||
|
||||
|
||||
/** 表单重置 */
|
||||
reset() {
|
||||
this.form = {
|
||||
@@ -532,92 +482,92 @@ export default {
|
||||
applicableScope: 'all',
|
||||
orderNum: 0,
|
||||
description: null,
|
||||
status: "1",
|
||||
status: '1',
|
||||
steps: []
|
||||
};
|
||||
if (this.$refs.formRef) {
|
||||
this.$refs.formRef.resetFields();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getList();
|
||||
},
|
||||
|
||||
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.$refs.queryFormRef.resetFields();
|
||||
this.handleQuery();
|
||||
},
|
||||
|
||||
|
||||
/** 多选框选中数据 */
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.id);
|
||||
this.ids = selection.map((item) => item.id);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
},
|
||||
|
||||
|
||||
/** 展开/折叠操作 */
|
||||
toggleExpandAll() {
|
||||
this.isExpandAll = !this.isExpandAll;
|
||||
this.toggleExpandAllTree(this.configList, this.isExpandAll);
|
||||
},
|
||||
|
||||
|
||||
/** 快捷操作 */
|
||||
showFlowDesigner() {
|
||||
this.$modal.msgInfo("流程设计器功能开发中...");
|
||||
this.$modal.msgInfo('流程设计器功能开发中...');
|
||||
},
|
||||
|
||||
|
||||
showTemplates() {
|
||||
this.$modal.msgInfo("配置模板功能开发中...");
|
||||
this.$modal.msgInfo('配置模板功能开发中...');
|
||||
},
|
||||
|
||||
|
||||
showTestFlow() {
|
||||
this.$modal.msgInfo("流程测试功能开发中...");
|
||||
this.$modal.msgInfo('流程测试功能开发中...');
|
||||
},
|
||||
|
||||
|
||||
/** 新增按钮操作 */
|
||||
handleAdd() {
|
||||
this.reset();
|
||||
this.dialog.visible = true;
|
||||
this.dialog.title = "添加审批人配置";
|
||||
this.dialog.title = '添加审批人配置';
|
||||
},
|
||||
|
||||
|
||||
/** 修改按钮操作 */
|
||||
handleUpdate(row) {
|
||||
this.reset();
|
||||
const id = row?.id || this.ids[0];
|
||||
getApproverConfig(id).then(response => {
|
||||
getApproverConfig(id).then((response) => {
|
||||
this.form = response.data;
|
||||
this.dialog.visible = true;
|
||||
this.dialog.title = "修改审批人配置";
|
||||
this.dialog.title = '修改审批人配置';
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 复制配置 */
|
||||
handleCopy(row) {
|
||||
getApproverConfig(row.id).then(response => {
|
||||
getApproverConfig(row.id).then((response) => {
|
||||
this.form = {
|
||||
...response.data,
|
||||
id: null,
|
||||
configName: response.data.configName + '_副本'
|
||||
};
|
||||
this.dialog.visible = true;
|
||||
this.dialog.title = "复制审批人配置";
|
||||
this.dialog.title = '复制审批人配置';
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 查看详情 */
|
||||
handleDetail(row) {
|
||||
getApproverConfig(row.id).then(response => {
|
||||
getApproverConfig(row.id).then((response) => {
|
||||
this.currentConfig = response.data;
|
||||
this.detailDialog.visible = true;
|
||||
this.detailDialog.title = "配置详情";
|
||||
this.detailDialog.title = '配置详情';
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 查看流程图 */
|
||||
handleViewFlow(row) {
|
||||
this.flowDialog.visible = true;
|
||||
@@ -625,45 +575,55 @@ export default {
|
||||
this.renderFlowChart(row);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 状态变更 */
|
||||
handleStatusChange(row) {
|
||||
let text = row.status === "1" ? "启用" : "停用";
|
||||
this.$modal.confirm('确认要"' + text + '""' + row.configName + '"配置吗?').then(() => {
|
||||
return updateApproverConfig(row);
|
||||
}).then(() => {
|
||||
this.$modal.msgSuccess(text + "成功");
|
||||
}).catch(() => {
|
||||
row.status = row.status === "0" ? "1" : "0";
|
||||
});
|
||||
let text = row.status === '1' ? '启用' : '停用';
|
||||
this.$modal
|
||||
.confirm('确认要"' + text + '""' + row.configName + '"配置吗?')
|
||||
.then(() => {
|
||||
return updateApproverConfig(row);
|
||||
})
|
||||
.then(() => {
|
||||
this.$modal.msgSuccess(text + '成功');
|
||||
})
|
||||
.catch(() => {
|
||||
row.status = row.status === '0' ? '1' : '0';
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 删除按钮操作 */
|
||||
handleDelete(row) {
|
||||
const ids = row?.id ? [row.id] : this.ids;
|
||||
const configs = row?.configName ? [row.configName] : this.configList.filter(item => this.ids.includes(item.id)).map(item => item.configName);
|
||||
|
||||
this.$modal.confirm('是否确认删除配置名称为"' + configs.join('", "') + '"的数据项?').then(() => {
|
||||
return delApproverConfig(ids);
|
||||
}).then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess("删除成功");
|
||||
}).catch(() => {});
|
||||
const configs = row?.configName
|
||||
? [row.configName]
|
||||
: this.configList.filter((item) => this.ids.includes(item.id)).map((item) => item.configName);
|
||||
|
||||
this.$modal
|
||||
.confirm('是否确认删除配置名称为"' + configs.join('", "') + '"的数据项?')
|
||||
.then(() => {
|
||||
return delApproverConfig(ids);
|
||||
})
|
||||
.then(() => {
|
||||
this.getList();
|
||||
this.$modal.msgSuccess('删除成功');
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
|
||||
|
||||
/** 提交按钮 */
|
||||
submitForm() {
|
||||
this.$refs.formRef.validate(valid => {
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
if (valid) {
|
||||
if (this.form.id != null) {
|
||||
updateApproverConfig(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
updateApproverConfig(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('修改成功');
|
||||
this.dialog.visible = false;
|
||||
this.getList();
|
||||
});
|
||||
} else {
|
||||
addApproverConfig(this.form).then(response => {
|
||||
this.$modal.msgSuccess("新增成功");
|
||||
addApproverConfig(this.form).then((response) => {
|
||||
this.$modal.msgSuccess('新增成功');
|
||||
this.dialog.visible = false;
|
||||
this.getList();
|
||||
});
|
||||
@@ -671,17 +631,17 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 审批类型变更 */
|
||||
handleTypeChange(value) {
|
||||
// 清空已配置的审批人
|
||||
if (this.form.steps) {
|
||||
this.form.steps.forEach(step => {
|
||||
this.form.steps.forEach((step) => {
|
||||
step.approvers = [];
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/** 添加步骤 */
|
||||
addStep() {
|
||||
if (!this.form.steps) {
|
||||
@@ -694,12 +654,12 @@ export default {
|
||||
approvers: []
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/** 删除步骤 */
|
||||
removeStep(index) {
|
||||
this.form.steps.splice(index, 1);
|
||||
},
|
||||
|
||||
|
||||
/** 上移步骤 */
|
||||
moveStepUp(index) {
|
||||
if (index > 0) {
|
||||
@@ -708,7 +668,7 @@ export default {
|
||||
this.form.steps[index - 1] = temp;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/** 下移步骤 */
|
||||
moveStepDown(index) {
|
||||
if (index < this.form.steps.length - 1) {
|
||||
@@ -717,36 +677,40 @@ export default {
|
||||
this.form.steps[index + 1] = temp;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/** 更新审批人名称 */
|
||||
updateApproverNames() {
|
||||
// 更新审批人名称用于显示
|
||||
},
|
||||
|
||||
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('cw/approverConfig/export', {
|
||||
...this.queryParams
|
||||
}, `approver_config_${new Date().getTime()}.xlsx`);
|
||||
this.download(
|
||||
'cw/approverConfig/export',
|
||||
{
|
||||
...this.queryParams
|
||||
},
|
||||
`approver_config_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
/** 渲染流程图 */
|
||||
renderFlowChart(row) {
|
||||
// 使用流程图库渲染流程图
|
||||
this.$modal.msgInfo("流程图功能开发中...");
|
||||
this.$modal.msgInfo('流程图功能开发中...');
|
||||
},
|
||||
|
||||
|
||||
/** 获取审批类型标签 */
|
||||
getApprovalTypeTag(type) {
|
||||
const typeMap = {
|
||||
'fixed': 'success',
|
||||
'role': 'warning',
|
||||
'role': 'warning',
|
||||
'dept': 'info',
|
||||
'custom': 'primary'
|
||||
};
|
||||
return typeMap[type] || 'info';
|
||||
},
|
||||
|
||||
|
||||
/** 获取审批类型文本 */
|
||||
getApprovalTypeText(type) {
|
||||
const textMap = {
|
||||
@@ -771,25 +735,25 @@ export default {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
border-color: #409EFF;
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
|
||||
.quick-action {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
|
||||
|
||||
.quick-icon {
|
||||
font-size: 28px;
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
@@ -807,14 +771,14 @@ export default {
|
||||
// 步骤徽章
|
||||
.step-badge {
|
||||
:deep(.el-badge__content) {
|
||||
background-color: #409EFF;
|
||||
background-color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
// 步骤配置卡片
|
||||
.steps-card {
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
.steps-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -827,32 +791,32 @@ export default {
|
||||
.steps-container {
|
||||
.step-item {
|
||||
margin-bottom: 16px;
|
||||
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.step-card {
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
.step-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.step-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
|
||||
|
||||
.el-icon {
|
||||
margin-right: 8px;
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.step-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -877,14 +841,14 @@ export default {
|
||||
@media (max-width: 768px) {
|
||||
.quick-action {
|
||||
padding: 15px;
|
||||
|
||||
|
||||
.quick-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -154,17 +154,12 @@
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>月度申报趋势</span>
|
||||
<el-select v-model="selectedYear" @change="handleYearChange" style="width: 120px;">
|
||||
<el-option
|
||||
v-for="year in yearOptions"
|
||||
:key="year"
|
||||
:label="year + '年'"
|
||||
:value="year"
|
||||
/>
|
||||
<el-select v-model="selectedYear" @change="handleYearChange" style="width: 120px">
|
||||
<el-option v-for="year in yearOptions" :key="year" :label="year + '年'" :value="year" />
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
<div ref="trendChart" style="height: 350px;"></div>
|
||||
<div ref="trendChart" style="height: 350px"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
@@ -174,7 +169,7 @@
|
||||
<template #header>
|
||||
<span>状态分布</span>
|
||||
</template>
|
||||
<div ref="statusChart" style="height: 350px;"></div>
|
||||
<div ref="statusChart" style="height: 350px"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -187,13 +182,8 @@
|
||||
<el-button type="primary" icon="Download" @click="handleExportDeptStatistics">导出部门统计</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-table
|
||||
:data="statistics.deptStatistics"
|
||||
border
|
||||
style="width: 100%"
|
||||
v-loading="statisticsLoading"
|
||||
>
|
||||
|
||||
<el-table :data="statistics.deptStatistics" border style="width: 100%" v-loading="statisticsLoading">
|
||||
<el-table-column prop="deptName" label="部门名称" align="center" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column prop="totalCount" label="申报数量" align="center" width="100" />
|
||||
<el-table-column prop="approvingCount" label="审批中" align="center" width="100">
|
||||
@@ -223,11 +213,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="审批率" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-progress
|
||||
:percentage="calculateApprovalRate(scope.row)"
|
||||
:status="getProgressStatus(scope.row)"
|
||||
:show-text="false"
|
||||
/>
|
||||
<el-progress :percentage="calculateApprovalRate(scope.row)" :status="getProgressStatus(scope.row)" :show-text="false" />
|
||||
<span class="rate-text">{{ calculateApprovalRate(scope.row) }}%</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -247,18 +233,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import {
|
||||
Plus, User, Clock, DataAnalysis, Files, CircleCheck, CircleClose,
|
||||
Money, Timer, TrendCharts, Finished
|
||||
} from '@element-plus/icons-vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { getApplicationStatistics, getStatisticsByDept, getStatisticsByMonth } from '@/api/cw/projectApplication'
|
||||
import { parseTime } from '@/utils/ruoyi'
|
||||
import { ref, reactive, onMounted, nextTick } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { Plus, User, Clock, DataAnalysis, Files, CircleCheck, CircleClose, Money, Timer, TrendCharts, Finished } from '@element-plus/icons-vue';
|
||||
import * as echarts from 'echarts';
|
||||
import { getApplicationStatistics, getStatisticsByDept, getStatisticsByMonth } from '@/api/cw/projectApplication';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
const router = useRouter()
|
||||
const router = useRouter();
|
||||
|
||||
// 响应式数据
|
||||
const statistics = reactive({
|
||||
@@ -271,138 +254,135 @@ const statistics = reactive({
|
||||
monthlyNew: 0,
|
||||
monthlyApproved: 0,
|
||||
deptStatistics: [] as any[]
|
||||
})
|
||||
});
|
||||
|
||||
const selectedYear = ref(new Date().getFullYear())
|
||||
const yearOptions = ref<number[]>([])
|
||||
const statisticsLoading = ref(false)
|
||||
const selectedYear = ref(new Date().getFullYear());
|
||||
const yearOptions = ref<number[]>([]);
|
||||
const statisticsLoading = ref(false);
|
||||
|
||||
// 图表引用
|
||||
const trendChart = ref()
|
||||
const statusChart = ref()
|
||||
let trendChartInstance: echarts.ECharts | null = null
|
||||
let statusChartInstance: echarts.ECharts | null = null
|
||||
const trendChart = ref();
|
||||
const statusChart = ref();
|
||||
let trendChartInstance: echarts.ECharts | null = null;
|
||||
let statusChartInstance: echarts.ECharts | null = null;
|
||||
|
||||
// 生成年份选项
|
||||
const generateYearOptions = () => {
|
||||
const currentYear = new Date().getFullYear()
|
||||
const currentYear = new Date().getFullYear();
|
||||
for (let i = currentYear - 4; i <= currentYear + 1; i++) {
|
||||
yearOptions.value.push(i)
|
||||
yearOptions.value.push(i);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 快捷操作
|
||||
const handleAdd = () => {
|
||||
router.push('/cw/application')
|
||||
}
|
||||
router.push('/cw/application');
|
||||
};
|
||||
|
||||
const showMyApplications = () => {
|
||||
router.push({ path: '/cw/application', query: { tab: 'my' } })
|
||||
}
|
||||
router.push({ path: '/cw/application', query: { tab: 'my' } });
|
||||
};
|
||||
|
||||
const showPendingApplications = () => {
|
||||
router.push({ path: '/cw/application', query: { tab: 'pending' } })
|
||||
}
|
||||
router.push({ path: '/cw/application', query: { tab: 'pending' } });
|
||||
};
|
||||
|
||||
const showStatistics = () => {
|
||||
router.push('/cw/application/summary')
|
||||
}
|
||||
router.push('/cw/application/summary');
|
||||
};
|
||||
|
||||
// 格式化金额
|
||||
const formatAmount = (amount: number | undefined): string => {
|
||||
if (!amount) return '0.00'
|
||||
return amount.toFixed(2)
|
||||
}
|
||||
if (!amount) return '0.00';
|
||||
return amount.toFixed(2);
|
||||
};
|
||||
|
||||
// 计算审批率
|
||||
const calculateApprovalRate = (row: any): number => {
|
||||
if (!row.totalCount || row.totalCount === 0) return 0
|
||||
return Math.round((row.approvedCount / row.totalCount) * 100)
|
||||
}
|
||||
if (!row.totalCount || row.totalCount === 0) return 0;
|
||||
return Math.round((row.approvedCount / row.totalCount) * 100);
|
||||
};
|
||||
|
||||
// 获取进度条状态
|
||||
const getProgressStatus = (row: any): string => {
|
||||
const rate = calculateApprovalRate(row)
|
||||
if (rate >= 80) return 'success'
|
||||
if (rate >= 60) return 'warning'
|
||||
return 'exception'
|
||||
}
|
||||
const rate = calculateApprovalRate(row);
|
||||
if (rate >= 80) return 'success';
|
||||
if (rate >= 60) return 'warning';
|
||||
return 'exception';
|
||||
};
|
||||
|
||||
// 查看部门详情
|
||||
const viewDepartmentDetail = (row: any) => {
|
||||
router.push({
|
||||
path: '/cw/application',
|
||||
query: { deptId: row.deptId, deptName: row.deptName }
|
||||
})
|
||||
}
|
||||
router.push({
|
||||
path: '/cw/application',
|
||||
query: { deptId: row.deptId, deptName: row.deptName }
|
||||
});
|
||||
};
|
||||
|
||||
// 导出部门数据
|
||||
const exportDepartmentData = (row: any) => {
|
||||
ElMessage.success(`导出部门【${row.deptName}】数据功能开发中...`)
|
||||
}
|
||||
ElMessage.success(`导出部门【${row.deptName}】数据功能开发中...`);
|
||||
};
|
||||
|
||||
// 导出部门统计
|
||||
const handleExportDeptStatistics = () => {
|
||||
ElMessage.success('导出部门统计功能开发中...')
|
||||
}
|
||||
ElMessage.success('导出部门统计功能开发中...');
|
||||
};
|
||||
|
||||
// 获取统计数据
|
||||
const loadStatistics = async () => {
|
||||
try {
|
||||
statisticsLoading.value = true
|
||||
const [statsRes, deptRes] = await Promise.all([
|
||||
getApplicationStatistics(selectedYear.value),
|
||||
getStatisticsByDept()
|
||||
])
|
||||
|
||||
statisticsLoading.value = true;
|
||||
const [statsRes, deptRes] = await Promise.all([getApplicationStatistics(selectedYear.value), getStatisticsByDept()]);
|
||||
|
||||
if (statsRes.code === 200) {
|
||||
Object.assign(statistics, statsRes.data)
|
||||
Object.assign(statistics, statsRes.data);
|
||||
}
|
||||
|
||||
|
||||
if (deptRes.code === 200) {
|
||||
statistics.deptStatistics = deptRes.data || []
|
||||
statistics.deptStatistics = deptRes.data || [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error)
|
||||
ElMessage.error('获取统计数据失败')
|
||||
console.error('获取统计数据失败:', error);
|
||||
ElMessage.error('获取统计数据失败');
|
||||
} finally {
|
||||
statisticsLoading.value = false
|
||||
statisticsLoading.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 年份变化处理
|
||||
const handleYearChange = () => {
|
||||
loadStatistics()
|
||||
loadTrendChart()
|
||||
}
|
||||
loadStatistics();
|
||||
loadTrendChart();
|
||||
};
|
||||
|
||||
// 加载趋势图表
|
||||
const loadTrendChart = async () => {
|
||||
try {
|
||||
const response = await getStatisticsByMonth(selectedYear.value)
|
||||
const response = await getStatisticsByMonth(selectedYear.value);
|
||||
if (response.code === 200) {
|
||||
renderTrendChart(response.data)
|
||||
renderTrendChart(response.data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取月度统计失败:', error)
|
||||
console.error('获取月度统计失败:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 渲染趋势图表
|
||||
const renderTrendChart = (data: any[]) => {
|
||||
if (!trendChartInstance) return
|
||||
|
||||
const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
||||
const applicationCounts = new Array(12).fill(0)
|
||||
const approvedCounts = new Array(12).fill(0)
|
||||
|
||||
data.forEach(item => {
|
||||
const monthIndex = item.month - 1
|
||||
if (!trendChartInstance) return;
|
||||
|
||||
const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];
|
||||
const applicationCounts = new Array(12).fill(0);
|
||||
const approvedCounts = new Array(12).fill(0);
|
||||
|
||||
data.forEach((item) => {
|
||||
const monthIndex = item.month - 1;
|
||||
if (monthIndex >= 0 && monthIndex < 12) {
|
||||
applicationCounts[monthIndex] = item.applicationCount || 0
|
||||
approvedCounts[monthIndex] = item.approvedCount || 0
|
||||
applicationCounts[monthIndex] = item.applicationCount || 0;
|
||||
approvedCounts[monthIndex] = item.approvedCount || 0;
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
@@ -437,15 +417,15 @@ const renderTrendChart = (data: any[]) => {
|
||||
itemStyle: { color: '#67C23A' }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
trendChartInstance.setOption(option)
|
||||
}
|
||||
};
|
||||
|
||||
trendChartInstance.setOption(option);
|
||||
};
|
||||
|
||||
// 渲染状态分布图
|
||||
const renderStatusChart = () => {
|
||||
if (!statusChartInstance) return
|
||||
|
||||
if (!statusChartInstance) return;
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
@@ -474,38 +454,38 @@ const renderStatusChart = () => {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
statusChartInstance.setOption(option)
|
||||
}
|
||||
};
|
||||
|
||||
statusChartInstance.setOption(option);
|
||||
};
|
||||
|
||||
// 初始化图表
|
||||
const initCharts = async () => {
|
||||
await nextTick()
|
||||
|
||||
await nextTick();
|
||||
|
||||
if (trendChart.value) {
|
||||
trendChartInstance = echarts.init(trendChart.value)
|
||||
loadTrendChart()
|
||||
trendChartInstance = echarts.init(trendChart.value);
|
||||
loadTrendChart();
|
||||
}
|
||||
|
||||
|
||||
if (statusChart.value) {
|
||||
statusChartInstance = echarts.init(statusChart.value)
|
||||
renderStatusChart()
|
||||
statusChartInstance = echarts.init(statusChart.value);
|
||||
renderStatusChart();
|
||||
}
|
||||
|
||||
|
||||
// 监听窗口大小变化
|
||||
window.addEventListener('resize', () => {
|
||||
trendChartInstance?.resize()
|
||||
statusChartInstance?.resize()
|
||||
})
|
||||
}
|
||||
trendChartInstance?.resize();
|
||||
statusChartInstance?.resize();
|
||||
});
|
||||
};
|
||||
|
||||
// 组件挂载
|
||||
onMounted(() => {
|
||||
generateYearOptions()
|
||||
loadStatistics()
|
||||
initCharts()
|
||||
})
|
||||
generateYearOptions();
|
||||
loadStatistics();
|
||||
initCharts();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -518,25 +498,25 @@ onMounted(() => {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1);
|
||||
border-color: #409EFF;
|
||||
border-color: #409eff;
|
||||
}
|
||||
|
||||
|
||||
.quick-action {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
|
||||
|
||||
.quick-icon {
|
||||
font-size: 28px;
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
@@ -550,32 +530,32 @@ onMounted(() => {
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
&.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, #fa709a 0%, #fee140 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
&.stat-card-danger {
|
||||
background: linear-gradient(135deg, #ff6b6b 0%, #ffa726 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
&.stat-card-info {
|
||||
background: linear-gradient(135deg, #a8edea 0%, #fed6e3 100%);
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
|
||||
:deep(.el-card__body) {
|
||||
padding: 0;
|
||||
}
|
||||
@@ -585,13 +565,13 @@ onMounted(() => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
|
||||
|
||||
.stat-icon {
|
||||
font-size: 32px;
|
||||
margin-right: 16px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
|
||||
.stat-info {
|
||||
.stat-value {
|
||||
font-size: 24px;
|
||||
@@ -599,7 +579,7 @@ onMounted(() => {
|
||||
line-height: 1.2;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
opacity: 0.9;
|
||||
@@ -612,7 +592,7 @@ onMounted(() => {
|
||||
.chart-card {
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -626,7 +606,7 @@ onMounted(() => {
|
||||
.table-card {
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e4e7ed;
|
||||
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -634,16 +614,16 @@ onMounted(() => {
|
||||
font-weight: 600;
|
||||
color: #2c3e50;
|
||||
}
|
||||
|
||||
|
||||
.amount-text {
|
||||
font-weight: 600;
|
||||
color: #606266;
|
||||
|
||||
|
||||
&.success {
|
||||
color: #67C23A;
|
||||
color: #67c23a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.rate-text {
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
@@ -674,24 +654,24 @@ onMounted(() => {
|
||||
@media (max-width: 768px) {
|
||||
.quick-action {
|
||||
padding: 15px;
|
||||
|
||||
|
||||
.quick-icon {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.stat-content {
|
||||
padding: 15px;
|
||||
|
||||
|
||||
.stat-icon {
|
||||
font-size: 24px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
|
||||
.stat-info .stat-value {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
@@ -125,13 +125,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" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 项目详情对话框 -->
|
||||
@@ -172,12 +166,14 @@
|
||||
clearable
|
||||
filterable
|
||||
:loading="loadingApprovers"
|
||||
style="width: 100%">
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
v-for="approver in availableApprovers"
|
||||
:key="approver.userId"
|
||||
:label="approver.nickName + '(' + approver.userName + ')'"
|
||||
:value="approver.userId">
|
||||
:value="approver.userId"
|
||||
>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
@@ -212,7 +208,8 @@
|
||||
<el-card>
|
||||
<h4>{{ record.nodeName }}</h4>
|
||||
<p><strong>审批人:</strong>{{ record.approverName }}</p>
|
||||
<p><strong>审批结果:</strong>
|
||||
<p>
|
||||
<strong>审批结果:</strong>
|
||||
<el-tag :type="getApprovalResultType(record.approveAction)">
|
||||
{{ getApprovalResultText(record.approveAction) }}
|
||||
</el-tag>
|
||||
@@ -239,10 +236,10 @@ import {
|
||||
getApprovalHistory,
|
||||
getAvailableApprovers,
|
||||
getFinanceApprovedRecords
|
||||
} from "@/api/cw/approvalRecord";
|
||||
import { financeApproveApplication, batchFinanceApproveApplication } from "@/api/cw/financeApproval";
|
||||
import { useDict } from "@/utils/dict";
|
||||
import ApplicationSummary from "../application/summary.vue";
|
||||
} from '@/api/cw/approvalRecord';
|
||||
import { financeApproveApplication, batchFinanceApproveApplication } from '@/api/cw/financeApproval';
|
||||
import { useDict } from '@/utils/dict';
|
||||
import ApplicationSummary from '../application/summary.vue';
|
||||
|
||||
export default {
|
||||
name: 'CwFinanceApproval',
|
||||
@@ -321,9 +318,7 @@ export default {
|
||||
},
|
||||
// 审批表单验证
|
||||
approvalRules: {
|
||||
approvalResult: [
|
||||
{ required: true, message: "请选择审批结果", trigger: "change" }
|
||||
],
|
||||
approvalResult: [{ required: true, message: '请选择审批结果', trigger: 'change' }],
|
||||
selectedApproverId: [
|
||||
{
|
||||
validator: (rule, value, callback) => {
|
||||
@@ -337,8 +332,8 @@ export default {
|
||||
}
|
||||
],
|
||||
approvalComment: [
|
||||
{ required: true, message: "请输入审批意见", trigger: "blur" },
|
||||
{ min: 5, max: 500, message: "审批意见长度在 5 到 500 个字符", trigger: "blur" }
|
||||
{ required: true, message: '请输入审批意见', trigger: 'blur' },
|
||||
{ min: 5, max: 500, message: '审批意见长度在 5 到 500 个字符', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
// 可选院领导列表
|
||||
@@ -357,15 +352,17 @@ export default {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
// 默认显示当前用户的待审批记录
|
||||
getFinancePendingApprovals(this.queryParams).then(response => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
}).catch(error => {
|
||||
console.error('获取待审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
getFinancePendingApprovals(this.queryParams)
|
||||
.then((response) => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取待审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
},
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
@@ -377,7 +374,7 @@ export default {
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.daterangeSubmitTime = [];
|
||||
this.resetForm("queryFormRef");
|
||||
this.resetForm('queryFormRef');
|
||||
this.handleQuery();
|
||||
},
|
||||
|
||||
@@ -385,15 +382,17 @@ export default {
|
||||
showPendingApprovals() {
|
||||
this.loading = true;
|
||||
|
||||
getFinancePendingApprovals({}).then(response => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条待审批记录`);
|
||||
}).catch(error => {
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
getFinancePendingApprovals({})
|
||||
.then((response) => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条待审批记录`);
|
||||
})
|
||||
.catch((error) => {
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
},
|
||||
|
||||
showMyApprovals() {
|
||||
@@ -401,22 +400,24 @@ export default {
|
||||
console.log('🔍 查询财务已审批记录');
|
||||
|
||||
// 使用专门的财务审批已审批查询
|
||||
getFinanceApprovedRecords({}).then(response => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条已审批记录`);
|
||||
console.log('✅ 财务已审批记录:', this.approvalList);
|
||||
}).catch(error => {
|
||||
console.error('❌ 获取财务已审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取已审批列表失败');
|
||||
});
|
||||
getFinanceApprovedRecords({})
|
||||
.then((response) => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条已审批记录`);
|
||||
console.log('✅ 财务已审批记录:', this.approvalList);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('❌ 获取财务已审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取已审批列表失败');
|
||||
});
|
||||
},
|
||||
|
||||
/** 多选框选中数据 */
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.applicationId);
|
||||
this.ids = selection.map((item) => item.applicationId);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
console.log('提取的项目申报ID:', this.ids);
|
||||
@@ -437,7 +438,7 @@ export default {
|
||||
this.approvalForm.applicationId = row.applicationId;
|
||||
this.approvalDialog.title = `财务审批 - ${row.applicationNo}`;
|
||||
this.approvalDialog.visible = true;
|
||||
|
||||
|
||||
// 预加载院领导列表
|
||||
this.loadAvailableApprovers(row.applicationId);
|
||||
},
|
||||
@@ -457,7 +458,7 @@ export default {
|
||||
/** 审批结果改变时的处理 */
|
||||
onApprovalResultChange(value) {
|
||||
console.log('📋 审批结果改变:', value);
|
||||
|
||||
|
||||
if (value === 'approve') {
|
||||
// 选择通过时,加载院领导列表
|
||||
if (this.currentApplicationId) {
|
||||
@@ -472,20 +473,20 @@ export default {
|
||||
/** 获取可选院领导列表 */
|
||||
async loadAvailableApprovers(applicationId) {
|
||||
console.log('🔍 开始加载院领导列表,applicationId:', applicationId);
|
||||
|
||||
|
||||
if (!applicationId) {
|
||||
console.warn('⚠️ applicationId为空,无法获取院领导列表');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.loadingApprovers = true;
|
||||
try {
|
||||
const response = await getAvailableApprovers(applicationId);
|
||||
console.log('📊 API响应成功,数据长度:', response.data?.length);
|
||||
|
||||
|
||||
this.availableApprovers = response.data || [];
|
||||
console.log('✅ 获取院领导列表成功:', this.availableApprovers.length, '个院领导');
|
||||
|
||||
|
||||
if (this.availableApprovers.length === 0) {
|
||||
this.$modal.msgWarning('没有找到可用的院领导,请联系管理员');
|
||||
}
|
||||
@@ -500,20 +501,22 @@ export default {
|
||||
|
||||
/** 提交财务审批 */
|
||||
submitApproval() {
|
||||
this.$refs["approvalFormRef"].validate(valid => {
|
||||
this.$refs['approvalFormRef'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.approvalDialog.loading = true;
|
||||
|
||||
financeApproveApplication(this.approvalForm).then(response => {
|
||||
this.$modal.msgSuccess("财务审批成功");
|
||||
this.approvalDialog.visible = false;
|
||||
this.approvalDialog.loading = false;
|
||||
this.getList();
|
||||
}).catch(error => {
|
||||
console.error('财务审批失败:', error);
|
||||
this.approvalDialog.loading = false;
|
||||
this.$modal.msgError('财务审批失败');
|
||||
});
|
||||
financeApproveApplication(this.approvalForm)
|
||||
.then((response) => {
|
||||
this.$modal.msgSuccess('财务审批成功');
|
||||
this.approvalDialog.visible = false;
|
||||
this.approvalDialog.loading = false;
|
||||
this.getList();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('财务审批失败:', error);
|
||||
this.approvalDialog.loading = false;
|
||||
this.$modal.msgError('财务审批失败');
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -526,21 +529,23 @@ export default {
|
||||
}
|
||||
|
||||
this.$modal.confirm('确认要批量通过选中的申报吗?').then(() => {
|
||||
const batchData = this.ids.map(applicationId => ({
|
||||
const batchData = this.ids.map((applicationId) => ({
|
||||
applicationId: applicationId,
|
||||
approvalResult: 'approve',
|
||||
approvalComment: '财务批量审批通过'
|
||||
}));
|
||||
|
||||
batchFinanceApproveApplication(batchData).then(response => {
|
||||
this.$modal.msgSuccess("批量审批成功");
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
}).catch(error => {
|
||||
console.error('批量审批失败:', error);
|
||||
this.$modal.msgError('批量审批失败');
|
||||
});
|
||||
batchFinanceApproveApplication(batchData)
|
||||
.then((response) => {
|
||||
this.$modal.msgSuccess('批量审批成功');
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('批量审批失败:', error);
|
||||
this.$modal.msgError('批量审批失败');
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
@@ -552,40 +557,48 @@ export default {
|
||||
}
|
||||
|
||||
this.$modal.confirm('确认要批量退回选中的申报吗?').then(() => {
|
||||
const batchData = this.ids.map(applicationId => ({
|
||||
const batchData = this.ids.map((applicationId) => ({
|
||||
applicationId: applicationId,
|
||||
approvalResult: 'reject',
|
||||
approvalComment: '财务审批退回,请修改后重新提交'
|
||||
}));
|
||||
|
||||
batchFinanceApproveApplication(batchData).then(response => {
|
||||
this.$modal.msgSuccess("批量退回成功");
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
}).catch(error => {
|
||||
console.error('批量退回失败:', error);
|
||||
this.$modal.msgError('批量退回失败');
|
||||
});
|
||||
batchFinanceApproveApplication(batchData)
|
||||
.then((response) => {
|
||||
this.$modal.msgSuccess('批量退回成功');
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('批量退回失败:', error);
|
||||
this.$modal.msgError('批量退回失败');
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/** 审批历史 */
|
||||
handleApprovalHistory(row) {
|
||||
getApprovalHistory(row.applicationId).then(response => {
|
||||
this.approvalHistory = response.data || [];
|
||||
this.historyDialog.visible = true;
|
||||
}).catch(error => {
|
||||
console.error('获取审批历史失败:', error);
|
||||
this.$modal.msgError('获取审批历史失败');
|
||||
});
|
||||
getApprovalHistory(row.applicationId)
|
||||
.then((response) => {
|
||||
this.approvalHistory = response.data || [];
|
||||
this.historyDialog.visible = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取审批历史失败:', error);
|
||||
this.$modal.msgError('获取审批历史失败');
|
||||
});
|
||||
},
|
||||
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('cw/approval/export', {
|
||||
...this.queryParams
|
||||
}, `finance_approval_${new Date().getTime()}.xlsx`);
|
||||
this.download(
|
||||
'cw/approval/export',
|
||||
{
|
||||
...this.queryParams
|
||||
},
|
||||
`finance_approval_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
|
||||
/** 格式化金额 */
|
||||
@@ -597,30 +610,42 @@ export default {
|
||||
/** 获取时间线类型 */
|
||||
getTimelineType(action) {
|
||||
switch (action) {
|
||||
case 'approve': return 'success';
|
||||
case 'reject': return 'danger';
|
||||
case 'submit': return 'primary';
|
||||
default: return 'info';
|
||||
case 'approve':
|
||||
return 'success';
|
||||
case 'reject':
|
||||
return 'danger';
|
||||
case 'submit':
|
||||
return 'primary';
|
||||
default:
|
||||
return 'info';
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取审批结果类型 */
|
||||
getApprovalResultType(action) {
|
||||
switch (action) {
|
||||
case 'approve': return 'success';
|
||||
case 'reject': return 'danger';
|
||||
case 'submit': return 'primary';
|
||||
default: return 'info';
|
||||
case 'approve':
|
||||
return 'success';
|
||||
case 'reject':
|
||||
return 'danger';
|
||||
case 'submit':
|
||||
return 'primary';
|
||||
default:
|
||||
return 'info';
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取审批结果文本 */
|
||||
getApprovalResultText(action) {
|
||||
switch (action) {
|
||||
case 'approve': return '通过';
|
||||
case 'reject': return '退回';
|
||||
case 'submit': return '提交';
|
||||
default: return '待处理';
|
||||
case 'approve':
|
||||
return '通过';
|
||||
case 'reject':
|
||||
return '退回';
|
||||
case 'submit':
|
||||
return '提交';
|
||||
default:
|
||||
return '待处理';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,13 +125,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" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
|
||||
<!-- 项目详情对话框 -->
|
||||
@@ -166,14 +160,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="审批意见" prop="approvalComment">
|
||||
<el-input
|
||||
v-model="approvalForm.approvalComment"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
placeholder="请输入审批意见"
|
||||
maxlength="500"
|
||||
show-word-limit
|
||||
/>
|
||||
<el-input v-model="approvalForm.approvalComment" type="textarea" :rows="4" placeholder="请输入审批意见" maxlength="500" show-word-limit />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
@@ -196,7 +183,8 @@
|
||||
<el-card>
|
||||
<h4>{{ record.nodeName }}</h4>
|
||||
<p><strong>审批人:</strong>{{ record.approverName }}</p>
|
||||
<p><strong>审批结果:</strong>
|
||||
<p>
|
||||
<strong>审批结果:</strong>
|
||||
<el-tag :type="getApprovalResultType(record.approveAction)">
|
||||
{{ getApprovalResultText(record.approveAction) }}
|
||||
</el-tag>
|
||||
@@ -221,10 +209,10 @@ import {
|
||||
exportApprovalRecord,
|
||||
getLeaderPendingApprovals,
|
||||
getLeaderApprovedApprovals
|
||||
} from "@/api/cw/approvalRecord";
|
||||
import { leaderApproveApplication, batchLeaderApproveApplication } from "@/api/cw/leaderApproval";
|
||||
import { useDict } from "@/utils/dict";
|
||||
import ApplicationSummary from "../application/summary.vue";
|
||||
} from '@/api/cw/approvalRecord';
|
||||
import { leaderApproveApplication, batchLeaderApproveApplication } from '@/api/cw/leaderApproval';
|
||||
import { useDict } from '@/utils/dict';
|
||||
import ApplicationSummary from '../application/summary.vue';
|
||||
|
||||
export default {
|
||||
name: 'CwLeaderApproval',
|
||||
@@ -302,12 +290,10 @@ export default {
|
||||
},
|
||||
// 审批表单验证
|
||||
approvalRules: {
|
||||
approvalResult: [
|
||||
{ required: true, message: "请选择审批结果", trigger: "change" }
|
||||
],
|
||||
approvalResult: [{ required: true, message: '请选择审批结果', trigger: 'change' }],
|
||||
approvalComment: [
|
||||
{ required: true, message: "请输入审批意见", trigger: "blur" },
|
||||
{ min: 5, max: 500, message: "审批意见长度在 5 到 500 个字符", trigger: "blur" }
|
||||
{ required: true, message: '请输入审批意见', trigger: 'blur' },
|
||||
{ min: 5, max: 500, message: '审批意见长度在 5 到 500 个字符', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
// 审批历史数据
|
||||
@@ -322,15 +308,17 @@ export default {
|
||||
getList() {
|
||||
this.loading = true;
|
||||
// 使用学院领导专用的待审批记录查询
|
||||
getLeaderPendingApprovals(this.queryParams).then(response => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
}).catch(error => {
|
||||
console.error('获取待审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
getLeaderPendingApprovals(this.queryParams)
|
||||
.then((response) => {
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取待审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
},
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
@@ -342,7 +330,7 @@ export default {
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.daterangeSubmitTime = [];
|
||||
this.resetForm("queryFormRef");
|
||||
this.resetForm('queryFormRef');
|
||||
this.handleQuery();
|
||||
},
|
||||
|
||||
@@ -351,39 +339,43 @@ export default {
|
||||
console.log('=== 🔍 查询学院领导待审批 ===');
|
||||
this.loading = true;
|
||||
|
||||
getLeaderPendingApprovals({}).then(response => {
|
||||
console.log('✅ 学院领导待审批数据获取成功:', response.data);
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条待审批记录`);
|
||||
}).catch(error => {
|
||||
console.error('❌ 获取学院领导待审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
getLeaderPendingApprovals({})
|
||||
.then((response) => {
|
||||
console.log('✅ 学院领导待审批数据获取成功:', response.data);
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条待审批记录`);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('❌ 获取学院领导待审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取待审批列表失败');
|
||||
});
|
||||
},
|
||||
|
||||
showMyApprovals() {
|
||||
console.log('=== 🔍 查询我已审批 ===');
|
||||
this.loading = true;
|
||||
|
||||
getLeaderApprovedApprovals({}).then(response => {
|
||||
console.log('✅ 已审批数据获取成功:', response.data);
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条已审批记录`);
|
||||
}).catch(error => {
|
||||
console.error('❌ 获取已审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取已审批列表失败');
|
||||
});
|
||||
getLeaderApprovedApprovals({})
|
||||
.then((response) => {
|
||||
console.log('✅ 已审批数据获取成功:', response.data);
|
||||
this.approvalList = response.data || [];
|
||||
this.total = this.approvalList.length;
|
||||
this.loading = false;
|
||||
this.$modal.msgSuccess(`查询到 ${this.total} 条已审批记录`);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('❌ 获取已审批列表失败:', error);
|
||||
this.loading = false;
|
||||
this.$modal.msgError('获取已审批列表失败');
|
||||
});
|
||||
},
|
||||
|
||||
/** 多选框选中数据 */
|
||||
handleSelectionChange(selection) {
|
||||
this.ids = selection.map(item => item.applicationId);
|
||||
this.ids = selection.map((item) => item.applicationId);
|
||||
this.single = selection.length !== 1;
|
||||
this.multiple = !selection.length;
|
||||
console.log('提取的项目申报ID:', this.ids);
|
||||
@@ -417,20 +409,22 @@ export default {
|
||||
|
||||
/** 提交审批 */
|
||||
submitApproval() {
|
||||
this.$refs["approvalFormRef"].validate(valid => {
|
||||
this.$refs['approvalFormRef'].validate((valid) => {
|
||||
if (valid) {
|
||||
this.approvalDialog.loading = true;
|
||||
|
||||
leaderApproveApplication(this.approvalForm).then(response => {
|
||||
this.$modal.msgSuccess("审批成功");
|
||||
this.approvalDialog.visible = false;
|
||||
this.approvalDialog.loading = false;
|
||||
this.getList();
|
||||
}).catch(error => {
|
||||
console.error('审批失败:', error);
|
||||
this.approvalDialog.loading = false;
|
||||
this.$modal.msgError('审批失败');
|
||||
});
|
||||
leaderApproveApplication(this.approvalForm)
|
||||
.then((response) => {
|
||||
this.$modal.msgSuccess('审批成功');
|
||||
this.approvalDialog.visible = false;
|
||||
this.approvalDialog.loading = false;
|
||||
this.getList();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('审批失败:', error);
|
||||
this.approvalDialog.loading = false;
|
||||
this.$modal.msgError('审批失败');
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -443,21 +437,23 @@ export default {
|
||||
}
|
||||
|
||||
this.$modal.confirm('确认要批量通过选中的申报吗?').then(() => {
|
||||
const batchData = this.ids.map(applicationId => ({
|
||||
const batchData = this.ids.map((applicationId) => ({
|
||||
applicationId: applicationId,
|
||||
approvalResult: 'approve',
|
||||
approvalComment: '分管领导批量审批通过'
|
||||
}));
|
||||
|
||||
batchLeaderApproveApplication(batchData).then(response => {
|
||||
this.$modal.msgSuccess("批量审批成功");
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
}).catch(error => {
|
||||
console.error('批量审批失败:', error);
|
||||
this.$modal.msgError('批量审批失败');
|
||||
});
|
||||
batchLeaderApproveApplication(batchData)
|
||||
.then((response) => {
|
||||
this.$modal.msgSuccess('批量审批成功');
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('批量审批失败:', error);
|
||||
this.$modal.msgError('批量审批失败');
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
@@ -469,40 +465,48 @@ export default {
|
||||
}
|
||||
|
||||
this.$modal.confirm('确认要批量退回选中的申报吗?').then(() => {
|
||||
const batchData = this.ids.map(applicationId => ({
|
||||
const batchData = this.ids.map((applicationId) => ({
|
||||
applicationId: applicationId,
|
||||
approvalResult: 'reject',
|
||||
approvalComment: '分管领导审批退回,请修改后重新提交'
|
||||
}));
|
||||
|
||||
batchLeaderApproveApplication(batchData).then(response => {
|
||||
this.$modal.msgSuccess("批量退回成功");
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
}).catch(error => {
|
||||
console.error('批量退回失败:', error);
|
||||
this.$modal.msgError('批量退回失败');
|
||||
});
|
||||
batchLeaderApproveApplication(batchData)
|
||||
.then((response) => {
|
||||
this.$modal.msgSuccess('批量退回成功');
|
||||
this.getList();
|
||||
this.ids = [];
|
||||
this.multiple = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('批量退回失败:', error);
|
||||
this.$modal.msgError('批量退回失败');
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/** 审批历史 */
|
||||
handleApprovalHistory(row) {
|
||||
getApprovalHistory(row.applicationId).then(response => {
|
||||
this.approvalHistory = response.data || [];
|
||||
this.historyDialog.visible = true;
|
||||
}).catch(error => {
|
||||
console.error('获取审批历史失败:', error);
|
||||
this.$modal.msgError('获取审批历史失败');
|
||||
});
|
||||
getApprovalHistory(row.applicationId)
|
||||
.then((response) => {
|
||||
this.approvalHistory = response.data || [];
|
||||
this.historyDialog.visible = true;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取审批历史失败:', error);
|
||||
this.$modal.msgError('获取审批历史失败');
|
||||
});
|
||||
},
|
||||
|
||||
/** 导出按钮操作 */
|
||||
handleExport() {
|
||||
this.download('cw/approval/export', {
|
||||
...this.queryParams
|
||||
}, `leader_approval_${new Date().getTime()}.xlsx`);
|
||||
this.download(
|
||||
'cw/approval/export',
|
||||
{
|
||||
...this.queryParams
|
||||
},
|
||||
`leader_approval_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
},
|
||||
|
||||
/** 格式化金额 */
|
||||
@@ -514,30 +518,42 @@ export default {
|
||||
/** 获取时间线类型 */
|
||||
getTimelineType(action) {
|
||||
switch (action) {
|
||||
case 'approve': return 'success';
|
||||
case 'reject': return 'danger';
|
||||
case 'submit': return 'primary';
|
||||
default: return 'info';
|
||||
case 'approve':
|
||||
return 'success';
|
||||
case 'reject':
|
||||
return 'danger';
|
||||
case 'submit':
|
||||
return 'primary';
|
||||
default:
|
||||
return 'info';
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取审批结果类型 */
|
||||
getApprovalResultType(action) {
|
||||
switch (action) {
|
||||
case 'approve': return 'success';
|
||||
case 'reject': return 'danger';
|
||||
case 'submit': return 'primary';
|
||||
default: return 'info';
|
||||
case 'approve':
|
||||
return 'success';
|
||||
case 'reject':
|
||||
return 'danger';
|
||||
case 'submit':
|
||||
return 'primary';
|
||||
default:
|
||||
return 'info';
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取审批结果文本 */
|
||||
getApprovalResultText(action) {
|
||||
switch (action) {
|
||||
case 'approve': return '通过';
|
||||
case 'reject': return '退回';
|
||||
case 'submit': return '提交';
|
||||
default: return '待处理';
|
||||
case 'approve':
|
||||
return '通过';
|
||||
case 'reject':
|
||||
return '退回';
|
||||
case 'submit':
|
||||
return '提交';
|
||||
default:
|
||||
return '待处理';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<el-col :span="12">
|
||||
<div class="chart-container">
|
||||
<h4>项目状态分布</h4>
|
||||
<div ref="statusChart" style="height: 300px;"></div>
|
||||
<div ref="statusChart" style="height: 300px"></div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
@@ -73,9 +73,7 @@
|
||||
<el-table-column prop="statusLabel" label="状态" width="120" />
|
||||
<el-table-column prop="count" label="数量" align="center" />
|
||||
<el-table-column label="占比" align="center">
|
||||
<template #default="scope">
|
||||
{{ getPercentage(scope.row.count, statusStatistics.totalCount) }}%
|
||||
</template>
|
||||
<template #default="scope"> {{ getPercentage(scope.row.count, statusStatistics.totalCount) }}% </template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
@@ -100,9 +98,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="通过率" align="center" width="100">
|
||||
<template #default="scope">
|
||||
{{ getPercentage(scope.row.approvedCount, scope.row.projectCount) }}%
|
||||
</template>
|
||||
<template #default="scope"> {{ getPercentage(scope.row.approvedCount, scope.row.projectCount) }}% </template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
@@ -124,24 +120,14 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="通过率" align="center" width="100">
|
||||
<template #default="scope">
|
||||
{{ getPercentage(scope.row.approvedCount, scope.row.projectCount) }}%
|
||||
</template>
|
||||
<template #default="scope"> {{ getPercentage(scope.row.approvedCount, scope.row.projectCount) }}% </template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 项目清单 -->
|
||||
<el-tab-pane label="项目清单" name="project">
|
||||
<el-table
|
||||
:data="projectList"
|
||||
stripe
|
||||
v-loading="loading"
|
||||
class="scroll-table"
|
||||
border
|
||||
:height="600"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-table :data="projectList" stripe v-loading="loading" class="scroll-table" border :height="600" style="width: 100%">
|
||||
<el-table-column prop="applicationNo" label="申报编号" width="160" fixed="left" />
|
||||
<el-table-column prop="projectName" label="项目名称" width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="departmentName" label="申报部门" width="150" />
|
||||
@@ -213,16 +199,11 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getStatisticsList,
|
||||
getStatusStatistics,
|
||||
getDepartmentStatistics,
|
||||
getYearlyStatistics
|
||||
} from '@/api/cw/statistics'
|
||||
import { parseTime } from '@/utils/ruoyi'
|
||||
import * as echarts from 'echarts'
|
||||
import Pagination from '@/components/Pagination/index.vue'
|
||||
import ApplicationSummary from '@/views/cw/application/summary.vue'
|
||||
import { getStatisticsList, getStatusStatistics, getDepartmentStatistics, getYearlyStatistics } from '@/api/cw/statistics';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import * as echarts from 'echarts';
|
||||
import Pagination from '@/components/Pagination/index.vue';
|
||||
import ApplicationSummary from '@/views/cw/application/summary.vue';
|
||||
|
||||
export default {
|
||||
name: 'CwStatistics',
|
||||
@@ -273,37 +254,33 @@ export default {
|
||||
applicationId: null
|
||||
},
|
||||
currentApplication: null
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getStatisticsData()
|
||||
this.getStatisticsData();
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initStatusChart()
|
||||
})
|
||||
this.initStatusChart();
|
||||
});
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.statusChartInstance) {
|
||||
this.statusChartInstance.dispose()
|
||||
this.statusChartInstance.dispose();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 获取统计数据 */
|
||||
async getStatisticsData() {
|
||||
try {
|
||||
await Promise.all([
|
||||
this.getStatusStatistics(),
|
||||
this.getDepartmentStatistics(),
|
||||
this.getYearlyStatistics()
|
||||
])
|
||||
if (this.activeTab === 'project') {
|
||||
this.getProjectList()
|
||||
await Promise.all([this.getStatusStatistics(), this.getDepartmentStatistics(), this.getYearlyStatistics()]);
|
||||
if (this.activeTab === 'project') {
|
||||
this.getProjectList();
|
||||
}
|
||||
} finally {
|
||||
// 确保初始化完成后重置loading状态
|
||||
if (this.activeTab !== 'project') {
|
||||
this.loading = false
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -311,53 +288,53 @@ export default {
|
||||
/** 获取状态统计 */
|
||||
async getStatusStatistics() {
|
||||
try {
|
||||
const response = await getStatusStatistics(this.queryParams.budgetYear)
|
||||
this.statusStatistics = response.data
|
||||
this.updateStatusChart()
|
||||
const response = await getStatusStatistics(this.queryParams.budgetYear);
|
||||
this.statusStatistics = response.data;
|
||||
this.updateStatusChart();
|
||||
} catch (error) {
|
||||
console.error('获取状态统计失败:', error)
|
||||
this.$modal.msgError('获取状态统计失败')
|
||||
console.error('获取状态统计失败:', error);
|
||||
this.$modal.msgError('获取状态统计失败');
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取部门统计 */
|
||||
async getDepartmentStatistics() {
|
||||
try {
|
||||
const response = await getDepartmentStatistics(this.queryParams.budgetYear)
|
||||
this.departmentStatistics = response.data
|
||||
const response = await getDepartmentStatistics(this.queryParams.budgetYear);
|
||||
this.departmentStatistics = response.data;
|
||||
} catch (error) {
|
||||
console.error('获取部门统计失败:', error)
|
||||
this.$modal.msgError('获取部门统计失败')
|
||||
console.error('获取部门统计失败:', error);
|
||||
this.$modal.msgError('获取部门统计失败');
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取年度统计 */
|
||||
async getYearlyStatistics() {
|
||||
try {
|
||||
const response = await getYearlyStatistics()
|
||||
this.yearlyStatistics = response.data
|
||||
const response = await getYearlyStatistics();
|
||||
this.yearlyStatistics = response.data;
|
||||
} catch (error) {
|
||||
console.error('获取年度统计失败:', error)
|
||||
this.$modal.msgError('获取年度统计失败')
|
||||
console.error('获取年度统计失败:', error);
|
||||
this.$modal.msgError('获取年度统计失败');
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取项目清单 */
|
||||
async getProjectList() {
|
||||
try {
|
||||
this.loading = true
|
||||
console.log('🎯 [统计页面-项目清单] 开始获取数据,查询参数:', this.queryParams)
|
||||
this.loading = true;
|
||||
console.log('🎯 [统计页面-项目清单] 开始获取数据,查询参数:', this.queryParams);
|
||||
|
||||
const response = await getStatisticsList({
|
||||
...this.queryParams,
|
||||
type: 'project'
|
||||
})
|
||||
});
|
||||
|
||||
console.log('🎯 [统计页面-项目清单] API响应:', response)
|
||||
console.log('🎯 [统计页面-项目清单] API响应:', response);
|
||||
|
||||
if (response.code === 200) {
|
||||
this.projectList = response.rows || []
|
||||
this.projectTotal = response.total || 0
|
||||
this.projectList = response.rows || [];
|
||||
this.projectTotal = response.total || 0;
|
||||
|
||||
// 如果没有数据,添加一些测试数据来演示样式效果
|
||||
if (this.projectList.length === 0) {
|
||||
@@ -413,79 +390,79 @@ export default {
|
||||
expectedEndDate: '2024-07-31',
|
||||
remarks: '校园道路两侧绿化带改造及景观提升'
|
||||
}
|
||||
]
|
||||
this.projectTotal = 3
|
||||
];
|
||||
this.projectTotal = 3;
|
||||
}
|
||||
|
||||
console.log('🎯 [统计页面-项目清单] 数据设置完成,项目列表长度:', this.projectList?.length || 0)
|
||||
console.log('🎯 [统计页面-项目清单] 数据设置完成,项目列表长度:', this.projectList?.length || 0);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('🎯 [统计页面-项目清单] 获取数据失败:', error)
|
||||
this.$modal.msgError('获取项目清单失败')
|
||||
console.error('🎯 [统计页面-项目清单] 获取数据失败:', error);
|
||||
this.$modal.msgError('获取项目清单失败');
|
||||
} finally {
|
||||
this.loading = false
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
handleQuery() {
|
||||
this.queryParams.pageNum = 1
|
||||
this.getStatisticsData()
|
||||
this.queryParams.pageNum = 1;
|
||||
this.getStatisticsData();
|
||||
},
|
||||
|
||||
/** 重置按钮操作 */
|
||||
resetQuery() {
|
||||
this.queryParams.budgetYear = ''
|
||||
this.handleQuery()
|
||||
this.queryParams.budgetYear = '';
|
||||
this.handleQuery();
|
||||
},
|
||||
|
||||
/** Tab切换 */
|
||||
handleTabClick(tab) {
|
||||
if (tab.name === 'project') {
|
||||
this.getProjectList()
|
||||
this.getProjectList();
|
||||
}
|
||||
},
|
||||
|
||||
/** 查看项目详情 */
|
||||
handleViewProject(row) {
|
||||
console.log('🔍 [统计页面] 查看项目详情:', row)
|
||||
console.log('🔍 [统计页面] 查看项目详情:', row);
|
||||
|
||||
this.currentApplication = row
|
||||
this.detailDialog.title = `项目详情 - ${row.projectName || '未命名项目'}`
|
||||
this.detailDialog.visible = true
|
||||
this.currentApplication = row;
|
||||
this.detailDialog.title = `项目详情 - ${row.projectName || '未命名项目'}`;
|
||||
this.detailDialog.visible = true;
|
||||
|
||||
console.log('🔍 [统计页面] 设置currentApplication:', this.currentApplication)
|
||||
console.log('🔍 [统计页面] applicationId:', row.applicationId)
|
||||
console.log('🔍 [统计页面] 设置currentApplication:', this.currentApplication);
|
||||
console.log('🔍 [统计页面] applicationId:', row.applicationId);
|
||||
},
|
||||
|
||||
/** 初始化状态图表 */
|
||||
initStatusChart() {
|
||||
if (this.$refs.statusChart) {
|
||||
this.statusChartInstance = echarts.init(this.$refs.statusChart)
|
||||
this.updateStatusChart()
|
||||
this.statusChartInstance = echarts.init(this.$refs.statusChart);
|
||||
this.updateStatusChart();
|
||||
|
||||
// 监听窗口大小变化
|
||||
window.addEventListener('resize', () => {
|
||||
if (this.statusChartInstance) {
|
||||
this.statusChartInstance.resize()
|
||||
this.statusChartInstance.resize();
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/** 更新状态图表 */
|
||||
updateStatusChart() {
|
||||
if (!this.statusChartInstance || !this.statusStatistics.statusStatistics) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
// 过滤掉数量为0的状态,只显示有数据的状态
|
||||
const data = this.statusStatistics.statusStatistics
|
||||
.filter(item => item.count > 0)
|
||||
.map(item => ({
|
||||
.filter((item) => item.count > 0)
|
||||
.map((item) => ({
|
||||
name: item.statusLabel,
|
||||
value: item.count
|
||||
}))
|
||||
}));
|
||||
|
||||
// 如果没有数据,显示空状态提示
|
||||
if (data.length === 0) {
|
||||
@@ -499,9 +476,9 @@ export default {
|
||||
fontSize: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
this.statusChartInstance.setOption(option)
|
||||
return
|
||||
};
|
||||
this.statusChartInstance.setOption(option);
|
||||
return;
|
||||
}
|
||||
|
||||
// 定义状态对应的颜色
|
||||
@@ -513,7 +490,7 @@ export default {
|
||||
'已拒绝': '#F56C6C',
|
||||
'已退回': '#E6A23C',
|
||||
'已取消': '#909399'
|
||||
}
|
||||
};
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
@@ -540,8 +517,8 @@ export default {
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: function(params) {
|
||||
return statusColors[params.name] || '#409EFF'
|
||||
color: function (params) {
|
||||
return statusColors[params.name] || '#409EFF';
|
||||
}
|
||||
},
|
||||
label: {
|
||||
@@ -553,41 +530,41 @@ export default {
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
this.statusChartInstance.setOption(option, true)
|
||||
this.statusChartInstance.setOption(option, true);
|
||||
},
|
||||
|
||||
/** 获取已通过项目数量 */
|
||||
getApprovedCount() {
|
||||
const approvedStat = this.statusStatistics.statusStatistics?.find(item => item.status === 'approved')
|
||||
return approvedStat ? approvedStat.count : 0
|
||||
const approvedStat = this.statusStatistics.statusStatistics?.find((item) => item.status === 'approved');
|
||||
return approvedStat ? approvedStat.count : 0;
|
||||
},
|
||||
|
||||
/** 格式化金额 */
|
||||
formatAmount(amount) {
|
||||
if (!amount) return '0.00'
|
||||
return Number(amount).toFixed(2)
|
||||
if (!amount) return '0.00';
|
||||
return Number(amount).toFixed(2);
|
||||
},
|
||||
|
||||
/** 计算百分比 */
|
||||
getPercentage(numerator, denominator) {
|
||||
if (!denominator || denominator === 0) return '0.00'
|
||||
return ((numerator / denominator) * 100).toFixed(2)
|
||||
if (!denominator || denominator === 0) return '0.00';
|
||||
return ((numerator / denominator) * 100).toFixed(2);
|
||||
},
|
||||
|
||||
parseTime,
|
||||
|
||||
/** 查看项目详情 */
|
||||
viewDetail(row) {
|
||||
console.log('查看项目详情:', row)
|
||||
this.currentApplication = row
|
||||
this.detailDialog.visible = true
|
||||
this.detailDialog.title = `项目详情 - ${row.projectName}`
|
||||
this.detailDialog.applicationId = row.applicationId
|
||||
console.log('查看项目详情:', row);
|
||||
this.currentApplication = row;
|
||||
this.detailDialog.visible = true;
|
||||
this.detailDialog.title = `项目详情 - ${row.projectName}`;
|
||||
this.detailDialog.applicationId = row.applicationId;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -4,37 +4,38 @@
|
||||
<el-form :model="form" label-width="120px">
|
||||
<el-form-item label="测试数据1">
|
||||
<el-button @click="loadTestData1" type="primary">加载单个OSS ID</el-button>
|
||||
<span style="margin-left: 10px; color: #666;">测试单个OSS文件回显</span>
|
||||
<span style="margin-left: 10px; color: #666">测试单个OSS文件回显</span>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="测试数据2">
|
||||
<el-button @click="loadTestData2" type="primary">加载多个OSS ID</el-button>
|
||||
<span style="margin-left: 10px; color: #666;">测试多个OSS文件回显</span>
|
||||
<span style="margin-left: 10px; color: #666">测试多个OSS文件回显</span>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="测试数据3">
|
||||
<el-button @click="loadTestData3" type="primary">加载URL格式</el-button>
|
||||
<span style="margin-left: 10px; color: #666;">测试直接URL回显</span>
|
||||
<span style="margin-left: 10px; color: #666">测试直接URL回显</span>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="清空数据">
|
||||
<el-button @click="clearData" type="danger">清空</el-button>
|
||||
<span style="margin-left: 10px; color: #666;">清空所有图片数据</span>
|
||||
<span style="margin-left: 10px; color: #666">清空所有图片数据</span>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="当前值">
|
||||
<el-input v-model="form.images" type="textarea" :rows="3" readonly />
|
||||
</el-form-item>
|
||||
|
||||
|
||||
<el-form-item label="图片上传">
|
||||
<ImageUpload v-model="form.images" :limit="5" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
||||
<div class="test-info">
|
||||
<h3>测试说明</h3>
|
||||
<ul>
|
||||
<li><strong>功能验证</strong>:
|
||||
<li>
|
||||
<strong>功能验证</strong>:
|
||||
<ol>
|
||||
<li>界面打开时历史图片是否正常显示(通过认证接口获取blob URL)</li>
|
||||
<li>点击图片预览是否正常工作</li>
|
||||
@@ -42,7 +43,8 @@
|
||||
<li>删除图片功能是否正常</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><strong>技术要点</strong>:
|
||||
<li>
|
||||
<strong>技术要点</strong>:
|
||||
<ul>
|
||||
<li>使用 Promise.all 并行处理多个文件的blob URL转换</li>
|
||||
<li>缓存机制避免重复请求相同图片的认证数据</li>
|
||||
@@ -89,30 +91,31 @@ const clearData = () => {
|
||||
<style lang="scss" scoped>
|
||||
.image-upload-test {
|
||||
padding: 20px;
|
||||
|
||||
|
||||
.test-info {
|
||||
margin-top: 30px;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 4px;
|
||||
|
||||
|
||||
h3 {
|
||||
margin-top: 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
|
||||
ul,
|
||||
ol {
|
||||
margin-left: 20px;
|
||||
|
||||
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
strong {
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
+106
-91
@@ -736,10 +736,10 @@ const viewForm = reactive<JobVO>({
|
||||
});
|
||||
|
||||
// 表单校验
|
||||
const rules = reactive({
|
||||
const rules = reactive<Record<string, any>>({
|
||||
title: [
|
||||
{ required: true, message: '职位名称不能为空', trigger: 'blur' },
|
||||
{ min: 2, max: 50, message: '长度在 2 到 50 个字符', trigger: 'blur' }
|
||||
{ min: 2 as number, max: 50 as number, message: '长度在 2 到 50 个字符', trigger: 'blur' }
|
||||
],
|
||||
department: [{ required: true, message: '部门不能为空', trigger: 'change' }],
|
||||
salaryRange: [{ required: true, message: '薪资范围不能为空', trigger: 'blur' }],
|
||||
@@ -795,6 +795,8 @@ const editForm = reactive<ApplicationVO>({
|
||||
jobTitle: '',
|
||||
applicantId: 0,
|
||||
applicantName: '',
|
||||
gender: '', // 新增:性别
|
||||
age: '', // 新增:年龄
|
||||
status: '',
|
||||
applyTime: '',
|
||||
resumePath: '',
|
||||
@@ -803,6 +805,7 @@ const editForm = reactive<ApplicationVO>({
|
||||
contactPhone: '',
|
||||
contactEmail: '',
|
||||
education: '',
|
||||
educationBackground: '', // 新增:教育背景
|
||||
experience: '',
|
||||
remark: '',
|
||||
createBy: '',
|
||||
@@ -821,6 +824,8 @@ const applicationDetail = reactive<ApplicationVO>({
|
||||
jobTitle: '',
|
||||
applicantId: 0,
|
||||
applicantName: '',
|
||||
gender: '', // 新增:性别
|
||||
age: '', // 新增:年龄
|
||||
status: '',
|
||||
applyTime: '',
|
||||
resumePath: '',
|
||||
@@ -829,6 +834,7 @@ const applicationDetail = reactive<ApplicationVO>({
|
||||
contactPhone: '',
|
||||
contactEmail: '',
|
||||
education: '',
|
||||
educationBackground: '', // 新增:教育背景
|
||||
experience: '',
|
||||
remark: '',
|
||||
createBy: '',
|
||||
@@ -856,7 +862,11 @@ function getList() {
|
||||
|
||||
/** 获取部门列表 */
|
||||
function getDepartmentList() {
|
||||
listDept({ status: '0' })
|
||||
listDept({
|
||||
pageNum: 1,
|
||||
pageSize: 1000, // 获取所有部门
|
||||
status: 0 // 修复:改为number类型
|
||||
})
|
||||
.then((response) => {
|
||||
const deptList = response.data || [];
|
||||
// 过滤出二级学院和行政单位下的部门,作为招聘部门选项
|
||||
@@ -1166,145 +1176,150 @@ function getApplicationList() {
|
||||
|
||||
/** 模拟申请数据 */
|
||||
function mockApplicationData() {
|
||||
// 创建基础模拟数据
|
||||
const mockData = [
|
||||
const mockData: ApplicationVO[] = [
|
||||
{
|
||||
applicationId: 1,
|
||||
jobId: 1,
|
||||
jobTitle: 'Java开发工程师',
|
||||
applicantId: 1,
|
||||
applicantName: '张文明',
|
||||
status: '0', // 待处理
|
||||
gender: '男', // 新增:性别
|
||||
age: 25, // 新增:年龄
|
||||
status: '0',
|
||||
applyTime: '2025-07-25 10:30:00',
|
||||
resumePath: '/uploads/resume/zhangwm_resume.pdf',
|
||||
selfDescription: '本科计算机科学与技术专业毕业,3年Java开发经验,熟悉Spring Boot、MyBatis框架,具有良好的团队合作精神。',
|
||||
selfDescription: '本科计算机科学与技术专业毕业,熟悉Java开发技术栈,有2年相关工作经验,对Spring Boot、MyBatis等框架有深入了解。',
|
||||
hrNotes: '初步筛选通过,安排下周一进行技术面试',
|
||||
contactPhone: '13812345678',
|
||||
contactEmail: 'zhangwm@example.com',
|
||||
education: '2018-2022 浙江大学 计算机科学与技术 本科',
|
||||
educationBackground: '2018-2022 浙江大学 计算机科学与技术 本科', // 新增:教育背景
|
||||
experience: '2022-2025 杭州某科技公司 Java开发工程师',
|
||||
remark: '内部推荐',
|
||||
createBy: '1',
|
||||
remark: '候选人技术基础扎实,沟通能力良好',
|
||||
createBy: 'admin',
|
||||
createTime: '2025-07-25 10:30:00',
|
||||
updateBy: '1',
|
||||
updateTime: '2025-07-25 10:30:00'
|
||||
updateBy: 'hr001',
|
||||
updateTime: '2025-07-25 14:20:00'
|
||||
},
|
||||
{
|
||||
applicationId: 2,
|
||||
jobId: 1,
|
||||
jobTitle: 'Java开发工程师',
|
||||
applicantId: 2,
|
||||
applicantName: '李华',
|
||||
status: '1', // 已通过
|
||||
applyTime: '2025-07-23 14:20:00',
|
||||
resumePath: '/uploads/resume/lihua_resume.pdf',
|
||||
selfDescription: '硕士学历,Java开发5年经验,精通分布式系统设计。',
|
||||
hrNotes: '技术能力强,沟通良好,建议录用',
|
||||
applicantName: '李小红',
|
||||
gender: '女', // 新增:性别
|
||||
age: 23, // 新增:年龄
|
||||
status: '1',
|
||||
applyTime: '2025-07-24 16:45:00',
|
||||
resumePath: '/uploads/resume/lixh_resume.pdf',
|
||||
selfDescription: '计算机相关专业应届毕业生,在校期间参与过多个项目开发,熟悉Java、MySQL、Redis等技术。',
|
||||
hrNotes: '应届生,技术基础待考察',
|
||||
contactPhone: '13987654321',
|
||||
contactEmail: 'lihua@example.com',
|
||||
education: '2016-2020 北京大学 计算机科学 本科\n2020-2023 清华大学 软件工程 硕士',
|
||||
experience: '2023-2025 北京某互联网公司 高级Java工程师',
|
||||
remark: '',
|
||||
createBy: '1',
|
||||
createTime: '2025-07-23 14:20:00',
|
||||
updateBy: '1',
|
||||
updateTime: '2025-07-24 16:45:00'
|
||||
contactEmail: 'lixh@example.com',
|
||||
education: '2020-2024 杭州电子科技大学 软件工程 本科',
|
||||
educationBackground: '2020-2024 杭州电子科技大学 软件工程 本科', // 新增:教育背景
|
||||
experience: '在校期间参与学校实验室项目开发',
|
||||
remark: '应届毕业生,可培养',
|
||||
createBy: 'admin',
|
||||
createTime: '2025-07-24 16:45:00',
|
||||
updateBy: 'hr001',
|
||||
updateTime: '2025-07-24 17:30:00'
|
||||
},
|
||||
{
|
||||
applicationId: 3,
|
||||
jobId: 2,
|
||||
jobTitle: '前端工程师',
|
||||
jobTitle: 'UI设计师',
|
||||
applicantId: 3,
|
||||
applicantName: '王芳',
|
||||
status: '2', // 已拒绝
|
||||
applyTime: '2025-07-20 09:15:00',
|
||||
resumePath: '/uploads/resume/wangfang_resume.pdf',
|
||||
selfDescription: '3年前端开发经验,熟练掌握Vue、React等框架。',
|
||||
hrNotes: '技术能力不匹配岗位需求',
|
||||
contactPhone: '13765432198',
|
||||
contactEmail: 'wangfang@example.com',
|
||||
education: '2019-2023 武汉大学 软件工程 本科',
|
||||
experience: '2023-2025 上海某公司 前端开发',
|
||||
remark: '',
|
||||
createBy: '1',
|
||||
createTime: '2025-07-20 09:15:00',
|
||||
updateBy: '1',
|
||||
updateTime: '2025-07-21 14:30:00'
|
||||
applicantName: '王设计',
|
||||
gender: '女', // 新增:性别
|
||||
age: 27, // 新增:年龄
|
||||
status: '2',
|
||||
applyTime: '2025-07-23 14:20:00',
|
||||
resumePath: '/uploads/resume/wangdesign_resume.pdf',
|
||||
selfDescription: '5年UI/UX设计经验,擅长移动端和Web端界面设计,熟练使用Figma、Sketch、Adobe系列软件。',
|
||||
hrNotes: '作品集质量很高,已通过初试',
|
||||
contactPhone: '13612345678',
|
||||
contactEmail: 'wangdesign@example.com',
|
||||
education: '2015-2019 中国美术学院 视觉传达设计 本科',
|
||||
educationBackground: '2015-2019 中国美术学院 视觉传达设计 本科', // 新增:教育背景
|
||||
experience: '2019-2024 某互联网公司 UI设计师',
|
||||
remark: '设计能力强,有良好的审美',
|
||||
createBy: 'admin',
|
||||
createTime: '2025-07-23 14:20:00',
|
||||
updateBy: 'hr002',
|
||||
updateTime: '2025-07-23 16:45:00'
|
||||
},
|
||||
{
|
||||
applicationId: 4,
|
||||
jobId: 3,
|
||||
jobTitle: '行政助理',
|
||||
jobTitle: '产品经理',
|
||||
applicantId: 4,
|
||||
applicantName: '赵静',
|
||||
status: '0', // 待处理
|
||||
applyTime: '2025-07-24 11:05:00',
|
||||
resumePath: '/uploads/resume/zhaojing_resume.pdf',
|
||||
selfDescription: '行政管理专业毕业,有2年行政工作经验,熟悉办公软件操作。',
|
||||
hrNotes: '',
|
||||
contactPhone: '13612345678',
|
||||
contactEmail: 'zhaojing@example.com',
|
||||
education: '2020-2024 南京大学 行政管理 本科',
|
||||
experience: '2024-2025 杭州某公司 行政文员',
|
||||
remark: '',
|
||||
createBy: '1',
|
||||
createTime: '2025-07-24 11:05:00',
|
||||
updateBy: '1',
|
||||
updateTime: '2025-07-24 11:05:00'
|
||||
applicantName: '陈产品',
|
||||
gender: '男', // 新增:性别
|
||||
age: 30, // 新增:年龄
|
||||
status: '3',
|
||||
applyTime: '2025-07-22 11:15:00',
|
||||
resumePath: '/uploads/resume/chenchanpin_resume.pdf',
|
||||
selfDescription: '8年产品经验,负责过多个从0到1的产品项目,具备完整的产品生命周期管理能力。',
|
||||
hrNotes: '面试表现优秀,待薪资谈判',
|
||||
contactPhone: '13512345678',
|
||||
contactEmail: 'chenchanpin@example.com',
|
||||
education: '2012-2016 浙江大学 工商管理 本科',
|
||||
educationBackground: '2012-2016 浙江大学 工商管理 本科', // 新增:教育背景
|
||||
experience: '2016-2024 多家互联网公司 产品经理',
|
||||
remark: '产品思维清晰,有丰富的实战经验',
|
||||
createBy: 'admin',
|
||||
createTime: '2025-07-22 11:15:00',
|
||||
updateBy: 'hr003',
|
||||
updateTime: '2025-07-22 15:30:00'
|
||||
},
|
||||
{
|
||||
applicationId: 5,
|
||||
jobId: 2,
|
||||
jobTitle: '前端工程师',
|
||||
jobId: 4,
|
||||
jobTitle: '市场专员',
|
||||
applicantId: 5,
|
||||
applicantName: '刘明',
|
||||
status: '1', // 已通过
|
||||
applyTime: '2025-07-22 10:40:00',
|
||||
resumePath: '/uploads/resume/liuming_resume.pdf',
|
||||
selfDescription: '4年前端开发经验,精通Vue3、TypeScript,有大型项目经验。',
|
||||
hrNotes: '技术能力强,经验丰富,建议录用',
|
||||
contactPhone: '13812345679',
|
||||
contactEmail: 'liuming@example.com',
|
||||
education: '2017-2021 浙江大学 软件工程 本科',
|
||||
experience: '2021-2025 杭州某科技公司 前端工程师',
|
||||
remark: '',
|
||||
createBy: '1',
|
||||
createTime: '2025-07-22 10:40:00',
|
||||
updateBy: '1',
|
||||
updateTime: '2025-07-23 15:20:00'
|
||||
applicantName: '刘市场',
|
||||
gender: '女', // 新增:性别
|
||||
age: 24, // 新增:年龄
|
||||
status: '4',
|
||||
applyTime: '2025-07-21 09:30:00',
|
||||
resumePath: '/uploads/resume/liushichang_resume.pdf',
|
||||
selfDescription: '市场营销专业毕业,有2年市场推广经验,熟悉新媒体运营和活动策划。',
|
||||
hrNotes: '不符合岗位要求,建议拒绝',
|
||||
contactPhone: '13412345678',
|
||||
contactEmail: 'liushichang@example.com',
|
||||
education: '2018-2022 浙江工商大学 市场营销 本科',
|
||||
educationBackground: '2018-2022 浙江工商大学 市场营销 本科', // 新增:教育背景
|
||||
experience: '2022-2024 某传媒公司 市场专员',
|
||||
remark: '经验不足,与岗位需求不匹配',
|
||||
createBy: 'admin',
|
||||
createTime: '2025-07-21 09:30:00',
|
||||
updateBy: 'hr001',
|
||||
updateTime: '2025-07-21 11:45:00'
|
||||
}
|
||||
];
|
||||
|
||||
// 应用筛选
|
||||
let filteredData = [...mockData];
|
||||
// 应用搜索过滤
|
||||
let filteredData = mockData;
|
||||
|
||||
// 按职位ID筛选
|
||||
if (applicationQueryParams.jobId) {
|
||||
filteredData = filteredData.filter((item) => item.jobId === applicationQueryParams.jobId);
|
||||
}
|
||||
|
||||
// 按职位名称筛选
|
||||
if (applicationQueryParams.jobTitle) {
|
||||
filteredData = filteredData.filter((item) => item.jobTitle.includes(applicationQueryParams.jobTitle));
|
||||
}
|
||||
|
||||
// 按应聘者姓名筛选
|
||||
if (applicationQueryParams.applicantName) {
|
||||
filteredData = filteredData.filter((item) => item.applicantName.includes(applicationQueryParams.applicantName));
|
||||
}
|
||||
|
||||
// 按联系电话筛选
|
||||
if (applicationQueryParams.contactPhone) {
|
||||
filteredData = filteredData.filter((item) => item.contactPhone.includes(applicationQueryParams.contactPhone));
|
||||
}
|
||||
|
||||
// 按状态筛选
|
||||
if (applicationQueryParams.status) {
|
||||
filteredData = filteredData.filter((item) => item.status === applicationQueryParams.status);
|
||||
}
|
||||
|
||||
// 设置数据
|
||||
applicationList.value = filteredData;
|
||||
// 分页处理
|
||||
const startIndex = (applicationQueryParams.pageNum - 1) * applicationQueryParams.pageSize;
|
||||
const endIndex = startIndex + applicationQueryParams.pageSize;
|
||||
const pageData = filteredData.slice(startIndex, endIndex);
|
||||
|
||||
applicationList.value = pageData;
|
||||
applicationTotal.value = filteredData.length;
|
||||
applicationLoading.value = false;
|
||||
}
|
||||
|
||||
@@ -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:application:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportPending" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showPendingSearch" @queryTable="getPendingList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -85,20 +85,20 @@
|
||||
<!-- 待审批申请表格 -->
|
||||
<el-table v-loading="pendingLoading" border :data="pendingList" @row-dblclick="handleViewApplication">
|
||||
<el-table-column label="申请人" align="center" prop="applicantName" width="100" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="所属部门" align="center" prop="department" width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="所属部门" align="center" prop="department" width="140" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国目的" align="center" prop="purposeText" width="100" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" min-width="130" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国时间" align="center" min-width="200" :show-overflow-tooltip="true">
|
||||
<el-table-column label="目的地" align="center" prop="destination" width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国时间" align="center" min-width="220" :show-overflow-tooltip="true">
|
||||
<template #default="scope"> {{ formatDate(scope.row.startDate) }} 至 {{ formatDate(scope.row.endDate) }} </template>
|
||||
</el-table-column>
|
||||
<el-table-column label="天数" align="center" prop="duration" width="60" />
|
||||
<el-table-column label="申请时间" align="center" prop="applyTime" width="160" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="申请状态" align="center" width="110">
|
||||
<el-table-column label="申请状态" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusTagType(scope.row.status)">{{ scope.row.statusText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="280">
|
||||
<el-table-column label="操作" align="center" width="180">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button
|
||||
@@ -106,7 +106,7 @@
|
||||
type="primary"
|
||||
icon="View"
|
||||
@click="handleViewApplication(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:query']"
|
||||
v-hasPermi="['rs:overseas:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="查看审批历史" placement="top" v-if="scope.row.status !== '0'">
|
||||
@@ -115,7 +115,7 @@
|
||||
type="info"
|
||||
icon="List"
|
||||
@click.stop="handleViewApprovalHistory(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:query']"
|
||||
v-hasPermi="['rs:overseas:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="通过" placement="top" v-if="scope.row.status === '0'">
|
||||
@@ -124,7 +124,7 @@
|
||||
type="success"
|
||||
icon="Check"
|
||||
@click="handleApprovalPass(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:approve']"
|
||||
v-hasPermi="['rs:overseas:approve']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="拒绝" placement="top" v-if="scope.row.status === '0'">
|
||||
@@ -133,7 +133,7 @@
|
||||
type="danger"
|
||||
icon="Close"
|
||||
@click="handleApprovalReject(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:approve']"
|
||||
v-hasPermi="['rs:overseas:approve']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
@@ -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:approval:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showRecordSearch" @queryTable="getRecordList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -228,29 +228,23 @@
|
||||
<!-- 审批记录表格 -->
|
||||
<el-table v-loading="recordLoading" border :data="recordList" @row-dblclick="handleViewRecord">
|
||||
<el-table-column label="申请人" align="center" prop="applicantName" width="100" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="所属部门" align="center" prop="department" width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="所属部门" align="center" prop="department" width="140" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国目的" align="center" prop="purposeText" width="100" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" min-width="130" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国时间" align="center" min-width="200" :show-overflow-tooltip="true">
|
||||
<el-table-column label="目的地" align="center" prop="destination" width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国时间" align="center" min-width="220" :show-overflow-tooltip="true">
|
||||
<template #default="scope"> {{ formatDate(scope.row.startDate) }} 至 {{ formatDate(scope.row.endDate) }} </template>
|
||||
</el-table-column>
|
||||
<el-table-column label="天数" align="center" prop="duration" width="60" />
|
||||
<el-table-column label="审批时间" align="center" prop="approvalTime" width="160" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="审批状态" align="center" width="110">
|
||||
<el-table-column label="审批状态" align="center" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getApprovalStatusTagType(scope.row.approvalStatus)">{{ scope.row.approvalStatusText }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="320">
|
||||
<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="View"
|
||||
@click="handleViewRecord(scope.row)"
|
||||
v-hasPermi="['rs:overseas:approval:query']"
|
||||
></el-button>
|
||||
<el-button link type="primary" icon="View" @click="handleViewRecord(scope.row)" v-hasPermi="['rs:overseas:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="查看审批历史" placement="top">
|
||||
<el-button
|
||||
@@ -258,7 +252,7 @@
|
||||
type="info"
|
||||
icon="List"
|
||||
@click.stop="handleViewApprovalHistory(scope.row)"
|
||||
v-hasPermi="['rs:overseas:approval:query']"
|
||||
v-hasPermi="['rs:overseas:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
@@ -13,13 +13,8 @@
|
||||
<el-form ref="applicationQueryForm" :model="applicationQueryParams" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="5">
|
||||
<el-form-item label="目的地" prop="destination">
|
||||
<el-input
|
||||
v-model="applicationQueryParams.destination"
|
||||
placeholder="请输入目的地国家"
|
||||
clearable
|
||||
@keyup.enter="handleApplicationQuery"
|
||||
/>
|
||||
<el-form-item label="目的地国家" prop="destination">
|
||||
<el-input v-model="applicationQueryParams.destination" placeholder="请输入目的地国家" clearable />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
@@ -69,12 +64,10 @@
|
||||
<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:overseas:application:add']"
|
||||
>新增申请</el-button
|
||||
>
|
||||
<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:application:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportApplication" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showApplicationSearch" @queryTable="getApplicationList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -85,7 +78,7 @@
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="申请人" align="center" prop="applicantName" width="100" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国目的" align="center" prop="purposeText" width="110" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="目的地国家" align="center" prop="destination" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国时间" align="center" min-width="200" :show-overflow-tooltip="true">
|
||||
<template #default="scope"> {{ formatDate(scope.row.startDate) }} 至 {{ formatDate(scope.row.endDate) }} </template>
|
||||
</el-table-column>
|
||||
@@ -106,7 +99,7 @@
|
||||
type="primary"
|
||||
icon="View"
|
||||
@click="handleViewApplication(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:query']"
|
||||
v-hasPermi="['rs:overseas:query']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 待审核状态:显示撤回按钮 -->
|
||||
@@ -116,7 +109,7 @@
|
||||
type="warning"
|
||||
icon="RefreshLeft"
|
||||
@click="handleCancelApplication(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:cancel']"
|
||||
v-hasPermi="['rs:overseas:cancel']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 已拒绝状态:显示重新提交按钮(需要修改并重新提交权限) -->
|
||||
@@ -126,7 +119,7 @@
|
||||
type="success"
|
||||
icon="RefreshRight"
|
||||
@click="handleUpdateAndResubmitApplication(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:edit', 'rs:overseas:application:submit']"
|
||||
v-hasPermi="['rs:overseas:edit', 'rs:overseas:submit']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 已通过和已拒绝状态:显示审批历史 -->
|
||||
@@ -140,7 +133,7 @@
|
||||
type="danger"
|
||||
icon="Delete"
|
||||
@click="handleDeleteApplication(scope.row)"
|
||||
v-hasPermi="['rs:overseas:application:remove']"
|
||||
v-hasPermi="['rs:overseas:remove']"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
@@ -178,7 +171,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="目的地" prop="destination">
|
||||
<el-form-item label="目的地国家" prop="destination">
|
||||
<el-input
|
||||
v-model="recordQueryParams.destination"
|
||||
placeholder="请输入目的地国家"
|
||||
@@ -214,7 +207,7 @@
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:overseas:record:export']">导出</el-button>
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showRecordSearch" @queryTable="getRecordList"></right-toolbar>
|
||||
</el-row>
|
||||
@@ -225,7 +218,7 @@
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="申请人" align="center" prop="applicantName" width="100" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国目的" align="center" prop="purposeText" width="110" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="目的地" align="center" prop="destination" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="目的地国家" align="center" prop="destination" min-width="120" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="出国时间" align="center" min-width="200" :show-overflow-tooltip="true">
|
||||
<template #default="scope"> {{ formatDate(scope.row.actualStartDate) }} 至 {{ formatDate(scope.row.actualEndDate) }} </template>
|
||||
</el-table-column>
|
||||
@@ -241,13 +234,7 @@
|
||||
<el-table-column label="操作" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="View"
|
||||
@click="handleViewRecord(scope.row)"
|
||||
v-hasPermi="['rs:overseas:record:query']"
|
||||
></el-button>
|
||||
<el-button link type="primary" icon="View" @click="handleViewRecord(scope.row)" v-hasPermi="['rs:overseas:query']"></el-button>
|
||||
</el-tooltip>
|
||||
<!-- 审批历史按钮:对于有关联申请的记录显示审批历史 -->
|
||||
<el-tooltip content="审批历史" placement="top" v-if="scope.row.applicationId">
|
||||
@@ -290,17 +277,6 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="目的地" prop="destinationCity">
|
||||
<el-input v-model="applicationForm.destinationCity" placeholder="请输入目的地" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<!-- 占位列,保持布局平衡 -->
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="目的详细说明" prop="purposeDetail">
|
||||
<el-input v-model="applicationForm.purposeDetail" type="textarea" :rows="3" placeholder="请详细说明出国目的" />
|
||||
</el-form-item>
|
||||
@@ -366,7 +342,7 @@
|
||||
<el-descriptions-item label="所属部门">{{ viewData.department }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系电话">{{ viewData.contactPhone }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出国目的">{{ viewData.purposeText }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的地">{{ viewData.destination }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的地国家">{{ viewData.destination }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开始日期">{{ formatDate((viewData as OverseasApplicationVO).startDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="结束日期">{{ formatDate((viewData as OverseasApplicationVO).endDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出国天数">{{ (viewData as OverseasApplicationVO).duration }}天</el-descriptions-item>
|
||||
@@ -391,7 +367,7 @@
|
||||
<el-descriptions-item label="所属部门">{{ viewData.department }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系电话">{{ viewData.contactPhone }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出国目的">{{ viewData.purposeText }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的地">{{ viewData.destination }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的地国家">{{ viewData.destination }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实际开始日期">{{ formatDate((viewData as OverseasRecordVO).actualStartDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实际结束日期">{{ formatDate((viewData as OverseasRecordVO).actualEndDate) }}</el-descriptions-item>
|
||||
<el-descriptions-item label="实际天数">{{ (viewData as OverseasRecordVO).actualDuration }}天</el-descriptions-item>
|
||||
@@ -546,7 +522,6 @@ const state = reactive({
|
||||
purpose: [{ required: true, message: '出国目的不能为空', trigger: 'change' }],
|
||||
purposeDetail: [{ required: true, message: '目的详细说明不能为空', trigger: 'blur' }],
|
||||
destination: [{ required: true, message: '目的地国家不能为空', trigger: 'blur' }],
|
||||
destinationCity: [{ required: true, message: '目的地不能为空', trigger: 'blur' }],
|
||||
startDate: [{ required: true, message: '开始日期不能为空', trigger: 'change' }],
|
||||
endDate: [{ required: true, message: '结束日期不能为空', trigger: 'change' }],
|
||||
budget: [{ required: true, message: '预算金额不能为空', trigger: 'blur' }],
|
||||
@@ -1062,9 +1037,8 @@ const getStatusTagType = (status: string): 'primary' | 'success' | 'info' | 'war
|
||||
|
||||
const getCompletionStatusTagType = (status: string): 'primary' | 'success' | 'info' | 'warning' | 'danger' => {
|
||||
const typeMap: Record<string, 'primary' | 'success' | 'info' | 'warning' | 'danger'> = {
|
||||
'0': 'warning', // 进行中
|
||||
'1': 'success', // 已完成
|
||||
'2': 'info' // 提前结束
|
||||
'2': 'danger' // 已拒绝
|
||||
};
|
||||
return typeMap[status] || 'info';
|
||||
};
|
||||
|
||||
@@ -1,95 +1,260 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 搜索表单 -->
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
|
||||
<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 label="审批状态" prop="approvalStatus">
|
||||
<el-select v-model="queryParams.approvalStatus" placeholder="请选择审批状态" clearable style="width: 200px">
|
||||
<el-option v-for="dict in rs_approval_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="审批人" prop="approverName">
|
||||
<el-input v-model="queryParams.approverName" 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>
|
||||
<el-card class="box-card">
|
||||
<!-- 出国审批管理选项卡 -->
|
||||
<el-tabs v-model="activeTab" type="border-card" @tab-click="handleTabClick">
|
||||
<!-- 出国审批标签页 -->
|
||||
<el-tab-pane label="出国审批" name="approval">
|
||||
<div class="tab-content">
|
||||
<!-- 搜索区域 -->
|
||||
<transition enter-active-class="animate__animated animate__fadeInDown" leave-active-class="animate__animated animate__fadeOutUp">
|
||||
<div 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="5">
|
||||
<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="5">
|
||||
<el-form-item label="审批状态" prop="approvalStatus">
|
||||
<el-select v-model="queryParams.approvalStatus" placeholder="请选择审批状态" clearable style="width: 100%">
|
||||
<el-option v-for="dict in rs_approval_status" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-form-item label="出国目的" prop="purpose">
|
||||
<el-select v-model="queryParams.purpose" placeholder="请选择出国目的" clearable style="width: 100%">
|
||||
<el-option v-for="dict in rs_overseas_purpose" :key="dict.value" :label="dict.label" :value="dict.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="9">
|
||||
<el-form-item label="审批时间">
|
||||
<el-date-picker
|
||||
v-model="dateRange"
|
||||
style="width: 100%"
|
||||
type="daterange"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
@change="handleDateRangeChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<!-- 操作按钮区域 - 位于搜索表单下方 -->
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['rs:overseas:approval:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['rs:overseas:approval:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['rs:overseas:approval:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['rs:overseas:approval:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</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-table
|
||||
v-loading="loading"
|
||||
:data="approvalList"
|
||||
@selection-change="handleSelectionChange"
|
||||
style="width: 100%"
|
||||
class="overseas-approval-table"
|
||||
:table-layout="'fixed'"
|
||||
empty-text="暂无数据"
|
||||
:header-cell-style="{ textAlign: 'center', background: '#f5f7fa', color: '#606266' }"
|
||||
:cell-style="{ textAlign: 'center' }"
|
||||
>
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column label="审批ID" align="center" prop="approvalId" min-width="100" />
|
||||
<el-table-column label="申请ID" align="center" prop="applicationId" min-width="100" />
|
||||
<el-table-column label="申请人" align="center" prop="applicantName" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="所属部门" align="center" prop="department" min-width="180" show-overflow-tooltip />
|
||||
<el-table-column label="出国目的" align="center" prop="purposeText" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column label="目的地" align="center" prop="destination" min-width="140" show-overflow-tooltip />
|
||||
<el-table-column label="天数" align="center" prop="duration" min-width="80" />
|
||||
<el-table-column label="审批人" align="center" prop="approverName" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="审批结果" align="center" prop="approvalStatus" min-width="110">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="rs_approval_status" :value="scope.row.approvalStatus" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批时间" align="center" prop="approvalTime" min-width="160" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="200" fixed="right" class-name="operation-column">
|
||||
<template #default="scope">
|
||||
<div class="operation-buttons">
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['rs:overseas:approval:query']" size="small"
|
||||
>详情</el-button
|
||||
>
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['rs:overseas:approval:edit']" size="small"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['rs:overseas:approval:remove']" size="small"
|
||||
>删除</el-button
|
||||
>
|
||||
<!-- 操作按钮区域 -->
|
||||
<el-card shadow="never" class="button-card table-card">
|
||||
<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-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 出国审批表格 -->
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
border
|
||||
:data="approvalList"
|
||||
@selection-change="handleSelectionChange"
|
||||
@row-dblclick="handleView"
|
||||
style="width: 100%"
|
||||
class="overseas-approval-table"
|
||||
empty-text="暂无数据"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="申请人" align="center" prop="applicantName" width="100" show-overflow-tooltip />
|
||||
<el-table-column label="出国目的" align="center" prop="purposeText" width="110" show-overflow-tooltip />
|
||||
<el-table-column label="目的地" align="center" prop="destination" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="出国时间" align="center" min-width="200" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.startDate && scope.row.endDate">
|
||||
{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.endDate, '{y}-{m}-{d}') }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预算金额" align="center" width="110">
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.budget">¥{{ formatMoney(scope.row.budget) }}</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批人" align="center" prop="approverName" width="120" show-overflow-tooltip />
|
||||
<el-table-column label="审批状态" align="center" prop="approvalStatus" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getApprovalStatusTagType(scope.row.approvalStatus)">
|
||||
<dict-tag :options="rs_approval_status" :value="scope.row.approvalStatus" />
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批时间" align="center" prop="approvalTime" width="160" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.approvalTime ? parseTime(scope.row.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') : '待审批' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" width="120">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['rs:overseas:query']"></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>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
<!-- 审批记录标签页 -->
|
||||
<el-tab-pane label="审批记录" name="record">
|
||||
<div class="tab-content">
|
||||
<!-- 搜索区域 -->
|
||||
<transition enter-active-class="animate__animated animate__fadeInDown" leave-active-class="animate__animated animate__fadeOutUp">
|
||||
<div v-show="showRecordSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="recordQueryForm" :model="recordQueryParams" label-width="100px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="申请人" prop="applicantName">
|
||||
<el-input
|
||||
v-model="recordQueryParams.applicantName"
|
||||
placeholder="请输入申请人姓名"
|
||||
clearable
|
||||
@keyup.enter="handleRecordQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="审批人" prop="approverName">
|
||||
<el-input
|
||||
v-model="recordQueryParams.approverName"
|
||||
placeholder="请输入审批人姓名"
|
||||
clearable
|
||||
@keyup.enter="handleRecordQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="审批状态" prop="approvalStatus">
|
||||
<el-select v-model="recordQueryParams.approvalStatus" placeholder="请选择审批状态" clearable style="width: 100%">
|
||||
<el-option v-for="dict in rs_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="handleRecordQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetRecordQuery">重置</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 :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button icon="Download" @click="handleExportRecord" v-hasPermi="['rs:overseas:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showRecordSearch" @queryTable="getRecordList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<!-- 审批记录表格 -->
|
||||
<el-table
|
||||
v-loading="recordLoading"
|
||||
border
|
||||
:data="recordList"
|
||||
@row-dblclick="handleViewRecord"
|
||||
style="width: 100%"
|
||||
empty-text="暂无数据"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="申请人" align="center" prop="applicantName" width="100" show-overflow-tooltip />
|
||||
<el-table-column label="出国目的" align="center" prop="purposeText" width="110" show-overflow-tooltip />
|
||||
<el-table-column label="目的地" align="center" prop="destination" min-width="120" show-overflow-tooltip />
|
||||
<el-table-column label="出国时间" align="center" min-width="200" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span v-if="scope.row.startDate && scope.row.endDate">
|
||||
{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }} 至 {{ parseTime(scope.row.endDate, '{y}-{m}-{d}') }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批人" align="center" prop="approverName" width="120" show-overflow-tooltip />
|
||||
<el-table-column label="审批级别" align="center" prop="approvalLevel" width="110">
|
||||
<template #default="scope">
|
||||
<dict-tag :options="rs_approval_level" :value="scope.row.approvalLevel" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批状态" align="center" prop="approvalStatus" width="120">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getApprovalStatusTagType(scope.row.approvalStatus)">
|
||||
<dict-tag :options="rs_approval_status" :value="scope.row.approvalStatus" />
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批时间" align="center" prop="approvalTime" width="160" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
<span>{{ scope.row.approvalTime ? parseTime(scope.row.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') : '待审批' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="审批意见" align="center" prop="approvalOpinion" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column label="操作" align="center" width="200">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="查看详情" placement="top">
|
||||
<el-button link type="primary" icon="View" @click="handleViewRecord(scope.row)" v-hasPermi="['rs:overseas:query']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="recordTotal > 0"
|
||||
:total="recordTotal"
|
||||
v-model:page="recordQueryParams.pageNum"
|
||||
v-model:limit="recordQueryParams.pageSize"
|
||||
@pagination="getRecordList"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改出国审批对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
@@ -137,31 +302,79 @@
|
||||
<el-descriptions-item label="所属部门">{{ detailData.department }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出国目的">{{ detailData.purposeText }}</el-descriptions-item>
|
||||
<el-descriptions-item label="目的地">{{ detailData.destination }}</el-descriptions-item>
|
||||
<el-descriptions-item label="天数">{{ detailData.duration }}</el-descriptions-item>
|
||||
<el-descriptions-item label="预算">{{ detailData.budget }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出国时间">
|
||||
<span v-if="detailData.startDate && detailData.endDate">
|
||||
{{ parseTime(detailData.startDate, '{y}-{m}-{d}') }} 至 {{ parseTime(detailData.endDate, '{y}-{m}-{d}') }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="预算金额">
|
||||
<span v-if="detailData.budget">¥{{ formatMoney(detailData.budget) }}</span>
|
||||
<span v-else>-</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批人">{{ detailData.approverName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审批级别">
|
||||
<dict-tag :options="rs_approval_level" :value="detailData.approvalLevel" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批状态">
|
||||
<dict-tag :options="rs_approval_status" :value="detailData.approvalStatus" />
|
||||
<el-tag :type="getApprovalStatusTagType(detailData.approvalStatus)">
|
||||
<dict-tag :options="rs_approval_status" :value="detailData.approvalStatus" />
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批时间">
|
||||
{{ parseTime(detailData.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
|
||||
{{ detailData.approvalTime ? parseTime(detailData.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') : '待审批' }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批意见" :span="2">{{ detailData.approvalOpinion }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审批意见" :span="2">{{ detailData.approvalOpinion || '待审批' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 审批记录详情对话框 -->
|
||||
<el-dialog title="审批记录详情" v-model="recordDetailOpen" width="800px" append-to-body>
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="审批ID">{{ recordDetailData.approvalId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请ID">{{ recordDetailData.applicationId }}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请人">{{ recordDetailData.applicantName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审批人">{{ recordDetailData.approverName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审批级别">
|
||||
<dict-tag :options="rs_approval_level" :value="recordDetailData.approvalLevel" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批状态">
|
||||
<el-tag :type="getApprovalStatusTagType(recordDetailData.approvalStatus)">
|
||||
<dict-tag :options="rs_approval_status" :value="recordDetailData.approvalStatus" />
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批时间">
|
||||
{{ parseTime(recordDetailData.approvalTime, '{y}-{m}-{d} {h}:{i}:{s}') }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="审批意见" :span="2">{{ recordDetailData.approvalOpinion }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="OverseasApproval">
|
||||
import { listOverseasApproval, getOverseasApproval, delOverseasApproval, addOverseasApproval, updateOverseasApproval } from '@/api/rs/overseas';
|
||||
import { nextTick } from 'vue';
|
||||
import {
|
||||
listOverseasApproval,
|
||||
listCombinedOverseasApproval,
|
||||
getOverseasApproval,
|
||||
delOverseasApproval,
|
||||
addOverseasApproval,
|
||||
updateOverseasApproval
|
||||
} from '@/api/rs/overseas';
|
||||
import { ref, reactive, toRefs, onMounted, getCurrentInstance, nextTick } from 'vue';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
const { rs_approval_status, rs_approval_level } = proxy.useDict('rs_approval_status', 'rs_approval_level');
|
||||
const { rs_approval_status, rs_approval_level, rs_overseas_purpose } = proxy.useDict(
|
||||
'rs_approval_status',
|
||||
'rs_approval_level',
|
||||
'rs_overseas_purpose'
|
||||
);
|
||||
|
||||
// 选项卡相关
|
||||
const activeTab = ref('approval');
|
||||
|
||||
// 出国审批相关
|
||||
const approvalList = ref([]);
|
||||
const open = ref(false);
|
||||
const detailOpen = ref(false);
|
||||
@@ -173,6 +386,15 @@ const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref('');
|
||||
const detailData = ref({});
|
||||
const dateRange = ref([]);
|
||||
|
||||
// 审批记录相关
|
||||
const recordList = ref([]);
|
||||
const recordLoading = ref(false);
|
||||
const recordTotal = ref(0);
|
||||
const showRecordSearch = ref(true);
|
||||
const recordDetailOpen = ref(false);
|
||||
const recordDetailData = ref({});
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
@@ -184,8 +406,19 @@ const data = reactive({
|
||||
approverName: null,
|
||||
approvalLevel: null,
|
||||
approvalStatus: null,
|
||||
approvalTime: null,
|
||||
applicantName: null // 新增:用于搜索申请人姓名
|
||||
approvalTimeBegin: null,
|
||||
approvalTimeEnd: null,
|
||||
applicantName: null, // 申请人姓名搜索
|
||||
purpose: null // 出国目的搜索
|
||||
},
|
||||
recordQueryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
applicantName: null,
|
||||
approverName: null,
|
||||
approvalStatus: null,
|
||||
approvalTimeBegin: null,
|
||||
approvalTimeEnd: null
|
||||
},
|
||||
rules: {
|
||||
applicationId: [{ required: true, message: '申请ID不能为空', trigger: 'blur' }],
|
||||
@@ -196,22 +429,77 @@ const data = reactive({
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
const { queryParams, recordQueryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 格式化金额 */
|
||||
function formatMoney(money) {
|
||||
if (!money) return '0.00';
|
||||
return parseFloat(money).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
||||
}
|
||||
|
||||
/** 获取审批状态标签类型 */
|
||||
function getApprovalStatusTagType(status) {
|
||||
const statusMap = {
|
||||
'0': 'warning', // 待审批
|
||||
'1': 'success', // 已通过
|
||||
'2': 'danger', // 已拒绝
|
||||
'3': 'info' // 已撤回
|
||||
};
|
||||
return statusMap[status] || 'info';
|
||||
}
|
||||
|
||||
/** 选项卡切换 */
|
||||
function handleTabClick(tab) {
|
||||
console.log('切换到选项卡:', tab.name);
|
||||
if (tab.name === 'approval') {
|
||||
getList();
|
||||
} else if (tab.name === 'record') {
|
||||
getRecordList();
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询出国审批列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listOverseasApproval(queryParams.value).then((response) => {
|
||||
console.log('response:', response);
|
||||
approvalList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
console.log('临时清空出国审批列表内容');
|
||||
|
||||
// 强制设置表格布局
|
||||
nextTick(() => {
|
||||
forceTableLayout();
|
||||
// 临时清空列表内容
|
||||
approvalList.value = [];
|
||||
total.value = 0;
|
||||
loading.value = false;
|
||||
|
||||
console.log('出国审批列表已清空');
|
||||
}
|
||||
|
||||
/** 查询审批记录列表 */
|
||||
function getRecordList() {
|
||||
recordLoading.value = true;
|
||||
// 审批记录只显示已完成的审批记录,不包含待审批申请
|
||||
listOverseasApproval(recordQueryParams.value)
|
||||
.then((response) => {
|
||||
console.log('审批记录response:', response);
|
||||
recordList.value = response.rows || [];
|
||||
recordTotal.value = response.total || 0;
|
||||
recordLoading.value = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('获取审批记录列表失败:', error);
|
||||
recordList.value = [];
|
||||
recordTotal.value = 0;
|
||||
recordLoading.value = false;
|
||||
proxy.$modal.msgError('获取审批记录失败,请稍后重试');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** 日期范围变化处理 */
|
||||
function handleDateRangeChange(dates) {
|
||||
if (dates && dates.length === 2) {
|
||||
queryParams.value.approvalTimeBegin = dates[0];
|
||||
queryParams.value.approvalTimeEnd = dates[1];
|
||||
} else {
|
||||
queryParams.value.approvalTimeBegin = null;
|
||||
queryParams.value.approvalTimeEnd = null;
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
@@ -222,23 +510,23 @@ function handleQuery() {
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
dateRange.value = [];
|
||||
queryParams.value.approvalTimeBegin = null;
|
||||
queryParams.value.approvalTimeEnd = null;
|
||||
proxy.resetForm('queryFormRef');
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
/** 强制设置表格布局为固定布局 */
|
||||
function forceTableLayout() {
|
||||
const tables = document.querySelectorAll('.overseas-approval-table table');
|
||||
tables.forEach((table) => {
|
||||
table.style.tableLayout = 'fixed';
|
||||
table.style.width = '100%';
|
||||
});
|
||||
/** 审批记录搜索按钮操作 */
|
||||
function handleRecordQuery() {
|
||||
recordQueryParams.value.pageNum = 1;
|
||||
getRecordList();
|
||||
}
|
||||
|
||||
const tableElements = document.querySelectorAll('.overseas-approval-table .el-table');
|
||||
tableElements.forEach((el) => {
|
||||
el.style.tableLayout = 'fixed';
|
||||
el.style.width = '100%';
|
||||
});
|
||||
/** 审批记录重置按钮操作 */
|
||||
function resetRecordQuery() {
|
||||
proxy.resetForm('recordQueryForm');
|
||||
handleRecordQuery();
|
||||
}
|
||||
|
||||
// 取消按钮
|
||||
@@ -289,12 +577,28 @@ function handleUpdate(row) {
|
||||
|
||||
/** 查看详情 */
|
||||
function handleView(row) {
|
||||
// 如果是待审批的申请(没有approvalId),直接显示申请信息
|
||||
if (!row.approvalId) {
|
||||
detailData.value = row;
|
||||
detailOpen.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果是已有的审批记录,查询完整信息
|
||||
getOverseasApproval(row.approvalId).then((response) => {
|
||||
detailData.value = response.data;
|
||||
detailOpen.value = true;
|
||||
});
|
||||
}
|
||||
|
||||
/** 查看审批记录详情 */
|
||||
function handleViewRecord(row) {
|
||||
getOverseasApproval(row.approvalId).then((response) => {
|
||||
recordDetailData.value = response.data;
|
||||
recordDetailOpen.value = true;
|
||||
});
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
proxy.$refs['approvalRef'].validate((valid) => {
|
||||
@@ -342,82 +646,25 @@ function handleExport() {
|
||||
);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
/** 导出审批记录 */
|
||||
function handleExportRecord() {
|
||||
proxy.download(
|
||||
'rs/overseas/approval/export',
|
||||
{
|
||||
...recordQueryParams.value
|
||||
},
|
||||
`approval_record_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
}
|
||||
|
||||
// 页面加载后强制设置表格布局
|
||||
nextTick(() => {
|
||||
forceTableLayout();
|
||||
});
|
||||
onMounted(() => {
|
||||
// 默认加载出国审批列表
|
||||
getList();
|
||||
console.log('页面加载时,当前选项卡:', activeTab.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 表格容器基础样式 */
|
||||
:deep(.overseas-approval-table) {
|
||||
width: 100% !important;
|
||||
table-layout: fixed !important;
|
||||
}
|
||||
|
||||
:deep(.overseas-approval-table .el-table__inner-wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
:deep(.overseas-approval-table .el-table__header-wrapper),
|
||||
:deep(.overseas-approval-table .el-table__body-wrapper) {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
:deep(.overseas-approval-table .el-table__header),
|
||||
:deep(.overseas-approval-table .el-table__body) {
|
||||
width: 100% !important;
|
||||
table-layout: fixed !important;
|
||||
}
|
||||
|
||||
/* 操作列样式优化 - 精确宽度控制 */
|
||||
:deep(.operation-column) {
|
||||
width: 200px !important;
|
||||
max-width: 200px !important;
|
||||
min-width: 200px !important;
|
||||
flex: 0 0 200px !important;
|
||||
padding: 8px !important;
|
||||
}
|
||||
|
||||
:deep(.operation-column .cell) {
|
||||
padding: 8px 12px !important;
|
||||
text-align: center !important;
|
||||
white-space: nowrap !important;
|
||||
overflow: visible !important;
|
||||
width: 100% !important;
|
||||
box-sizing: border-box !important;
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
}
|
||||
|
||||
/* 操作按钮容器 */
|
||||
.operation-buttons {
|
||||
display: flex !important;
|
||||
justify-content: center !important;
|
||||
align-items: center !important;
|
||||
gap: 4px !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* 操作按钮样式优化 */
|
||||
:deep(.operation-column .el-button) {
|
||||
margin: 0 !important;
|
||||
padding: 6px 10px !important;
|
||||
font-size: 12px !important;
|
||||
min-width: auto !important;
|
||||
white-space: nowrap !important;
|
||||
border-radius: 4px !important;
|
||||
}
|
||||
|
||||
:deep(.operation-column .el-button + .el-button) {
|
||||
margin-left: 4px !important;
|
||||
}
|
||||
|
||||
/* 页面容器基础样式 */
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
@@ -426,6 +673,36 @@ onMounted(() => {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 卡片样式 */
|
||||
.box-card {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/* 选项卡内容区域 */
|
||||
.tab-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* 搜索按钮容器 */
|
||||
.search-btn-container {
|
||||
text-align: left;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
/* 表格卡片样式 */
|
||||
.table-card {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.button-card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* 表格样式优化 */
|
||||
:deep(.overseas-approval-table) {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
/* 表格空数据状态样式 */
|
||||
:deep(.el-table__empty-block) {
|
||||
width: 100% !important;
|
||||
@@ -441,12 +718,6 @@ onMounted(() => {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
/* 表格固定列优化 */
|
||||
:deep(.el-table__fixed-right) {
|
||||
right: 0 !important;
|
||||
border-left: 1px solid #ebeef5 !important;
|
||||
}
|
||||
|
||||
/* 响应式布局优化 */
|
||||
@media (max-width: 1200px) {
|
||||
:deep(.overseas-approval-table .el-table__body-wrapper),
|
||||
|
||||
@@ -157,22 +157,12 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="课程名称" prop="courseName">
|
||||
<el-input
|
||||
v-model="recordQueryParams.courseName"
|
||||
placeholder="请输入课程名称"
|
||||
clearable
|
||||
@keyup.enter="handleRecordQuery"
|
||||
/>
|
||||
<el-input v-model="recordQueryParams.courseName" placeholder="请输入课程名称" clearable @keyup.enter="handleRecordQuery" />
|
||||
</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-input v-model="recordQueryParams.userName" placeholder="请输入学员姓名" clearable @keyup.enter="handleRecordQuery" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
@@ -685,7 +675,8 @@ import {
|
||||
submitTrainingApplication,
|
||||
updateApplicationStatus,
|
||||
deleteTrainingApplication,
|
||||
getTrainingApprovalHistory
|
||||
getTrainingApprovalHistory,
|
||||
resubmitTrainingApplication
|
||||
} from '@/api/rs/training';
|
||||
import { parseTime } from '@/utils/ruoyi';
|
||||
import type {
|
||||
@@ -892,6 +883,7 @@ const recordQueryParams = reactive<RecordQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
courseId: undefined as string | number | undefined,
|
||||
courseName: '',
|
||||
userName: '',
|
||||
completionStatus: '',
|
||||
params: {}
|
||||
@@ -1018,7 +1010,11 @@ function getTrainingList() {
|
||||
|
||||
/** 获取部门列表 */
|
||||
function getDepartmentList() {
|
||||
listDept({ status: '0' })
|
||||
listDept({
|
||||
pageNum: 1,
|
||||
pageSize: 1000, // 获取所有部门
|
||||
status: 0
|
||||
})
|
||||
.then((response) => {
|
||||
const deptList = response.data || [];
|
||||
// 过滤出二级学院和行政单位下的部门,作为培训部门选项
|
||||
@@ -1290,27 +1286,38 @@ function submitApplicationForm() {
|
||||
apiData.status = '0';
|
||||
}
|
||||
|
||||
// 使用更新API
|
||||
updateTrainingApplication(apiData)
|
||||
.then(async () => {
|
||||
// 如果是重新提交模式,保存后自动提交申请
|
||||
if (isResubmitMode.value) {
|
||||
await submitTrainingApplication(apiData);
|
||||
// 如果是重新提交模式,使用专门的重新提交API
|
||||
if (isResubmitMode.value) {
|
||||
resubmitTrainingApplication(applicationForm.applicationId, apiData)
|
||||
.then(() => {
|
||||
proxy?.$modal.msgSuccess('修改并重新提交成功!您的申请已重新进入审批流程。');
|
||||
isResubmitMode.value = false; // 重置重新提交模式
|
||||
} else {
|
||||
applicationDialogVisible.value = false;
|
||||
getApplicationList();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('重新提交申请失败:', error);
|
||||
proxy?.$modal.msgError(`重新提交失败: ${error.message || '服务器错误'}`);
|
||||
})
|
||||
.finally(() => {
|
||||
applicationDialogLoading.value = false;
|
||||
});
|
||||
} else {
|
||||
// 使用更新API
|
||||
updateTrainingApplication(apiData)
|
||||
.then(() => {
|
||||
proxy?.$modal.msgSuccess('申请更新成功');
|
||||
}
|
||||
applicationDialogVisible.value = false;
|
||||
getApplicationList();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('更新申请失败:', error);
|
||||
proxy?.$modal.msgError(`更新失败: ${error.message || '服务器错误'}`);
|
||||
})
|
||||
.finally(() => {
|
||||
applicationDialogLoading.value = false;
|
||||
});
|
||||
applicationDialogVisible.value = false;
|
||||
getApplicationList();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('更新申请失败:', error);
|
||||
proxy?.$modal.msgError(`更新失败: ${error.message || '服务器错误'}`);
|
||||
})
|
||||
.finally(() => {
|
||||
applicationDialogLoading.value = false;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// 新增申请
|
||||
console.log('提交的培训申请数据:', apiData); // 调试日志
|
||||
@@ -1645,7 +1652,7 @@ function remoteSearchUser(query: string) {
|
||||
function getRecordList() {
|
||||
console.log('开始加载培训记录列表');
|
||||
recordLoading.value = true;
|
||||
|
||||
|
||||
// 实际实现应该是调用API
|
||||
listTrainingRecord(recordQueryParams)
|
||||
.then((response) => {
|
||||
@@ -2064,12 +2071,12 @@ function forceReinitialize() {
|
||||
console.log('强制重新初始化组件状态');
|
||||
isInitialized.value = false;
|
||||
isDataLoaded.value = false;
|
||||
|
||||
|
||||
// 重置关键状态
|
||||
courseOptions.value = [];
|
||||
recordList.value = [];
|
||||
applicationList.value = [];
|
||||
|
||||
|
||||
// 重新加载当前选项卡数据
|
||||
if (trainingSubTab.value === 'application') {
|
||||
getApplicationList();
|
||||
@@ -2085,7 +2092,7 @@ function forceReinitialize() {
|
||||
// 新增:activated生命周期钩子 - 处理Keep-Alive缓存激活
|
||||
onActivated(() => {
|
||||
console.log('组件被激活,重新加载当前选项卡数据');
|
||||
|
||||
|
||||
// 直接重新加载当前选项卡的数据,不依赖复杂的状态判断
|
||||
if (trainingSubTab.value === 'application') {
|
||||
console.log('重新加载培训申请数据');
|
||||
@@ -2097,14 +2104,14 @@ onActivated(() => {
|
||||
console.log('重新加载培训课程数据');
|
||||
getTrainingList();
|
||||
}
|
||||
|
||||
|
||||
// 同时加载课程选项,确保下拉选项可用
|
||||
loadCourseOptions();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
console.log('组件挂载,开始初始化');
|
||||
|
||||
|
||||
// 采用培训审批页面的成功模式:同时加载所有数据
|
||||
getTrainingList();
|
||||
getApplicationList();
|
||||
|
||||
@@ -12,28 +12,33 @@
|
||||
班级信息管理模块提供完整的班级信息管理功能,包括:
|
||||
|
||||
### 📊 统计概览
|
||||
|
||||
- 总班级数统计
|
||||
- 正常班级数统计
|
||||
- 总学生数统计
|
||||
- 平均学生数统计
|
||||
|
||||
### 🔍 查询功能
|
||||
|
||||
- 班级代码、班级名称模糊查询
|
||||
- 年级、学院、专业级联查询
|
||||
- 班级类型、班级状态筛选
|
||||
- 班主任姓名查询
|
||||
|
||||
### 📝 基础管理
|
||||
|
||||
- 班级信息新增、修改、删除
|
||||
- 班级信息详情查看
|
||||
- 班级信息批量导出
|
||||
|
||||
### 👥 人员配置
|
||||
|
||||
- 班主任、辅导员配置
|
||||
- 班干部信息管理(班长、学习委员、生活委员等)
|
||||
- 联系方式管理
|
||||
|
||||
### 📈 统计功能
|
||||
|
||||
- 学生数量统计更新
|
||||
- 批量统计刷新
|
||||
- 实时数据同步
|
||||
@@ -41,12 +46,14 @@
|
||||
## 🎨 页面设计
|
||||
|
||||
### 页面布局
|
||||
|
||||
- **搜索区域**: 8个搜索条件,支持组合查询
|
||||
- **统计卡片**: 4个统计指标,渐变色彩设计
|
||||
- **表格区域**: 完整的班级信息展示
|
||||
- **操作按钮**: 查看、编辑、删除、统计更新
|
||||
|
||||
### 对话框设计
|
||||
|
||||
- **新增/编辑**: 分页签设计(基本信息、人员配置、联系方式)
|
||||
- **详情查看**: 描述列表展示完整信息
|
||||
- **响应式布局**: 适配不同屏幕尺寸
|
||||
@@ -54,18 +61,21 @@
|
||||
## 🔧 技术特性
|
||||
|
||||
### 前端技术
|
||||
|
||||
- **Vue 3.5.13** + **TypeScript 5.8.3**
|
||||
- **Element Plus** UI组件库
|
||||
- **Composition API** 组合式API
|
||||
- **响应式设计** 适配多端
|
||||
|
||||
### 样式设计
|
||||
|
||||
- **参考后勤管理模块** 保持风格一致
|
||||
- **渐变色卡片** 美观的统计展示
|
||||
- **悬停效果** 良好的交互体验
|
||||
- **操作按钮** 图标化设计
|
||||
|
||||
### 数据处理
|
||||
|
||||
- **级联选择** 学院-专业联动
|
||||
- **表单验证** 完整的输入校验
|
||||
- **状态管理** 响应式数据更新
|
||||
@@ -76,6 +86,7 @@
|
||||
### 16个标准API接口
|
||||
|
||||
#### 基础CRUD接口
|
||||
|
||||
1. `GET /list` - 查询班级信息列表
|
||||
2. `POST /export` - 导出班级信息列表
|
||||
3. `GET /{id}` - 获取班级信息详情
|
||||
@@ -84,6 +95,7 @@
|
||||
6. `DELETE /{ids}` - 删除班级信息
|
||||
|
||||
#### 业务查询接口
|
||||
|
||||
7. `GET /getByClassCode/{classCode}` - 根据班级代码查询
|
||||
8. `GET /getByGrade/{grade}` - 根据年级查询
|
||||
9. `GET /getByCollegeCode/{collegeCode}` - 根据学院代码查询
|
||||
@@ -92,6 +104,7 @@
|
||||
12. `GET /getByClassTeacherId/{classTeacherId}` - 根据班主任ID查询
|
||||
|
||||
#### 辅助功能接口
|
||||
|
||||
13. `GET /getClassOptions` - 获取班级选项列表
|
||||
14. `POST /updateStudentCount/{id}` - 更新班级学生统计
|
||||
15. `POST /batchUpdateStudentCount` - 批量更新学生统计
|
||||
@@ -100,6 +113,7 @@
|
||||
## 🎯 权限控制
|
||||
|
||||
### 权限编码
|
||||
|
||||
- `xg:classInfo:list` - 班级信息查询
|
||||
- `xg:classInfo:query` - 班级信息详情
|
||||
- `xg:classInfo:add` - 班级信息新增
|
||||
@@ -108,6 +122,7 @@
|
||||
- `xg:classInfo:export` - 班级信息导出
|
||||
|
||||
### 按钮权限
|
||||
|
||||
- 所有操作按钮都配置了对应的权限控制
|
||||
- 使用 `v-hasPermi` 指令进行权限验证
|
||||
- 无权限时自动隐藏相关按钮
|
||||
@@ -115,24 +130,28 @@
|
||||
## 📊 数据字典
|
||||
|
||||
### 班级类型 (xg_class_type)
|
||||
|
||||
- `regular` - 普通班级
|
||||
- `honor` - 荣誉班级
|
||||
- `experimental` - 实验班级
|
||||
- `special` - 特殊班级
|
||||
|
||||
### 班级状态 (xg_class_status)
|
||||
|
||||
- `1` - 正常
|
||||
- `2` - 暂停
|
||||
- `3` - 毕业
|
||||
- `4` - 解散
|
||||
|
||||
### 年级选项 (xg_grade_options)
|
||||
|
||||
- 支持动态配置年级选项
|
||||
- 适配不同学制需求
|
||||
|
||||
## 🔄 数据流程
|
||||
|
||||
### 查询流程
|
||||
|
||||
1. 用户输入查询条件
|
||||
2. 前端组装查询参数
|
||||
3. 调用列表查询API
|
||||
@@ -140,6 +159,7 @@
|
||||
5. 前端渲染表格和统计
|
||||
|
||||
### 新增/修改流程
|
||||
|
||||
1. 用户填写表单信息
|
||||
2. 前端表单验证
|
||||
3. 调用新增/修改API
|
||||
@@ -148,6 +168,7 @@
|
||||
6. 刷新列表和统计
|
||||
|
||||
### 统计更新流程
|
||||
|
||||
1. 用户点击统计更新
|
||||
2. 调用统计更新API
|
||||
3. 后端重新计算学生数
|
||||
@@ -157,18 +178,21 @@
|
||||
## 🎨 样式规范
|
||||
|
||||
### 色彩设计
|
||||
|
||||
- **主色调**: 蓝色系 (#409eff)
|
||||
- **统计卡片**: 渐变色设计
|
||||
- **状态标签**: 语义化颜色
|
||||
- **交互效果**: 悬停和点击反馈
|
||||
|
||||
### 布局规范
|
||||
|
||||
- **页面间距**: 8px 外边距
|
||||
- **组件间距**: 10px 组件间距
|
||||
- **表格样式**: 斑马纹和悬停效果
|
||||
- **按钮样式**: 图标化小按钮
|
||||
|
||||
### 响应式设计
|
||||
|
||||
- **搜索区域**: 4列布局,支持响应式
|
||||
- **统计卡片**: 4列布局,移动端自适应
|
||||
- **表格列**: 固定宽度和自适应结合
|
||||
@@ -177,6 +201,7 @@
|
||||
## 📝 使用说明
|
||||
|
||||
### 基本操作
|
||||
|
||||
1. **查询班级**: 使用搜索条件筛选班级信息
|
||||
2. **新增班级**: 点击"新增班级"按钮,填写班级信息
|
||||
3. **修改班级**: 点击表格行的"编辑"按钮
|
||||
@@ -184,12 +209,14 @@
|
||||
5. **删除班级**: 选择班级后点击"删除"按钮
|
||||
|
||||
### 高级功能
|
||||
|
||||
1. **批量操作**: 选择多个班级进行批量删除
|
||||
2. **导出数据**: 根据查询条件导出Excel文件
|
||||
3. **统计更新**: 手动更新班级学生统计数据
|
||||
4. **级联查询**: 学院-专业联动查询
|
||||
|
||||
### 注意事项
|
||||
|
||||
- 班级代码必须唯一,系统会自动校验
|
||||
- 删除班级前请确认该班级下无学生信息
|
||||
- 统计数据会定期自动更新,也可手动刷新
|
||||
@@ -198,12 +225,14 @@
|
||||
## 🚀 扩展功能
|
||||
|
||||
### 计划功能
|
||||
|
||||
- 班级学生管理集成
|
||||
- 班级活动管理
|
||||
- 班级成绩统计
|
||||
- 班级考勤管理
|
||||
|
||||
### 技术优化
|
||||
|
||||
- 虚拟滚动优化大数据量
|
||||
- 缓存机制提升查询性能
|
||||
- 实时数据推送
|
||||
@@ -214,4 +243,4 @@
|
||||
**📅 创建时间**: 2025-01-01
|
||||
**👨💻 开发者**: Cursor AI
|
||||
**📝 版本**: v1.0.0
|
||||
**🔄 更新**: 持续迭代中
|
||||
**🔄 更新**: 持续迭代中
|
||||
@@ -59,12 +59,7 @@
|
||||
<el-col :span="6">
|
||||
<el-form-item label="班主任" prop="classTeacherId">
|
||||
<el-select v-model="queryParams.classTeacherId" placeholder="请选择班主任" clearable style="width: 100%">
|
||||
<el-option
|
||||
v-for="teacher in classTeacherOptions"
|
||||
:key="teacher.value"
|
||||
:label="teacher.label"
|
||||
:value="teacher.value"
|
||||
/>
|
||||
<el-option v-for="teacher in classTeacherOptions" :key="teacher.value" :label="teacher.label" :value="teacher.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@@ -668,7 +663,6 @@ const getList = async () => {
|
||||
total: total.value,
|
||||
listLength: classInfoList.value.length
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('获取列表失败:', error);
|
||||
classInfoList.value = [];
|
||||
@@ -697,11 +691,11 @@ const getOptions = async () => {
|
||||
console.log('部门树根节点数量:', rootDepts.length);
|
||||
|
||||
// 处理每个一级部门
|
||||
rootDepts.forEach(rootDept => {
|
||||
rootDepts.forEach((rootDept) => {
|
||||
console.log(`处理一级部门: ${rootDept.label}, ID: ${rootDept.id}`);
|
||||
// 处理一级部门下的二级学院
|
||||
if (rootDept.children && rootDept.children.length > 0) {
|
||||
rootDept.children.forEach(child => {
|
||||
rootDept.children.forEach((child) => {
|
||||
// 确保ID是有效的数字
|
||||
const childId = child.id;
|
||||
if (childId && !isNaN(Number(childId))) {
|
||||
@@ -805,7 +799,7 @@ const handleCollegeChange = async (deptId: string | number) => {
|
||||
// 处理响应数据
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
// 转换为选项格式
|
||||
const deptMajors = res.data.map(dept => {
|
||||
const deptMajors = res.data.map((dept) => {
|
||||
// 确保使用数字类型的ID
|
||||
const majorId = Number(dept.deptId);
|
||||
console.log(`专业选项: ${dept.deptName}, ID: ${majorId}`);
|
||||
@@ -856,7 +850,7 @@ const handleFormCollegeChange = async (deptId: string | number) => {
|
||||
// 处理响应数据
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
// 转换为选项格式
|
||||
const deptMajors = res.data.map(dept => {
|
||||
const deptMajors = res.data.map((dept) => {
|
||||
// 确保使用数字类型的ID
|
||||
const majorId = Number(dept.deptId);
|
||||
console.log(`表单专业选项: ${dept.deptName}, ID: ${majorId}`);
|
||||
@@ -889,7 +883,7 @@ const handleFormCollegeChange = async (deptId: string | number) => {
|
||||
|
||||
/** 专业变更处理 */
|
||||
const handleMajorChange = (majorCode: string | number) => {
|
||||
const selectedMajor = formMajorOptions.value.find(option => option.value === Number(majorCode));
|
||||
const selectedMajor = formMajorOptions.value.find((option) => option.value === Number(majorCode));
|
||||
form.value.majorName = selectedMajor ? selectedMajor.label : '';
|
||||
console.log('专业变更,选择专业:', majorCode, '专业名称:', form.value.majorName);
|
||||
};
|
||||
@@ -898,7 +892,7 @@ const handleMajorChange = (majorCode: string | number) => {
|
||||
/** 班主任变更处理 */
|
||||
const handleClassTeacherChange = (teacherId: string | number) => {
|
||||
form.value.classTeacherId = teacherId;
|
||||
const selectedTeacher = classTeacherOptions.value.find(option => option.value === teacherId);
|
||||
const selectedTeacher = classTeacherOptions.value.find((option) => option.value === teacherId);
|
||||
form.value.classTeacherName = selectedTeacher ? selectedTeacher.label : '';
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ web/src/views/xg-xx/collectionBatch/
|
||||
## 🎯 功能特性
|
||||
|
||||
### 1. 批次列表管理
|
||||
|
||||
- ✅ 批次列表展示(支持分页)
|
||||
- ✅ 多条件搜索过滤
|
||||
- ✅ 批次状态和类型标签展示
|
||||
@@ -33,24 +34,28 @@ web/src/views/xg-xx/collectionBatch/
|
||||
- ✅ 批次操作(新增、编辑、删除)
|
||||
|
||||
### 2. 批次表单管理
|
||||
|
||||
- ✅ 批次新增和编辑
|
||||
- ✅ 分组表单设计(基本信息、时间设置、目标设置等)
|
||||
- ✅ 表单验证
|
||||
- ✅ 保存和发布功能
|
||||
|
||||
### 3. 批次详情查看
|
||||
|
||||
- ✅ 批次详细信息展示
|
||||
- ✅ 卡片式布局
|
||||
- ✅ 实时状态更新
|
||||
- ✅ 批次操作按钮
|
||||
|
||||
### 4. 统计分析
|
||||
|
||||
- ✅ 批次统计数据展示
|
||||
- ✅ 图表可视化(ECharts)
|
||||
- ✅ 学院完成情况统计
|
||||
- ✅ 多维度数据分析
|
||||
|
||||
### 5. 权限配置
|
||||
|
||||
- ✅ 角色权限管理
|
||||
- ✅ 批量权限配置
|
||||
- ✅ 权限有效期设置
|
||||
@@ -68,6 +73,7 @@ web/src/views/xg-xx/collectionBatch/
|
||||
## 📦 组件说明
|
||||
|
||||
### BatchStatusTag.vue
|
||||
|
||||
批次状态标签组件,用于显示批次的当前状态。
|
||||
|
||||
```vue
|
||||
@@ -75,11 +81,13 @@ web/src/views/xg-xx/collectionBatch/
|
||||
```
|
||||
|
||||
**Props:**
|
||||
|
||||
- `status`: 批次状态(draft, published, active, paused, ended, archived)
|
||||
- `showIcon`: 是否显示图标
|
||||
- `effect`: 标签效果(dark, light, plain)
|
||||
|
||||
### BatchTypeTag.vue
|
||||
|
||||
批次类型标签组件,用于显示批次的类型。
|
||||
|
||||
```vue
|
||||
@@ -87,11 +95,13 @@ web/src/views/xg-xx/collectionBatch/
|
||||
```
|
||||
|
||||
**Props:**
|
||||
|
||||
- `type`: 批次类型(student_info, scholarship, evaluation, other)
|
||||
- `showIcon`: 是否显示图标
|
||||
- `effect`: 标签效果
|
||||
|
||||
### ProgressBar.vue
|
||||
|
||||
进度条组件,用于显示批次的完成进度。
|
||||
|
||||
```vue
|
||||
@@ -99,6 +109,7 @@ web/src/views/xg-xx/collectionBatch/
|
||||
```
|
||||
|
||||
**Props:**
|
||||
|
||||
- `current`: 当前完成数量
|
||||
- `total`: 总数量
|
||||
- `strokeWidth`: 进度条宽度
|
||||
@@ -106,6 +117,7 @@ web/src/views/xg-xx/collectionBatch/
|
||||
- `showDetail`: 是否显示详细信息
|
||||
|
||||
### BatchActions.vue
|
||||
|
||||
批次操作组件,提供批次相关的操作按钮。
|
||||
|
||||
```vue
|
||||
@@ -113,9 +125,11 @@ web/src/views/xg-xx/collectionBatch/
|
||||
```
|
||||
|
||||
**Props:**
|
||||
|
||||
- `batch`: 批次数据对象
|
||||
|
||||
**Events:**
|
||||
|
||||
- `start`: 开始批次
|
||||
- `pause`: 暂停批次
|
||||
- `resume`: 恢复批次
|
||||
@@ -127,6 +141,7 @@ web/src/views/xg-xx/collectionBatch/
|
||||
- `delete`: 删除批次
|
||||
|
||||
### SearchForm.vue
|
||||
|
||||
搜索表单组件,用于批次列表的搜索过滤。
|
||||
|
||||
```vue
|
||||
@@ -134,6 +149,7 @@ web/src/views/xg-xx/collectionBatch/
|
||||
```
|
||||
|
||||
**Events:**
|
||||
|
||||
- `search`: 搜索事件,返回查询参数
|
||||
- `reset`: 重置事件
|
||||
|
||||
@@ -142,16 +158,19 @@ web/src/views/xg-xx/collectionBatch/
|
||||
### 1. 批次管理流程
|
||||
|
||||
1. **创建批次**
|
||||
|
||||
- 点击"新增批次"按钮
|
||||
- 填写批次基本信息、时间设置、目标设置等
|
||||
- 保存草稿或直接发布
|
||||
|
||||
2. **管理批次**
|
||||
|
||||
- 在列表中查看批次状态和进度
|
||||
- 使用搜索功能快速定位批次
|
||||
- 通过操作按钮管理批次状态
|
||||
|
||||
3. **查看统计**
|
||||
|
||||
- 进入统计页面查看批次数据
|
||||
- 查看图表分析和学院完成情况
|
||||
- 导出统计报告
|
||||
@@ -248,14 +267,17 @@ getOverallStatistics(): Promise<any>
|
||||
### 常见问题
|
||||
|
||||
1. **页面无法访问**
|
||||
|
||||
- 检查路由配置是否正确
|
||||
- 确认用户权限是否充足
|
||||
|
||||
2. **数据加载失败**
|
||||
|
||||
- 检查 API 接口是否正常
|
||||
- 确认后端服务是否启动
|
||||
|
||||
3. **图表显示异常**
|
||||
|
||||
- 检查 ECharts 是否正确引入
|
||||
- 确认数据格式是否正确
|
||||
|
||||
@@ -282,4 +304,4 @@ getOverallStatistics(): Promise<any>
|
||||
|
||||
**版本信息**:V1.0.0
|
||||
**更新时间**:2025-01-17
|
||||
**维护团队**:前端开发组
|
||||
**维护团队**:前端开发组
|
||||
@@ -7,55 +7,17 @@
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-if="batch.batchStatus === 'draft'"
|
||||
command="start"
|
||||
icon="VideoPlay"
|
||||
>
|
||||
开始批次
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="batch.batchStatus === 'active'"
|
||||
command="pause"
|
||||
icon="VideoPause"
|
||||
>
|
||||
暂停批次
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="batch.batchStatus === 'paused'"
|
||||
command="resume"
|
||||
icon="VideoPlay"
|
||||
>
|
||||
恢复批次
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-if="['active', 'paused'].includes(batch.batchStatus)"
|
||||
command="end"
|
||||
icon="VideoCamera"
|
||||
>
|
||||
结束批次
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item v-if="batch.batchStatus === 'draft'" command="start" icon="VideoPlay"> 开始批次 </el-dropdown-item>
|
||||
<el-dropdown-item v-if="batch.batchStatus === 'active'" command="pause" icon="VideoPause"> 暂停批次 </el-dropdown-item>
|
||||
<el-dropdown-item v-if="batch.batchStatus === 'paused'" command="resume" icon="VideoPlay"> 恢复批次 </el-dropdown-item>
|
||||
<el-dropdown-item v-if="['active', 'paused'].includes(batch.batchStatus)" command="end" icon="VideoCamera"> 结束批次 </el-dropdown-item>
|
||||
<el-dropdown-item divided />
|
||||
<el-dropdown-item command="copy" icon="CopyDocument">
|
||||
复制批次
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="statistics" icon="TrendCharts">
|
||||
统计分析
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="permission" icon="Lock">
|
||||
权限配置
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="copy" icon="CopyDocument"> 复制批次 </el-dropdown-item>
|
||||
<el-dropdown-item command="statistics" icon="TrendCharts"> 统计分析 </el-dropdown-item>
|
||||
<el-dropdown-item command="permission" icon="Lock"> 权限配置 </el-dropdown-item>
|
||||
<el-dropdown-item divided />
|
||||
<el-dropdown-item command="export" icon="Download">
|
||||
导出数据
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
command="delete"
|
||||
icon="Delete"
|
||||
style="color: #f56c6c"
|
||||
>
|
||||
删除批次
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="export" icon="Download"> 导出数据 </el-dropdown-item>
|
||||
<el-dropdown-item command="delete" icon="Delete" style="color: #f56c6c"> 删除批次 </el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
|
||||
@@ -46,7 +46,7 @@ const typeConfig = {
|
||||
};
|
||||
|
||||
const tagType = computed(() => {
|
||||
return typeConfig[props.type as keyof typeof typeConfig]?.type as 'primary' | 'success' | 'warning' | 'info' | 'danger' || 'info';
|
||||
return (typeConfig[props.type as keyof typeof typeConfig]?.type as 'primary' | 'success' | 'warning' | 'info' | 'danger') || 'info';
|
||||
});
|
||||
|
||||
const typeText = computed(() => {
|
||||
|
||||
@@ -1,12 +1,6 @@
|
||||
<template>
|
||||
<div class="progress-container">
|
||||
<el-progress
|
||||
:percentage="percentage"
|
||||
:stroke-width="strokeWidth"
|
||||
:color="progressColor"
|
||||
:show-text="showText"
|
||||
:format="format"
|
||||
/>
|
||||
<el-progress :percentage="percentage" :stroke-width="strokeWidth" :color="progressColor" :show-text="showText" :format="format" />
|
||||
<div v-if="showDetail" class="progress-detail">
|
||||
<span class="detail-text">{{ current }}/{{ total }}</span>
|
||||
<span v-if="showRate" class="rate-text">({{ percentage.toFixed(1) }}%)</span>
|
||||
|
||||
@@ -4,22 +4,12 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="批次名称" prop="batchName">
|
||||
<el-input
|
||||
v-model="searchForm.batchName"
|
||||
placeholder="请输入批次名称"
|
||||
clearable
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<el-input v-model="searchForm.batchName" placeholder="请输入批次名称" clearable @keyup.enter="handleSearch" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="批次编码" prop="batchCode">
|
||||
<el-input
|
||||
v-model="searchForm.batchCode"
|
||||
placeholder="请输入批次编码"
|
||||
clearable
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<el-input v-model="searchForm.batchCode" placeholder="请输入批次编码" clearable @keyup.enter="handleSearch" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
@@ -49,22 +39,12 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="学年学期" prop="academicYear">
|
||||
<el-input
|
||||
v-model="searchForm.academicYear"
|
||||
placeholder="请输入学年学期"
|
||||
clearable
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<el-input v-model="searchForm.academicYear" placeholder="请输入学年学期" clearable @keyup.enter="handleSearch" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-form-item label="目标届别" prop="targetGrades">
|
||||
<el-input
|
||||
v-model="searchForm.targetGrades"
|
||||
placeholder="请输入目标届别"
|
||||
clearable
|
||||
@keyup.enter="handleSearch"
|
||||
/>
|
||||
<el-input v-model="searchForm.targetGrades" placeholder="请输入目标届别" clearable @keyup.enter="handleSearch" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
|
||||
Loaded 100 of 159 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user