Browse Source

监督端-查询统计

dev-v1.0.2
庄锐波 5 months ago
parent
commit
e8ac2ca515
  1. 13
      doc/庄锐波-工作周报.md
  2. 61
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/NonRegistrationController.java
  3. 51
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/NonRegistrationExportVo.java
  4. 74
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/NonRegistrationReportVo.java
  5. 19
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/NonEnforcementRegistrationMapper.java
  6. 27
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/INonEnforcementRegistrationReport.java
  7. 79
      zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/NonEnforcementRegistrationReportImpl.java
  8. 99
      zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/NonEnforcementRegistrationReportMapper.xml
  9. 69
      zdxt-web-client/zdxt-admin-plus-ui/src/api/efcode/report/non-registration.ts
  10. 302
      zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/non_registration/index.vue

13
doc/庄锐波-工作周报.md

@ -191,16 +191,16 @@
* 迁移一期中的以下功能,预计时间需要2周左右
```text
执法监督码
├── [❌]统计查询
│ ├── [❌]行政执法
│ │ ├── [❌]涉企执法情况
├── [🟡]统计查询
│ ├── [🟡]行政执法
│ │ ├── [🟡]涉企执法情况
│ │ ├── [❌]企业受检次数
│ │ ├── [❌]企业信息情况
│ │ ├── [❌]执法单位情况
│ │ ├── [❌]执法投诉情况
│ │ ├── [❌]检查计划情况
│ ├── [❌]非行政执法
│ │ ├── [❌]非行政执法
│ ├── [🟡]非行政执法
│ │ ├── [🟡]非行政执法
├── [✅]工作报表
│ │ ├── [✅]执法分析
├── [✅]综合管理
@ -209,4 +209,5 @@
```
* 可能需要分部分时间处理计划,预约,任务,预告的bug和网络策略通后进行部署方面的工作,上边的迁移工作时间可能会延长.
**下周工作:**
**下周工作:**
* 继续完成迁移一期的统计报表功能.预计21号前完成.

61
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/controller/web/supervision/report/NonRegistrationController.java

@ -0,0 +1,61 @@
package com.zdxt.enforcementcode.controller.web.supervision.report;
import com.zdxt.enforcementcode.domain.bo.NonEnforcementRegistrationBo;
import com.zdxt.enforcementcode.domain.vo.report.NonRegistrationExportVo;
import com.zdxt.enforcementcode.domain.vo.report.NonRegistrationReportVo;
import com.zdxt.enforcementcode.report.INonEnforcementRegistrationReport;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 非行政执法(入企登记)报表
*
* @author zdxt
*/
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/web/supervision/report/non-registration")
public class NonRegistrationController {
private final INonEnforcementRegistrationReport reportService;
/**
* 列表分页(V2 排序)
*/
@GetMapping("/list")
public TableDataInfo<NonRegistrationReportVo> list(NonEnforcementRegistrationBo bo, PageQuery pageQuery) {
return reportService.list(bo, pageQuery);
}
/**
* 列表导出(FastExcel)
*/
@PostMapping("/exportList")
public void exportList(NonEnforcementRegistrationBo bo, HttpServletResponse response) {
try {
List<NonRegistrationExportVo> list = reportService.exportList(bo);
ExcelUtil.exportExcel(list, "非行政执法登记", NonRegistrationExportVo.class, response);
} catch (Exception e) {
log.error("导出非行政执法登记 Excel 异常", e);
response.reset();
response.setContentType("application/json; charset=utf-8");
try {
response.getWriter().write("{\"code\":500,\"msg\":\"导出失败: " + e.getMessage() + "\"}");
} catch (Exception ignored) {
}
}
}
}

51
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/NonRegistrationExportVo.java

