From 876a3314873185d60a4c0c6d59ac51d34f3616d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=84=E9=94=90=E6=B3=A2?= <10549902+zhuangruibo@user.noreply.gitee.com> Date: Fri, 26 Jun 2026 19:14:11 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E8=AE=A1=E5=88=92bug=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../enforcement/AppEnfCpTaskController.java | 16 + .../domain/vo/EfcodeCpTaskVo.java | 6 + .../service/IEfcodeCpTaskService.java | 8 + .../service/impl/EfcodeCpTaskServiceImpl.java | 64 ++++ .../enforcementcode/EfcodeCpTaskMapper.xml | 4 +- .../src/api/enforcement/task.js | 3 + .../my/reserve/cp_reserve_manual.vue | 329 ++++++++++-------- .../enforcement/my/task/cp_task_mine.vue | 175 ++++++++-- .../src/main/resources/application-prod.yml | 4 +- 9 files changed, 424 insertions(+), 185 deletions(-) diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java index 4d1af96e..7b36f279 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpTaskController.java @@ -12,6 +12,8 @@ import org.springframework.web.bind.annotation.*; import java.util.Date; import java.util.List; +import java.util.Map; +import java.util.Arrays; /** * 行政执法检查计划-任务 @@ -70,4 +72,18 @@ public class AppEnfCpTaskController extends EfcodeCpTaskController { EfcodeCpTaskVo detail = cpTaskService.queryMyTaskDetail(planId); return R.ok(detail); } + + /** + * 批量查询任务列表中联合执法任务的关联单位信息(第二次请求) + * + * @param planIds 计划ID列表,逗号分隔 + * @return Map: key=planId, value=关联的其他单位计划信息 + */ + @GetMapping("/myListAssociatedPlans") + public R>> myListAssociatedPlans( + @RequestParam String planIds) { + List planIdList = Arrays.asList(planIds.split(",")); + Map> result = cpTaskService.queryAssociatedPlansBatch(planIdList); + return R.ok(result); + } } diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java index d2841009..98e2c47e 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java @@ -103,6 +103,12 @@ public class EfcodeCpTaskVo implements Serializable { @com.baomidou.mybatisplus.annotation.TableField(exist = false) private String enforceUserNames; + /** + * 执法人员电话(多个逗号分隔) + */ + @com.baomidou.mybatisplus.annotation.TableField(exist = false) + private String enforceUserTels; + /** * 被检查企业/机构信用代码 */ diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java index 0b6d7909..3e3ce9b1 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpTaskService.java @@ -95,6 +95,14 @@ public interface IEfcodeCpTaskService { */ EfcodeCpTaskVo queryMyTaskDetail(String planId); + /** + * 批量查询关联计划信息(用于列表页第二次请求加载联合执法关联单位信息) + * + * @param planIds 计划ID列表(通常为isUnion=1的任务对应的planId) + * @return Map: key=planId, value=该计划关联的其他单位信息 + */ + java.util.Map> queryAssociatedPlansBatch(List planIds); + /** * 强制创建任务(忽略其他条件),根据计划信息直接生成任务记录并回写 plan.task_id * diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java index 6cd89991..9f51f32d 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java +++ b/zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java @@ -21,8 +21,10 @@ import com.zdxt.enforcementcode.service.IEfcodeCpTaskService; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.ArrayList; import java.util.Collection; +import java.util.stream.Collectors; /** * 行政执法检查计划-任务Service业务层处理 @@ -180,6 +182,68 @@ public class EfcodeCpTaskServiceImpl implements IEfcodeCpTaskService { return detail; } + /** + * 批量查询关联计划信息(用于列表页第二次请求加载联合执法关联单位信息) + */ + @Override + public Map> queryAssociatedPlansBatch(List planIds) { + Map> result = new HashMap<>(); + if (planIds == null || planIds.isEmpty()) { + return result; + } + // 1. 查询这些planId对应的计划,获取各自的taskId + List sourcePlans = cpPlanMapper.selectList( + Wrappers.lambdaQuery() + .in(EfcodeCpPlan::getId, planIds) + .eq(EfcodeCpPlan::getIsDelete, 0L) + .isNotNull(EfcodeCpPlan::getTaskId) + ); + if (sourcePlans == null || sourcePlans.isEmpty()) { + return result; + } + // 2. 收集所有taskId,并建立 planId -> taskId 的映射 + Map planToTask = new HashMap<>(); + List taskIds = new ArrayList<>(); + for (EfcodeCpPlan p : sourcePlans) { + planToTask.put(p.getId(), p.getTaskId()); + if (!taskIds.contains(p.getTaskId())) { + taskIds.add(p.getTaskId()); + } + } + // 3. 查询所有相关taskId下的计划(排除当前用户的planId) + List allRelatedPlans = cpPlanMapper.selectList( + Wrappers.lambdaQuery() + .in(EfcodeCpPlan::getTaskId, taskIds) + .notIn(EfcodeCpPlan::getId, planIds) + .eq(EfcodeCpPlan::getIsDelete, 0L) + ); + if (allRelatedPlans == null || allRelatedPlans.isEmpty()) { + return result; + } + // 4. 按taskId分组 + Map> groupedByTask = allRelatedPlans.stream() + .collect(Collectors.groupingBy(EfcodeCpPlan::getTaskId)); + // 5. 映射回各planId + for (Map.Entry entry : planToTask.entrySet()) { + String planId = entry.getKey(); + String taskId = entry.getValue(); + List otherPlans = groupedByTask.get(taskId); + if (otherPlans != null && !otherPlans.isEmpty()) { + List associated = new ArrayList<>(); + for (EfcodeCpPlan p : otherPlans) { + EfcodeCpTaskVo.AssociatedPlan ap = new EfcodeCpTaskVo.AssociatedPlan(); + ap.setBureauDeptName(p.getBureauDeptName()); + ap.setEnforceUserNames(p.getEnforceUserNames()); + ap.setEnforceUserTels(p.getEnforceUserTels()); + ap.setEnforceContent(p.getEnforceContent()); + associated.add(ap); + } + result.put(planId, associated); + } + } + return result; + } + /** * 强制创建任务(忽略其他条件),根据计划信息直接生成任务记录并回写 plan.task_id * diff --git a/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml index 5d776672..4fd185fe 100644 --- a/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml +++ b/zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml @@ -16,7 +16,9 @@ p.enforce_content, p.enterprise_name, p.is_union, - p.bureau_dept_name + p.bureau_dept_name, + p.enforce_user_names, + p.enforce_user_tels FROM efcode_cp_task t INNER JOIN efcode_cp_plan p ON p.task_id = t.id diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/task.js b/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/task.js index 4b42f453..1b276b10 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/task.js +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/task.js @@ -13,4 +13,7 @@ export const getMyTaskDates = (yearMonth, success, error) => _get(taskBaseUrl + // 我的任务详情(通过 planId 查询) export const getMyTaskDetail = (planId, success, error) => _get(taskBaseUrl + "/myDetail", { planId }, success, error); +// 批量查询联合执法任务的关联单位信息(第二次请求) +export const getMyTaskAssociatedPlans = (planIds, success, error) => _get(taskBaseUrl + "/myListAssociatedPlans", { planIds }, success, error); + // endregion diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue index 942cedb0..9a97e618 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_manual.vue @@ -25,8 +25,7 @@ v-for="item in reserveList" :key="item.id" class="reserve-card" - :class="{ 'approved-card': item.opStatus === 1, 'rejected-card': item.opStatus === 2, 'pending-card': item.opStatus === 3, 'selected-card': selectedId === item.id }" - @click="onSelectCard(item)" + :class="{ 'approved-card': item.opStatus === 1, 'rejected-card': item.opStatus === 2, 'pending-card': item.opStatus === 3 }" >
@@ -38,76 +37,60 @@
-
-
预约单位
-
-
-
执法单位:
-
{{ item.bureauDeptName || '-' }}
-
-
-
执法人员:
-
{{ item.enforceUserNames || '-' }}
-
-
-
联系电话:
-
{{ item.enforceUserTels || '-' }}
-
-
-
计划时间:
-
{{ formatPlanDate(item.planDate) }} {{ getPlanTimeText(item.planTime) }}
-
-
-
企业名称:
-
{{ item.enterpriseName || '-' }}
-
-
-
执法事项:
-
{{ item.enforceContent || '-' }}
-
-
+
+
+ 预约单位 +
+
{{ item.enterpriseName || item.bureauDeptName || '-' }}
+
{{ formatPlanDate(item.planDate) }} {{ getPlanTimeText(item.planTime) }}
+
+
+
执法单位:
+
{{ item.bureauDeptName || '-' }}
+
+
+
执法人员:
+
{{ item.enforceUserNames || '-' }}
+
+
+
执法事项:
+
{{ item.enforceContent || '-' }}
-
-
被约单位
-
-
-
执法单位:
-
{{ item.targetBureauDeptName || '-' }}
-
-
-
执法人员:
-
{{ item.targetEnforceUserNames || '-' }}
-
-
-
联系电话:
-
{{ item.targetEnforceUserTels || '-' }}
-
-
-
计划时间:
-
{{ formatPlanDate(item.targetPlanDate) }} {{ getPlanTimeText(item.targetPlanTime) }}
-
-
-
企业名称:
-
{{ item.targetEnterpriseName || '-' }}
-
-
-
执法事项:
-
{{ item.targetEnforceContent || '-' }}
-
-
+
+
+ 被约单位 +
+
{{ item.targetEnterpriseName || item.targetBureauDeptName || '-' }}
+
联合单位
+
+
+
执法单位:
+
{{ item.targetBureauDeptName || '-' }}
+
+
+
执法人员:
+
{{ item.targetEnforceUserNames || '-' }}
+
+
+
执法事项:
+
{{ item.targetEnforceContent || '-' }}
+
+
+
计划时间:
+
{{ formatPlanDate(item.targetPlanDate) }} {{ getPlanTimeText(item.targetPlanTime) }}
-
+
预约时间:
{{ formatDate(item.reserveTime) }}
- -
+ +
@@ -141,7 +124,6 @@ import { getReserveList, approveReserveByManual, rejectReserveByManual } from '@ import useCommon from '@/store/Common.js'; const commonStore = useCommon(); -const selectedId = ref(null); const reserveList = ref([]); const loading = ref(false); const finished = ref(false); @@ -205,13 +187,10 @@ const isSentByMe = (item) => { return String(item.senderId) === String(commonStore.userId); }; -// 选中卡片(再次点击取消选中) -const onSelectCard = (item) => { - if (item.opStatus !== 3 || isSentByMe(item)) return; // 非待确认或我发起的不可选 - selectedId.value = selectedId.value === item.id ? null : item.id; +// 操作后置处理 +const afterOperate = (item, action) => { + onRefresh(); }; - -// 下拉刷新 const onRefresh = () => { pageNum.value = 1; finished.value = false; @@ -304,13 +283,6 @@ const onReject = (item) => { }); }).catch(() => {}); }; - -// 操作后置处理 -const afterOperate = (item, action) => { - // TODO: 可在此处扩展后置逻辑,如通知、跳转等 - selectedId.value = null; - onRefresh(); -}; diff --git a/zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-prod.yml b/zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-prod.yml index cff7af61..0cd1e35e 100644 --- a/zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-prod.yml +++ b/zdxt-web-server/zdxt-gateway-web-server/src/main/resources/application-prod.yml @@ -30,14 +30,14 @@ spring: - StripPrefix=0 - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - id: supervision-service - uri: http://10.76.108.9:18001 + uri: http://10.76.108.9:18000 predicates: - Path=/sup-ep/** filters: - StripPrefix=0 - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin, RETAIN_UNIQUE - id: enforcement-service - uri: http://10.76.108.8:18002 + uri: http://10.76.108.8:18000 predicates: - Path=/enf-ep/** filters: From 0ddf2cf39ccae369b89aa7da84ad261dfd578f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BA=84=E9=94=90=E6=B3=A2?= <10549902+zhuangruibo@user.noreply.gitee.com> Date: Fri, 26 Jun 2026 20:21:32 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E8=AE=A1=E5=88=92bug=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../my/reserve/cp_reserve_system.vue | 468 +++++++++++------- 1 file changed, 278 insertions(+), 190 deletions(-) diff --git a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_system.vue b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_system.vue index d1808e35..f858ecec 100644 --- a/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_system.vue +++ b/zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/reserve/cp_reserve_system.vue @@ -25,64 +25,76 @@ v-for="item in reserveList" :key="item.id" class="reserve-card" - :class="{ 'approved-card': item.opStatus === 1, 'rejected-card': item.opStatus === 2, 'pending-card': item.opStatus === 3, 'selected-card': selectedId === item.id }" - @click="onSelectCard(item)" + :class="{ 'approved-card': item.opStatus === 1, 'rejected-card': item.opStatus === 2, 'pending-card': item.opStatus === 3 }" >
+
系统匹配
{{ getStatusText(item.opStatus) }}
-
{{ item.enforceContent || '执法事项' }}
- -
-
企业名称:
-
{{ item.enterpriseName || '-' }}
-
- -
-
计划时间:
-
{{ formatDateShort(item.planDate) }} {{ getPlanTimeText(item.planTime) }}
-
- -
-
执法单位:
-
{{ item.bureauDeptName || '-' }}
-
- -
-
匹配时间:
-
{{ formatDate(item.reserveTime) }}
+ +
+
+ 本单位计划 +
+
{{ item.enterpriseName || '-' }}
+
{{ formatDateShort(item.planDate) }} {{ getPlanTimeText(item.planTime) }}
+
+
+
执法单位:
+
{{ item.bureauDeptName || '-' }}
+
+
+
执法人员:
+
{{ formatUserInfo(item.enforceUserNames, item.enforceUserTels) }}
+
+
+
执法事项:
+
{{ item.enforceContent || '-' }}
+
+
+
匹配时间:
+
{{ formatDate(item.reserveTime) }}
+
- -
-
关联计划
-
-
- 预约状态: - {{ getStatusText(member.opStatus) }} + +
+
+ 关联单位 ({{ groupMembersMap[item.id].length }}) +
+
+
{{ member.bureauDeptName || '-' }}
+
+
+
计划时间:
+
{{ formatDateShort(member.planDate) }} {{ getPlanTimeText(member.planTime) }}
-
- 执法单位: - {{ member.bureauDeptName || '-' }} +
+
预约状态:
+
+ {{ getStatusText(member.opStatus) }} +
-
- 执法事项: - {{ member.enforceContent || '-' }} +
+
执法人员:
+
{{ formatUserInfo(member.enforceUserNames, member.enforceUserTels) }}
-
- 计划时间: - {{ formatDateShort(member.planDate) }} {{ getPlanTimeText(member.planTime) }} +
+
执法事项:
+
{{ member.enforceContent || '-' }}
-
+
-
加载中...
+
+
加载关联计划中...
+
- -
+ +
@@ -138,9 +150,8 @@ import { showConfirmDialog, showSuccessToast, showDialog } from 'vant'; import { getReserveList, getReserveDetail, approveReserve, rejectReserveBySystem, getReserveGroupMembers } from '@/api/enforcement/reserve'; -const selectedId = ref(null); -const groupMembers = ref([]); // 选中卡片的同组关联计划 -const groupLoading = ref(false); +const groupMembersMap = ref({}); // key=item.id, value=关联计划列表 +const groupLoadingSet = ref(new Set()); const reserveList = ref([]); const loading = ref(false); const finished = ref(false); @@ -181,6 +192,17 @@ const getPlanTimeText = (time) => { return map[time] || ''; }; +// 格式化执法人员信息(姓名+电话多行展示) +const formatUserInfo = (names, tels) => { + if (!names) return '-'; + const nameArr = names.split(','); + const telArr = tels ? tels.split(',') : []; + return nameArr.map((n, i) => { + const tel = telArr[i] ? ' ' + telArr[i].trim() : ''; + return n.trim() + tel; + }).join('\n'); +}; + // 格式化日期(带时分) const formatDate = (dateStr) => { if (!dateStr) return '-'; @@ -210,37 +232,13 @@ const onLoad = () => { fetchList(); }; -// 选中卡片(再次点击取消选中) -const onSelectCard = (item) => { - if (selectedId.value === item.id) { - selectedId.value = null; - groupMembers.value = []; - return; - } - selectedId.value = item.id; - groupMembers.value = []; - // 加载同组关联计划 - if (item.planGroupId) { - groupLoading.value = true; - getReserveGroupMembers( - item.planGroupId, - item.id, - (res) => { - groupLoading.value = false; - if (res.code === 200) { - groupMembers.value = res.data || []; - } - }, - () => { groupLoading.value = false; } - ); - } -}; - // 下拉刷新 const onRefresh = () => { pageNum.value = 1; finished.value = false; reserveList.value = []; + groupMembersMap.value = {}; + groupLoadingSet.value = new Set(); fetchList(); }; @@ -274,6 +272,8 @@ const fetchList = () => { } else { pageNum.value++; } + // 第二次请求:自动加载关联计划 + loadGroupMembers(rows); } else { finished.value = true; } @@ -286,6 +286,28 @@ const fetchList = () => { ); }; +// 自动加载关联计划(第二次请求) +const loadGroupMembers = (rows) => { + const itemsWithGroup = rows.filter(item => item.planGroupId && !groupMembersMap.value[item.id]); + if (itemsWithGroup.length === 0) return; + itemsWithGroup.forEach(item => { + groupLoadingSet.value.add(item.id); + getReserveGroupMembers( + item.planGroupId, + item.id, + (res) => { + groupLoadingSet.value.delete(item.id); + if (res.code === 200) { + groupMembersMap.value[item.id] = res.data || []; + } + }, + () => { + groupLoadingSet.value.delete(item.id); + } + ); + }); +}; + // 查看备注 const onShowMessage = (item) => { showDialog({ @@ -348,7 +370,8 @@ const buildTimeOptions = (item) => { }); } // 关联计划的时间 - for (const member of groupMembers.value) { + const members = groupMembersMap.value[item.id] || []; + for (const member of members) { if (member.planDate) { options.push({ bureauDeptName: member.bureauDeptName || '-', @@ -374,7 +397,7 @@ const doApprove = (id, params) => { approveReserve(id, params, (res) => { if (res.code === 200) { showSuccessToast('已同意'); - afterOperate(); + onRefresh(); } else { showDialog({ title: '提示', message: res.msg || '操作失败' }); } @@ -390,21 +413,13 @@ const onReject = (item) => { rejectReserveBySystem(item.id, (res) => { if (res.code === 200) { showSuccessToast('已拒绝'); - afterOperate(); + onRefresh(); } else { showDialog({ title: '提示', message: res.msg || '操作失败' }); } }); }).catch(() => {}); }; - -// 操作后置处理 -const afterOperate = () => { - selectedId.value = null; - groupMembers.value = []; - pendingApproveItem.value = null; - onRefresh(); -};