Diseño e implementación de un sistema de gestión de recursos humanos empresarial basado en SpringBoot

1. Introducción

Con el desarrollo de la reforma económica y la apertura, la competencia entre las empresas es cada vez más feroz.La esencia de un equipo es el talento. El aumento continuo en la demanda de talentos por parte de las empresas también ha llevado al cambio continuo de la demanda de gestión de recursos humanos. Los métodos de gestión tradicionales ya no pueden satisfacer la forma de gestión actual, por lo que el sistema de gestión de recursos humanos se puede gestionar a través de Internet, ahorrando así gastos adicionales y mejorando el nivel de gestión.

La racionalidad de la gestión de los recursos humanos de la empresa es un vínculo importante para determinar la dirección del desarrollo futuro de las empresas. Sin embargo, algunas pequeñas y medianas empresas todavía tienen algunos sistemas de gestión básicos, que no pueden realizar la informatización e inteligenteización de la gestión.

Teniendo en cuenta el costo de diseñar el sistema, muchas empresas prefieren utilizar un sistema de gestión de bajo precio y funciones deficientes.Aunque parece ahorrar el costo para la empresa en la superficie, todavía desperdicia más mano de obra y recursos materiales a largo plazo. proceso de uso y recursos financieros. Por lo tanto, para realmente ahorrar costos y lograr una gestión eficaz de los recursos humanos, es necesario utilizar un sistema inteligente de gestión de recursos humanos. Mejore la eficiencia de la gestión de personal y realmente encuentre formas de ahorrar dinero para la empresa. Este sistema se desarrolla en función de las necesidades comerciales de la gestión de recursos humanos de la empresa combinada con tecnología de la información para garantizar que el sistema pueda completar de manera inteligente todo el trabajo de gestión empresarial, garantizar la estabilidad y permanencia del sistema y mejorar la eficiencia de la gestión de recursos humanos. .

2. Tecnología de desarrollo

2.1 lenguaje Java

Java es un lenguaje de programación multiplataforma ampliamente utilizado lanzado en 1995 por Sun Microsystems (ahora Oracle). Es simple, orientado a objetos, robusto, seguro y portátil, y es ampliamente utilizado en el desarrollo de varios tipos de aplicaciones y sistemas.

Las siguientes son algunas características y descripciones clave del lenguaje Java:

(1) Fácil de aprender: Java toma prestada la sintaxis del lenguaje C++ y elimina algunas características complejas y propensas a errores, lo que hace que Java sea relativamente más fácil de aprender. Tiene una estructura gramatical clara, una rica biblioteca de clases y potentes herramientas, lo que facilita a los desarrolladores el aprendizaje y el uso de Java.

(2) Orientado a objetos: Java es un lenguaje de programación puro orientado a objetos. Admite funciones orientadas a objetos, como encapsulación, herencia y polimorfismo, lo que permite a los desarrolladores estructurar y organizar el código de una manera más intuitiva y modular. El estilo de programación orientado a objetos también ayuda a mejorar la reutilización y el mantenimiento del código.

(3) Multiplataforma: Java es altamente portátil, puede escribirse una vez y ejecutarse en todas partes. Utiliza la máquina virtual de Java (JVM) como capa intermedia de la plataforma para convertir el código de bytes de Java en código ejecutable en una plataforma específica. Esto permite que los programas de Java se ejecuten en diferentes sistemas operativos (como Windows, Linux, Mac, etc.) y hardware, proporcionando a los desarrolladores una amplia gama de entornos de destino.

(4) Biblioteca de clases y herramientas poderosas: Java tiene una biblioteca de clases poderosa y rica, que proporciona una variedad de clases y métodos predefinidos, para que los desarrolladores puedan construir varias aplicaciones rápidamente. Estas bibliotecas de clases incluyen funciones en red, interfaz gráfica, conexión a bases de datos, encriptación, subprocesos múltiples, etc. Además, Java tiene ricas herramientas de desarrollo, como un entorno de desarrollo integrado (IDE) y un depurador, para ayudar a los desarrolladores a mejorar la eficiencia y la calidad del desarrollo.

(5) Seguridad: Java está diseñado como un lenguaje altamente seguro. Proporciona mecanismos de seguridad como la verificación de código de bytes y un modelo de seguridad de espacio aislado para evitar posibles infracciones de seguridad y operaciones maliciosas. Esto hace que Java tenga una gran credibilidad y seguridad a la hora de desarrollar redes y sistemas distribuidos.

