AOP realiza informes de exportación unificados: los informes originales pueden ser muy interesantes

Prefacio

Nota: La función del blog anterior se desarrolló en tiempo libre, por lo que el blog tiene algo de código. La idea de esta función está en la construcción de aficionados, y el código fuente del esquema de configuración en segundo plano se escribe durante el trabajo, por lo que el código no es de código abierto para evitar la programación en prisión.

Para el desarrollo, el flujo de informes es el más reacio a tocar, aburrido, no lógicamente difícil, pero extremadamente engorroso. (Esto es un poco ofensivo especializarse en flujo de trabajo). Sin embargo, no importa en qué industria se dedique, implicará un flujo de informes más o menos, y no puede ocultarlo. Aquí, me doy cuenta de la función de exportación de informes unificados a través del pensamiento de aspectos, evitando una interfaz de informe única y repetida: el informe original puede ser muy interesante.

■ Demanda

Admite exportar esta página y exportar toda la interfaz de datos

■ Análisis

Al ver esta demanda,
un tipo de código animal: desarrollo de CV ; primero se quejó en secreto, y luego enumeró todos los informes que deben exportarse, y luego inmediatamente hizo clic en el teclado, uno por un CV, eliminado, eliminado, cambiado y trabajo duro, preguntó sobre el salario de 2500 . Si hace esto, sin mencionar el engorroso desarrollo, se estima que usted redactará los nuevos informes en el período posterior, y una vez que haya nuevos cambios, tendrá que cambiarlos uno por uno;

Código tipo 2 animal: desarrollo abstracto ; ¿eh? Primero extrae los puntos en común, escribe una clase de herramienta y luego escribe la interfaz una por una, llama a la clase de herramienta. Para los más avanzados, seleccione un determinado modo de diseño y use solo una interfaz para proporcionar varias descargas de informes. Los puntos comunes se eliminan, pero la interfaz aún debe escribirse y luego se hace referencia a las herramientas. Los desarrolladores también deben escribir nuevos informes posteriores. Esto es mucho más simple, pero los nuevos requisitos de informes aún requieren una pequeña cantidad de codificación. Los informes de exportación posteriores están todos en sus manos, con solo una pequeña cantidad de CV, lo cual es bueno decirlo, pero en manos de los colegas, debe desperdiciar recursos de desarrollo, porque las herramientas que escribe pueden no ser utilizadas o adoptadas por los colegas.

Tres tipos de animales de código: desarrollo de aspectos ; creo que todo se puede cortar, y el desarrollo de aspectos es una muy buena idea para resolver problemas sin abusar de la programación de aspectos. Observe las páginas que tienen requisitos de exportación de informes y extraiga los puntos comunes de estas exportaciones de informes: todas son consultas de datos y paginación.
Primero busque los fideos cortados-um. . ¿No es solo una mejora de la consulta de datos? Cambie la interfaz de visualización de la consulta de datos para guardar la consulta de datos en Excel;
busque el punto de contacto: mi primera idea es establecer una nota, usar la nota como punto de entrada y marcar la interfaz para la anotación Ingrese, analice los datos json devueltos. Entonces, piense en cómo distinguir entre la consulta de datos de la interfaz y la exportación de informes, y utilice la solicitud con parámetros. ¿Agregar un sufijo a la interfaz de consulta? Después de pensar durante mucho tiempo, he estado pensando en cómo incrustar este parámetro de una manera poco intrusiva, hasta el día siguiente, mi inspiración brilló de repente, ¿eh? Paginación, sí, el objeto de paginación, el punto de característica de la capa de servicio, el valor de retorno del objeto de paginación, a veces me confundo, tomo un descanso, salto para mirarlo y encuentro que estoy atrapado en la esquina. Este corte es preciso, el corte es básicamente el punto de demanda y el valor de retorno del aspecto está más cerca del formato de datos original (el atributo de lista del objeto de paginación es el parámetro requerido por el informe), y es más perfecto que el nuevo informe básicamente no es necesario Cambie el código.

Paso de descomposición

①, tejer en la consulta de paginación
②, obtener la lista de valores de retorno de página
③, filtrar campos, realizar procesamiento de datos
④, devolver datos

Herida abierta

■ 1. Punto de tejido

①Establecer un comentario

Establecer un comentario para tejer en situaciones especiales (no necesariamente usado, reservado)

/**
 * @author bbq
 */