@ -0,0 +1,51 @@
package com.zdxt.enforcementcode.domain.vo.report;
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
import cn.idev.excel.annotation.ExcelProperty;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 非行政执法导出 Excel VO(10 列,对齐旧系统导出格式)。
*
* @author zdxt
*/
@Data
@ExcelIgnoreUnannotated
public class NonRegistrationExportVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty(value = "单位名称")
private String bureauDeptName;
@ExcelProperty(value = "企业名称")
private String enterpriseName;
@ExcelProperty(value = "统一信用码")
private String enterpriseNumber;
@ExcelProperty(value = "企业注册地")
private String area;
@ExcelProperty(value = "企业所属街道")
private String street;
@ExcelProperty(value = "入企人员")
private String lawEnforcer;
@ExcelProperty(value = "入企时间")
private String enforcementTime;
@ExcelProperty(value = "入企事由")
private String lawEnforcementTypeText;
@ExcelProperty(value = "入企事项")
private String lawEnforcementItemText;
@ExcelProperty(value = "活动依据")
private String lawEnforcementBasisText;
}

74
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/domain/vo/report/NonRegistrationReportVo.java

@ -0,0 +1,74 @@
package com.zdxt.enforcementcode.domain.vo.report;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 非行政执法(入企登记)报表行 VO。
* <p>对应前端列表展示字段:单位名称、企业名称、企业注册地、企业所属街道、入企人员、入企时间、入企事由、入企事项、活动依据。
*
* @author zdxt
*/
@Data
public class NonRegistrationReportVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 执法主体(单位名称)
*/
private String bureauDeptName;
/**
* 企业名称
*/
private String enterpriseName;
/**
* 企业统一信用代码
*/
private String enterpriseNumber;
/**
* 企业注册地址(原始)
*/
private String enterpriseAddress;
/**
* 企业注册区(来自 non_enforcement_registration.district)
*/
private String area;
/**
* 企业所属街道(来自 non_enforcement_registration.street)
*/
private String street;
/**
* 入企人员(SQL 内已 CONCAT_WS 主+其他执法人员)
*/
private String lawEnforcer;
/**
* 入企时间(SQL DATE_FORMAT 后的字符串)
*/
private String enforcementTime;
/**
* 入企事由文本
*/
private String lawEnforcementTypeText;
/**
* 入企事项文本
*/
private String lawEnforcementItemText;
/**
* 活动依据文本
*/
private String lawEnforcementBasisText;
}

19
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/mapper/NonEnforcementRegistrationMapper.java

@ -1,8 +1,12 @@
package com.zdxt.enforcementcode.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdxt.enforcementcode.domain.NonEnforcementRegistration;
import com.zdxt.enforcementcode.domain.bo.NonEnforcementRegistrationBo;
import com.zdxt.enforcementcode.domain.vo.NonEnforcementRegistrationVo;
import com.zdxt.enforcementcode.domain.vo.report.NonRegistrationReportVo;
import org.apache.ibatis.annotations.Param;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.springframework.stereotype.Repository;
@ -69,4 +73,19 @@ public interface NonEnforcementRegistrationMapper extends BaseMapperPlus<NonEnfo
List<NonEnforcementRegistrationVo> getList(NonEnforcementRegistrationBo bo);
int getListTotal(NonEnforcementRegistrationBo bo);
/**
* 报表 — 非行政执法分页(V2 排序:JOIN sys_dict_data 按 dict_sort 排序)。
* <p>不使用 @EfcodeDataFilter 注解,由 Service 层手动构建单列过滤条件传入(带表别名 n)。
*/
IPage<NonRegistrationReportVo> selectReportPageV2(@Param("page") Page<NonRegistrationReportVo> page,
@Param("bo") NonEnforcementRegistrationBo bo,
@Param("dataFilter") String dataFilter);
/**
* 报表 — 非行政执法全量加载(用于导出,V2 排序)。
* <p>不使用 @EfcodeDataFilter 注解,由 Service 层手动构建单列过滤条件传入。
*/
List<NonRegistrationReportVo> selectReportAll(@Param("bo") NonEnforcementRegistrationBo bo,
@Param("dataFilter") String dataFilter);
}

