Browse Source

执法端-计划

dev-V1.0.1
庄锐波 5 months ago
parent
commit
0965b9d7a7
  1. 21
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java
  2. 18
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java
  3. 26
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java
  4. 2
      zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpPlanMapper.xml
  5. 2
      zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml
  6. 2
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue
  7. 47
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_detail.vue
  8. 23
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_mine.vue

21
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/EfcodeCpTaskVo.java

@ -11,6 +11,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
@ -138,5 +139,25 @@ public class EfcodeCpTaskVo implements Serializable {
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
private String remark;
/**
* 关联同组其他单位的计划列表(联合执法时有多条)
*/
@com.baomidou.mybatisplus.annotation.TableField(exist = false)
private List<AssociatedPlan> associatedPlans;
/**
* 关联计划简要信息
*/
@Data
public static class AssociatedPlan implements Serializable {
/** 执法单位名称 */
private String bureauDeptName;
/** 执法人员姓名(多个逗号分隔) */
private String enforceUserNames;
/** 执法人员电话(多个逗号分隔) */
private String enforceUserTels;
/** 执法事项 */
private String enforceContent;
}
}

18
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpReserveServiceImpl.java

@ -447,19 +447,29 @@ public class EfcodeCpReserveServiceImpl implements IEfcodeCpReserveService {
);
log.info("[预约后置] planGroupId={}, 已同意数量={}, 最大联合数={}", reserve.getPlanGroupId(), approvedCount, maxUnionUnit);
if (approvedCount >= maxUnionUnit) {
// 达标:为该分组所有计划生成任务
// 达标:只生成1条任务,所有同组计划共享该task_id
List<EfcodeCpReserve> groupReserves = baseMapper.selectList(
Wrappers.<EfcodeCpReserve>lambdaQuery()
.eq(EfcodeCpReserve::getPlanGroupId, reserve.getPlanGroupId())
.eq(EfcodeCpReserve::getOpStatus, 1L)
);
String sharedTaskId = null;
for (EfcodeCpReserve r : groupReserves) {
EfcodeCpPlan plan = cpPlanMapper.selectById(r.getPlanId());
if (plan != null && StringUtils.isBlank(plan.getTaskId())) {
cpTaskService.forceGenerateTask(plan);
if (plan == null || StringUtils.isNotBlank(plan.getTaskId())) continue;
if (sharedTaskId == null) {
// 用第一条计划生成唯一一条任务
sharedTaskId = cpTaskService.forceGenerateTask(plan);
} else {
// 其余计划直接回写同一个task_id
EfcodeCpPlan planUpdate = new EfcodeCpPlan();
planUpdate.setId(plan.getId());
planUpdate.setTaskId(sharedTaskId);
planUpdate.setReserveStatus(3L);
cpPlanMapper.updateById(planUpdate);
}
}
log.info("[预约后置] planGroupId={} 联合数量达标,已为{}条计划生成任务", reserve.getPlanGroupId(), groupReserves.size());
log.info("[预约后置] planGroupId={} 联合数量达标,生成1条任务taskId={},关联{}条计划", reserve.getPlanGroupId(), sharedTaskId, groupReserves.size());
}
}
}

26
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpTaskServiceImpl.java

