10 changed files with 788 additions and 6 deletions
@ -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) { |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
@ -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); |
||||
|
} |
||||
@ -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; |
||||
|
} |
||||
|
} |
||||
@ -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') >= 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') <= 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> |
||||
@ -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' |
||||
|
}); |
||||
|
}; |
||||
@ -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…
Reference in new issue