27
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/INonEnforcementRegistrationReport.java

@ -0,0 +1,27 @@
package com.zdxt.enforcementcode.report;
import com.zdxt.enforcementcode.domain.bo.NonEnforcementRegistrationBo;
import com.zdxt.enforcementcode.domain.vo.report.NonRegistrationExportVo;
import com.zdxt.enforcementcode.domain.vo.report.NonRegistrationReportVo;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import java.util.List;
/**
* 非行政执法(入企登记)报表服务接口
*
* @author zdxt
*/
public interface INonEnforcementRegistrationReport {
/**
* 列表分页(V2 排序)
*/
TableDataInfo<NonRegistrationReportVo> list(NonEnforcementRegistrationBo bo, PageQuery pageQuery);
/**
* 列表导出(V2 排序,全量)
*/
List<NonRegistrationExportVo> exportList(NonEnforcementRegistrationBo bo);
}

79
zdxt-modules/zdxt-enforcement-code/src/main/java/com/zdxt/enforcementcode/report/impl/NonEnforcementRegistrationReportImpl.java

@ -0,0 +1,79 @@
package com.zdxt.enforcementcode.report.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zdxt.enforcementcode.common.util.DataFilterUtil;
import com.zdxt.enforcementcode.domain.bo.NonEnforcementRegistrationBo;
import com.zdxt.enforcementcode.domain.vo.report.NonRegistrationExportVo;
import com.zdxt.enforcementcode.domain.vo.report.NonRegistrationReportVo;
import com.zdxt.enforcementcode.mapper.NonEnforcementRegistrationMapper;
import com.zdxt.enforcementcode.report.INonEnforcementRegistrationReport;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* 非行政执法(入企登记)报表服务实现
*
* @author zdxt
*/
@Slf4j
@RequiredArgsConstructor
@Service
public class NonEnforcementRegistrationReportImpl implements INonEnforcementRegistrationReport {
private final NonEnforcementRegistrationMapper registrationMapper;
@Override
public TableDataInfo<NonRegistrationReportVo> list(NonEnforcementRegistrationBo bo, PageQuery pageQuery) {
// V2:SQL层JOIN字典表排序 + 服务端分页
// 手动构建单列权限过滤(bureau_dept_id),表别名 n
Page<NonRegistrationReportVo> page = pageQuery.build();
String dataFilter = buildSingleColumnFilter("n");
IPage<NonRegistrationReportVo> result = registrationMapper.selectReportPageV2(page, bo, dataFilter);
return TableDataInfo.build(result);
}
@Override
public List<NonRegistrationExportVo> exportList(NonEnforcementRegistrationBo bo) {
// 全量加载(V2 排序),手动构建单列权限过滤(bureau_dept_id)
String dataFilter = buildSingleColumnFilter("n");
List<NonRegistrationReportVo> dataList = registrationMapper.selectReportAll(bo, dataFilter);
return dataList.stream().map(vo -> {
NonRegistrationExportVo export = new NonRegistrationExportVo();
export.setBureauDeptName(vo.getBureauDeptName());
export.setEnterpriseName(vo.getEnterpriseName());
export.setEnterpriseNumber(vo.getEnterpriseNumber());
export.setArea(vo.getArea());
export.setStreet(vo.getStreet());
export.setLawEnforcer(vo.getLawEnforcer());
export.setEnforcementTime(vo.getEnforcementTime());
export.setLawEnforcementTypeText(vo.getLawEnforcementTypeText());
export.setLawEnforcementItemText(vo.getLawEnforcementItemText());
export.setLawEnforcementBasisText(vo.getLawEnforcementBasisText());
return export;
}).collect(Collectors.toList());
}
/**
* 构建单列数据权限过滤条件:bureau_dept_id(执法单位)。
* <p>带 "AND " 前缀,可直接拼在现有 WHERE 条件后。
* <p>超管或 ViewAllDataRole 返回空字符串(不过滤),保证 XML 中 ${dataFilter} 占位安全。
*
* @param tableAlias 表别名(不带点),无别名传 ""
* @return 拼接后的 "AND ..." SQL 片段;超管/全数据角色返回空串
*/
private String buildSingleColumnFilter(String tableAlias) {
String filter = DataFilterUtil.buildFilterSql(tableAlias, "bureau_dept_id", true, true);
if (filter == null) {
return "";
}
return "AND " + filter;
}
}