(6) Compatibilidad con subprocesos múltiples: Java admite de forma nativa la programación de subprocesos múltiples, lo que permite ejecutar varias tareas al mismo tiempo. Mediante el uso de subprocesos, los desarrolladores pueden implementar computación paralela, mejorar la velocidad de respuesta del programa y la potencia de procesamiento. Java proporciona mecanismos integrados de administración y sincronización de subprocesos que facilitan la escritura de código seguro para subprocesos.

Con todo, Java es un lenguaje de programación potente, portátil, seguro y fácil de aprender. Se basa en la idea de la programación orientada a objetos y tiene ricas bibliotecas de clases y soporte de herramientas. A través de la función multiplataforma de la máquina virtual Java, los desarrolladores pueden escribir código una vez para ejecutarlo en múltiples sistemas operativos y hardware. Java se usa ampliamente en el desarrollo de aplicaciones de escritorio, aplicaciones empresariales, aplicaciones móviles y sistemas integrados.

2.2Bota de resorte

Spring Boot es un marco para crear rápidamente aplicaciones Spring de nivel de producción, autónomas y fácilmente configurables. Se basa en el marco Spring y utiliza el principio de convención sobre configuración, con el objetivo de simplificar el desarrollo y la implementación de aplicaciones Spring.

Aquí hay algunas características clave y descripciones del marco Spring Boot:

(1) Configuración simplificada: Spring Boot configura las aplicaciones Spring de manera que las convenciones son superiores a las configuraciones, lo que permite a los desarrolladores iniciar proyectos y desarrollarlos rápidamente. Configura automáticamente muchas funciones de uso común, como conexiones a bases de datos, desarrollo web, seguridad, etc., siguiendo las mejores prácticas de forma predeterminada.

(2) Soporte de microservicios: Spring Boot se enfoca en crear aplicaciones basadas en arquitectura de microservicios. Proporciona algunas características y herramientas convenientes, como servidores de aplicaciones integrados (como Tomcat, Jetty), registro y descubrimiento de servicios, equilibrio de carga, etc., lo que permite a los desarrolladores crear y administrar microservicios fácilmente.

(3) Gestión de dependencias automatizada: Spring Boot simplifica la configuración de dependencias del proyecto a través de la gestión de dependencias automatizada. Proporciona un concepto llamado "Iniciador", que es un paquete de dependencias predefinido, que puede introducir varias bibliotecas de dependencias relacionadas al mismo tiempo. Los desarrolladores solo necesitan agregar las dependencias de inicio apropiadas y Spring Boot resolverá e importará automáticamente las dependencias requeridas.

(4) Contenedor de Servlet integrado: Spring Boot integra contenedores de Servlet integrados (como Tomcat, Jetty), lo que facilita y hace más conveniente el desarrollo y la implementación de aplicaciones web. Los desarrolladores no necesitan instalar y configurar contenedores de Servlet manualmente, solo necesitan escribir códigos y pueden ejecutar y probar aplicaciones directamente.

(5) Supervisión y gestión potentes: Spring Boot proporciona funciones de supervisión y gestión potentes, lo que permite a los desarrolladores comprender mejor los indicadores de estado y rendimiento de la aplicación. Integra muchas herramientas de monitoreo listas para usar, como controles de estado, métricas, registro, etc., para facilitar a los desarrolladores la resolución de problemas y la optimización del rendimiento.

(6) Compatibilidad con el ecosistema: como una versión derivada del marco Spring, Spring Boot puede hacer un uso completo de todos los aspectos del ecosistema Spring. Puede integrar fácilmente otros módulos y extensiones del marco Spring, como Spring Security, Spring Data, etc., para proporcionar a los desarrolladores funciones y soporte más ricos y completos.

En general, Spring Boot es un marco que simplifica el desarrollo de aplicaciones Spring. Proporciona muchas funciones convenientes y convenientes, como configuración simplificada, soporte de microservicios y administración automática de dependencias. Al usar Spring Boot, los desarrolladores pueden crear e implementar rápidamente aplicaciones eficientes y sólidas, y disfrutar de las ricas funciones y el soporte del ecosistema Spring.

2.3 Vue

Vue.js es un marco JavaScript popular para crear interfaces de usuario (UI), especialmente aplicaciones de una sola página. Vue es popular entre los desarrolladores por su simplicidad, capacidad de respuesta y flexibilidad, y es fácil de integrar en proyectos existentes.

Estas son algunas características clave y descripciones de la tecnología Vue:

(1) Responsivo: Vue utiliza un mecanismo de vinculación de datos receptivo. Al vincular los datos a la vista, cuando los datos cambien, la vista se actualizará automáticamente. Esto permite a los desarrolladores gestionar y responder a los cambios en los datos de forma intuitiva y concisa.

(2) Componentización: Vue alienta a los desarrolladores a dividir las aplicaciones en múltiples componentes reutilizables. Cada componente tiene su propia plantilla, lógica y estilo, lo que hace que el proceso de desarrollo sea más modular y fácil de mantener. La comunicación entre los componentes se logra a través de accesorios y eventos.

(3) DOM virtual: Vue utiliza DOM virtual para optimizar el rendimiento de la representación de páginas. Virtual DOM es un objeto JavaScript ligero que representa la estructura DOM real. Al comparar los cambios en el DOM virtual, Vue solo actualiza las partes que realmente deben cambiarse, lo que mejora la eficiencia de representación de la página.

(4) Sintaxis de plantilla: Vue proporciona una sintaxis de plantilla concisa y flexible para vincular declarativamente datos a DOM. La sintaxis de las plantillas admite la interpolación, las directivas y las expresiones, lo que facilita a los desarrolladores el uso de la lógica de JavaScript y el contenido dinámico en las plantillas.

(5) Enrutamiento y gestión de estado: Vue proporciona complementos oficiales como Vue Router y Vuex para enrutamiento y gestión de estado. Vue Router se utiliza para implementar la función de enrutamiento de aplicaciones de una sola página, mientras que Vuex proporciona una gestión de estado centralizada para facilitar el uso compartido y la gestión de estados entre múltiples componentes.

(6) Ecosistema y soporte de la comunidad: Vue tiene una comunidad activa de código abierto y un gran ecosistema. Muchas bibliotecas y complementos de terceros se integran a la perfección con Vue, lo que brinda funciones ricas y soporte de herramientas. La comunidad de Vue proporciona una gran cantidad de documentación, tutoriales y ejemplos, lo que brinda a los desarrolladores recursos para aprender y resolver problemas.

Mediante el uso de la tecnología Vue, los desarrolladores pueden crear interfaces de usuario interactivas y realizar enlaces dinámicos de datos y vistas. Funciones como la capacidad de respuesta, la creación de componentes y el DOM virtual de Vue hacen que el proceso de desarrollo sea más eficiente y flexible. Al mismo tiempo, el soporte de la comunidad y el ecosistema de Vue brindan una gran cantidad de herramientas y recursos para ayudar a los desarrolladores a crear y mantener mejor las aplicaciones de Vue.

2.4 MySQL

MySQL es un sistema de gestión de bases de datos relacionales (RDBMS) de código abierto, desarrollado por la empresa sueca MySQL AB. Es ampliamente utilizado en varios tipos de aplicaciones, desde pequeños sitios web personales hasta grandes aplicaciones de nivel empresarial.

Las siguientes son algunas características clave y descripciones de la base de datos MySQL:

(1) Base de datos relacional: MySQL es un sistema de administración de base de datos relacional que organiza y almacena datos en función de los conceptos de tablas y relaciones. Admite SQL (lenguaje de consulta estructurado) como lenguaje estándar para consultar y administrar bases de datos.

(2) Confiable y estable: MySQL es famoso por su confiabilidad y estabilidad, y es utilizado por muchas organizaciones grandes para procesar datos importantes. Tiene alta disponibilidad, tolerancia a fallas e integridad de datos, y es adecuado para procesar grandes cantidades de datos a nivel empresarial.

(3) Multiplataforma: MySQL puede ejecutarse en múltiples sistemas operativos, incluidos Windows, Linux, Mac, etc. Esto permite a los desarrolladores usar MySQL para crear e implementar aplicaciones en diferentes plataformas.

(4) Alto rendimiento: MySQL funciona bien en el procesamiento de grandes cantidades de datos y tiene velocidades de lectura y escritura eficientes. Realiza varias optimizaciones de rendimiento, como indexación, optimización de consultas y mecanismos de almacenamiento en caché, para proporcionar capacidades de procesamiento y acceso rápido a los datos.

(5) Escalabilidad: MySQL tiene una buena escalabilidad y puede manejar grandes cantidades de datos sin afectar el rendimiento. Admite la expansión horizontal y la expansión vertical, lo que permite aumentar la capacidad y el rendimiento de la base de datos al agregar más servidores, particiones y clústeres.

(6) Seguridad: MySQL proporciona una variedad de mecanismos de seguridad para proteger la seguridad de los datos. Admite funciones como la autenticación de usuarios, el control de acceso, la transmisión cifrada y el procesamiento de transacciones, y puede proteger los datos confidenciales contra el acceso no autorizado y los ataques maliciosos.

