pom.xml
@@ -279,6 +279,13 @@ <version>${ruoyi-vue-plus.version}</version> </dependency> <!-- oa模块 --> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-oa</artifactId> <version>${ruoyi-vue-plus.version}</version> </dependency> </dependencies> </dependencyManagement> @@ -292,6 +299,7 @@ <module>ruoyi-demo</module> <module>ruoyi-extend</module> <module>ruoyi-oss</module> <module>ruoyi-oa</module> </modules> <packaging>pom</packaging> ruoyi-admin/pom.xml
@@ -63,6 +63,12 @@ <artifactId>ruoyi-demo</artifactId> </dependency> <!-- oa模块 --> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-oa</artifactId> </dependency> </dependencies> <build> ruoyi-admin/src/main/java/com/ruoyi/web/controller/oa/BsCityController.java
New file @@ -0,0 +1,36 @@ package com.ruoyi.web.controller.oa; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.oa.service.IBsCityService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; /** * 城市设置Controller * * @author ruoyi * @date 2021-12-03 */ @Validated @Api(value = "城市设置控制器", tags = {"城市设置管理"}) @RequiredArgsConstructor(onConstructor_ = @Autowired) @RestController @RequestMapping("/oa/city") public class BsCityController extends BaseController { private final IBsCityService iBsCityService; /** * 根据省份编码查询城市设置列表 */ @ApiOperation("根据省份编码查询城市设置列表") @GetMapping public AjaxResult list(@RequestParam String provinceCode) { return AjaxResult.success(iBsCityService.queryList(provinceCode)); } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/oa/BsProvinceController.java
New file @@ -0,0 +1,36 @@ package com.ruoyi.web.controller.oa; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.validation.annotation.Validated; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.oa.service.IBsProvinceService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; /** * 省份设置Controller * * @author ruoyi * @date 2021-12-03 */ @Validated @Api(value = "省份设置控制器", tags = {"省份设置管理"}) @RequiredArgsConstructor(onConstructor_ = @Autowired) @RestController @RequestMapping("/oa/province") public class BsProvinceController extends BaseController { private final IBsProvinceService iBsProvinceService; /** * 查询省份设置列表 */ @ApiOperation("查询省份设置列表") @GetMapping public AjaxResult list() { return AjaxResult.success(iBsProvinceService.queryList()); } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/oa/BsSchoolController.java
New file @@ -0,0 +1,118 @@ package com.ruoyi.web.controller.oa; import com.ruoyi.common.annotation.DataDictClass; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import com.ruoyi.common.core.validate.QueryGroup; import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.oa.domain.bo.BsSchoolBo; import com.ruoyi.oa.domain.vo.BsSchoolVo; import com.ruoyi.oa.service.IBsSchoolService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import java.util.Arrays; import java.util.List; /** * 学校Controller * * @author ruoyi * @date 2021-12-03 */ @Validated @Api(value = "学校控制器", tags = {"学校管理"}) @RequiredArgsConstructor(onConstructor_ = @Autowired) @RestController @RequestMapping("/oa/school") public class BsSchoolController extends BaseController { private final IBsSchoolService iBsSchoolService; /** * 查询学校列表 */ @ApiOperation("查询学校列表") @PreAuthorize("@ss.hasPermi('oa:school:list')") @GetMapping("/list") @DataDictClass public TableDataInfo<BsSchoolVo> list(@Validated(QueryGroup.class) BsSchoolBo bo) { return iBsSchoolService.queryPageList(bo); } /** * 导出学校列表 */ @ApiOperation("导出学校列表") @PreAuthorize("@ss.hasPermi('oa:school:export')") @Log(title = "学校", businessType = BusinessType.EXPORT) @GetMapping("/export") public void export(@Validated BsSchoolBo bo, HttpServletResponse response) { List<BsSchoolVo> list = iBsSchoolService.queryList(bo); ExcelUtil.exportExcel(list, "学校", BsSchoolVo.class, response); } /** * 获取学校详细信息 */ @ApiOperation("获取学校详细信息") @PreAuthorize("@ss.hasPermi('oa:school:query')") @GetMapping("/{id}") public AjaxResult<BsSchoolVo> getInfo(@ApiParam("主键") @NotNull(message = "主键不能为空") @PathVariable("id") Long id) { return AjaxResult.success(iBsSchoolService.queryById(id)); } /** * 新增学校 */ @ApiOperation("新增学校") @PreAuthorize("@ss.hasPermi('oa:school:add')") @Log(title = "学校", businessType = BusinessType.INSERT) @RepeatSubmit() @PostMapping() public AjaxResult<Void> add(@Validated(AddGroup.class) @RequestBody BsSchoolBo bo) { return toAjax(iBsSchoolService.insertByBo(bo) ? 1 : 0); } /** * 修改学校 */ @ApiOperation("修改学校") @PreAuthorize("@ss.hasPermi('oa:school:edit')") @Log(title = "学校", businessType = BusinessType.UPDATE) @RepeatSubmit() @PutMapping() public AjaxResult<Void> edit(@Validated(EditGroup.class) @RequestBody BsSchoolBo bo) { return toAjax(iBsSchoolService.updateByBo(bo) ? 1 : 0); } /** * 删除学校 */ @ApiOperation("删除学校") @PreAuthorize("@ss.hasPermi('oa:school:remove')") @Log(title = "学校" , businessType = BusinessType.DELETE) @DeleteMapping("/{ids}") public AjaxResult<Void> remove(@ApiParam("主键串") @NotEmpty(message = "主键不能为空") @PathVariable Long[] ids) { return toAjax(iBsSchoolService.deleteWithValidByIds(Arrays.asList(ids), true) ? 1 : 0); } } ruoyi-admin/src/main/resources/application-dev.yml
@@ -51,9 +51,9 @@ # 主库数据源 master: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true url: jdbc:mysql://47.95.0.46:3307/ytsl_oa?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true username: root password: root password: test1214 # 从库数据源 slave: lazy: true ruoyi-admin/src/main/resources/application.yml
@@ -16,9 +16,9 @@ captcha: # 页面 <参数设置> 可开启关闭 验证码校验 # 验证码类型 math 数组计算 char 字符验证 type: MATH type: CHAR # line 线段干扰 circle 圆圈干扰 shear 扭曲干扰 category: CIRCLE category: LINE # 数字验证码位数 numberLength: 1 # 字符验证码长度 ruoyi-common/src/main/java/com/ruoyi/common/annotation/DataDictClass.java
New file @@ -0,0 +1,11 @@ package com.ruoyi.common.annotation; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Documented public @interface DataDictClass { } ruoyi-common/src/main/java/com/ruoyi/common/annotation/Dict.java
New file @@ -0,0 +1,33 @@ package com.ruoyi.common.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @Description: 字典注解 * @Date:2021-11-17 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Dict { /** * @Description: 数据code * @Date:2021-11-17 */ String dicCode(); /** * @Description: 数据Text * @Date:2021-11-17 */ String dicText() default ""; /** * @Description: 数据字典表 * @Date:2021-11-17 */ String dictTable() default ""; } ruoyi-common/src/main/java/com/ruoyi/common/api/CommonAPI.java
New file @@ -0,0 +1,23 @@ package com.ruoyi.common.api; public interface CommonAPI { /** * 字典表的 翻译 * @param table * @param text * @param code * @param key * @return */ String translateDictFromTable(String table, String text, String code, String key); /** * 普通字典的翻译 * @param code * @param key * @return */ String translateDict(String code, String key); } ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstant.java
New file @@ -0,0 +1,46 @@ package com.ruoyi.common.constant; /** * @date: 21-11-17 * @description: 缓存常量 */ public interface CacheConstant { /** * 字典信息缓存 */ public static final String SYS_DICT_CACHE = "sys:cache:dict"; /** * 表字典信息缓存 */ public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable"; public static final String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys"; /** * 数据权限配置缓存 */ public static final String SYS_DATA_PERMISSIONS_CACHE = "sys:cache:permission:datarules"; /** * 缓存用户信息 */ public static final String SYS_USERS_CACHE = "sys:cache:user"; /** * 全部部门信息缓存 */ public static final String SYS_DEPARTS_CACHE = "sys:cache:depart:alldata"; /** * 全部部门ids缓存 */ public static final String SYS_DEPART_IDS_CACHE = "sys:cache:depart:allids"; /** * 字典信息缓存 */ public static final String SYS_DYNAMICDB_CACHE = "sys:cache:dbconnect:dynamic:"; } ruoyi-common/src/main/java/com/ruoyi/common/enums/CommonConstant.java
New file @@ -0,0 +1,12 @@ package com.ruoyi.common.enums; public interface CommonConstant { /**字典翻译文本后缀*/ public static final String DICT_TEXT_SUFFIX = "_dictText"; /** * 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用 */ public final static String THIRD_LOGIN_CODE = "third_login_code"; } ruoyi-common/src/main/java/com/ruoyi/common/utils/OConvertUtils.java
New file @@ -0,0 +1,651 @@ package com.ruoyi.common.utils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Field; import java.math.BigDecimal; import java.math.BigInteger; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.sql.Date; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @Author 张代浩 * */ @Slf4j public class OConvertUtils { public static boolean isEmpty(Object object) { if (object == null) { return (true); } if ("".equals(object)) { return (true); } if ("null".equals(object)) { return (true); } return (false); } public static boolean isNotEmpty(Object object) { if (object != null && !object.equals("") && !object.equals("null")) { return (true); } return (false); } public static String decode(String strIn, String sourceCode, String targetCode) { String temp = code2code(strIn, sourceCode, targetCode); return temp; } public static String StrToUTF(String strIn, String sourceCode, String targetCode) { strIn = ""; try { strIn = new String(strIn.getBytes("ISO-8859-1"), "GBK"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return strIn; } private static String code2code(String strIn, String sourceCode, String targetCode) { String strOut = null; if (strIn == null || (strIn.trim()).equals("")) { return strIn; } try { byte[] b = strIn.getBytes(sourceCode); for (int i = 0; i < b.length; i++) { System.out.print(b[i] + " "); } strOut = new String(b, targetCode); } catch (Exception e) { e.printStackTrace(); return null; } return strOut; } public static int getInt(String s, int defval) { if (s == null || s == "") { return (defval); } try { return (Integer.parseInt(s)); } catch (NumberFormatException e) { return (defval); } } public static int getInt(String s) { if (s == null || s == "") { return 0; } try { return (Integer.parseInt(s)); } catch (NumberFormatException e) { return 0; } } public static int getInt(String s, Integer df) { if (s == null || s == "") { return df; } try { return (Integer.parseInt(s)); } catch (NumberFormatException e) { return 0; } } public static Integer[] getInts(String[] s) { Integer[] integer = new Integer[s.length]; if (s == null) { return null; } for (int i = 0; i < s.length; i++) { integer[i] = Integer.parseInt(s[i]); } return integer; } public static double getDouble(String s, double defval) { if (s == null || s == "") { return (defval); } try { return (Double.parseDouble(s)); } catch (NumberFormatException e) { return (defval); } } public static double getDou(Double s, double defval) { if (s == null) { return (defval); } return s; } /*public static Short getShort(String s) { if (StringUtil.isNotEmpty(s)) { return (Short.parseShort(s)); } else { return null; } }*/ public static int getInt(Object object, int defval) { if (isEmpty(object)) { return (defval); } try { return (Integer.parseInt(object.toString())); } catch (NumberFormatException e) { return (defval); } } public static Integer getInt(Object object) { if (isEmpty(object)) { return null; } try { return (Integer.parseInt(object.toString())); } catch (NumberFormatException e) { return null; } } public static int getInt(BigDecimal s, int defval) { if (s == null) { return (defval); } return s.intValue(); } public static Integer[] getIntegerArry(String[] object) { int len = object.length; Integer[] result = new Integer[len]; try { for (int i = 0; i < len; i++) { result[i] = new Integer(object[i].trim()); } return result; } catch (NumberFormatException e) { return null; } } public static String getString(String s) { return (getString(s, "")); } /** * 转义成Unicode编码 * @param s * @return */ /*public static String escapeJava(Object s) { return StringEscapeUtils.escapeJava(getString(s)); }*/ public static String getString(Object object) { if (isEmpty(object)) { return ""; } return (object.toString().trim()); } public static String getString(int i) { return (String.valueOf(i)); } public static String getString(float i) { return (String.valueOf(i)); } public static String getString(String s, String defval) { if (isEmpty(s)) { return (defval); } return (s.trim()); } public static String getString(Object s, String defval) { if (isEmpty(s)) { return (defval); } return (s.toString().trim()); } public static long stringToLong(String str) { Long test = new Long(0); try { test = Long.valueOf(str); } catch (Exception e) { } return test.longValue(); } /** * 获取本机IP */ public static String getIp() { String ip = null; try { InetAddress address = InetAddress.getLocalHost(); ip = address.getHostAddress(); } catch (UnknownHostException e) { e.printStackTrace(); } return ip; } /** * 判断一个类是否为基本数据类型。 * * @param clazz * 要判断的类。 * @return true 表示为基本数据类型。 */ private static boolean isBaseDataType(Class clazz) throws Exception { return (clazz.equals(String.class) || clazz.equals(Integer.class) || clazz.equals(Byte.class) || clazz.equals(Long.class) || clazz.equals(Double.class) || clazz.equals(Float.class) || clazz.equals(Character.class) || clazz.equals(Short.class) || clazz.equals(BigDecimal.class) || clazz.equals(BigInteger.class) || clazz.equals(Boolean.class) || clazz.equals(Date.class) || clazz.isPrimitive()); } /** * @param request * IP * @return IP Address */ public static String getIpAddrByRequest(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } /** * @return 本机IP * @throws SocketException */ public static String getRealIp() throws SocketException { String localip = null;// 本地IP,如果没有配置外网IP则返回它 String netip = null;// 外网IP Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces(); InetAddress ip = null; boolean finded = false;// 是否找到外网IP while (netInterfaces.hasMoreElements() && !finded) { NetworkInterface ni = netInterfaces.nextElement(); Enumeration<InetAddress> address = ni.getInetAddresses(); while (address.hasMoreElements()) { ip = address.nextElement(); if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 外网IP netip = ip.getHostAddress(); finded = true; break; } else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) {// 内网IP localip = ip.getHostAddress(); } } } if (netip != null && !"".equals(netip)) { return netip; } else { return localip; } } /** * java去除字符串中的空格、回车、换行符、制表符 * * @param str * @return */ public static String replaceBlank(String str) { String dest = ""; if (str != null) { Pattern p = Pattern.compile("\\s*|\t|\r|\n"); Matcher m = p.matcher(str); dest = m.replaceAll(""); } return dest; } /** * 判断元素是否在数组内 * * @param substring * @param source * @return */ public static boolean isIn(String substring, String[] source) { if (source == null || source.length == 0) { return false; } for (int i = 0; i < source.length; i++) { String aSource = source[i]; if (aSource.equals(substring)) { return true; } } return false; } /** * 获取Map对象 */ public static Map<Object, Object> getHashMap() { return new HashMap<Object, Object>(); } /** * SET转换MAP * * @param str * @return */ public static Map<Object, Object> SetToMap(Set<Object> setobj) { Map<Object, Object> map = getHashMap(); for (Iterator iterator = setobj.iterator(); iterator.hasNext();) { Map.Entry<Object, Object> entry = (Map.Entry<Object, Object>) iterator.next(); map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim()); } return map; } public static boolean isInnerIP(String ipAddress) { boolean isInnerIp = false; long ipNum = getIpNum(ipAddress); /** * 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址 **/ long aBegin = getIpNum("10.0.0.0"); long aEnd = getIpNum("10.255.255.255"); long bBegin = getIpNum("172.16.0.0"); long bEnd = getIpNum("172.31.255.255"); long cBegin = getIpNum("192.168.0.0"); long cEnd = getIpNum("192.168.255.255"); isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || ipAddress.equals("127.0.0.1"); return isInnerIp; } private static long getIpNum(String ipAddress) { String[] ip = ipAddress.split("\\."); long a = Integer.parseInt(ip[0]); long b = Integer.parseInt(ip[1]); long c = Integer.parseInt(ip[2]); long d = Integer.parseInt(ip[3]); long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d; return ipNum; } private static boolean isInner(long userIp, long begin, long end) { return (userIp >= begin) && (userIp <= end); } /** * 将下划线大写方式命名的字符串转换为驼峰式。 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> * 例如:hello_world->helloWorld * * @param name * 转换前的下划线大写方式命名的字符串 * @return 转换后的驼峰式命名的字符串 */ public static String camelName(String name) { StringBuilder result = new StringBuilder(); // 快速检查 if (name == null || name.isEmpty()) { // 没必要转换 return ""; } else if (!name.contains("_")) { // 不含下划线,仅将首字母小写 //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase(); //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 } // 用下划线将原始字符串分割 String camels[] = name.split("_"); for (String camel : camels) { // 跳过原始字符串中开头、结尾的下换线或双重下划线 if (camel.isEmpty()) { continue; } // 处理真正的驼峰片段 if (result.length() == 0) { // 第一个驼峰片段,全部字母都小写 result.append(camel.toLowerCase()); } else { // 其他的驼峰片段,首字母大写 result.append(camel.substring(0, 1).toUpperCase()); result.append(camel.substring(1).toLowerCase()); } } return result.toString(); } /** * 将下划线大写方式命名的字符串转换为驼峰式。 * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> * 例如:hello_world,test_id->helloWorld,testId * * @param name * 转换前的下划线大写方式命名的字符串 * @return 转换后的驼峰式命名的字符串 */ public static String camelNames(String names) { if(names==null||names.equals("")){ return null; } StringBuffer sf = new StringBuffer(); String[] fs = names.split(","); for (String field : fs) { field = camelName(field); sf.append(field + ","); } String result = sf.toString(); return result.substring(0, result.length() - 1); } //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 /** * 将下划线大写方式命名的字符串转换为驼峰式。(首字母写) * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br> * 例如:hello_world->HelloWorld * * @param name * 转换前的下划线大写方式命名的字符串 * @return 转换后的驼峰式命名的字符串 */ public static String camelNameCapFirst(String name) { StringBuilder result = new StringBuilder(); // 快速检查 if (name == null || name.isEmpty()) { // 没必要转换 return ""; } else if (!name.contains("_")) { // 不含下划线,仅将首字母小写 return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); } // 用下划线将原始字符串分割 String camels[] = name.split("_"); for (String camel : camels) { // 跳过原始字符串中开头、结尾的下换线或双重下划线 if (camel.isEmpty()) { continue; } // 其他的驼峰片段,首字母大写 result.append(camel.substring(0, 1).toUpperCase()); result.append(camel.substring(1).toLowerCase()); } return result.toString(); } //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 /** * 将驼峰命名转化成下划线 * @param para * @return */ public static String camelToUnderline(String para){ if(para.length()<3){ return para.toLowerCase(); } StringBuilder sb=new StringBuilder(para); int temp=0;//定位 //从第三个字符开始 避免命名不规范 for(int i=2;i<para.length();i++){ if(Character.isUpperCase(para.charAt(i))){ sb.insert(i+temp, "_"); temp+=1; } } return sb.toString().toLowerCase(); } /** * 随机数 * @param place 定义随机数的位数 */ public static String randomGen(int place) { String base = "qwertyuioplkjhgfdsazxcvbnmQAZWSXEDCRFVTGBYHNUJMIKLOP0123456789"; StringBuffer sb = new StringBuffer(); Random rd = new Random(); for(int i=0;i<place;i++) { sb.append(base.charAt(rd.nextInt(base.length()))); } return sb.toString(); } /** * 获取类的所有属性,包括父类 * * @param object * @return */ public static Field[] getAllFields(Object object) { Class<?> clazz = object.getClass(); List<Field> fieldList = new ArrayList<>(); while (clazz != null) { fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); clazz = clazz.getSuperclass(); } Field[] fields = new Field[fieldList.size()]; fieldList.toArray(fields); return fields; } /** * 将map的key全部转成小写 * @param list * @return */ public static List<Map<String, Object>> toLowerCasePageList(List<Map<String, Object>> list){ List<Map<String, Object>> select = new ArrayList<>(); for (Map<String, Object> row : list) { Map<String, Object> resultMap = new HashMap<>(); Set<String> keySet = row.keySet(); for (String key : keySet) { String newKey = key.toLowerCase(); resultMap.put(newKey, row.get(key)); } select.add(resultMap); } return select; } /** * 将entityList转换成modelList * @param fromList * @param tClass * @param <F> * @param <T> * @return */ public static<F,T> List<T> entityListToModelList(List<F> fromList, Class<T> tClass){ if(fromList == null || fromList.isEmpty()){ return null; } List<T> tList = new ArrayList<>(); for(F f : fromList){ T t = entityToModel(f, tClass); tList.add(t); } return tList; } public static<F,T> T entityToModel(F entity, Class<T> modelClass) { log.debug("entityToModel : Entity属性的值赋值到Model"); Object model = null; if (entity == null || modelClass ==null) { return null; } try { model = modelClass.newInstance(); } catch (InstantiationException e) { log.error("entityToModel : 实例化异常", e); } catch (IllegalAccessException e) { log.error("entityToModel : 安全权限异常", e); } BeanUtils.copyProperties(entity, model); return (T)model; } /** * 判断 list 是否为空 * * @param list * @return true or false * list == null : true * list.size() == 0 : true */ public static boolean listIsEmpty(Collection list) { return (list == null || list.size() == 0); } /** * 判断 list 是否不为空 * * @param list * @return true or false * list == null : false * list.size() == 0 : false */ public static boolean listIsNotEmpty(Collection list) { return !listIsEmpty(list); } } ruoyi-demo/src/main/java/com/ruoyi/demo/domain/TestDemo.java
@@ -59,10 +59,4 @@ @Version private Long version; /** * 删除标志 */ @TableLogic private Long delFlag; } ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/DictAspect.java
New file @@ -0,0 +1,189 @@ package com.ruoyi.framework.aspectj; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.metadata.IPage; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.ruoyi.common.annotation.DataDictClass; import com.ruoyi.common.annotation.Dict; import com.ruoyi.common.api.CommonAPI; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.CommonConstant; import com.ruoyi.common.utils.OConvertUtils; import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; /** * @Description: 字典aop类 * @Date: 21-11-17 */ @Aspect @Component @SuppressWarnings({"unused"}) @Slf4j public class DictAspect { @Autowired private CommonAPI commonAPI; // 定义切点Pointcut @Pointcut("@annotation(dataDictClass)") public void dataDictClass(DataDictClass dataDictClass) { } @Around("@annotation(dataDictClass)") public Object doAround(ProceedingJoinPoint pjp, DataDictClass dataDictClass) throws Throwable { long time1 = System.currentTimeMillis(); Object result = pjp.proceed(); long time2 = System.currentTimeMillis(); log.debug("获取JSON数据 耗时:" + (time2 - time1) + "ms"); long start = System.currentTimeMillis(); this.parseDictText(result); long end = System.currentTimeMillis(); log.debug("解析注入JSON数据 耗时" + (end - start) + "ms"); return result; } /** * 本方法针对返回对象为Result 的IPage的分页列表数据进行动态字典注入 * 字典注入实现 通过对实体类添加注解@dict 来标识需要的字典内容,字典分为单字典code即可 ,table字典 code table text配合使用与原来jeecg的用法相同 * 示例为SysUser 字段为sex 添加了注解@Dict(dicCode = "sex") 会在字典服务立马查出来对应的text 然后在请求list的时候将这个字典text,已字段名称加_dictText形式返回到前端 * 例输入当前返回值的就会多出一个sex_dictText字段 * { * sex:1, * sex_dictText:"男" * } * 前端直接取值sext_dictText在table里面无需再进行前端的字典转换了 * customRender:function (text) { * if(text==1){ * return "男"; * }else if(text==2){ * return "女"; * }else{ * return text; * } * } * 目前vue是这么进行字典渲染到table上的多了就很麻烦了 这个直接在服务端渲染完成前端可以直接用 * * @param result */ private void parseDictText(Object result) { // TableDataInfo分页 if (result instanceof TableDataInfo) { (((TableDataInfo) result)).setRows(transformation(((TableDataInfo<?>) result).getRows())); } if (result instanceof AjaxResult) { // 分页 if (((AjaxResult) result).getData() instanceof IPage) { ((IPage) ((AjaxResult) result).getData()).setRecords(transformation(((IPage) ((AjaxResult) result).getData()).getRecords())); } // 无分页-list if (((AjaxResult) result).getData() instanceof ArrayList) { (((AjaxResult) result)).setData(transformation((List<?>) ((AjaxResult) result).getData())); } // object if (((AjaxResult) result).getData() instanceof Object) { (((AjaxResult) result)).setData(transformation(Arrays.asList(((AjaxResult<?>) result).getData())).get(0)); } } } /** * 翻译字典文本 * * @param code * @param text * @param table * @param key * @return */ private String translateDictValue(String code, String text, String table, String key) { if (OConvertUtils.isEmpty(key)) { return null; } StringBuffer textValue = new StringBuffer(); String[] keys = key.split(","); for (String k : keys) { String tmpValue = null; log.debug(" 字典 key : " + k); if (k.trim().length() == 0) { continue; //跳过循环 } if (!StringUtils.isEmpty(table)) { log.debug("--DictAspect------dicTable=" + table + " ,dicText= " + text + " ,dicCode=" + code); tmpValue = commonAPI.translateDictFromTable(table, text, code, k.trim()); } else { tmpValue = commonAPI.translateDict(code, k.trim()); } if (tmpValue != null) { if (!"".equals(textValue.toString())) { textValue.append(","); } textValue.append(tmpValue); } } return textValue.toString(); } /** * 数据转换 * * @param list * @return */ private List<JSONObject> transformation(List<?> list) { List<JSONObject> items = new ArrayList<>(); for (Object record : list) { ObjectMapper mapper = new ObjectMapper(); String json = "{}"; try { //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat json = mapper.writeValueAsString(record); } catch (JsonProcessingException e) { log.error("json解析失败" + e.getMessage(), e); } JSONObject item = JSONObject.parseObject(json); //update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------ //for (Field field : record.getClass().getDeclaredFields()) { for (Field field : OConvertUtils.getAllFields(record)) { //update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------ if (field.getAnnotation(Dict.class) != null) { String code = field.getAnnotation(Dict.class).dicCode(); String text = field.getAnnotation(Dict.class).dicText(); String table = field.getAnnotation(Dict.class).dictTable(); String key = String.valueOf(item.get(field.getName())); //翻译字典值对应的txt String textValue = translateDictValue(code, text, table, key); log.debug(" 字典Val : " + textValue); log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + ": " + textValue); item.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue); } //date类型默认转换string格式化日期 if (field.getType().getName().equals("java.util.Date") && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) { SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName())))); } } items.add(item); } return items; } } ruoyi-oa/pom.xml
New file @@ -0,0 +1,30 @@ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>ruoyi-vue-plus</artifactId> <groupId>com.ruoyi</groupId> <version>3.4.0</version> </parent> <modelVersion>4.0.0</modelVersion> <packaging>jar</packaging> <artifactId>ruoyi-oa</artifactId> <description> oa服务 </description> <dependencies> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-framework</artifactId> </dependency> <dependency> <groupId>com.ruoyi</groupId> <artifactId>ruoyi-common</artifactId> </dependency> </dependencies> </project> ruoyi-oa/src/main/java/com/ruoyi/oa/domain/BsCity.java
New file @@ -0,0 +1,82 @@ package com.ruoyi.oa.domain; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; import java.math.BigDecimal; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.domain.BaseEntity; /** * 城市设置对象 bs_city * * @author ruoyi * @date 2021-12-03 */ @Data @Accessors(chain = true) @TableName("bs_city") public class BsCity { private static final long serialVersionUID=1L; /** * 自增列 */ @TableId(value = "CITY_ID") private Long cityId; /** * 市代码 */ private String cityCode; /** * 市名称 */ private String cityName; /** * 简称 */ private String shortName; /** * 省代码 */ private String provinceCode; /** * 经度 */ private String lng; /** * 纬度 */ private String lat; /** * 排序 */ private Integer sort; /** * 创建时间 */ private Date gmtCreate; /** * 修改时间 */ private Date gmtModified; /** * 备注 */ private String memo; /** * 状态 */ private Long dataState; /** * 租户ID */ private String tenantCode; } ruoyi-oa/src/main/java/com/ruoyi/oa/domain/BsProvince.java
New file @@ -0,0 +1,78 @@ package com.ruoyi.oa.domain; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; import java.math.BigDecimal; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import com.ruoyi.common.core.domain.BaseEntity; /** * 省份设置对象 bs_province * * @author ruoyi * @date 2021-12-03 */ @Data @Accessors(chain = true) @TableName("bs_province") public class BsProvince { private static final long serialVersionUID=1L; /** * 自增列 */ @TableId(value = "PROVINCE_ID") private Long provinceId; /** * 省份代码 */ private String provinceCode; /** * 省份名称 */ private String provinceName; /** * 简称 */ private String shortName; /** * 经度 */ private String lng; /** * 纬度 */ private String lat; /** * 排序 */ private Integer sort; /** * 创建时间 */ private Date gmtCreate; /** * 修改时间 */ private Date gmtModified; /** * 备注 */ private String memo; /** * 状态 */ private Long dataState; /** * 租户ID */ private String tenantCode; } ruoyi-oa/src/main/java/com/ruoyi/oa/domain/BsSchool.java
New file @@ -0,0 +1,74 @@ package com.ruoyi.oa.domain; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import java.io.Serializable; import java.util.Date; import java.math.BigDecimal; import com.ruoyi.common.core.domain.BaseEntity; /** * 学校对象 bas_school * * @author ruoyi * @date 2021-12-03 */ @Data @Accessors(chain = true) @TableName("bs_school") public class BsSchool extends BaseEntity { private static final long serialVersionUID=1L; /** * id */ @TableId(value = "id") private Long id; /** * 学校代码 */ private String code; /** * 学校名称 */ private String name; /** * 省代码 */ private String provinceCode; /** * 市代码 */ private String cityCode; /** * 区代码 */ private String areaCode; /** * 办学层次 */ private String schoolRunLevel; /** * 学科范围 */ private String disciplineScope; /** * 备注 */ private String remarks; /** * 删除标识 */ @TableLogic private String delFlag; /** * 乐观锁 */ @Version private Integer version; } ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/BsSchoolBo.java
New file @@ -0,0 +1,101 @@ package com.ruoyi.oa.domain.bo; import com.ruoyi.common.core.validate.AddGroup; import com.ruoyi.common.core.validate.EditGroup; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import javax.validation.constraints.*; import java.util.Date; import com.ruoyi.common.core.domain.BaseEntity; /** * 学校业务对象 bas_school * * @author ruoyi * @date 2021-12-03 */ @Data @EqualsAndHashCode(callSuper = true) @ApiModel("学校业务对象") public class BsSchoolBo extends BaseEntity { private Long id; /** * 学校代码 */ @ApiModelProperty(value = "学校代码", required = true) @NotBlank(message = "学校代码不能为空", groups = { AddGroup.class, EditGroup.class }) private String code; /** * 学校名称 */ @ApiModelProperty(value = "学校名称", required = true) @NotBlank(message = "学校名称不能为空", groups = { AddGroup.class, EditGroup.class }) private String name; /** * 省代码 */ @ApiModelProperty(value = "省代码", required = true) // @NotBlank(message = "省代码不能为空", groups = { AddGroup.class, EditGroup.class }) private String provinceCode; /** * 市代码 */ @ApiModelProperty(value = "市代码", required = true) // @NotBlank(message = "市代码不能为空", groups = { AddGroup.class, EditGroup.class }) private String cityCode; /** * 办学层次 */ @ApiModelProperty(value = "办学层次", required = true) @NotBlank(message = "办学层次不能为空", groups = { AddGroup.class, EditGroup.class }) private String schoolRunLevel; /** * 学科范围 */ @ApiModelProperty(value = "学科范围", required = true) @NotBlank(message = "学科范围不能为空", groups = { AddGroup.class, EditGroup.class }) private String disciplineScope; /** * 备注 */ @ApiModelProperty(value = "备注") private String remarks; /** * 分页大小 */ @ApiModelProperty("分页大小") private Integer pageSize; /** * 当前页数 */ @ApiModelProperty("当前页数") private Integer pageNum; /** * 排序列 */ @ApiModelProperty("排序列") private String orderByColumn; /** * 排序的方向desc或者asc */ @ApiModelProperty(value = "排序的方向", example = "asc,desc") private String isAsc; } ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/BsCityVo.java
New file @@ -0,0 +1,121 @@ package com.ruoyi.oa.domain.vo; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.ruoyi.common.annotation.ExcelDictFormat; import com.ruoyi.common.convert.ExcelDictConvert; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Date; /** * 城市设置视图对象 bs_city * * @author ruoyi * @date 2021-12-03 */ @Data @ApiModel("城市设置视图对象") @ExcelIgnoreUnannotated public class BsCityVo { private static final long serialVersionUID = 1L; /** * 自增列 */ @ExcelProperty(value = "自增列") @ApiModelProperty("自增列") private Long cityId; /** * 市代码 */ @ExcelProperty(value = "市代码") @ApiModelProperty("市代码") private String cityCode; /** * 市名称 */ @ExcelProperty(value = "市名称") @ApiModelProperty("市名称") private String cityName; /** * 简称 */ @ExcelProperty(value = "简称") @ApiModelProperty("简称") private String shortName; /** * 省代码 */ @ExcelProperty(value = "省代码") @ApiModelProperty("省代码") private String provinceCode; /** * 经度 */ @ExcelProperty(value = "经度") @ApiModelProperty("经度") private String LNG; /** * 纬度 */ @ExcelProperty(value = "纬度") @ApiModelProperty("纬度") private String LAT; /** * 排序 */ @ExcelProperty(value = "排序") @ApiModelProperty("排序") private Integer SORT; /** * 创建时间 */ @ExcelProperty(value = "创建时间") @ApiModelProperty("创建时间") private Date gmtCreate; /** * 修改时间 */ @ExcelProperty(value = "修改时间") @ApiModelProperty("修改时间") private Date gmtModified; /** * 备注 */ @ExcelProperty(value = "备注") @ApiModelProperty("备注") private String MEMO; /** * 状态 */ @ExcelProperty(value = "状态") @ApiModelProperty("状态") private Long dataState; /** * 租户ID */ @ExcelProperty(value = "租户ID") @ApiModelProperty("租户ID") private String tenantCode; } ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/BsProvinceVo.java
New file @@ -0,0 +1,114 @@ package com.ruoyi.oa.domain.vo; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.ruoyi.common.annotation.ExcelDictFormat; import com.ruoyi.common.convert.ExcelDictConvert; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Date; /** * 省份设置视图对象 bs_province * * @author ruoyi * @date 2021-12-03 */ @Data @ApiModel("省份设置视图对象") @ExcelIgnoreUnannotated public class BsProvinceVo { private static final long serialVersionUID = 1L; /** * 自增列 */ @ExcelProperty(value = "自增列") @ApiModelProperty("自增列") private Long provinceId; /** * 省份代码 */ @ExcelProperty(value = "省份代码") @ApiModelProperty("省份代码") private String provinceCode; /** * 省份名称 */ @ExcelProperty(value = "省份名称") @ApiModelProperty("省份名称") private String provinceName; /** * 简称 */ @ExcelProperty(value = "简称") @ApiModelProperty("简称") private String shortName; /** * 经度 */ @ExcelProperty(value = "经度") @ApiModelProperty("经度") private String LNG; /** * 纬度 */ @ExcelProperty(value = "纬度") @ApiModelProperty("纬度") private String LAT; /** * 排序 */ @ExcelProperty(value = "排序") @ApiModelProperty("排序") private Integer SORT; /** * 创建时间 */ @ExcelProperty(value = "创建时间") @ApiModelProperty("创建时间") private Date gmtCreate; /** * 修改时间 */ @ExcelProperty(value = "修改时间") @ApiModelProperty("修改时间") private Date gmtModified; /** * 备注 */ @ExcelProperty(value = "备注") @ApiModelProperty("备注") private String MEMO; /** * 状态 */ @ExcelProperty(value = "状态") @ApiModelProperty("状态") private Long dataState; /** * 租户ID */ @ExcelProperty(value = "租户ID") @ApiModelProperty("租户ID") private String tenantCode; } ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/BsSchoolVo.java
New file @@ -0,0 +1,89 @@ package com.ruoyi.oa.domain.vo; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.ruoyi.common.annotation.Dict; import com.ruoyi.common.annotation.ExcelDictFormat; import com.ruoyi.common.convert.ExcelDictConvert; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.Date; /** * 学校视图对象 bas_school * * @author ruoyi * @date 2021-12-03 */ @Data @ApiModel("学校视图对象") @ExcelIgnoreUnannotated public class BsSchoolVo { private static final long serialVersionUID = 1L; /** * id */ @ExcelProperty(value = "id") @ApiModelProperty("id") private Long id; /** * 学校代码 */ @ExcelProperty(value = "学校代码") @ApiModelProperty("学校代码") private String code; /** * 学校名称 */ @ExcelProperty(value = "学校名称") @ApiModelProperty("学校名称") private String name; /** * 省代码 */ @ExcelProperty(value = "省代码") @ApiModelProperty("省代码") @Dict(dictTable = "bs_province", dicCode = "PROVINCE_CODE", dicText = "PROVINCE_NAME") private String provinceCode; /** * 市代码 */ @ExcelProperty(value = "市代码") @ApiModelProperty("市代码") @Dict(dictTable = "bs_city", dicCode = "CITY_CODE", dicText = "CITY_NAME") private String cityCode; /** * 办学层次 */ @ExcelProperty(value = "办学层次", converter = ExcelDictConvert.class) @ExcelDictFormat(dictType = "DICT105") @ApiModelProperty("办学层次") private String schoolRunLevel; /** * 学科范围 */ @ExcelProperty(value = "学科范围", converter = ExcelDictConvert.class) @ExcelDictFormat(dictType = "DICT106") @ApiModelProperty("学科范围") private String disciplineScope; /** * 备注 */ @ExcelProperty(value = "备注") @ApiModelProperty("备注") private String remarks; } ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/BsCityMapper.java
New file @@ -0,0 +1,14 @@ package com.ruoyi.oa.mapper; import com.ruoyi.oa.domain.BsCity; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; /** * 城市设置Mapper接口 * * @author ruoyi * @date 2021-12-03 */ public interface BsCityMapper extends BaseMapperPlus<BsCity> { } ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/BsProvinceMapper.java
New file @@ -0,0 +1,14 @@ package com.ruoyi.oa.mapper; import com.ruoyi.oa.domain.BsProvince; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; /** * 省份设置Mapper接口 * * @author ruoyi * @date 2021-12-03 */ public interface BsProvinceMapper extends BaseMapperPlus<BsProvince> { } ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/BsSchoolMapper.java
New file @@ -0,0 +1,14 @@ package com.ruoyi.oa.mapper; import com.ruoyi.oa.domain.BsSchool; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; /** * 学校Mapper接口 * * @author ruoyi * @date 2021-12-03 */ public interface BsSchoolMapper extends BaseMapperPlus<BsSchool> { } ruoyi-oa/src/main/java/com/ruoyi/oa/service/IBsCityService.java
New file @@ -0,0 +1,20 @@ package com.ruoyi.oa.service; import com.ruoyi.oa.domain.BsCity; import com.ruoyi.oa.domain.vo.BsCityVo; import com.ruoyi.common.core.mybatisplus.core.IServicePlus; import java.util.List; /** * 城市设置Service接口 * * @author ruoyi * @date 2021-12-03 */ public interface IBsCityService extends IServicePlus<BsCity, BsCityVo> { /** * 查询列表 */ List<BsCity> queryList(String provinceCode); } ruoyi-oa/src/main/java/com/ruoyi/oa/service/IBsProvinceService.java
New file @@ -0,0 +1,21 @@ package com.ruoyi.oa.service; import com.ruoyi.oa.domain.BsProvince; import com.ruoyi.oa.domain.vo.BsProvinceVo; import com.ruoyi.common.core.mybatisplus.core.IServicePlus; import java.util.List; /** * 省份设置Service接口 * * @author ruoyi * @date 2021-12-03 */ public interface IBsProvinceService extends IServicePlus<BsProvince, BsProvinceVo> { /** * 查询列表 */ List<BsProvince> queryList(); } ruoyi-oa/src/main/java/com/ruoyi/oa/service/IBsSchoolService.java
New file @@ -0,0 +1,56 @@ package com.ruoyi.oa.service; import com.ruoyi.oa.domain.BsSchool; import com.ruoyi.oa.domain.bo.BsSchoolBo; import com.ruoyi.oa.domain.vo.BsSchoolVo; import com.ruoyi.common.core.mybatisplus.core.IServicePlus; import com.ruoyi.common.core.page.TableDataInfo; import java.util.Collection; import java.util.List; /** * 学校Service接口 * * @author ruoyi * @date 2021-12-03 */ public interface IBsSchoolService extends IServicePlus<BsSchool, BsSchoolVo> { /** * 查询单个 * @return */ BsSchoolVo queryById(Long id); /** * 查询列表 */ TableDataInfo<BsSchoolVo> queryPageList(BsSchoolBo bo); /** * 查询列表 */ List<BsSchoolVo> queryList(BsSchoolBo bo); /** * 根据新增业务对象插入学校 * @param bo 学校新增业务对象 * @return */ Boolean insertByBo(BsSchoolBo bo); /** * 根据编辑业务对象修改学校 * @param bo 学校编辑业务对象 * @return */ Boolean updateByBo(BsSchoolBo bo); /** * 校验并删除数据 * @param ids 主键集合 * @param isValid 是否校验,true-删除前校验,false-不校验 * @return */ Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid); } ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/BsCityServiceImpl.java
New file @@ -0,0 +1,26 @@ package com.ruoyi.oa.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.oa.domain.vo.BsCityVo; import com.ruoyi.oa.domain.BsCity; import com.ruoyi.oa.mapper.BsCityMapper; import com.ruoyi.oa.service.IBsCityService; import java.util.List; /** * 城市设置Service业务层处理 * * @author ruoyi * @date 2021-12-03 */ @Service public class BsCityServiceImpl extends ServicePlusImpl<BsCityMapper, BsCity, BsCityVo> implements IBsCityService { @Override public List<BsCity> queryList(String provinceCode) { return baseMapper.selectList(new QueryWrapper<BsCity>().lambda().eq(BsCity::getProvinceCode, provinceCode).orderByAsc(BsCity::getSort)); } } ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/BsProvinceServiceImpl.java
New file @@ -0,0 +1,26 @@ package com.ruoyi.oa.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import org.springframework.stereotype.Service; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.ruoyi.oa.domain.vo.BsProvinceVo; import com.ruoyi.oa.domain.BsProvince; import com.ruoyi.oa.mapper.BsProvinceMapper; import com.ruoyi.oa.service.IBsProvinceService; import java.util.List; /** * 省份设置Service业务层处理 * * @author ruoyi * @date 2021-12-03 */ @Service public class BsProvinceServiceImpl extends ServicePlusImpl<BsProvinceMapper, BsProvince, BsProvinceVo> implements IBsProvinceService { @Override public List<BsProvince> queryList() { return baseMapper.selectList(new QueryWrapper<BsProvince>().lambda().orderByAsc(BsProvince::getSort)); } } ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/BsSchoolServiceImpl.java
New file @@ -0,0 +1,109 @@ package com.ruoyi.oa.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.http.HttpStatus; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.core.page.PagePlus; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.oa.domain.bo.BsSchoolBo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.oa.domain.vo.BsSchoolVo; import com.ruoyi.oa.domain.BsSchool; import com.ruoyi.oa.mapper.BsSchoolMapper; import com.ruoyi.oa.service.IBsSchoolService; import java.util.List; import java.util.Map; import java.util.Collection; /** * 学校Service业务层处理 * * @author ruoyi * @date 2021-12-03 */ @Service public class BsSchoolServiceImpl extends ServicePlusImpl<BsSchoolMapper, BsSchool, BsSchoolVo> implements IBsSchoolService { @Value("${mybatis-plus.global-config.dbConfig.logicNotDeleteValue}") private String logicNotDeleteValue; @Override public BsSchoolVo queryById(Long id){ return getVoById(id); } @Override public TableDataInfo<BsSchoolVo> queryPageList(BsSchoolBo bo) { PagePlus<BsSchool, BsSchoolVo> result = pageVo(PageUtils.buildPagePlus(), buildQueryWrapper(bo)); return PageUtils.buildDataInfo(result); } @Override public List<BsSchoolVo> queryList(BsSchoolBo bo) { return listVo(buildQueryWrapper(bo)); } private LambdaQueryWrapper<BsSchool> buildQueryWrapper(BsSchoolBo bo) { Map<String, Object> params = bo.getParams(); LambdaQueryWrapper<BsSchool> lqw = Wrappers.lambdaQuery(); lqw.like(StringUtils.isNotBlank(bo.getCode()), BsSchool::getCode, bo.getCode()); lqw.like(StringUtils.isNotBlank(bo.getName()), BsSchool::getName, bo.getName()); lqw.eq(StringUtils.isNotBlank(bo.getProvinceCode()), BsSchool::getProvinceCode, bo.getProvinceCode()); lqw.eq(StringUtils.isNotBlank(bo.getCityCode()), BsSchool::getCityCode, bo.getCityCode()); lqw.eq(StringUtils.isNotBlank(bo.getSchoolRunLevel()), BsSchool::getSchoolRunLevel, bo.getSchoolRunLevel()); lqw.eq(StringUtils.isNotBlank(bo.getDisciplineScope()), BsSchool::getDisciplineScope, bo.getDisciplineScope()); return lqw; } @Override public Boolean insertByBo(BsSchoolBo bo) { List<BsSchool> list = baseMapper.selectList(new QueryWrapper<BsSchool>().lambda().eq(BsSchool::getCode, bo.getCode())); if (list.size() > 0) { throw new ServiceException("学校代码重复", HttpStatus.HTTP_PARTIAL); } BsSchool add = BeanUtil.toBean(bo, BsSchool.class); add.setDelFlag(logicNotDeleteValue); boolean flag = save(add); if (flag) { bo.setId(add.getId()); } return flag; } @Override public Boolean updateByBo(BsSchoolBo bo) { List<BsSchool> list = baseMapper.selectList(new QueryWrapper<BsSchool>().lambda() .eq(BsSchool::getCode, bo.getCode()).ne(BsSchool::getId, bo.getId())); if (list.size() > 0) { throw new ServiceException("学校代码重复", HttpStatus.HTTP_PARTIAL); } BsSchool update = BeanUtil.toBean(bo, BsSchool.class); validEntityBeforeSave(update); return updateById(update); } /** * 保存前的数据校验 * * @param entity 实体类数据 */ private void validEntityBeforeSave(BsSchool entity){ //TODO 做一些数据校验,如唯一约束 } @Override public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) { if(isValid){ //TODO 做一些业务上的校验,判断是否需要校验 } return removeByIds(ids); } } ruoyi-oa/src/main/resources/mapper/oa/BsProvinceMapper.xml
New file @@ -0,0 +1,23 @@ <?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.ruoyi.oa.mapper.BsProvinceMapper"> <resultMap type="com.ruoyi.oa.domain.BsProvince" id="BsProvinceResult"> <result property="provinceId" column="PROVINCE_ID"/> <result property="provinceCode" column="PROVINCE_CODE"/> <result property="provinceName" column="PROVINCE_NAME"/> <result property="shortName" column="SHORT_NAME"/> <result property="LNG" column="LNG"/> <result property="LAT" column="LAT"/> <result property="SORT" column="SORT"/> <result property="gmtCreate" column="GMT_CREATE"/> <result property="gmtModified" column="GMT_MODIFIED"/> <result property="MEMO" column="MEMO"/> <result property="dataState" column="DATA_STATE"/> <result property="tenantCode" column="TENANT_CODE"/> </resultMap> </mapper> ruoyi-oa/src/main/resources/mapper/oa/BsSchoolMapper.xml
New file @@ -0,0 +1,26 @@ <?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.ruoyi.oa.mapper.BsSchoolMapper"> <resultMap type="com.ruoyi.oa.domain.BsSchool" id="BasSchoolResult"> <result property="id" column="id"/> <result property="code" column="code"/> <result property="name" column="name"/> <result property="provinceCode" column="province_code"/> <result property="cityCode" column="city_code"/> <result property="areaCode" column="area_code"/> <result property="schoolRunLevel" column="school_run_level"/> <result property="disciplineScope" column="discipline_scope"/> <result property="remarks" column="remarks"/> <result property="createBy" column="create_by"/> <result property="createTime" column="create_time"/> <result property="updateBy" column="update_by"/> <result property="updateTime" column="update_time"/> <result property="delFlag" column="del_flag"/> <result property="version" column="version"/> </resultMap> </mapper> ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDictDataMapper.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.mybatisplus.core.BaseMapperPlus; import org.apache.ibatis.annotations.Param; import java.util.List; @@ -20,4 +21,8 @@ .eq(SysDictData::getDictType, dictType) .orderByAsc(SysDictData::getDictSort)); } String queryDictTextByKey(@Param("code") String code, @Param("key") String key); String queryTableDictTextByKey(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("key") String key); } ruoyi-system/src/main/java/com/ruoyi/system/service/ISysDictDataService.java
@@ -64,4 +64,24 @@ * @return 结果 */ int updateDictData(SysDictData dictData); /** * 通过字典code获取字典数据 * * @param code 字典code * @param key 字典值 * @return 字典text */ String queryDictTextByKey(String code, String key); /** * 通过查询指定table的 text code 获取字典值text * dictTableCache采用redis缓存有效期10分钟 * @param table * @param text * @param code * @param key * @return */ String queryTableDictTextByKey(String table, String text, String code, String key); } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/CommonApiImpl.java
New file @@ -0,0 +1,34 @@ package com.ruoyi.system.service.impl; import com.ruoyi.common.api.CommonAPI; import com.ruoyi.system.service.ISysDictDataService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Description: 底层共通业务API,提供其他独立模块调用 * @Date:2021-11-17 */ @Slf4j @Service public class CommonApiImpl implements CommonAPI { /** * 当前系统数据库类型 */ private static String DB_TYPE = ""; @Autowired private ISysDictDataService dictDataService; @Override public String translateDictFromTable(String table, String text, String code, String key) { return dictDataService.queryTableDictTextByKey(table, text, code, key); } @Override public String translateDict(String code, String key) { return dictDataService.queryDictTextByKey(code, key); } } ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDictDataServiceImpl.java
@@ -1,6 +1,7 @@ package com.ruoyi.system.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.constant.CacheConstant; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl; @@ -10,6 +11,7 @@ import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.SysDictDataMapper; import com.ruoyi.system.service.ISysDictDataService; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.util.List; @@ -131,4 +133,35 @@ String getCacheKey(String configKey) { return Constants.SYS_DICT_KEY + configKey; } /** * 通过查询指定code 获取字典值text * * @param code * @param key * @return */ @Override @Cacheable(value = CacheConstant.SYS_DICT_CACHE, key = "#code+':'+#key") public String queryDictTextByKey(String code, String key) { System.out.println("无缓存dictText的时候调用这里!"); return baseMapper.queryDictTextByKey(code, key); } /** * 通过查询指定table的 text code 获取字典值text * dictTableCache采用redis缓存有效期10分钟 * * @param table * @param text * @param code * @param key * @return */ @Override @Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE) public String queryTableDictTextByKey(String table, String text, String code, String key) { System.out.println("无缓存dictTable的时候调用这里!"); return baseMapper.queryTableDictTextByKey(table, text, code, key); } } ruoyi-system/src/main/resources/mapper/system/SysDictDataMapper.xml
@@ -20,4 +20,11 @@ <result property="updateTime" column="update_time"/> </resultMap> <select id="queryDictTextByKey" resultType="java.lang.String"> select s.dict_label from sys_dict_data s where s.dict_type = #{code} and s.dict_value = #{key} </select> <select id="queryTableDictTextByKey" resultType="java.lang.String"> select ${text} as "text" from ${table} where ${code}= #{key} </select> </mapper>