99
zdxt-modules/zdxt-enforcement-code/src/main/resources/mapper/enforcementcode/NonEnforcementRegistrationReportMapper.xml

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zdxt.enforcementcode.mapper.NonEnforcementRegistrationMapper">
<!-- 报表查询通用 WHERE 片段 -->
<sql id="reportWhereCondition">
AND n.has_delete = 0
<if test="bo.bureauDeptName != null and bo.bureauDeptName != ''">
AND n.bureau_dept_name LIKE CONCAT('%', #{bo.bureauDeptName}, '%')
</if>
<if test="bo.lawEnforcer != null and bo.lawEnforcer != ''">
AND ( n.law_enforcer LIKE CONCAT('%', #{bo.lawEnforcer}, '%')
OR n.law_enforcer_other LIKE CONCAT('%', #{bo.lawEnforcer}, '%') )
</if>
<if test="bo.enterpriseName != null and bo.enterpriseName != ''">
AND n.enterprise_name LIKE CONCAT('%', #{bo.enterpriseName}, '%')
</if>
<if test="bo.lawEnforcementItemText != null and bo.lawEnforcementItemText != ''">
AND n.law_enforcement_item_text LIKE CONCAT('%', #{bo.lawEnforcementItemText}, '%')
</if>
<if test="bo.lawEnforcementType != null">
AND n.law_enforcement_type = #{bo.lawEnforcementType}
</if>
<!-- 区域/街道:以 enterprise_address LIKE 匹配(对齐旧系统) -->
<if test="bo.areaText != null and bo.areaText != ''">
AND n.enterprise_address LIKE CONCAT('%', #{bo.areaText}, '%')
</if>
<if test="bo.streetText != null and bo.streetText != ''">
AND n.enterprise_address LIKE CONCAT('%', #{bo.streetText}, '%')
</if>
<!-- 时段过滤 -->
<if test="bo.dateSearch == 'year' and bo.year != null and bo.year != ''">
AND YEAR(n.enforcement_time) = #{bo.year}
</if>
<if test="bo.dateSearch == 'quarter' and bo.year != null and bo.year != '' and bo.quarter != null and bo.quarter != ''">
AND YEAR(n.enforcement_time) = #{bo.year} AND QUARTER(n.enforcement_time) = #{bo.quarter}
</if>
<if test="bo.dateSearch == 'month' and bo.year != null and bo.year != '' and bo.month != null and bo.month != ''">
AND YEAR(n.enforcement_time) = #{bo.year} AND MONTH(n.enforcement_time) = #{bo.month}
</if>
<if test="bo.dateSearch == 'selectTime' and bo.startTime != null and bo.startTime != ''">
AND DATE_FORMAT(n.enforcement_time,'%Y-%m-%d') &gt;= STR_TO_DATE(#{bo.startTime},'%Y-%m-%d')
</if>
<if test="bo.dateSearch == 'selectTime' and bo.endTime != null and bo.endTime != ''">
AND DATE_FORMAT(n.enforcement_time,'%Y-%m-%d') &lt;= STR_TO_DATE(#{bo.endTime},'%Y-%m-%d')
</if>
<!-- 数据权限(Service 层手动构建,超管为空字符串) -->
${dataFilter}
</sql>
<!-- 报表分页(V2 字典 JOIN 排序) -->
<select id="selectReportPageV2" resultType="com.zdxt.enforcementcode.domain.vo.report.NonRegistrationReportVo">
SELECT
n.bureau_dept_name AS bureauDeptName,
n.enterprise_name AS enterpriseName,
n.enterprise_number AS enterpriseNumber,
n.enterprise_address AS enterpriseAddress,
n.district AS area,
n.street AS street,
CONCAT_WS(',', NULLIF(n.law_enforcer,''), NULLIF(n.law_enforcer_other,'')) AS lawEnforcer,
DATE_FORMAT(n.enforcement_time, '%Y-%m-%d %H:%i:%s') AS enforcementTime,
n.law_enforcement_type_text AS lawEnforcementTypeText,
n.law_enforcement_item_text AS lawEnforcementItemText,
n.law_enforcement_basis_text AS lawEnforcementBasisText
FROM non_enforcement_registration n
LEFT JOIN sys_dict_data area ON area.dict_type='address_type' AND area.status='0' AND area.dict_label = n.district
LEFT JOIN sys_dict_data street ON street.dict_type=area.dict_value AND street.status='0' AND street.dict_label = n.street
<where>
<include refid="reportWhereCondition"/>
</where>
ORDER BY IFNULL(area.dict_sort, 9999), IFNULL(street.dict_sort, 9999), n.enforcement_time DESC
</select>
<!-- 全量加载(导出,V2 排序) -->
<select id="selectReportAll" resultType="com.zdxt.enforcementcode.domain.vo.report.NonRegistrationReportVo">
SELECT
n.bureau_dept_name AS bureauDeptName,
n.enterprise_name AS enterpriseName,
n.enterprise_number AS enterpriseNumber,
n.enterprise_address AS enterpriseAddress,
n.district AS area,
n.street AS street,
CONCAT_WS(',', NULLIF(n.law_enforcer,''), NULLIF(n.law_enforcer_other,'')) AS lawEnforcer,
DATE_FORMAT(n.enforcement_time, '%Y-%m-%d %H:%i:%s') AS enforcementTime,
n.law_enforcement_type_text AS lawEnforcementTypeText,
n.law_enforcement_item_text AS lawEnforcementItemText,
n.law_enforcement_basis_text AS lawEnforcementBasisText
FROM non_enforcement_registration n
LEFT JOIN sys_dict_data area ON area.dict_type='address_type' AND area.status='0' AND area.dict_label = n.district
LEFT JOIN sys_dict_data street ON street.dict_type=area.dict_value AND street.status='0' AND street.dict_label = n.street
<where>
<include refid="reportWhereCondition"/>
</where>
ORDER BY IFNULL(area.dict_sort, 9999), IFNULL(street.dict_sort, 9999), n.enforcement_time DESC
</select>
</mapper>

69
zdxt-web-client/zdxt-admin-plus-ui/src/api/efcode/report/non-registration.ts

@ -0,0 +1,69 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
const BASE_URL = '/web/supervision/report/non-registration';
/** 查询参数 */
export interface NonRegistrationQuery {
pageNum?: number;
pageSize?: number;
/** 单位名称 */
bureauDeptName?: string;
/** 入企人员(同时匹配 law_enforcer / law_enforcer_other) */
lawEnforcer?: string;
/** 企业名称 */
enterpriseName?: string;
/** 入企事项 */
lawEnforcementItemText?: string;
/** 入企事由(字典 no_check_category 的 dictValue) */
lawEnforcementType?: number | string;
/** 区域 dictValue */
area?: string;
/** 区域 dictLabel(用于 enterprise_address LIKE 匹配) */
areaText?: string;
/** 街道 dictValue */
street?: string;
/** 街道 dictLabel(用于 enterprise_address LIKE 匹配) */
streetText?: string;
/** 时段类型:year / quarter / month / selectTime */
dateSearch?: string;
year?: string;
quarter?: string;
month?: string;
startTime?: string;
endTime?: string;
}
/** 列表行 VO */
export interface NonRegistrationReportVo {
bureauDeptName: string;
enterpriseName: string;
enterpriseNumber: string;
enterpriseAddress: string;
area: string;
street: string;
lawEnforcer: string;
enforcementTime: string;
lawEnforcementTypeText: string;
lawEnforcementItemText: string;
lawEnforcementBasisText: string;
}
/** 列表分页 */
export const listNonRegistration = (params: NonRegistrationQuery): AxiosPromise => {
return request({
url: `${BASE_URL}/list`,
method: 'get',
params
});
};
/** 列表导出 */
export const exportNonRegistration = (params: NonRegistrationQuery): AxiosPromise<Blob> => {
return request({
url: `${BASE_URL}/exportList`,
method: 'post',
params,
responseType: 'blob'
});
};

302
zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/report/non_registration/index.vue

@ -0,0 +1,302 @@
<script setup lang="ts">
import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue';
import { ElMessage } from 'element-plus';
import {
listNonRegistration, exportNonRegistration
} from '@/api/efcode/report/non-registration';
import type { NonRegistrationQuery, NonRegistrationReportVo } from '@/api/efcode/report/non-registration';
import { getDicts } from '@/api/system/dict/data';
const queryParams = reactive<NonRegistrationQuery>({
pageNum: 1,
pageSize: 20,
bureauDeptName: undefined,
lawEnforcer: undefined,
enterpriseName: undefined,
lawEnforcementItemText: undefined,
lawEnforcementType: undefined,
area: undefined,
areaText: undefined,
street: undefined,
streetText: undefined,
dateSearch: 'year',
year: undefined,
quarter: undefined,
month: undefined,
startTime: undefined,
endTime: undefined
});
const loading = ref(false);
const tableData = ref<NonRegistrationReportVo[]>([]);
const total = ref(0);
const tableHeight = ref<number | undefined>(undefined);
const tableRef = ref();
// 字典
const noCheckCategoryOptions = ref<any[]>([]);
const addressTypeOptions = ref<any[]>([]);
const streetOptions = ref<any[]>([]);
// 时段
const timeMode = ref<'year' | 'quarter' | 'month' | 'selectTime'>('year');
const selectedYear = ref<string>(String(new Date().getFullYear()));
const selectedQuarter = ref<string>(String(Math.ceil((new Date().getMonth() + 1) / 3)));
const selectedMonth = ref<string>(String(new Date().getMonth() + 1).padStart(2, '0'));
const quarterOptions = [
{ label: '第一季度', value: '1' },
{ label: '第二季度', value: '2' },
{ label: '第三季度', value: '3' },
{ label: '第四季度', value: '4' }
];
const monthOptions = Array.from({ length: 12 }, (_, i) => {
const v = String(i + 1).padStart(2, '0');
return { label: `${i + 1}月`, value: v };
});
const yearOptions = (() => {
const curr = new Date().getFullYear();
return Array.from({ length: 5 }, (_, i) => String(curr - i));
})();
onMounted(() => {
loadDicts();
applyTimeFilter();
handleQuery();
nextTick(() => calcTableHeight());
window.addEventListener('resize', calcTableHeight);
});
onUnmounted(() => {
window.removeEventListener('resize', calcTableHeight);
});
const calcTableHeight = () => {
const el = tableRef.value?.$el as HTMLElement;
if (!el) return;
const rect = el.getBoundingClientRect();
tableHeight.value = window.innerHeight - rect.top - 102;
};
/** 加载字典 */
const loadDicts = async () => {
try {
const [reasonRes, areaRes] = await Promise.all([
getDicts('no_check_category'),
getDicts('address_type')
]);
noCheckCategoryOptions.value = reasonRes.data || [];
addressTypeOptions.value = areaRes.data || [];
} catch (e) {
console.error('加载字典失败', e);
}
};
/** 区域变更 → 加载街道 */
const handleAreaChange = async (val: string | undefined) => {
queryParams.street = undefined;
queryParams.streetText = undefined;
streetOptions.value = [];
if (val) {
const matched = addressTypeOptions.value.find((item: any) => item.dictValue === val);
queryParams.areaText = matched ? matched.dictLabel : undefined;
if (matched) {
try {
const res = await getDicts(matched.dictValue);
streetOptions.value = res.data || [];
} catch (e) {}
}
} else {
queryParams.areaText = undefined;
}
};
/** 街道变更 → 同步 streetText */
const handleStreetChange = (val: string | undefined) => {
if (val) {
const matched = streetOptions.value.find((item: any) => item.dictValue === val);
queryParams.streetText = matched ? matched.dictLabel : undefined;
} else {
queryParams.streetText = undefined;
}
};
/** 时段模式变更 */
const handleTimeModeChange = () => {
// 清空所有时段字段,再按当前模式重置
queryParams.year = undefined;
queryParams.quarter = undefined;
queryParams.month = undefined;
queryParams.startTime = undefined;
queryParams.endTime = undefined;
queryParams.dateSearch = timeMode.value;
applyTimeFilter();
};
/** 应用时段筛选到 queryParams */
const applyTimeFilter = () => {
queryParams.dateSearch = timeMode.value;
if (timeMode.value === 'year') {
queryParams.year = selectedYear.value;
} else if (timeMode.value === 'quarter') {
queryParams.year = selectedYear.value;
queryParams.quarter = selectedQuarter.value;
} else if (timeMode.value === 'month') {
queryParams.year = selectedYear.value;
queryParams.month = selectedMonth.value;
}
};
/** 搜索 */
const handleQuery = () => {
applyTimeFilter();
queryParams.pageNum = 1;
getList();
};
/** 重置 */
const resetQuery = () => {
Object.assign(queryParams, {
pageNum: 1,
pageSize: 20,
bureauDeptName: undefined,
lawEnforcer: undefined,
enterpriseName: undefined,
lawEnforcementItemText: undefined,
lawEnforcementType: undefined,
area: undefined,
areaText: undefined,
street: undefined,
streetText: undefined,
dateSearch: 'year',
year: undefined,
quarter: undefined,
month: undefined,
startTime: undefined,
endTime: undefined
});
timeMode.value = 'year';
selectedYear.value = String(new Date().getFullYear());
selectedQuarter.value = String(Math.ceil((new Date().getMonth() + 1) / 3));
selectedMonth.value = String(new Date().getMonth() + 1).padStart(2, '0');
streetOptions.value = [];
applyTimeFilter();
handleQuery();
};
/** 查询列表 */
const getList = async () => {
loading.value = true;
try {
const res = await listNonRegistration(queryParams);
tableData.value = res.rows || [];
total.value = res.total || 0;
} finally {
loading.value = false;
}
};
/** 导出 */
const handleExport = async () => {
try {
applyTimeFilter();
const res = await exportNonRegistration(queryParams);
const blob = new Blob([res as any], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `非行政执法登记.xlsx`;
link.click();
window.URL.revokeObjectURL(url);
} catch (e) {
ElMessage.error('导出失败');
}
};
</script>
<template>
<div class="p-2">
<!-- 搜索区域 -->
<div class="mb-[10px]">
<el-card shadow="hover">
<el-form :model="queryParams" :inline="true" label-width="90px">
<el-form-item label="单位名称" prop="bureauDeptName">
<el-input v-model="queryParams.bureauDeptName" placeholder="请输入单位名称" clearable @keyup.enter="handleQuery" style="width: 140px" />
</el-form-item>
<el-form-item label="入企人员" prop="lawEnforcer">
<el-input v-model="queryParams.lawEnforcer" placeholder="请输入入企人员" clearable @keyup.enter="handleQuery" style="width: 120px" />
</el-form-item>
<el-form-item label="企业名称" prop="enterpriseName">
<el-input v-model="queryParams.enterpriseName" placeholder="请输入企业名称" clearable @keyup.enter="handleQuery" style="width: 140px" />
</el-form-item>
<el-form-item label="入企事项" prop="lawEnforcementItemText">
<el-input v-model="queryParams.lawEnforcementItemText" placeholder="请输入入企事项" clearable @keyup.enter="handleQuery" style="width: 140px" />
</el-form-item>
<el-form-item label="入企事由" prop="lawEnforcementType">
<el-select v-model="queryParams.lawEnforcementType" placeholder="请选择入企事由" clearable style="width: 140px">
<el-option v-for="item in noCheckCategoryOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
<div style="width: 100%; height: 0;"></div>
<el-form-item label="企业注册地" prop="area">
<el-select v-model="queryParams.area" placeholder="区" clearable style="width: 150px" @change="handleAreaChange">
<el-option v-for="item in addressTypeOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
<el-select v-model="queryParams.street" placeholder="街道" clearable style="width: 180px; margin-left: 4px" @change="handleStreetChange">
<el-option v-for="item in streetOptions" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue" />
</el-select>
</el-form-item>
<el-form-item label="时段">
<el-select v-model="timeMode" style="width: 90px" @change="handleTimeModeChange">
<el-option label="年度" value="year" />
<el-option label="季度" value="quarter" />
<el-option label="月度" value="month" />
<el-option label="自定义" value="selectTime" />
</el-select>
<el-select v-if="timeMode === 'year' || timeMode === 'quarter' || timeMode === 'month'" v-model="selectedYear" style="width: 100px; margin-left: 4px" @change="applyTimeFilter">
<el-option v-for="y in yearOptions" :key="y" :label="y + '年'" :value="y" />
</el-select>
<el-select v-if="timeMode === 'quarter'" v-model="selectedQuarter" style="width: 110px; margin-left: 4px" @change="applyTimeFilter">
<el-option v-for="q in quarterOptions" :key="q.value" :label="q.label" :value="q.value" />
</el-select>
<el-select v-if="timeMode === 'month'" v-model="selectedMonth" style="width: 90px; margin-left: 4px" @change="applyTimeFilter">
<el-option v-for="m in monthOptions" :key="m.value" :label="m.label" :value="m.value" />
</el-select>
<template v-if="timeMode === 'selectTime'">
<el-date-picker v-model="queryParams.startTime" type="date" placeholder="开始日期" value-format="YYYY-MM-DD" style="width: 140px; margin-left: 4px" />
<span style="margin: 0 4px">-</span>
<el-date-picker v-model="queryParams.endTime" type="date" placeholder="结束日期" value-format="YYYY-MM-DD" style="width: 140px" />
</template>
</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-button type="warning" icon="Download" @click="handleExport">导出</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
<!-- 表格区域 -->
<el-card shadow="hover">
<el-table ref="tableRef" v-loading="loading" :data="tableData" :height="tableHeight" border stripe>
<el-table-column label="单位名称" prop="bureauDeptName" min-width="160" :show-overflow-tooltip="true" />
<el-table-column label="企业名称" prop="enterpriseName" min-width="200" :show-overflow-tooltip="true" />
<el-table-column label="企业注册地" prop="area" width="110" align="center" />
<el-table-column label="企业所属街道" prop="street" width="120" align="center" />
<el-table-column label="入企人员" prop="lawEnforcer" min-width="120" :show-overflow-tooltip="true" />
<el-table-column label="入企时间" prop="enforcementTime" width="160" align="center" />
<el-table-column label="入企事由" prop="lawEnforcementTypeText" min-width="120" :show-overflow-tooltip="true" />
<el-table-column label="入企事项" prop="lawEnforcementItemText" min-width="180" :show-overflow-tooltip="true" />
<el-table-column label="活动依据" prop="lawEnforcementBasisText" min-width="180" :show-overflow-tooltip="true" />
</el-table>
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
</el-card>
</div>
</template>
<style scoped lang="scss">
</style>
Loading…
Cancel
Save