(7) Funciones enriquecidas: MySQL proporciona funciones y características enriquecidas, como procedimientos almacenados, activadores, restricciones de clave externa, vistas, copia de seguridad y recuperación, etc. Estas características permiten a los desarrolladores administrar y operar bases de datos de manera más flexible y eficiente.

Con todo, MySQL es un sistema de gestión de bases de datos relacionales confiable, estable y de alto rendimiento. Sobresale en confiabilidad, escalabilidad y seguridad, y es multiplataforma y rico en funciones. Como software de código abierto, MySQL tiene una gran comunidad de usuarios y un grupo de desarrolladores activo, que brinda mucho soporte, documentación y recursos. Ya sea un sitio web pequeño o una gran aplicación de nivel empresarial, MySQL es una opción poderosa.

3. Diseño funcional

 La investigación y el desarrollo de este proyecto adopta principalmente el patrón de diseño del navegador web. La estructura de su sistema se muestra en la Figura 3-1:

Este sistema utiliza tecnología moderna de redes informáticas para integrar los métodos tradicionales de propaganda de información y está diseñado y completado de acuerdo con el proceso práctico. Al mismo tiempo, mejorar el servicio y diseñar preliminarmente una plataforma de sistema de recursos humanos empresarial para facilitar las operaciones de transacciones relacionadas. Para que el sistema juegue un papel más importante en varias gestiones y realice una gestión eficiente de la información computarizada, los requisitos funcionales del objetivo de desarrollo se introducen de la siguiente manera:

(1) Módulo de inicio de sesión del administrador

El administrador tiene derecho a gestionar la plataforma de recursos humanos de la empresa del sistema, pero todo registro y uso de permisos debe ser autorizado por el superadministrador. El administrador puede gestionar la gestión de departamentos, la gestión de formación, la gestión de contratación, la gestión de licencias, la gestión de empleados, y gestión de asistencia Administración, Administración de Nómina.

(2) Módulo de gestión de departamentos

Los administradores con determinados derechos de gestión pueden ver la lista de gestión de departamentos y agregar, eliminar, modificar y consultar la gestión de departamentos correspondiente.

(3) Módulo de gestión de usuarios

Los administradores con ciertos derechos de administración pueden ver los datos de la lista de usuarios, así como las operaciones correspondientes de adición, eliminación, modificación y consulta de usuarios.

(4) Módulo de gestión de listas de gestión de formación

Los administradores con ciertos derechos de gestión pueden ver los datos de la lista de gestión de formación de usuarios y modificar la gestión de formación.

4. Realice la visualización del efecto.

 

5. Artículos de referencia

 6. Código central