@ -21,6 +21,7 @@ import com.zdxt.enforcementcode.service.IEfcodeCpTaskService;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;
import java.util.Collection;
/**
@ -153,7 +154,30 @@ public class EfcodeCpTaskServiceImpl implements IEfcodeCpTaskService {
*/
@Override
public EfcodeCpTaskVo queryMyTaskDetail(String planId) {
return baseMapper.selectMyTaskDetail(planId);
EfcodeCpTaskVo detail = baseMapper.selectMyTaskDetail(planId);
if (detail == null || StringUtils.isBlank(detail.getId())) {
return detail;
}
// 查询同一 task_id 下其他单位的计划(排除当前 planId)
List<EfcodeCpPlan> otherPlans = cpPlanMapper.selectList(
Wrappers.<EfcodeCpPlan>lambdaQuery()
.eq(EfcodeCpPlan::getTaskId, detail.getId())
.ne(EfcodeCpPlan::getId, planId)
.eq(EfcodeCpPlan::getIsDelete, 0L)
);
if (otherPlans != null && !otherPlans.isEmpty()) {
List<EfcodeCpTaskVo.AssociatedPlan> 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);
}
detail.setAssociatedPlans(associated);
}
return detail;
}
/**

2
zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpPlanMapper.xml

@ -19,7 +19,7 @@
create_by, create_dept, create_time, update_by, update_time
FROM efcode_cp_plan
<where>
reserve_status = 1
reserve_status in (1,4,5)
AND is_delete = 0
<if test="currentUserId != null">
AND create_by != #{currentUserId}

2
zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/EfcodeCpTaskMapper.xml

@ -23,7 +23,7 @@
INNER JOIN efcode_cp_plan p ON p.task_id = t.id
<where>
p.is_delete = 0
AND p.reserve_status IN (1, 4, 5)
AND p.task_id IS NOT NULL AND p.task_id != ''
AND (
p.create_by = #{userId}
OR EXISTS (

2
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue

@ -296,7 +296,7 @@ const form = ref({
enforceUserTels: '',
enforceUserCodes: '',
isPublic: 1,
isUnion: 0,
isUnion: 1,
reserveStatus: 0,
systemReserved: 0,
manualReserved: 0,

47
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_detail.vue

@ -93,6 +93,40 @@
</div>
</div>
<!-- 关联单位计划卡片(联合执法时展示其他单位信息) -->
<div v-if="detail.associatedPlans && detail.associatedPlans.length > 0" class="detail-card">
<div class="card-header">
<div class="header-icon-wrap blue">
<van-icon name="cluster-o" size="15" color="#fff" />
</div>
<span>联合单位 ({{ detail.associatedPlans.length }})</span>
</div>
<div
v-for="(ap, idx) in detail.associatedPlans"
:key="idx"
class="associated-plan-item"
>
<div class="info-list">
<div class="info-item">
<span class="info-label">执法单位</span>
<span class="info-value bold">{{ ap.bureauDeptName || '-' }}</span>
</div>
<div class="info-item">
<span class="info-label">执法人员</span>
<span class="info-value">{{ ap.enforceUserNames || '-' }}</span>
</div>
<div v-if="ap.enforceUserTels && ap.enforceUserTels !== '-'" class="info-item">
<span class="info-label">联系电话</span>
<span class="info-value">{{ ap.enforceUserTels }}</span>
</div>
<div v-if="ap.enforceContent" class="info-item">
<span class="info-label">执法事项</span>
<span class="info-value">{{ ap.enforceContent }}</span>
</div>
</div>
</div>
</div>
<!-- 备注卡片 -->
<div v-if="detail.remark" class="detail-card">
<div class="card-header">
@ -389,4 +423,17 @@ onMounted(() => {
border-radius: 8px;
border-left: 3px solid #2382cf;
}
/* 关联单位计划项 */
.associated-plan-item {
padding: 12px;
background: #f6f9fe;
border-radius: 8px;
border-left: 3px solid #2382cf;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
}
</style>

23
zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/task/cp_task_mine.vue

@ -67,8 +67,7 @@
@click="onTaskClick(item)"
>
<div class="task-time-col">
<div class="time-start">{{ getTimeStart(item) }}</div>
<div class="time-end">{{ getTimeEnd(item) }}</div>
<div class="time-label">{{ getTimeLabel(item) }}</div>
</div>
<div class="task-info-col">
<div class="task-title-row">
@ -259,21 +258,30 @@ const taskList = ref([]);
const loading = ref(false);
// 时段转时间显示
const getTimeLabel = (item) => {
const time = item.planActualTime || item.planTime;
if (time === 1) return '上午';
if (time === 2) return '下午';
return '其他';
};
const getTimeStart = (item) => {
const time = item.planActualTime || item.planTime;
if (time === 1) return '09:00';
if (time === 2) return '14:00';
return '00:00';
return '';
};
const getTimeEnd = (item) => {
const time = item.planActualTime || item.planTime;
if (time === 1) return '12:00';
if (time === 2) return '18:00';
return '23:59';
return '';
};
const getTimeRange = (item) => {
const time = item.planActualTime || item.planTime;
if (time === 3) return '其他';
return `${getTimeStart(item)}-${getTimeEnd(item)}`;
};
@ -515,11 +523,10 @@ onMounted(() => {
min-width: 48px;
flex-shrink: 0;
.time-start, .time-end {
font-size: 15px;
.time-label {
font-size: 14px;
font-weight: 700;
color: #333;
line-height: 1.6;
color: #2382cf;
}
}

Loading…
Cancel
Save