Browse Source

执法端-计划

dev-V1.0.1
庄锐波 4 months ago
parent
commit
eaad51f91c
  1. 8
      script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql
  2. 40
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpSettingController.java
  3. 4
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java
  4. 6
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/EfcodeCpPlanController.java
  5. 68
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpSettingService.java
  6. 52
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpSettingServiceImpl.java
  7. 19
      zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js
  8. 2
      zdxt-web-client/zdxt-efcode-enforcement-app/src/http/http.js
  9. 210
      zdxt-web-client/zdxt-efcode-enforcement-app/src/views/enforcement/my/plan/cp_plan_edit.vue

8
script/sql/zfjd-refactoring-v1/013-计划任务表设计.sql

@ -180,8 +180,8 @@ CREATE TABLE `efcode_cp_setting`
/*初始化数据*/
INSERT INTO `efcode_cp_setting` (`id`, `setting_name`, `setting_value`, `remark`, `create_by`, `create_dept`)
VALUES ('CP_SETTING_SUBMIT_DEADLINE', '下阶段计划提交最晚时间', '26', '每月几号前需提交下阶段计划<=', 'admin', NULL),
('CP_SETTING_AUTO_MATCH_START', '系统自动推荐匹配开始时间', '26', '系统自动推荐匹配的开始时间(号)>=', 'admin',
VALUES ('CP_SETTING_SUBMIT_DEADLINE', '下阶段计划提交最晚时间', '26', '每月几号前需提交下阶段计划<=', '0', NULL),
('CP_SETTING_AUTO_MATCH_START', '系统自动推荐匹配开始时间', '26', '系统自动推荐匹配的开始时间(号)>=', '0',
NULL),
('CP_SETTING_MANUAL_MATCH_DAYS', '手工匹配距计划开始天数', '3', '手工匹配距离计划开始的天数>=', 'admin', NULL),
('CP_MAX_UNION_UNIT', '单次联合单位最大数量', '3', '单次联合单位最大数量>=2', 'admin', NULL);
('CP_SETTING_MANUAL_MATCH_DAYS', '手工匹配距计划开始天数', '3', '手工匹配距离计划开始的天数>=', '0', NULL),
('CP_MAX_UNION_UNIT', '单次联合单位最大数量', '3', '单次联合单位最大数量>=2', '0', NULL);

40
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfCpSettingController.java

@ -2,8 +2,11 @@ package com.zdxt.enforcementcode.controller.app.enforcement;
import com.zdxt.enforcementcode.controller.web.supervision.EfcodeCpSettingController;
import com.zdxt.enforcementcode.service.IEfcodeCpSettingService;
import org.dromara.common.core.domain.R;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 行政执法检查计划-设置
@ -16,7 +19,42 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/app-enf/cpSetting")
public class AppEnfCpSettingController extends EfcodeCpSettingController {
private final IEfcodeCpSettingService efcodeCpSettingService;
public AppEnfCpSettingController(IEfcodeCpSettingService efcodeCpSettingService) {
super(efcodeCpSettingService);
this.efcodeCpSettingService = efcodeCpSettingService;
}
/**
* 获取下阶段计划提交最晚时间(每月几号前需提交下阶段计划<=)
*/
@GetMapping("/submitDeadline")
public R<Integer> getSubmitDeadline() {
return R.ok(efcodeCpSettingService.getSubmitDeadline());
}
/**
* 获取系统自动推荐匹配开始时间()
*/
@GetMapping("/autoMatchStart")
public R<Integer> getAutoMatchStart() {
return R.ok(efcodeCpSettingService.getAutoMatchStart());
}
/**
* 获取手工匹配距计划开始天数
*/
@GetMapping("/manualMatchDays")
public R<Integer> getManualMatchDays() {
return R.ok(efcodeCpSettingService.getManualMatchDays());
}
/**
* 获取单次联合单位最大数量
*/
@GetMapping("/maxUnionUnit")
public R<Integer> getMaxUnionUnit() {
return R.ok(efcodeCpSettingService.getMaxUnionUnit());
}
}

4
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/app/enforcement/AppEnfLoginController.java

@ -81,7 +81,7 @@ public class AppEnfLoginController extends LoginController {
// 7. 构建LoginUser并生成SaToken
String token = doSaTokenLogin(user.getUserId(), user.getUserName(), user.getNickName(),
user.getDeptId(), "enforcement_user", "enforcement_app", "f0535c2a32ab4d0496ab9a699b2a7d36");
user.getDeptId(), "app_user", "enforcement_app", "f0535c2a32ab4d0496ab9a699b2a7d36");
// 验证关键组织信息不能为空
@ -115,7 +115,7 @@ public class AppEnfLoginController extends LoginController {
data.put("organName", srzOrgan.getName());
data.put("bureauUnitId", bureauDept.getDeptId());
data.put("bureauUnitName", bureauDept.getDeptId());
data.put("bureauUnitName", bureauDept.getDeptName());
return R.ok(data);
}

6
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/EfcodeCpPlanController.java

@ -42,7 +42,6 @@ public class EfcodeCpPlanController extends BaseController {
/**
* 查询行政执法检查计划-计划列表
*/
@SaCheckPermission("enforcementcode:cpPlan:list")
@GetMapping("/list")
public TableDataInfo<EfcodeCpPlanVo> list(EfcodeCpPlanBo bo, PageQuery pageQuery) {
return efcodeCpPlanService.queryPageList(bo, pageQuery);
@ -51,7 +50,6 @@ public class EfcodeCpPlanController extends BaseController {
/**
* 导出行政执法检查计划-计划列表
*/
@SaCheckPermission("enforcementcode:cpPlan:export")
@Log(title = "行政执法检查计划-计划", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(EfcodeCpPlanBo bo, HttpServletResponse response) {
@ -64,7 +62,6 @@ public class EfcodeCpPlanController extends BaseController {
*
* @param id 主键
*/
@SaCheckPermission("enforcementcode:cpPlan:query")
@GetMapping("/{id}")
public R<EfcodeCpPlanVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable String id) {
@ -74,7 +71,6 @@ public class EfcodeCpPlanController extends BaseController {
/**
* 新增行政执法检查计划-计划
*/
@SaCheckPermission("enforcementcode:cpPlan:add")
@Log(title = "行政执法检查计划-计划", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
@ -85,7 +81,6 @@ public class EfcodeCpPlanController extends BaseController {
/**
* 修改行政执法检查计划-计划
*/
@SaCheckPermission("enforcementcode:cpPlan:edit")
@Log(title = "行政执法检查计划-计划", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
@ -98,7 +93,6 @@ public class EfcodeCpPlanController extends BaseController {
*
* @param ids 主键串
*/
@SaCheckPermission("enforcementcode:cpPlan:remove")
@Log(title = "行政执法检查计划-计划", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")

68
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/IEfcodeCpSettingService.java

@ -16,6 +16,46 @@ import java.util.List;
*/
public interface IEfcodeCpSettingService {
/**
* 设置项主键下阶段计划提交最晚时间(每月几号前需提交下阶段计划<=)
*/
String SETTING_ID_SUBMIT_DEADLINE = "CP_SETTING_SUBMIT_DEADLINE";
/**
* 设置项主键系统自动推荐匹配开始时间()>=
*/
String SETTING_ID_AUTO_MATCH_START = "CP_SETTING_AUTO_MATCH_START";
/**
* 设置项主键手工匹配距离计划开始天数>=
*/
String SETTING_ID_MANUAL_MATCH_DAYS = "CP_SETTING_MANUAL_MATCH_DAYS";
/**
* 设置项主键单次联合单位最大数量>=2
*/
String SETTING_ID_MAX_UNION_UNIT = "CP_MAX_UNION_UNIT";
/**
* 默认值下阶段计划提交最晚时间
*/
int DEFAULT_SUBMIT_DEADLINE = 26;
/**
* 默认值系统自动推荐匹配开始时间()
*/
int DEFAULT_AUTO_MATCH_START = 26;
/**
* 默认值手工匹配距计划开始天数
*/
int DEFAULT_MANUAL_MATCH_DAYS = 3;
/**
* 默认值单次联合单位最大数量
*/
int DEFAULT_MAX_UNION_UNIT = 3;
/**
* 查询行政执法检查计划-设置
*
@ -24,6 +64,34 @@ public interface IEfcodeCpSettingService {
*/
EfcodeCpSettingVo queryById(String id);
/**
* 获取下阶段计划提交最晚时间(每月几号前需提交下阶段计划<=)
*
* @return 数值未配置或无法解析时返回默认值 {@link #DEFAULT_SUBMIT_DEADLINE}
*/
Integer getSubmitDeadline();
/**
* 获取系统自动推荐匹配开始时间()
*
* @return 数值未配置或无法解析时返回默认值 {@link #DEFAULT_AUTO_MATCH_START}
*/
Integer getAutoMatchStart();
/**
* 获取手工匹配距计划开始天数
*
* @return 数值未配置或无法解析时返回默认值 {@link #DEFAULT_MANUAL_MATCH_DAYS}
*/
Integer getManualMatchDays();
/**
* 获取单次联合单位最大数量
*
* @return 数值未配置或无法解析时返回默认值 {@link #DEFAULT_MAX_UNION_UNIT}
*/
Integer getMaxUnionUnit();
/**
* 分页查询行政执法检查计划-设置列表
*

52
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/service/impl/EfcodeCpSettingServiceImpl.java

@ -44,6 +44,58 @@ public class EfcodeCpSettingServiceImpl implements IEfcodeCpSettingService {
return baseMapper.selectVoById(id);
}
/**
* 获取下阶段计划提交最晚时间(每月几号前需提交下阶段计划<=)
*/
@Override
public Integer getSubmitDeadline() {
return getIntSetting(SETTING_ID_SUBMIT_DEADLINE, DEFAULT_SUBMIT_DEADLINE);
}
/**
* 获取系统自动推荐匹配开始时间()
*/
@Override
public Integer getAutoMatchStart() {
return getIntSetting(SETTING_ID_AUTO_MATCH_START, DEFAULT_AUTO_MATCH_START);
}
/**
* 获取手工匹配距计划开始天数
*/
@Override
public Integer getManualMatchDays() {
return getIntSetting(SETTING_ID_MANUAL_MATCH_DAYS, DEFAULT_MANUAL_MATCH_DAYS);
}
/**
* 获取单次联合单位最大数量
*/
@Override
public Integer getMaxUnionUnit() {
return getIntSetting(SETTING_ID_MAX_UNION_UNIT, DEFAULT_MAX_UNION_UNIT);
}
/**
* 根据设置主键获取整型配置值不存在或解析失败时返回默认值
*
* @param settingId 设置主键
* @param defaultValue 默认值
* @return 配置值
*/
private Integer getIntSetting(String settingId, int defaultValue) {
EfcodeCpSettingVo vo = baseMapper.selectVoById(settingId);
if (vo == null || StringUtils.isBlank(vo.getSettingValue())) {
return defaultValue;
}
try {
return Integer.parseInt(vo.getSettingValue().trim());
} catch (NumberFormatException e) {
log.warn("设置项[{}]的值[{}]无法解析为整数,返回默认值[{}]", settingId, vo.getSettingValue(), defaultValue);
return defaultValue;
}
}
/**
* 分页查询行政执法检查计划-设置列表
*

19
zdxt-web-client/zdxt-efcode-enforcement-app/src/api/enforcement/plan.js

@ -20,3 +20,22 @@ export const editPlan = (params, success, error) => _put(planBaseUrl, params, su
export const deletePlan = (ids, success, error) => _delete(planBaseUrl + "/" + ids, {}, success, error);
// endregion
// region 计划-设置接口
const settingBaseUrl = "/app-enf/cpSetting";
// 下阶段计划提交最晚时间(每月几号前需提交下阶段计划<=)
export const getSubmitDeadline = (success, error) => _get(settingBaseUrl + "/submitDeadline", {}, success, error);
// endregion
// region 企业检索接口
const enterpriseSearchBaseUrl = "/enforcementcode/enterpriseSearch";
// 按企业名称联合检索(>=3字符)
export const searchUnionByEnterpriseName = (enterpriseName, success, error) =>
_get(enterpriseSearchBaseUrl + "/searchUnionByEnterpriseName", { enterpriseName }, success, error);
// endregion

2
zdxt-web-client/zdxt-efcode-enforcement-app/src/http/http.js

@ -22,7 +22,7 @@ http.interceptors.request.use(
if (token) {
config.headers['Authorization'] = 'Bearer ' + token;
}
config.headers['clientid'] = 'enterprise';
config.headers['clientid'] = 'f0535c2a32ab4d0496ab9a699b2a7d36';
return config
},
err => {

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

@ -12,7 +12,7 @@
<van-notice-bar
v-if="showNotice"
left-icon="info-o"
text="请各执法单位,于本月25日前提交次月的计划"
:text="noticeText"
:scrollable="false"
background="#fff9dc"
color="#7d661c"
@ -80,9 +80,30 @@
<van-field
v-model="form.enterpriseName"
label="企业名称"
placeholder="请输入执法企业"
placeholder="输入≥3个字符检索企业"
required
@update:model-value="onEnterpriseNameInput"
/>
<!-- 企业检索结果下拉 -->
<div v-if="showEnterpriseSuggest" class="enterprise-suggest">
<div v-if="enterpriseSearching" class="suggest-empty">
<van-loading size="16" />&nbsp;检索中...
</div>
<template v-else>
<div
v-for="(item, idx) in enterpriseOptions"
:key="idx"
class="suggest-item"
@click="onSelectEnterprise(item)"
>
<div class="suggest-name">{{ item.enterpriseName }}</div>
<div class="suggest-number">{{ item.enterpriseNumber }}</div>
</div>
<div v-if="!enterpriseOptions.length" class="suggest-empty">
未检索到匹配企业
</div>
</template>
</div>
<!-- 执法人员 -->
<van-field label="执法人员" required>
@ -152,6 +173,7 @@
v-model="datePickerValue"
title="选择计划时间"
:min-date="minDate"
:max-date="maxDate"
@confirm="onDateConfirm"
@cancel="showDatePicker = false"
/>
@ -162,16 +184,50 @@
<script setup name="cpPlanEdit">
import { useRouter, useRoute } from 'vue-router';
import { showToast } from 'vant';
import { addPlan, editPlan, getPlanDetail } from '@/api/enforcement/plan';
import { addPlan, editPlan, getPlanDetail, getSubmitDeadline, searchUnionByEnterpriseName } from '@/api/enforcement/plan';
const router = useRouter();
const route = useRoute();
const {useCommon} = $globalStore;
const isEdit = computed(() => !!route.query.id);
const showNotice = ref(true);
const submitting = ref(false);
const showDatePicker = ref(false);
const minDate = new Date();
//
const submitDeadline = ref(26);
// min/max
const dateRange = computed(() => {
const today = new Date();
const currentYear = today.getFullYear();
const currentMonth = today.getMonth(); // 0-based
const currentDay = today.getDate();
//
if (form.value.planType !== 1) {
const tomorrow = new Date(currentYear, currentMonth, currentDay + 1);
return { min: tomorrow, max: null };
}
// >= deadline
// minDate
const startMonthOffset = currentDay >= submitDeadline.value ? 2 : 1;
const minDateValue = new Date(currentYear, currentMonth + startMonthOffset, 1);
return { min: minDateValue, max: null };
});
const minDate = computed(() => dateRange.value.min);
const maxDate = computed(() => dateRange.value.max || new Date(2099, 11, 31));
//
const noticeText = computed(() => {
if (form.value.planType === 1) {
return `请各执法单位,于每月${submitDeadline.value}日前提交次月的日常计划`;
}
return '专项计划时间不受提交截止日限制';
});
//
const form = ref({
@ -205,6 +261,13 @@ const form = ref({
//
const personList = ref([]);
//
const enterpriseOptions = ref([]);
const showEnterpriseSuggest = ref(false);
const enterpriseSearching = ref(false);
let enterpriseSearchTimer = null;
let enterpriseSearchSeq = 0;
//
const datePickerValue = ref([
String(new Date().getFullYear()),
@ -221,11 +284,57 @@ const planDateDisplay = computed(() => {
//
onMounted(() => {
//
form.value.bureauDeptId = useCommon.bureauUnitId || '';
form.value.bureauDeptName = useCommon.bureauUnitName || '';
//
loadSubmitDeadline();
if (isEdit.value) {
loadDetail(route.query.id);
}
});
//
const loadSubmitDeadline = () => {
getSubmitDeadline((res) => {
if (res && res.code === 200 && res.data != null) {
const val = Number(res.data);
if (!isNaN(val) && val > 0) {
submitDeadline.value = val;
}
}
//
syncDatePickerToMinDate();
}, () => {
// 使 26
syncDatePickerToMinDate();
});
};
//
const syncDatePickerToMinDate = () => {
if (isEdit.value) return; //
const d = minDate.value;
datePickerValue.value = [
String(d.getFullYear()),
String(d.getMonth() + 1).padStart(2, '0'),
String(d.getDate()).padStart(2, '0'),
];
};
//
watch(() => form.value.planType, () => {
syncDatePickerToMinDate();
//
if (form.value.planDate) {
const selected = new Date(form.value.planDate);
if (selected < minDate.value || (dateRange.value.max && selected > dateRange.value.max)) {
form.value.planDate = '';
form.value.planActualDate = '';
}
}
});
const loadDetail = (id) => {
getPlanDetail(id, (res) => {
if (res.code === 200 && res.data) {
@ -251,6 +360,49 @@ const onDateConfirm = ({ selectedValues }) => {
showDatePicker.value = false;
};
// ()
const onEnterpriseNameInput = (val) => {
// enterpriseNumber/enterpriseId
form.value.enterpriseNumber = '';
form.value.enterpriseId = '';
if (enterpriseSearchTimer) {
clearTimeout(enterpriseSearchTimer);
}
const keyword = (val || '').trim();
if (keyword.length < 3) {
showEnterpriseSuggest.value = false;
enterpriseOptions.value = [];
return;
}
enterpriseSearchTimer = setTimeout(() => {
const seq = ++enterpriseSearchSeq;
showEnterpriseSuggest.value = true;
enterpriseSearching.value = true;
searchUnionByEnterpriseName(keyword, (res) => {
//
if (seq !== enterpriseSearchSeq) return;
enterpriseSearching.value = false;
if (res && res.code === 200 && Array.isArray(res.data)) {
enterpriseOptions.value = res.data;
} else {
enterpriseOptions.value = [];
}
}, () => {
if (seq !== enterpriseSearchSeq) return;
enterpriseSearching.value = false;
enterpriseOptions.value = [];
});
}, 350);
};
//
const onSelectEnterprise = (item) => {
form.value.enterpriseName = item.enterpriseName || '';
form.value.enterpriseNumber = item.enterpriseNumber || '';
showEnterpriseSuggest.value = false;
enterpriseOptions.value = [];
};
//
const onAddPerson = () => {
// TODO:
@ -289,6 +441,10 @@ const validate = () => {
showToast('请输入企业名称');
return false;
}
if (!form.value.enterpriseNumber) {
showToast('请从检索结果中选择企业');
return false;
}
return true;
};
@ -422,6 +578,52 @@ const onSubmit = () => {
}
}
.enterprise-suggest {
background: #fff;
margin: -4px 14px 8px;
border: 1px solid #e6edf5;
border-radius: 8px;
max-height: 220px;
overflow-y: auto;
box-shadow: 0 4px 10px rgba(44, 116, 190, 0.08);
.suggest-item {
padding: 10px 14px;
border-bottom: 1px solid #f0f2f5;
cursor: pointer;
&:last-child {
border-bottom: none;
}
&:active {
background: #f5faff;
}
.suggest-name {
font-size: 14px;
color: #333;
line-height: 1.4;
}
.suggest-number {
font-size: 12px;
color: #999;
margin-top: 2px;
}
}
.suggest-empty {
padding: 14px;
text-align: center;
color: #999;
font-size: 13px;
display: flex;
align-items: center;
justify-content: center;
}
}
.submit-wrap {
padding: 22px 0 0;

Loading…
Cancel
Save