@RestController
@RequestMapping("renren/checkmanger")
public class CheckMangerController {
    @Autowired
    private CheckMangerService checkMangerService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    /*@RequiresPermissions("renren:checkmanger:list")*/
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = checkMangerService.queryPage(params);
        Object principal = SecurityUtils.getSubject().getPrincipal();
        SysUserEntity userEntity = (SysUserEntity) principal;
        return R.ok().put("page", page).put("user",userEntity.getUsername());
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    /*@RequiresPermissions("renren:checkmanger:info")*/
    public R info(@PathVariable("id") Integer id){
		CheckMangerEntity checkManger = checkMangerService.getById(id);

        return R.ok().put("checkManger", checkManger);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    /*@RequiresPermissions("renren:checkmanger:save")*/
    public R save(@RequestBody CheckMangerEntity checkManger){
        Object principal = SecurityUtils.getSubject().getPrincipal();
        SysUserEntity userEntity = (SysUserEntity) principal;
        QueryWrapper<CheckMangerEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("staff_num",userEntity.getUserNum());
        List<CheckMangerEntity> list = checkMangerService.list(queryWrapper);
        //上班打卡
        if (checkManger.getRemark().equals("1")){
            if (list.size()>0){
                CheckMangerEntity checkMangerEntity = list.get(0);
                Date shanDa = checkMangerEntity.getShanDa();
                String format = DateUtils.format(shanDa, "yyyy-MM-dd");
                String format2 = DateUtils.format(new Date(), "yyyy-MM-dd");
                if (format.equals(format2)){
                    return R.error("今天已签到");
                }
            }
            checkManger.setShanDa(new Date());
        }
        if (checkManger.getRemark().equals("2")){
            if (list.size()>0){
                CheckMangerEntity checkMangerEntity = list.get(0);
                Date shanDa = checkMangerEntity.getXiaDa();
                String format = DateUtils.format(shanDa, "yyyy-MM-dd");
                if (format!=null){
                    String format2 = DateUtils.format(new Date(), "yyyy-MM-dd");
                    if (format.equals(format2)){
                        return R.error("今天已签到");
                    }
                }

            }
            CheckMangerEntity entity = list.get(0);
            entity.setXiaDa(new Date());
        /*    entity.setStaffNum(userEntity.getUserNum());
            entity.setPartName(userEntity.getUserPart());
            entity.setStaffName(userEntity.getUsereal());*/
            checkMangerService.updateById(entity);
            return R.ok();
        }

        checkManger.setStaffNum(userEntity.getUserNum());
        checkManger.setPartName(userEntity.getUserPart());
        checkManger.setStaffName(userEntity.getUsereal());


        checkMangerService.save(checkManger);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    /*@RequiresPermissions("renren:checkmanger:update")*/
    public R update(@RequestBody CheckMangerEntity checkManger){
		checkMangerService.updateById(checkManger);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    /*@RequiresPermissions("renren:checkmanger:delete")*/
    public R delete(@RequestBody Integer[] ids){
		checkMangerService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}
@RestController
@RequestMapping("renren/coursemanager")
public class CourseManagerController {
    @Autowired
    private CourseManagerService courseManagerService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = courseManagerService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Integer id){
		CourseManagerEntity courseManager = courseManagerService.getById(id);

        return R.ok().put("courseManager", courseManager);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody CourseManagerEntity courseManager){
		courseManagerService.save(courseManager);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody CourseManagerEntity courseManager){
		courseManagerService.updateById(courseManager);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Integer[] ids){
		courseManagerService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}
@RestController
@RequestMapping("renren/coursetype")
public class CourseTypeController {
    @Autowired
    private CourseTypeService courseTypeService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = courseTypeService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Integer id){
		CourseTypeEntity courseType = courseTypeService.getById(id);

        return R.ok().put("courseType", courseType);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody CourseTypeEntity courseType){
		courseTypeService.save(courseType);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody CourseTypeEntity courseType){
		courseTypeService.updateById(courseType);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Integer[] ids){
		courseTypeService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}
@RestController
@RequestMapping("renren/hupart")
public class HuPartController {
    @Autowired
    private HuPartService huPartService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    /*@RequiresPermissions("renren:hupart:list")*/
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = huPartService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    /*@RequiresPermissions("renren:hupart:info")*/
    public R info(@PathVariable("id") Integer id){
		HuPartEntity huPart = huPartService.getById(id);

        return R.ok().put("huPart", huPart);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    /*@RequiresPermissions("renren:hupart:save")*/
    public R save(@RequestBody HuPartEntity huPart){
		huPartService.save(huPart);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    /*@RequiresPermissions("renren:hupart:update")*/
    public R update(@RequestBody HuPartEntity huPart){
		huPartService.updateById(huPart);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
   /* @RequiresPermissions("renren:hupart:delete")*/
    public R delete(@RequestBody Integer[] ids){
		huPartService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}
@RestController
@RequestMapping("renren/leavemanger")
public class LeaveMangerController {
    @Autowired
    private LeaveMangerService leaveMangerService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    /*@RequiresPermissions("renren:leavemanger:list")*/
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = leaveMangerService.queryPage(params);

        Object principal = SecurityUtils.getSubject().getPrincipal();
        SysUserEntity userEntity = (SysUserEntity) principal;
        return R.ok().put("page", page).put("user",userEntity.getUsername());
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    /*@RequiresPermissions("renren:leavemanger:info")*/
    public R info(@PathVariable("id") Integer id){
		LeaveMangerEntity leaveManger = leaveMangerService.getById(id);

        return R.ok().put("leaveManger", leaveManger);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    /*@RequiresPermissions("renren:leavemanger:save")*/
    public R save(@RequestBody LeaveMangerEntity leaveManger){
		leaveMangerService.save(leaveManger);

        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    /*@RequiresPermissions("renren:leavemanger:update")*/
    public R update(@RequestBody LeaveMangerEntity leaveManger){
		leaveMangerService.updateById(leaveManger);

        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    /*@RequiresPermissions("renren:leavemanger:delete")*/
    public R delete(@RequestBody Integer[] ids){
		leaveMangerService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

}

Supongo que te gusta

Origin blog.csdn.net/lf21qp/article/details/131691293
Recomendado
Clasificación