From ef10b99d3384a3d7f3892e770a2d108c8190a681 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BB=98=E7=BB=AA=E5=A3=AE?= <2235602974@qq.com> Date: Sat, 26 Mar 2022 14:41:17 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=E5=B2=97=E4=BD=8D=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/2pigxx.sql | 40 +++++ db/6pigxx_config.sql | 2 +- .../pigx/admin/api/entity/SysPost.java | 101 +++++++++++++ .../pigx/admin/api/vo/PostExcelVO.java | 64 ++++++++ .../admin/controller/SysPostController.java | 139 ++++++++++++++++++ .../pigx/admin/mapper/SysPostMapper.java | 33 +++++ .../pigx/admin/service/SysPostService.java | 50 +++++++ .../service/impl/SysPostServiceImpl.java | 111 ++++++++++++++ .../src/main/resources/file/post.xlsx | Bin 0 -> 8905 bytes 9 files changed, 539 insertions(+), 1 deletion(-) create mode 100644 pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java create mode 100644 pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java create mode 100644 pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java create mode 100644 pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java create mode 100644 pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java create mode 100644 pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java create mode 100644 pigx-upms/pigx-upms-biz/src/main/resources/file/post.xlsx diff --git a/db/2pigxx.sql b/db/2pigxx.sql index ab36c632d..af31f87ba 100644 --- a/db/2pigxx.sql +++ b/db/2pigxx.sql @@ -73,6 +73,34 @@ INSERT INTO `sys_dept_relation` VALUES (7, 12); INSERT INTO `sys_dept_relation` VALUES (8, 8); COMMIT; +-- ---------------------------- +-- Table structure for sys_post +-- ---------------------------- +DROP TABLE IF EXISTS `sys_post`; +CREATE TABLE `sys_post` ( + `post_id` bigint NOT NULL COMMENT '岗位ID', + `post_code` varchar(64) CHARACTER SET utf8mb4 NOT NULL COMMENT '岗位编码', + `post_name` varchar(50) CHARACTER SET utf8mb4 NOT NULL COMMENT '岗位名称', + `post_sort` int(0) NOT NULL COMMENT '岗位排序', + `remark` varchar(500) CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT '岗位描述', + `del_flag` char(1) CHARACTER SET utf8mb4 NOT NULL DEFAULT '0' COMMENT '是否删除 -1:已删除 0:正常', + `create_time` datetime(0) NULL DEFAULT NULL COMMENT '创建时间', + `create_by` varchar(64) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '创建人', + `update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间', + `update_by` varchar(64) CHARACTER SET utf8mb4 NOT NULL DEFAULT '' COMMENT '更新人', + `tenant_id` bigint(0) NULL DEFAULT NULL COMMENT '租户ID', + PRIMARY KEY (`post_id`) USING BTREE +) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '岗位信息表'; + +-- ---------------------------- +-- Records of sys_post +-- ---------------------------- +BEGIN; +INSERT INTO `sys_post` VALUES (1, 'CTO', 'CTO', 0, 'CTO', '0', '2022-03-26 13:48:17', '', '2022-03-26 13:50:14', '', 1); +INSERT INTO `sys_post` VALUES (2, 'CEO', 'CEO', 1, 'CEO', '0', '2022-03-26 13:48:27', '', '2022-03-26 13:48:38', '', 1); +COMMIT; + + -- ---------------------------- -- Table structure for sys_dict -- ---------------------------- @@ -323,6 +351,12 @@ INSERT INTO `sys_menu` VALUES (1500, '租户管理', '', '/admin/tenant/index', INSERT INTO `sys_menu` VALUES (1501, '租户新增', 'admin_systenant_add', NULL, 1500, '1', 0, '0', '1', ' ', '2018-05-15 21:35:18', ' ', '2020-03-24 08:56:52', '0', 1); INSERT INTO `sys_menu` VALUES (1502, '租户修改', 'admin_systenant_edit', NULL, 1500, '1', 1, '0', '1', ' ', '2018-05-15 21:35:18', ' ', '2020-03-24 08:56:53', '0', 1); INSERT INTO `sys_menu` VALUES (1503, '租户删除', 'admin_systenant_del', NULL, 1500, '1', 2, '0', '1', ' ', '2018-05-15 21:35:18', ' ', '2020-03-24 08:56:54', '0', 1); +INSERT INTO `sys_menu` VALUES (1600, '岗位管理', NULL, '/admin/post/index', 1000, 'icon-record', 6, '0', '0', ' ', '2022-03-26 13:04:14', ' ', NULL, '0', 1); +INSERT INTO `sys_menu` VALUES (1601, '岗位信息查看', 'sys_post_view', NULL, 1600, NULL, 0, '0', '1', ' ', '2022-03-26 13:05:34', ' ', NULL, '0', 1); +INSERT INTO `sys_menu` VALUES (1602, '岗位信息新增', 'sys_post_add', NULL, 1600, NULL, 1, '0', '1', ' ', '2022-03-26 13:06:00', ' ', NULL, '0', 1); +INSERT INTO `sys_menu` VALUES (1603, '岗位信息修改', 'sys_post_edit', NULL, 1600, NULL, 2, '0', '1', ' ', '2022-03-26 13:06:31', ' ', '2022-03-26 13:06:38', '0', 1); +INSERT INTO `sys_menu` VALUES (1604, '岗位信息删除', 'sys_post_del', NULL, 1600, NULL, 3, '0', '1', ' ', '2022-03-26 13:06:31', ' ', NULL, '0', 1); +INSERT INTO `sys_menu` VALUES (1605, '岗位导入导出', 'sys_post_export', NULL, 1600, NULL, 4, '0', '1', ' ', '2022-03-26 13:06:31', ' ', '2022-03-26 06:32:02', '0', 1); INSERT INTO `sys_menu` VALUES (2000, '系统管理', NULL, '/system', -1, 'icon-xitongpeizhi', 1, '0', '0', ' ', '2017-11-07 20:56:00', ' ', '2022-02-05 16:15:14', '0', 1); INSERT INTO `sys_menu` VALUES (2100, '日志管理', NULL, '/admin/log/index', 2000, 'icon-rizhi', 5, '0', '0', ' ', '2017-11-20 14:06:22', ' ', '2020-03-24 08:56:56', '0', 1); INSERT INTO `sys_menu` VALUES (2101, '日志删除', 'sys_log_del', NULL, 2100, NULL, 1, '0', '1', ' ', '2017-11-20 20:37:37', ' ', '2021-05-25 03:12:55', '0', 1); @@ -578,6 +612,12 @@ INSERT INTO `sys_role_menu` VALUES (1, 1500); INSERT INTO `sys_role_menu` VALUES (1, 1501); INSERT INTO `sys_role_menu` VALUES (1, 1502); INSERT INTO `sys_role_menu` VALUES (1, 1503); +INSERT INTO `sys_role_menu` VALUES (1, 1600); +INSERT INTO `sys_role_menu` VALUES (1, 1601); +INSERT INTO `sys_role_menu` VALUES (1, 1602); +INSERT INTO `sys_role_menu` VALUES (1, 1603); +INSERT INTO `sys_role_menu` VALUES (1, 1604); +INSERT INTO `sys_role_menu` VALUES (1, 1605); INSERT INTO `sys_role_menu` VALUES (1, 2000); INSERT INTO `sys_role_menu` VALUES (1, 2100); INSERT INTO `sys_role_menu` VALUES (1, 2101); diff --git a/db/6pigxx_config.sql b/db/6pigxx_config.sql index f14bf11ce..3d20832f4 100644 --- a/db/6pigxx_config.sql +++ b/db/6pigxx_config.sql @@ -38,7 +38,7 @@ INSERT INTO `config_info` VALUES (3, 'pigx-codegen-dev.yml', 'DEFAULT_GROUP', '# INSERT INTO `config_info` VALUES (4, 'pigx-daemon-elastic-job-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n## 定时任务\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true', '4124589805657db024b20772cccf57f5', '2019-04-18 02:12:57', '2020-11-09 16:18:05', NULL, '172.16.1.198', '', '', '定时任务-elastic-job配置', 'null', 'null', 'yaml', 'null'); INSERT INTO `config_info` VALUES (5, 'pigx-gateway-dev.yml', 'DEFAULT_GROUP', 'gateway:\n encode-key: \'pigxpigxpigxpigx\'\n\nswagger:\n ignore-providers:\n - pigx-monitor\n - pigx-auth\n - pigx-tx-manager\n\nribbon:\n rule:\n gray-enabled: true\n\n# 验证码相关配置参考: http://t.cn/A647jEdu\naj:\n captcha:\n cache-type: redis\n water-mark: pig4cloud', 'cd9f8a6a46e2c128f3b172be76ea3221', '2019-04-18 02:13:52', '2021-11-09 12:09:34', '', '127.0.0.1', '', '', '', '', '', 'yaml', ''); INSERT INTO `config_info` VALUES (6, 'pigx-monitor-dev.yml', 'DEFAULT_GROUP', 'spring:\n # 安全配置\n security:\n user:\n name: ENC(rZHA4LW5hHmhLAAzJoFNag==) # pigx\n password: ENC(bjeyh+Aeii3kHXkoo00ZUw==) # pigx\n autoconfigure:\n exclude: com.pig4cloud.pigx.common.core.config.JacksonConfiguration\n boot:\n admin:\n ui:\n title: \'pigx 服务状态监控\'\n brand: \'pigx 服务状态监控\'\n external-views:\n - label: \"SQL监控\"\n url: /druid/sql.html\n order: 2000\n iframe: true\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n endpoint:\n health:\n show-details: ALWAYS #显示详细信息\n\n\n# druid 监控的服务\nmonitor:\n applications:\n - pigx-upms-biz\n - pigx-pay-platform\n', 'cbc0b536fe11eeff0dcf81be11dab6e4', '2019-04-18 02:14:17', '2022-02-18 13:44:07', 'nacos', '127.0.0.1', '', '', '监控配置文件', 'null', 'null', 'yaml', 'null'); -INSERT INTO `config_info` VALUES (7, 'pigx-upms-biz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n client-secret: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n scope: server\n ignore-urls:\n - /error\n - /druid/**\n - /actuator/**\n - /v2/api-docs\n\n# 数据源\nspring:\n autoconfigure:\n exclude: org.springframework.cloud.gateway.config.GatewayAutoConfiguration,org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n stat-view-servlet:\n enabled: true\n allow: \"\"\n url-pattern: /druid/*\n #login-username: admin\n #login-password: admin\n filter:\n stat:\n enabled: true\n log-slow-sql: true\n slow-sql-millis: 10000\n merge-sql: false\n wall:\n config:\n multi-statement-allow: true\n\n# 文件系统 (minio测试环境,不可当生产使用)\noss:\n endpoint: http://minio.pig4cloud.com\n access-key: lengleng\n secret-key: lengleng\n bucket-name: tmp\n\n# Logger Config\nlogging:\n level:\n com.pig4cloud.pigx.admin.mapper: debug\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - sys_user\n - sys_role\n - sys_menu\n - sys_dept\n - sys_log\n - sys_social_details\n - sys_dict\n - sys_dict_item\n - sys_public_param\n - sys_log\n - sys_file\n - sys_oauth_client_details ', '1d1062f04c4b7c0a99984be0e05083c8', '2019-04-18 02:32:44', '2022-02-17 15:33:21', 'nacos', '127.0.0.1', '', '', '', '', '', 'yaml', ''); +INSERT INTO `config_info` VALUES (7, 'pigx-upms-biz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n client-secret: ENC(ltJPpR50wT0oIY9kfOe1Iw==)\n scope: server\n ignore-urls:\n - /error\n - /druid/**\n - /actuator/**\n - /v2/api-docs\n\n# 数据源\nspring:\n autoconfigure:\n exclude: org.springframework.cloud.gateway.config.GatewayAutoConfiguration,org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n stat-view-servlet:\n enabled: true\n allow: \"\"\n url-pattern: /druid/*\n #login-username: admin\n #login-password: admin\n filter:\n stat:\n enabled: true\n log-slow-sql: true\n slow-sql-millis: 10000\n merge-sql: false\n wall:\n config:\n multi-statement-allow: true\n\n# 文件系统 (minio测试环境,不可当生产使用)\noss:\n endpoint: http://minio.pig4cloud.com\n access-key: lengleng\n secret-key: lengleng\n bucket-name: tmp\n\n# Logger Config\nlogging:\n level:\n com.pig4cloud.pigx.admin.mapper: debug\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - sys_user\n - sys_role\n - sys_menu\n - sys_dept\n - sys_log\n - sys_social_details\n - sys_dict\n - sys_dict_item\n - sys_public_param\n - sys_log\n - sys_file\n - sys_oauth_client_details\n - sys_post', '1d1062f04c4b7c0a99984be0e05083c8', '2019-04-18 02:32:44', '2022-02-17 15:33:21', 'nacos', '127.0.0.1', '', '', '', '', '', 'yaml', ''); INSERT INTO `config_info` VALUES (8, 'pigx-tx-manager-dev.yml', 'DEFAULT_GROUP', '# 页面配置\nspring:\n mvc:\n static-path-pattern: /**\n resources:\n static-locations: classpath:/static/\n\n\n# LCN 配置\ntm:\n transaction:\n netty:\n delaytime: 5 # 客户端链接最大通讯时间 (秒)\n hearttime: 15 # 客户端心跳时间 (秒)\n redis:\n savemaxtime: 30 # redis 保存时间 (秒)\n socket:\n port: 9998 # 通讯端口\n maxconnection: 1000 #最大链接数\n compensate:\n auto: false #是否自动补偿\n notifyUrl: http://ip:port/path #补偿结果通知(配消息总线里面)\n tryTime: 30 # z再次重试时间间隔\n maxWaitTime: 5000 # 请求超时的最大时间 (毫秒)', '885f5c125f2df7a08692929ccce154be', '2019-04-18 02:54:03', '2019-04-18 02:54:03', NULL, '127.0.0.1', '', '', '分布式事务协调模块', NULL, NULL, 'yaml', NULL); INSERT INTO `config_info` VALUES (9, 'pigx-daemon-quartz-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)\n scope: server\n\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n resources:\n static-locations: classpath:/static/,classpath:/views/\n quartz:\n #相关属性配置\n properties:\n org:\n quartz:\n scheduler:\n instanceName: clusteredScheduler\n instanceId: AUTO\n jobStore:\n class: org.springframework.scheduling.quartz.LocalDataSourceJobStore\n driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate\n tablePrefix: QRTZ_\n isClustered: true\n clusterCheckinInterval: 10000\n useProperties: false\n threadPool:\n class: org.quartz.simpl.SimpleThreadPool\n threadCount: 50\n threadPriority: 5\n threadsInheritContextClassLoaderOfInitializingThread: true\n #数据库方式\n job-store-type: jdbc\n #初始化表结构\n #jdbc:\n #initialize-schema: never\n\n', '9ff6e1d6f4d7f8776cb13e31c9dc8ce9', '2019-04-18 03:08:34', '2022-02-18 14:44:22', 'nacos', '127.0.0.1', '', '', '', '', '', 'yaml', ''); INSERT INTO `config_info` VALUES (10, 'pigx-pay-platform-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n ignore-urls:\n - /druid/**\n - /error\n - /actuator/**\n - /v2/api-docs\n# 数据源\nspring:\n datasource:\n type: com.alibaba.druid.pool.DruidDataSource\n druid:\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL_USER:root}\n password: ${MYSQL_PWD:root}\n url: jdbc:mysql://${MYSQL_HOST:pigx-mysql}:${MYSQL_PORT:3306}/${MYSQL_DB:pigxx_pay}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true&allowPublicKeyRetrieval=true\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n template-loader-path: classpath:/templates/\n# 租户表维护\npigx:\n pay:\n test: lengleng\n aliPayConfig:\n expire-time: 30\n return-url: http://pig4cloud.com\n notify-url: http://wechat.pigx.top/pay/notify/ali/callbak\n wxPayConfig:\n notify-url: https://admin.pig4cloud.com/pay/notify/wx/callbak\n mergePayConfig:\n return-url: http://pig4cloud.com\n notify-url: http://wechat.pigx.top/pay/notify/merge/callbak\n xsequence: #发号器相关配置\n db:\n retry-times: 3\n table-name: pay_sequence\n tenant:\n column: tenant_id\n tables:\n - pay_channel\n - pay_trade_order\n - pay_goods_order\n - pay_notify_record', 'ee15c87a8ec17f7272d0f2f4597ee764', '2019-05-28 11:46:27', '2022-02-18 14:44:43', 'nacos', '127.0.0.1', '', '', '支付模块配置', 'null', 'null', 'yaml', 'null'); diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java new file mode 100644 index 000000000..4aa528da3 --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/entity/SysPost.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.admin.api.entity; + +import com.baomidou.mybatisplus.annotation.*; +import com.baomidou.mybatisplus.extension.activerecord.Model; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 岗位信息表 + * + * @author fxz + * @date 2022-03-26 12:50:43 + */ +@Data +@TableName("sys_post") +@EqualsAndHashCode(callSuper = true) +@ApiModel(value = "岗位信息表") +public class SysPost extends Model { + + private static final long serialVersionUID = 1L; + + /** + * 岗位ID + */ + @TableId(value = "post_id", type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "岗位ID") + private Long postId; + + /** + * 岗位编码 + */ + @NotBlank(message = "岗位编码不能为空") + @ApiModelProperty(value = "岗位编码") + private String postCode; + + /** + * 岗位名称 + */ + @NotBlank(message = "岗位名称不能为空") + @ApiModelProperty(value = "岗位名称") + private String postName; + + /** + * 岗位排序 + */ + @NotNull(message = "排序值不能为空") + @ApiModelProperty(value = "岗位排序") + private Integer postSort; + + /** + * 岗位描述 + */ + @ApiModelProperty(value = "岗位描述") + private String remark; + + /** + * 是否删除 -1:已删除 0:正常 + */ + @TableLogic + @ApiModelProperty(value = "是否删除 -1:已删除 0:正常") + private String delFlag; + + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; + + /** + * 更新时间 + */ + @ApiModelProperty(value = "更新时间") + @TableField(fill = FieldFill.UPDATE) + private LocalDateTime updateTime; + +} diff --git a/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java new file mode 100644 index 000000000..3c0a5d961 --- /dev/null +++ b/pigx-upms/pigx-upms-api/src/main/java/com/pig4cloud/pigx/admin/api/vo/PostExcelVO.java @@ -0,0 +1,64 @@ +package com.pig4cloud.pigx.admin.api.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 岗位excel 对应的实体 + * + * @author fxz + * @date 2022/3/21 + */ +@Data +@ColumnWidth(30) +public class PostExcelVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 主键ID + */ + @ExcelProperty("岗位编号") + private Long postId; + + /** + * 岗位名称 + */ + @NotBlank(message = "岗位名称不能为空") + @ExcelProperty("岗位名称") + private String postName; + + /** + * 岗位标识 + */ + @NotBlank(message = "岗位标识不能为空") + @ExcelProperty("岗位标识") + private String postCode; + + /** + * 岗位排序 + */ + @NotNull(message = "岗位排序不能为空") + @ExcelProperty("岗位排序") + private Integer postSort; + + /** + * 岗位描述 + */ + @NotBlank(message = "岗位描述不能为空") + @ExcelProperty(value = "岗位描述") + private String remark; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + private LocalDateTime createTime; + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java new file mode 100644 index 000000000..e953bcb3a --- /dev/null +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/controller/SysPostController.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.admin.controller; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.pig4cloud.pigx.admin.api.entity.SysPost; +import com.pig4cloud.pigx.admin.api.vo.PostExcelVO; +import com.pig4cloud.pigx.admin.service.SysPostService; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.excel.annotation.RequestExcel; +import com.pig4cloud.pigx.common.excel.annotation.ResponseExcel; +import com.pig4cloud.pigx.common.log.annotation.SysLog; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * 岗位信息表 + * + * @author fxz + * @date 2022-03-26 12:50:43 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/post") +@Api(value = "post", tags = "岗位信息表管理") +public class SysPostController { + + private final SysPostService sysPostService; + + /** + * 分页查询 + * @param page 分页对象 + * @param sysPost 岗位信息表 + * @return + */ + @ApiOperation(value = "分页查询", notes = "分页查询") + @GetMapping("/page") + @PreAuthorize("@pms.hasPermission('sys_post_view')") + public R getSysPostPage(Page page, SysPost sysPost) { + return R.ok(sysPostService.page(page, Wrappers.query(sysPost))); + } + + /** + * 通过id查询岗位信息表 + * @param postId id + * @return R + */ + @ApiOperation(value = "通过id查询", notes = "通过id查询") + @GetMapping("/{postId}") + @PreAuthorize("@pms.hasPermission('sys_post_view')") + public R getById(@PathVariable("postId") Long postId) { + return R.ok(sysPostService.getById(postId)); + } + + /** + * 新增岗位信息表 + * @param sysPost 岗位信息表 + * @return R + */ + @ApiOperation(value = "新增岗位信息表", notes = "新增岗位信息表") + @SysLog("新增岗位信息表") + @PostMapping + @PreAuthorize("@pms.hasPermission('sys_post_add')") + public R save(@RequestBody SysPost sysPost) { + return R.ok(sysPostService.save(sysPost)); + } + + /** + * 修改岗位信息表 + * @param sysPost 岗位信息表 + * @return R + */ + @ApiOperation(value = "修改岗位信息表", notes = "修改岗位信息表") + @SysLog("修改岗位信息表") + @PutMapping + @PreAuthorize("@pms.hasPermission('sys_post_edit')") + public R updateById(@RequestBody SysPost sysPost) { + return R.ok(sysPostService.updateById(sysPost)); + } + + /** + * 通过id删除岗位信息表 + * @param postId id + * @return R + */ + @ApiOperation(value = "通过id删除岗位信息表", notes = "通过id删除岗位信息表") + @SysLog("通过id删除岗位信息表") + @DeleteMapping("/{postId}") + @PreAuthorize("@pms.hasPermission('sys_post_del')") + public R removeById(@PathVariable Long postId) { + return R.ok(sysPostService.removeById(postId)); + } + + /** + * 导出excel 表格 + * @return excel 文件流 + */ + @ResponseExcel + @GetMapping("/export") + @PreAuthorize("@pms.hasPermission('sys_post_export')") + public List export() { + return sysPostService.listPost(); + } + + /** + * 导入岗位 + * @param excelVOList 岗位列表 + * @param bindingResult 错误信息列表 + * @return ok fail + */ + @PostMapping("/import") + @PreAuthorize("@pms.hasPermission('sys_post_export')") + public R importRole(@RequestExcel List excelVOList, BindingResult bindingResult) { + return sysPostService.importPost(excelVOList, bindingResult); + } + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java new file mode 100644 index 000000000..b81edcd61 --- /dev/null +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/mapper/SysPostMapper.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.admin.mapper; + +import com.pig4cloud.pigx.admin.api.entity.SysPost; +import com.pig4cloud.pigx.common.data.datascope.PigxBaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * 岗位信息表 + * + * @author fxz + * @date 2022-03-26 12:50:43 + */ +@Mapper +public interface SysPostMapper extends PigxBaseMapper { + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java new file mode 100644 index 000000000..43b3f1440 --- /dev/null +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/SysPostService.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ + +package com.pig4cloud.pigx.admin.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.pig4cloud.pigx.admin.api.entity.SysPost; +import com.pig4cloud.pigx.admin.api.vo.PostExcelVO; +import com.pig4cloud.pigx.common.core.util.R; +import org.springframework.validation.BindingResult; + +import java.util.List; + +/** + * 岗位信息表 + * + * @author fxz + * @date 2022-03-26 12:50:43 + */ +public interface SysPostService extends IService { + + /** + * 导出excel 表格 + * @return + */ + List listPost(); + + /** + * 导入岗位 + * @param excelVOList 岗位列表 + * @param bindingResult 错误信息列表 + * @return ok fail + */ + R importPost(List excelVOList, BindingResult bindingResult); + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java new file mode 100644 index 000000000..31b82e6d8 --- /dev/null +++ b/pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/service/impl/SysPostServiceImpl.java @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2018-2025, lengleng All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) + */ +package com.pig4cloud.pigx.admin.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.pig4cloud.pigx.admin.api.entity.SysPost; +import com.pig4cloud.pigx.admin.api.vo.PostExcelVO; +import com.pig4cloud.pigx.admin.mapper.SysPostMapper; +import com.pig4cloud.pigx.admin.service.SysPostService; +import com.pig4cloud.pigx.common.core.util.R; +import com.pig4cloud.pigx.common.excel.vo.ErrorMessage; +import org.springframework.stereotype.Service; +import org.springframework.validation.BindingResult; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 岗位信息表 + * + * @author fxz + * @date 2022-03-26 12:50:43 + */ +@Service +public class SysPostServiceImpl extends ServiceImpl implements SysPostService { + + /** + * 导入岗位 + * @param excelVOList 岗位列表 + * @param bindingResult 错误信息列表 + * @return ok fail + */ + @Override + public R importPost(List excelVOList, BindingResult bindingResult) { + // 通用校验获取失败的数据 + List errorMessageList = (List) bindingResult.getTarget(); + + // 个性化校验逻辑 + List postList = this.list(); + + // 执行数据插入操作 组装 PostDto + for (int i = 0; i < excelVOList.size(); i++) { + PostExcelVO excel = excelVOList.get(i); + Set errorMsg = new HashSet<>(); + // 检验岗位名称或者岗位编码是否存在 + boolean existPost = postList.stream().anyMatch(post -> excel.getPostName().equals(post.getPostName()) + || excel.getPostCode().equals(post.getPostCode())); + + if (existPost) { + errorMsg.add(String.format("%s %s 岗位名或岗位编码已经存在", excel.getPostName(), excel.getPostCode())); + } + + // 数据合法情况 + if (CollUtil.isEmpty(errorMsg)) { + insertExcelPost(excel); + } + else { + // 数据不合法 + errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg)); + } + } + if (CollUtil.isNotEmpty(errorMessageList)) { + return R.failed(errorMessageList); + } + return R.ok(); + } + + /** + * 导出excel 表格 + * @return + */ + @Override + public List listPost() { + List postList = this.list(Wrappers.emptyWrapper()); + // 转换成execl 对象输出 + return postList.stream().map(post -> { + PostExcelVO postExcelVO = new PostExcelVO(); + BeanUtil.copyProperties(post, postExcelVO); + return postExcelVO; + }).collect(Collectors.toList()); + } + + /** + * 插入excel Post + */ + private void insertExcelPost(PostExcelVO excel) { + SysPost sysPost = new SysPost(); + BeanUtil.copyProperties(excel, sysPost); + this.save(sysPost); + } + +} diff --git a/pigx-upms/pigx-upms-biz/src/main/resources/file/post.xlsx b/pigx-upms/pigx-upms-biz/src/main/resources/file/post.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4e98211b965b0f799455a25bac73f76b6a308c7d GIT binary patch literal 8905 zcma)C1yqz>x2C&G8p)v>q$EVT1_Y$L85p`tI))BG8k7)}5|Boa96F`D8$oF<=>3ZS zyZ^dpt(kY$%#L$*oxS!mKm~XNG?@Dpro1eE|NLX2-hD6wn*yD{4$d6FJ2Ha1FHnAw zVdV+(2*Sd^NW#Iu;QXD;*ujC_!w!@g|3x023n%m-@BqgNJW7Pi)W8%N`Pu|~+`DhU z4ZcCH8=|mN<#F`*3@OWp43VmR7in8l#529;_WR(IL{NpD&BQbD70^K83aX`1H49{J z^~%kcPiO^0ZtB_iz_S7O03Yhu*h&otN;nd6B3jn31%x=e0pw-Z#)x7OhE8o1~B* zB>56gm)VY0u=LxSretPBE?WcAc&70?Me($1Ua&+WI!3>#$X7^}cgPTCw`WP9YRYoX zK+2ouk5AR&vcViw2P%exWohAFUOUiSSFLn>!9C0h0bV!Q2wJqTU|UJPMWs5mS2r+O zSg*W8gVP<#;c|GLyC=cqfa_i&u@;UN*ngUNVB$FZ#hsb0@63$*cQc!Uoy_m;?3*yB z(9TKFv4D6Rmhh9EYHl4vKa2_kAuLFPp;=aTzs4jzg|2?D<%wObj;c@J(~TQ}jRX%j z#^XhNNWc73DHm}dj7|#k=nRvW^2QPZ;sol4=LR;Zd9+%*3hW#v+K$?!T5l@hR=CSw z0j#0sd{V+2%rOQb9$`P03wT2uZmerQ;~ndRV0oT(eue=gIlxV}mT!k|2CG*} zYEm(PVdPD^b7A&a3*aMLny?g&Z}qH_vZ}ggD~>aj9WO!jx)sh;pb3(nm)AyAd|W<$ zk%mOEB?UIATNj#mKs=V7cd$$HiL+-l!YC;!*j)S3JNWBu^&u@k7~oyK6(^wMWE8_Y zxKW|2%$+S1SuZAhQW=+^wyV2|A|{g`rfgF0cFkJC~9)J*@ton*ES1|I*Dxy0QC#5PcvhtWB@QB<3r^w4; z{2(&Zlwz-*$`Fz{VlJy4$B|;5Ix5wzO>|Db0ntd#HiyV?-3)Y|Z6B(T-P$(r)66cLMQ=KxNwl6**^AR0ii{C=NkL-W1Gw^qI^#J`c{J#@m{U&e+ zJJ~v0nVY*jtVZEik5iOl#SWc?n(psI+f-nLpP zWOmZ^b8apJZ^JX$*_^q1lSja-#qZK$oY>oiJ^;`Stb?S?Pbzd~FiJQ-N+V@%WP*&( zt_)MAmarX)2v~P8I9_F0v$ITdvF_OlD5}cB>e4EcGB3ny0cZ35UiMC7f>h2+&YYlR zeXc`137_}u*?oFWq_b1nNG;K*Q1i6`d;CyDUA?v94$NWnj*(ePl~W45$<$c`=B;eW z`k=>${+@3NBHm0(kUG%M09El*6>Qc)nsWga$m%;)}l&z zi(e%TeICy8Xud^43l1Zf2}y86_|ZwOy9nUzU~`B01kv;G48>$j9>xxLYmvm5HGy%9 z;GD-Eb~Co3Wb4UY1gt%gzD}s);1P;l-|`rSJs#(!lAx52?Hxf0o5*NPAoL04VLTbM zn(ic&HpcP6W1I0TeEz)h-L4p-@t(-IABNlB7eUs-LU}5p`~f=OqaPl&MDI(xbj!1@B?7UCD+*3go&S3mY)$V^ZvxhgQHQs9lMNyB_d(-YV7 z=6o}-$iSWh^U+V(R4sDjYjo2qht>f%_XZ;n^6s&}&h4+_{O=KZe^uUvu#1(so%w?b zq6~^=I7EbjVIlclLH;EBMf@u+_p}wjWKVFKA8q<;?KZ`m?ckEc!|TR=j?P4gPoR;p zc|C3ZRUeJcT&DK1AR!_efozl>8bQ+ukN|TC26I~SRzaUmc9d$E+P#{Fp4qQ8j5mBY zDCM%huZv{=$?A6RI5O%f7T2TTcWfV zSZ42kHB9)4-ZaAqd-p{}h>joYnpufD9xMi}V}z0e+D~Z+K(>uOR-Rf$X7NexyJ)96 z19==dUk)kM&rO1)@i5;0EoUpI*ebVPXY^N>GvA5z(O#)BjfsnU8cMaMlK{I_!t=AocboT1xX=HFP8Cy%Kn4k5fJgVKAwED*izFn`2#F;guB@fB2)!}j! zoevZ5Pcz$EkbrfOJN)&h_DzR{u#6~11tgDVEKT$E`zw$bFSifptX=q7h~^Jl>e@UD z3vO5&k<4#OSk4T}FttA&k|r(LvYbuZJJ*_CPUc`38h&}wE1YT5eq1KOMZe{NsQ+>N z$;|gDqBz`qZ)J}v%{@MTrww$1(ohrEVjS9(URPT-iJv3~u;Q>x33R8cpgmJQ4G|K5)lw^7p&G=}!b#4naMPmkqD4I!YF9ebT)>QZaNEM7>Y1rl5s} zO*dN+?Uz_GlK7&JQHka;eOBizP!)leUF$(%S0JJwVq7R($KuRVJ&P&2hiPaLdTrDm z!TeedE&F2imT#1;*!l}O^7yi@2t*Mh$UgVJVyi15wENKLjr9JakIk|@t;=TQoOH3q z;=T(UoV*_U3|EcSd>&&mV;fUSR()3|v9N`EEDlQN9)adM}|>Tc=onfkF$g+`Gx8o3QCwiP00H&@SWZ zC%$p(*dx0wKSvt(wVOR846Hc2tELexF728wl_%_*Wr9bVGgKQnPHuF?H&DGfi*`@W z@gId%$YB_cCt|>|>V1u`ITA?B#wYn{%KNIxyW^!YO?*R4@DpRW0f^VPE#0LpUO^*c zxAju>v2$*G>{qKMje0DdOO20tT$(BbWC-{9W@NM7HxQEcv}K9Efbi0>@S@Li- zH`8Is!8mwwOjusz^1@MH_$glls5mokgb3BNZi>#u!UY?j3(c`vXnfP!Dx-R$UrLV6 ziGxmW z$W_-{5A$(j**5I=NHaT!TCsZ-ykmZETd&a<$q9y6s1q?ve4^F=0%LDv_b|na zU|=wR-y_a0o*;AQ`<7)~4;(uqOX45<)xBKrOB8-X1jR#NW2^=3Fm&D;&=UM{AQ%G?}7bHZ3)PQC#of(Xmr4(nCW9<91M<^%=!Dde4H}r^FvNc>CGG1eK4XI z$jQS)wSDs_sF)d%Iv@C%;YZ!p_SoD-IFY`{ZhM(Nv4ZOO$kHtMlp!M%YST;$8DQ(x zQ8!WRUktoc7$+M^-@I1g|E98VGxZI9e)h5dA<04$bx(3PLCH&nZTe@1V*cXu!4~`_ zUq||CbC<>rBE&a)lUb$)ioOd5CBOBgxk+%Qor%yHi9kT$`li|kmd$Vz?UqlS+xyVG zF+x|uY(_#cHBZ_^JI710m>tMHc1k|@8dPgZp&j>=XyA=tdAFcttf+wZF?qJT)dlS$ z748S?O=1f}kM&l!r&JWBI4rBTzAl<(*wD`v`#oD=1CgfJ1?eyFON{ie0?x%1eS(>l z96w*6?N5~35@!t&i6+=8q&>=*jM=VcJx9K@o8q)NwBZL9)xBy$3$H?Df%(eGyJF*9 z8<}aKZbd?(Ta@Wr10qIA%NU19tt%2}St%Z<8}Dkpt#EX6G5To3$}5C5AcPj;(zKRT zok?LZDqaS61cJ@_ur`bzOAP(W6O1y>1yESeTNcf|X5tyg{wU`tZ#uZ9gYt!#H0!8Y{=*X-g#3 zSyG*?SL7{Q@MX7lJMU5+FXyzYY#D7MYyM0OBl8f_G@i|ztbY5BGtE^S4df!BItSXW zpI0OOps6rvgU0{q`Q@+!*hQ$`K(W+;uYd5m+mB`P$;#MY`NjKEfG)wQs~lC>#xg>-sm82vr9PjuB+BH}`D zUA~u<#nktTA&eIoEKJfC;`$N3K7(fGZ;da!EBL6YtgD~KZk>0;fU9^7Bd!Arx-k06 zHn+X)JM-O*oNPZGpxbg0V-R7R`b$cpl9WnaxgvzInl&r%5NiA6La z$i>;B(t7GG0<$U`=ct5dg=28eK%-Btx5TJ$pt&B%&k_$mS1L{!P=%)u%4KgyTA!cG zS8em6qy*DP4r44Gdm)41N8?emX$KRADKExna1>a4zz)C?Yn2wpO464uBW=nE*Lim!(P<9?3#&9zOhSJJr0^S63 zrCjJF-jJU7CO7$@4eBgT#cWC(l8vW`Svrx2Foy<9NM!7s~V#B=Us1V$KjW)b6 z)x-i)QVrOfT~VNC=h!jnJopyDZf$44AJByTqNroMMXMMDAdI9G^@6 zvV_yda?y%Fz`khlr8;3o6tIon5x3@b2Rn^BR8A(j4)Xlqu6)9qTbGfi_G;F#aLW22 z0ix{06k}Q0;vlii1gcw1+SAt5=yc^(8RC`ZRap5o^+a3jd$WN{bfnbKK{@A5M9u^doPit?Ep@$=?w;Gcxu(4M3!I>^q zdx$YI7d=Vwvsq#79&mCW%kxx(mwb;ld7P=9Eln(9KV9%c){IEQgs;*?d7FK?epv5{ zFay)Q{`gZi3@u73moUkhF9uf|o)=y{n+m0vsQ;NLe#gx>H=_-qFBm_}=nw~PzdIbC zHBr6vC+!jEg(%|N*~#`6jf3ULMpjDz8@G*5uiJZ8hp(dsMFnpc(NTK?Tf-t#Nk7H| z8xwoFIC-+rI?~=@Jq9$owbDm=s z^YGWjo1X(6O_rkzog@+^(~u<2FiU?gq)p}9Bh^)QgSUkRhojVT{s2QiN56}!<(sXk zu7m7Bt+is>VAqR-7X1t#;`G&Gczg7s#7Nv!+N6#sx3TYU;)q67RMWJQ$*+%- zF?JY&Xb9x}rT=c0C4y33yJZ=jPc;|f*Qm3p&O+PtP&Cej=DiMD{Z(F$~FS(n1d7boIS-$Kt2)O z9WyfTKCjeiWCjuX0C%P?XYa+AgWKt*fX|fvQz=`Q2PqU`ni@C)c{0 z)MVVCcGnJFS`Tid8+p?OduYqI8SCu^@6h_;_xqptKfTdd7}^nTAangtRn=g-sZl-c z`RIb=LZcok6UqM_>H^=e<4s#e1#(-Oq9|LaZJ5{vk8Tk@y>Jx*I(e?PYWop`Hm~@+ zO4)d*!Y{-72p!U|VuOkx%ZB|kH)8*6Tqh{zLZEjIE6&|~^d1_xn`}5+89SMqy>M}| zwzvG%zgAV0b@!_>DzGsR^bJ;NaF6i-)nxk>22^_b6lyilFdav$fohEGa(xPNeLaH; z)f(>=*)%I_SJo<-*x6NKw)9<4E?z|=`? zU34Hy6-O|2kQ5iw*9l%oBOzH_)J3Fu%A@t1zw@N8k!O%cd*_)J@~(J*vpG}Au^>|^ zVs2DvG<$c?S19-A`7tK{1-%>p#bZaaI!p9v!%}cN_2j~>i5R=DZ(`Q|w#?=z@6jceqqLY*@lx`MXv}T;rvvc*t@Ub;qTpC2Tzn( zu4ZLf5e$ZufBaacnTZ~zvVjGG;ZGSVSbd$*RWC)m{MGZ*n6(}!O+1D-rLQ=(X;dm? z-7|&lGj4C2tXAkPr`~80DV4r2uhl3DYLQglk!gufu+2DQbb});L!&=o=(?!2k zI*n)AZIHJ+hiZ%gA^H9S%t~{Y+9~j5ey?Yd@UClwL-ZTRynBSq-|dJdDcYfWit5Ih zo9-cwH!B6R*hf)z-9AR5Lg9OE5k?*6BOm&c(#{I2w_QyYkKaiMXJFDMcgN1iml$hc zLrS#S@g{Zqzs!V@?o4XvWDa^b>h%_IYrMVtZQ*X*i~c7K`#t4{ghBbQoH(8LnA3W* zk~<;plnV#Vu9BH=K&s;H5CeXK_Fi+7gevP;J#uW?`Fi?-k68oR++zc-f|$lYSJgmq zaJO5t>Yybv4CPl+RGs>6op={r{e?|L<_}-^{som`A*KXU6(F zbCTXY?^5_T+23RN59`|81$5^@P*c#buj5EGmvp8N-8?CxCc z9GBO67}>!s2LR~IT;0JKHiL~RC(ulg5rh4Le+;P^>j0Z0C*1C^CJGi4B3sUKa8N__ zO*=(l>=QhbBdS@BF{ME@!=w?IDGDBGOP%X9MXEptdxF9)+ADEmQ0V$Jz-g)Y$GrIT zB>))a7`J-cWU5h(wUBqY&vlrLq7<#PDJIzCLD$JY-i<`GrWh_^80M)*7}}+5;9QV; z^5Lxi%@M0`o1kxkmr#^0M#meB!qk|t$H#q+Oz|KEp-03`XO3$RCb&gMI?k4NX^wd} z#l6RXbS1&|F6QHZ-Jstm_P5c-p$x&5s!&kF}*h_TUew^vOV(k!--^v}oU$4d=QwP2OK-p!R-P$j-T<_= ze$nQE%%=-qIed6w!>Ntj8u*@KqEwDa#37~)2psHRjr z`4t^C1EyHkt(gMVlG7P`e$9o+GF)QqYaVRU6zz4zvt9?#bA;0@noQYU#V#BPMi5K_ z-+0!K{UY+HrqlQdq?;MZOA8-{-9nLFpez`{JfdncgyS3mt0@b5GH z`;zl}-6PsQcj@p)#{5(1!xD7Q^IK`opFF=(=D#Vs&&l8GUfKQn8`AzyeGjqrd*a{v z0DouuU*!Fvi5^18e{sj$h4i0F{{WO9vOmN>|6<3vgYEue{}T=UZ->4I`hKtbLtEXU zb$9jVzcKvNO5J3CD^L$N`mmDS>-lY^gTJ%=M_qd;=V4RxmmJnRXz|}#oQDz~&h!3~ z;CwgUyO;3ibnpLvb{6DctbYJZ|BR4_5Yt~8)&9=*7vS`8%MY8GzXUMdp;mWW{=3=! z+otc4+TZKm!x6tde9!zRZu`%jKSXZtd4GGY`agL8!f}BLh`*8*_wG*-$ai$5l=po9 E1CA*q?*IS* literal 0 HcmV?d00001