@Target({
    
    ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface XXAnnotation {
    
    
    String value() default "";
}

Nota: La meta-anotación
@Target —— ElementType.METHOD, ElementType.TYPE significa que se puede colocar en clases y métodos
@Retention —— RetentionPolicy.RUNTIME Después de que jvm cargue el archivo de clase,
@Inherited todavía está allí —— Cuando se aplica a la clase, la anotación se subclasifica Heredar
@ Documented-javadoc generado por el logo

②Establecer una sección

Establezca un aspecto, el punto de contacto es la capa de servicio y el valor de retorno es el método del objeto de paginación o el método marcado con la anotación ①

/**
 * @author bbq
 */
@Aspect
public class XXAspect {
    
    
    public static final int MAX_EXPORT_COUNT = 10_000;
    
	// 切点 为service层并且返回值为分页对象的方法 或标有 ①注解的方法
    @Around(value = "@annotation(XXAnnotation) || " +
            "execution (包名.Page 包名.*.service层.*.*(..))")
    public Object XX(ProceedingJoinPoint joinPoint) throws Throwable {
    
    
        try {
    
    
            Object[] args = joinPoint.getArgs();
            
            // 判断切点方法的参数,找到参数分页对象,判断请求参数是查询数据还是下载报表
            for (int i = 0; i < args.length; i++) {
    
    
                if (args[i] != null && Page.class.isAssignableFrom(args[i].getClass()) && "1".equals(((Page<T>)args[i]).getIsExportExcel())) {
    
    
                    return excute(joinPoint, (Page<T>) args[i]);
                }
            }
        } catch (Exception e) {
    
    
            。。。
        }
        return joinPoint.proceed();
    }

    public Object excute(...){
    
    ...}
}

■ 2. Organizar parámetros y datos

Si es para descargar el informe, ingrese este método.

public Object excute(ProceedingJoinPoint joinPoint, Page<T> page) throws Throwable {
    
    
		// 判断是否下载全部,查询全部则设置查询上限(防止报表行数太多)。
        if(page.getPageSize() == -1) {
    
    
            page.setPageSize(MAX_EXPORT_COUNT);
            page.setPageNo(0);
        }
        // 然后才执行分页查询,并可得出list列表。
        Page pageResult = (Page)joinPoint.proceed();

        String fileName = "占位符" + DateUtils.getDate("yyyyMMdd-HHmmss") + ".xlsx";
        try {
    
    
        	// list有数据即可通过反射获取数据的类,没有数据返回空json,前端作无数据弹窗
            Class format = Object.class;
            if(pageResult != null && pageResult.getList() != null && pageResult.getList().size() > 0) {
    
    
                format = pageResult.getList().get(0).getClass();
            }
            new ExportExcel(format).setDataList(pageResult.getList()).write(page.getResponse(), fileName).dispose();

        } catch (IllegalArgumentException e) {
    
    
            。。。
        }
        return null;
    }

■ 3. Obtener datos de informes

Después de obtener la lista, puede llamar a la clase de herramienta de exportación de informes y luego determinar qué campos deben exportarse y proporcionar 3 métodos para que elija.

① Anotación de configuración de clase de entidad

Este método es ampliamente utilizado. Las funciones básicas de informes de código abierto tienen esta función. Son similares en que se anotan en los atributos o métodos, y luego la clase de herramienta de exportación de informes puede obtener la información del campo. Generalmente, las anotaciones no se pueden repetir. Método de repetición de anotaciones
Definir una nueva anotación ExcelFields

/**
 * @author bbq
 */
@Target({
    
    ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelFields {
    
    
	ExcelField[] value();
}

Luego, agregue esta oración a la anotación ExcelField original para lograr múltiples anotaciones. Puede poner un montón de anotaciones en la clase para mapear los campos del informe.

@Repeatable(ExcelFields.class)

Defina otra anotación para obtener el título.

/**
 * @author bbq
 */
@Target({
    
    ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelTitle {
    
    
	String value();
}

②La interfaz pasa el campo de consulta (no recomendado)

He considerado que este tipo de campo derivado tiene una decisión de transferencia de parámetros de front-end, pero luego pensé que no era razonable y lo abandoné.

③ Plan de configuración entre bastidores (muy recomendable)

Al final, elegí el esquema de configuración en segundo plano. Aunque el desarrollo fue un poco problemático, se resolvió una vez y no se usó para cambios de código más tarde. Agregue esta función de configuración de informes a la página de administración en segundo plano con la máxima autoridad. Gestión de dos configuraciones, esto tiene una relación principal-subtabla, la
tabla principal tiene los siguientes campos: nombre de clase de ruta completa, nombre de archivo de informe, número de versión;
subtabla tiene nombre de campo, nombre de etiqueta de informe asignado, clasificación.
Los campos se pueden obtener reflejando el nombre de la clase, los campos y los métodos se pueden capturar. He capturado tanto los campos como los métodos. Si el atributo capturado es de un tipo básico, se devuelve como un nodo y el atributo capturado se devuelve como un nodo padre.Tenga en cuenta que debe configurarse en árbol de carga diferida, si es recursivo, caerá en un bucle infinito

Si le resulta problemático configurar uno por uno, puede agregar un método a la sección de informe de exportación para generar automáticamente la información del campo de configuración a través de la interfaz (tiene que ser entrelazada con los datos json). El personal de configuración solo necesita verificar los campos que deben exportarse, escribir el nombre de la etiqueta y Solo ordena.

Si los informes se exportan con frecuencia, puede considerar agregar esta información a la caché de redis.

■ 4. Obtenga los datos del informe a continuación

En el aspecto anterior, el objeto de paginación se obtiene mediante reflexión y se obtiene la lista, si la lista tiene datos, la clase de los datos se puede obtener mediante reflexión. Luego puede encontrar la clase que configuramos a través de la clase obtenida por reflexión, y luego puede obtener toda la información de la configuración.Si una clase corresponde a más de un informe, se puede introducir el mecanismo de número de versión para distinguir.
Con el nombre del título, el campo, la etiqueta correspondiente al campo, la clasificación del campo y otra información, se completa la configuración de un informe.
El informe correspondiente se puede exportar utilizando la herramienta de exportación de informes a través de la información configurada.

Al final

De esta manera, una función de informe simple de exportación unificada de bajo costo de mantenimiento se puede realizar a través de aop.

Supongo que te gusta

Origin blog.csdn.net/qq_24054301/article/details/106887155
Recomendado
Clasificación