!11 集成企业微信登录

Merge pull request !11 from Bo/bo_dev
This commit is contained in:
Bo 2021-07-29 03:26:44 +00:00 committed by Gitee
commit 32c5e9835f
28 changed files with 1163 additions and 111 deletions

View File

@ -1,7 +1,6 @@
package com.ruoyi.bps.controller; package com.ruoyi.bps.controller;
import com.ruoyi.bps.domain.ExpImportQuery; import com.ruoyi.bps.domain.ExpImportQuery;
import com.ruoyi.bps.domain.ExpSubsPushResp;
import com.ruoyi.bps.domain.ExpressInfo; import com.ruoyi.bps.domain.ExpressInfo;
import com.ruoyi.bps.mapper.ExpressInfoMapper; import com.ruoyi.bps.mapper.ExpressInfoMapper;
import com.ruoyi.bps.service.IExpImportQueryService; import com.ruoyi.bps.service.IExpImportQueryService;
@ -11,20 +10,14 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ExceptionUtil;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -168,8 +161,9 @@ public class ExpImportQueryController extends BaseController
return prefix + "/detail"; return prefix + "/detail";
} }
/**
* Excel导入查模板下载
*/
@GetMapping ( "/importTemplate" ) @GetMapping ( "/importTemplate" )
@ResponseBody @ResponseBody
public AjaxResult importTemplate ( ) { public AjaxResult importTemplate ( ) {
@ -177,40 +171,16 @@ public class ExpImportQueryController extends BaseController
return util.importTemplateExcel ( "快递查询导入模板" ); return util.importTemplateExcel ( "快递查询导入模板" );
} }
/**
* Excel导入查询
*/
@PostMapping("/importData") @PostMapping("/importData")
@Log(title = "Excel批量导入快递查询", businessType = BusinessType.IMPORT)
@ResponseBody @ResponseBody
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{ {
String queryTime= DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss");
String queryId= LocalDateTime.now().toString();
ExcelUtil<ExpressInfo> util= new ExcelUtil<ExpressInfo>(ExpressInfo.class); ExcelUtil<ExpressInfo> util= new ExcelUtil<ExpressInfo>(ExpressInfo.class);
List<ExpressInfo> expressInfoList=util.importExcel(file.getInputStream()); List<ExpressInfo> expressInfoList=util.importExcel(file.getInputStream());
ExpImportQuery expImportQuery=new ExpImportQuery(); return expImportQueryService.importData(expressInfoList);
try{
for( ExpressInfo expressInfo:expressInfoList){
ExpressInfo ei= expressInfoService.SelectExpressInfo(expressInfo);
ei.setQueryId(queryId);
ei.setQueryUserName(ShiroUtils.getSysUser().getUserName());
ei.setQueryType("excel");
ei.setQueryTime(queryTime);
expressInfoService.insertExpressInfo(ei);
}
expImportQuery.setQueryTime(queryTime);
expImportQuery.setQueryLoginName(ShiroUtils.getLoginName());
expImportQuery.setQueryUserName(ShiroUtils.getSysUser().getUserName());
expImportQuery.setFinishTime(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss"));
expImportQuery.setQueryIp(ShiroUtils.getIp());
expImportQuery.setStatus("success");
expImportQuery.setQueryQty(String.valueOf(expressInfoList.size()));
expImportQuery.setQueryId(queryId);
expImportQueryService.insertExpImportQuery(expImportQuery);
return AjaxResult.success("导入查询成功!");
}catch (Exception e){
expImportQuery.setStatus("fail");
return AjaxResult.error(e.getMessage());
}
} }
} }

View File

@ -15,6 +15,9 @@ public class ExpressInfo extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 消息 */
private String sid;
/** 消息 */ /** 消息 */
@Excel(name = "消息",type= Excel.Type.EXPORT) @Excel(name = "消息",type= Excel.Type.EXPORT)
private String message; private String message;
@ -98,6 +101,14 @@ public class ExpressInfo extends BaseEntity
return serialVersionUID; return serialVersionUID;
} }
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
public String getMessage() { public String getMessage() {
return message; return message;
} }
@ -261,7 +272,8 @@ public class ExpressInfo extends BaseEntity
@Override @Override
public String toString() { public String toString() {
return "ExpressInfo{" + return "ExpressInfo{" +
"message='" + message + '\'' + "sid='" + sid + '\'' +
", message='" + message + '\'' +
", deliveryNum='" + deliveryNum + '\'' + ", deliveryNum='" + deliveryNum + '\'' +
", nu='" + nu + '\'' + ", nu='" + nu + '\'' +
", ischeck='" + ischeck + '\'' + ", ischeck='" + ischeck + '\'' +

View File

@ -48,7 +48,7 @@ public interface ExpressInfoMapper
/** /**
* 删除快递信息 * 删除快递信息
* *
* @param message 快递信息ID * @param message 快递信息ID
* @return 结果 * @return 结果
*/ */
@ -61,4 +61,22 @@ public interface ExpressInfoMapper
* @return 结果 * @return 结果
*/ */
public int deleteExpressInfoByIds(String[] messages); public int deleteExpressInfoByIds(String[] messages);
/**
* 批量新增快递信息
*
* @param expressInfoList 角色菜单列表
* @return 结果
*/
public int batchInsertExpressInfo(List<ExpressInfo> expressInfoList);
/**
* 删除快递信息
*
* @param queryId 快递信息queryId
* @return 结果
*/
public int deleteExpressInfoByQueryId(String queryId);
} }

View File

@ -2,6 +2,8 @@ package com.ruoyi.bps.service;
import java.util.List; import java.util.List;
import com.ruoyi.bps.domain.ExpImportQuery; import com.ruoyi.bps.domain.ExpImportQuery;
import com.ruoyi.bps.domain.ExpressInfo;
import com.ruoyi.common.core.domain.AjaxResult;
/** /**
* Excel批量快递查询Service接口 * Excel批量快递查询Service接口
@ -58,4 +60,13 @@ public interface IExpImportQueryService
* @return 结果 * @return 结果
*/ */
public int deleteExpImportQueryById(Long sid); public int deleteExpImportQueryById(Long sid);
/**
* 删除Excel批量快递查询信息
*
* @param expressInfoList Excel导入的快递列表
* @return 结果
*/
public AjaxResult importData(List<ExpressInfo> expressInfoList) throws Exception;
} }

View File

@ -1,12 +1,24 @@
package com.ruoyi.bps.service.impl; package com.ruoyi.bps.service.impl;
import java.util.List; import com.ruoyi.bps.domain.ExpImportQuery;
import com.ruoyi.bps.domain.ExpressInfo;
import com.ruoyi.bps.mapper.ExpImportQueryMapper;
import com.ruoyi.bps.mapper.ExpressInfoMapper;
import com.ruoyi.bps.service.IExpImportQueryService;
import com.ruoyi.bps.service.IExpressInfoService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.bps.mapper.ExpImportQueryMapper; import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.bps.domain.ExpImportQuery;
import com.ruoyi.bps.service.IExpImportQueryService; import java.time.LocalDateTime;
import com.ruoyi.common.core.text.Convert; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** /**
* Excel批量快递查询Service业务层处理 * Excel批量快递查询Service业务层处理
@ -20,6 +32,12 @@ public class ExpImportQueryServiceImpl implements IExpImportQueryService
@Autowired @Autowired
private ExpImportQueryMapper expImportQueryMapper; private ExpImportQueryMapper expImportQueryMapper;
@Autowired
private IExpressInfoService expressInfoService;
@Autowired
private ExpressInfoMapper expressInfoMapper;
/** /**
* 查询Excel批量快递查询 * 查询Excel批量快递查询
* *
@ -75,9 +93,15 @@ public class ExpImportQueryServiceImpl implements IExpImportQueryService
* @return 结果 * @return 结果
*/ */
@Override @Override
@Transactional
public int deleteExpImportQueryByIds(String ids) public int deleteExpImportQueryByIds(String ids)
{ {
return expImportQueryMapper.deleteExpImportQueryByIds(Convert.toStrArray(ids)); for(String str:Arrays.asList(ids.split(",")))
{
expressInfoMapper.deleteExpressInfoByQueryId(str);
}
int message= expImportQueryMapper.deleteExpImportQueryByIds(Convert.toStrArray(ids));
return message;
} }
/** /**
@ -91,4 +115,60 @@ public class ExpImportQueryServiceImpl implements IExpImportQueryService
{ {
return expImportQueryMapper.deleteExpImportQueryById(sid); return expImportQueryMapper.deleteExpImportQueryById(sid);
} }
/**
* Excel批量快递查询信息
*
* @param expressInfoList Excel导入的快递列表
* @return 结果
*/
@Override
@Transactional
public AjaxResult importData(List<ExpressInfo> expressInfoList) throws Exception {
String queryTime= DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss");
String queryId= LocalDateTime.now().toString();
ExpImportQuery expImportQuery=new ExpImportQuery();
List<ExpressInfo> expressInfoListForInsert=new ArrayList<>();
/* try{*/
//将查询到的快递结果放到expressInfoListForInsert并插入到数据库表expressInfo
for( ExpressInfo expressInfo:expressInfoList){
ExpressInfo ei= expressInfoService.SelectExpressInfo(expressInfo);
ei.setQueryId(queryId);
ei.setQueryUserName(ShiroUtils.getSysUser().getUserName());
ei.setQueryType("excel");
ei.setQueryTime(queryTime);
//expressInfoService.insertExpressInfo(ei);
expressInfoListForInsert.add(ei);
/* for(int i=1;i<1001;i++){ //测试批量插入效率用时打开Mark产生5万条数据
expressInfoListForInsert.add(ei);
}*/
}
int size= expressInfoListForInsert.size();
List<ExpressInfo> expressInfos= new ArrayList<>();
for(int i=1;i<=size;i++){
expressInfos.add(expressInfoListForInsert.get(i-1));
if( (i%400==0 ) ||i== size) {
expressInfoMapper.batchInsertExpressInfo(expressInfos);
expressInfos.clear();
}
}
//将本次excel导入查询记录到数据表exp_import_query
expImportQuery.setQueryTime(queryTime);
expImportQuery.setQueryLoginName(ShiroUtils.getLoginName());
expImportQuery.setQueryUserName(ShiroUtils.getSysUser().getUserName());
expImportQuery.setFinishTime(DateUtils.dateTimeNow("yyyy-MM-dd HH:mm:ss"));
expImportQuery.setQueryIp(ShiroUtils.getIp());
expImportQuery.setStatus("success");
expImportQuery.setQueryQty(String.valueOf(expressInfoList.size()));
expImportQuery.setQueryId(queryId);
int message=expImportQueryMapper.insertExpImportQuery(expImportQuery);
return AjaxResult.success(message);
/*}catch (Exception e){
expImportQuery.setStatus("fail");
return AjaxResult.error(e.getMessage());
}*/
}
} }

View File

@ -5,6 +5,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<mapper namespace="com.ruoyi.bps.mapper.ExpressInfoMapper"> <mapper namespace="com.ruoyi.bps.mapper.ExpressInfoMapper">
<resultMap type="ExpressInfo" id="ExpressInfoResult"> <resultMap type="ExpressInfo" id="ExpressInfoResult">
<result property="sid" column="sid" />
<result property="message" column="message" /> <result property="message" column="message" />
<result property="nu" column="nu" /> <result property="nu" column="nu" />
<result property="ischeck" column="ischeck" /> <result property="ischeck" column="ischeck" />
@ -24,10 +25,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="queryUserName" column="queryUserName" /> <result property="queryUserName" column="queryUserName" />
<result property="queryId" column="queryId" /> <result property="queryId" column="queryId" />
<result property="queryType" column="queryType" /> <result property="queryType" column="queryType" />
<result property="deliveryNum" column="deliveryNum" />
</resultMap> </resultMap>
<sql id="selectExpressInfoVo"> <sql id="selectExpressInfoVo">
select message, nu, ischeck, com, status, `data`, `state`, `condition`, routeInfo, returnCode, `result`, phone, select sid, message, nu, deliveryNum, ischeck, com, status, `data`, `state`, `condition`, routeInfo, returnCode, `result`, phone,
collectTime, singedTime, lastUpdateTime, queryTime, queryUserName, queryId, queryType collectTime, singedTime, lastUpdateTime, queryTime, queryUserName, queryId, queryType
from expressInfo from expressInfo
</sql> </sql>
@ -39,12 +42,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="com != null and com != ''"> and com = #{com}</if> <if test="com != null and com != ''"> and com = #{com}</if>
<if test="phone != null and phone != ''"> and phone = #{phone}</if> <if test="phone != null and phone != ''"> and phone = #{phone}</if>
<if test="queryId != null and queryId != ''"> and queryId = #{queryId}</if> <if test="queryId != null and queryId != ''"> and queryId = #{queryId}</if>
<if test="deliveryNum != null and deliveryNum != ''"> and deliveryNum = #{deliveryNum}</if>
</where> </where>
</select> </select>
<select id="selectExpressInfoById" parameterType="String" resultMap="ExpressInfoResult"> <select id="selectExpressInfoById" parameterType="String" resultMap="ExpressInfoResult">
<include refid="selectExpressInfoVo"/> <include refid="selectExpressInfoVo"/>
where message = #{message} where sid = #{sid}
</select> </select>
<insert id="insertExpressInfo" parameterType="ExpressInfo"> <insert id="insertExpressInfo" parameterType="ExpressInfo">
@ -69,6 +73,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="queryUserName != null">queryUserName,</if> <if test="queryUserName != null">queryUserName,</if>
<if test="queryId != null">queryId,</if> <if test="queryId != null">queryId,</if>
<if test="queryType != null">queryType,</if> <if test="queryType != null">queryType,</if>
<if test="deliveryNum != null">deliveryNum,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="message != null">#{message},</if> <if test="message != null">#{message},</if>
@ -90,6 +95,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="queryUserName != null">#{queryUserName},</if> <if test="queryUserName != null">#{queryUserName},</if>
<if test="queryId != null">#{queryId},</if> <if test="queryId != null">#{queryId},</if>
<if test="queryType != null">#{queryType},</if> <if test="queryType != null">#{queryType},</if>
<if test="deliveryNum != null">#{deliveryNum},</if>
</trim> </trim>
</insert> </insert>
@ -114,19 +120,37 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="queryUserName != null">queryUserName = #{queryUserName},</if> <if test="queryUserName != null">queryUserName = #{queryUserName},</if>
<if test="queryId != null">queryId = #{queryId},</if> <if test="queryId != null">queryId = #{queryId},</if>
<if test="queryType != null">queryType = #{queryType},</if> <if test="queryType != null">queryType = #{queryType},</if>
<if test="deliveryNum != null">deliveryNum = #{deliveryNum},</if>
</trim> </trim>
where message = #{message} where message = #{message}
</update> </update>
<delete id="deleteExpressInfoById" parameterType="String"> <delete id="deleteExpressInfoById" parameterType="String">
delete from expressInfo where message = #{message} delete from expressInfo where sid = #{sid}
</delete> </delete>
<delete id="deleteExpressInfoByIds" parameterType="String"> <delete id="deleteExpressInfoByIds" parameterType="String">
delete from expressInfo where message in delete from expressInfo where sid in
<foreach item="message" collection="array" open="(" separator="," close=")"> <foreach item="sid" collection="array" open="(" separator="," close=")">
#{message} #{sid}
</foreach> </foreach>
</delete> </delete>
<insert id="batchInsertExpressInfo">
insert into expressInfo(message, nu, deliveryNum, ischeck, com, status, `data`, `state`, `condition`, routeInfo, returnCode, `result`, phone,
collectTime, singedTime, lastUpdateTime, queryTime, queryUserName, queryId, queryType) values
<foreach item="expressInfo" index="index" collection="list" separator=",">
( #{expressInfo.message}, #{expressInfo.nu}, #{expressInfo.deliveryNum}, #{expressInfo.ischeck}, #{expressInfo.com}, #{expressInfo.status},
#{expressInfo.data}, #{expressInfo.state}, #{expressInfo.condition}, #{expressInfo.routeInfo}, #{expressInfo.returnCode},
#{expressInfo.result}, #{expressInfo.phone}, #{expressInfo.collectTime}, #{expressInfo.singedTime}, #{expressInfo.lastUpdateTime},
#{expressInfo.queryTime}, #{expressInfo.queryUserName}, #{expressInfo.queryId}, #{expressInfo.queryType}
)
</foreach>
</insert>
<delete id="deleteExpressInfoByQueryId" parameterType="String">
delete from expressInfo where queryId in (select queryId from exp_import_query where sid= #{sid})
</delete>
</mapper> </mapper>

View File

@ -7,7 +7,7 @@
<div class="wrapper wrapper-content animated fadeInRight ibox-content"> <div class="wrapper wrapper-content animated fadeInRight ibox-content">
<form class="form-horizontal m" id="form-expImportQuery-add"> <form class="form-horizontal m" id="form-expImportQuery-add">
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">查询ID</label> <label class="col-sm-3 control-label">查询编号</label>
<div class="col-sm-8"> <div class="col-sm-8">
<input name="queryId" class="form-control" type="text"> <input name="queryId" class="form-control" type="text">
</div> </div>

View File

@ -11,8 +11,8 @@
<div class="select-list"> <div class="select-list">
<ul> <ul>
<li> <li>
<label>查询ID</label> <label>查询编号</label>
<input type="text" name="queryId" th:field="*{queryId}"/> <input type="text" name="queryId" th:field="*{queryId}" readonly/>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -42,6 +42,9 @@
<a class="btn btn-info" onclick="$.table.importExcel()"> <a class="btn btn-info" onclick="$.table.importExcel()">
<i class="fa fa-upload"></i> 导入 <i class="fa fa-upload"></i> 导入
</a> </a>
<a onclick="$.table.importTemplate()" class="btn btn-default btn-xs">
<i class="fa fa-file-excel-o"></i> 下载导入模板
</a>
<!--<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="bps:expImportQuery:add"> <!--<a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="bps:expImportQuery:add">
<i class="fa fa-plus"></i> 添加 <i class="fa fa-plus"></i> 添加
</a> </a>
@ -78,6 +81,8 @@
exportUrl: prefix + "/export", exportUrl: prefix + "/export",
importUrl: prefix + "/importData", importUrl: prefix + "/importData",
importTemplateUrl: prefix + "/importTemplate", importTemplateUrl: prefix + "/importTemplate",
sortName: "querytime",
sortOrder: "desc",
modalName: "Excel批量快递查询", modalName: "Excel批量快递查询",
columns: [{ columns: [{
checkbox: true checkbox: true
@ -89,7 +94,7 @@
}, },
{ {
field: 'queryId', field: 'queryId',
title: '查询ID' title: '查询编号'
}, },
{ {
field: 'queryTime', field: 'queryTime',
@ -143,9 +148,9 @@
<form enctype="multipart/form-data" class="mt20 mb10"> <form enctype="multipart/form-data" class="mt20 mb10">
<div class="col-xs-offset-1"> <div class="col-xs-offset-1">
<input type="file" id="file" name="file"/> <input type="file" id="file" name="file"/>
<div class="mt10 pt5"> <!--<div class="mt10 pt5">
<a onclick="$.table.importTemplate()" class="btn btn-default btn-xs"><i class="fa fa-file-excel-o"></i> 下载模板</a> <a onclick="$.table.importTemplate()" class="btn btn-default btn-xs"><i class="fa fa-file-excel-o"></i> 下载模板</a>
</div> </div>-->
<span class="pull-left mt10" style="color: red; "> <span class="pull-left mt10" style="color: red; ">
提示仅允许导入“xls”或“xlsx”格式文件 提示仅允许导入“xls”或“xlsx”格式文件
</span> </span>

View File

@ -27,7 +27,7 @@
<input type="text" name="deliveryNum"/> <input type="text" name="deliveryNum"/>
</li> </li>
<li> <li>
<a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>&nbsp;搜索</a> <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i>实时查询</a>
<a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a> <a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i>&nbsp;重置</a>
</li> </li>
</ul> </ul>
@ -78,11 +78,17 @@
modalName: "快递信息", modalName: "快递信息",
columns: [{ columns: [{
checkbox: false checkbox: false
},
{
field: 'sid',
title: 'SID',
visible: false
}, },
/* /*
{ {
field: 'message', field: 'message',
title: '消息' title: '消息',
visible: false
},*/ },*/
{ {
field: 'deliveryNum', field: 'deliveryNum',
@ -95,7 +101,8 @@
/* /*
{ {
field: 'ischeck', field: 'ischeck',
title: '签收状态' title: '签收状态',
visible: false
},*/ },*/
{ {
field: 'com', field: 'com',
@ -107,7 +114,8 @@
/* /*
{ {
field: 'status', field: 'status',
title: '通信状态' title: '通信状态',
visible: false
},*/ },*/
{ {
field: 'data', field: 'data',
@ -125,19 +133,23 @@
},/* },/*
{ {
field: 'condition', field: 'condition',
title: '状态标志' title: '状态标志',
visible: false
}, },
{ {
field: 'routeInfo', field: 'routeInfo',
title: '路由信息' title: '路由信息',
visible: false
}, },
{ {
field: 'returnCode', field: 'returnCode',
title: '返回码' title: '返回码',
visible: false
}, },
{ {
field: 'result', field: 'result',
title: '返回结果' title: '返回结果',
visible: false
},*/ },*/
{ {
@ -170,8 +182,8 @@
align: 'center', align: 'center',
formatter: function(value, row, index) { formatter: function(value, row, index) {
var actions = []; var actions = [];
actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.message + '\')"><i class="fa fa-edit"></i>编辑</a> '); actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="javascript:void(0)" onclick="$.operate.edit(\'' + row.sid + '\')"><i class="fa fa-edit"></i>编辑</a> ');
actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.message + '\')"><i class="fa fa-remove"></i>删除</a>'); actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="javascript:void(0)" onclick="$.operate.remove(\'' + row.sid + '\')"><i class="fa fa-remove"></i>删除</a>');
return actions.join(''); return actions.join('');
} }
}*/] }*/]

View File

@ -1,19 +1,23 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.util.CustToken;
import com.ruoyi.system.service.IWechatApiService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/** /**
* 登录验证 * 登录验证
@ -23,23 +27,47 @@ import com.ruoyi.common.utils.StringUtils;
@Controller @Controller
public class SysLoginController extends BaseController public class SysLoginController extends BaseController
{ {
@Autowired
private IWechatApiService wechatApiService;
@GetMapping("/login") @GetMapping("/login")
public String login(HttpServletRequest request, HttpServletResponse response) public String login(HttpServletRequest request, HttpServletResponse response, Map<String,String> map)
{ {
String loginType= request.getParameter("loginType");
if(StringUtils.isNotEmpty(loginType) && request.getParameter("loginType").equals("wechat")){
String code= request.getParameter("code");
//String state = request.getParameter("state");
String username=wechatApiService.GetLoginNameWithWechatCode(code);
//如果没有获取到用户名说明验证失败跳转登录页
if(StringUtils.isEmpty(username)){
return "login";
}
String password="";
Boolean rememberMe=true;
map.put("loginType","wechat");
map.put("username",username);
map.put("password",password);
return "loginwechat";
}
// 如果是Ajax请求返回Json字符串 // 如果是Ajax请求返回Json字符串
if (ServletUtils.isAjaxRequest(request)) if (ServletUtils.isAjaxRequest(request))
{ {
return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}"); return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}");
} }
return "login"; return "login";
} }
@PostMapping("/login") @PostMapping("/login")
@ResponseBody @ResponseBody
public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe) public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe,String loginType)
{ {
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); // UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
CustToken token=new CustToken(username,password,rememberMe,loginType);
Subject subject = SecurityUtils.getSubject(); Subject subject = SecurityUtils.getSubject();
try try
{ {

View File

@ -0,0 +1,81 @@
package com.ruoyi.web.controller.system;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.util.CustToken;
import com.ruoyi.system.service.IWechatApiService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
@Controller
public class WechatApiController extends BaseController {
@Autowired
IWechatApiService wechatApiService;
@RequestMapping("anon/getAccessToken")
public String getAccessToken() {
return wechatApiService.GetAccessToken();
}
@GetMapping("anon/wechatLogin")
@ResponseBody
public AjaxResult WechatLogin(HttpServletRequest request)
{
String code= request.getParameter("code");
String state = request.getParameter("state");
String username=wechatApiService.GetLoginNameWithWechatCode(code);
String password="";
Boolean rememberMe=true;
String loginType=request.getParameter("loginType");
//UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
CustToken token=new CustToken(username,password,rememberMe,loginType);
Subject subject = SecurityUtils.getSubject();
try
{
subject.login(token);
return success();
}
catch (AuthenticationException e)
{
String msg = "用户或密码错误";
if (StringUtils.isNotEmpty(e.getMessage()))
{
msg = e.getMessage();
}
return error(msg);
}
}
@GetMapping("anon/userInfo")
public Map<String, Object> getJSON(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
BufferedReader streamReader = new BufferedReader( new InputStreamReader(request.getInputStream(), "UTF-8"));
StringBuilder responseStrBuilder = new StringBuilder();
String inputStr;
while ((inputStr = streamReader.readLine()) != null) {
responseStrBuilder.append(inputStr);
}
Map<String, Object> params = JSON.parseObject(responseStrBuilder.toString(), Map.class);
return params;
}
}

View File

@ -19,7 +19,7 @@ server:
port: 80 port: 80
servlet: servlet:
# 应用的访问路径 # 应用的访问路径
context-path: /it_war context-path: /it
tomcat: tomcat:
# tomcat的URI编码 # tomcat的URI编码
uri-encoding: UTF-8 uri-encoding: UTF-8
@ -141,3 +141,11 @@ xss:
swagger: swagger:
# 是否开启swagger # 是否开启swagger
enabled: true enabled: true
#企业微信
wechat:
corpId: ww4ed3771457e5f463
agentId: 1000080
secret: drtHKYabI9_EgjJQ8aqDPTQkY1WUYeWUTMkYw7D_z64
token: 111
aesKey: 111

View File

@ -44,8 +44,8 @@
<form id="signupForm" autocomplete="off"> <form id="signupForm" autocomplete="off">
<h4 class="no-margins">登录:</h4> <h4 class="no-margins">登录:</h4>
<p class="m-t-md">请输入用户名、密码进行登录!</p> <p class="m-t-md">请输入用户名、密码进行登录!</p>
<input type="text" name="username" class="form-control uname" placeholder="用户名" value="admin" /> <input type="text" name="username" class="form-control uname" placeholder="用户名" />
<input type="password" name="password" class="form-control pword" placeholder="密码" value="admin123" /> <input type="password" name="password" class="form-control pword" placeholder="密码" />
<div class="row m-t" th:if="${captchaEnabled==true}"> <div class="row m-t" th:if="${captchaEnabled==true}">
<div class="col-xs-6"> <div class="col-xs-6">
<input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" /> <input type="text" name="validateCode" class="form-control code" placeholder="验证码" maxlength="5" />

View File

@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<title>登录BPS后台管理系统</title>
<meta name="description" content="BPS后台管理框架">
<!-- 360浏览器急速模式 -->
<meta name="renderer" content="webkit">
<!-- 避免IE使用兼容模式 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script>
if(window.top!==window.self){alert('未登录或登录超时。请重新登录');window.top.location=window.location};
</script>
<style type="text/css">
html, body {
margin: 0;
padding: 0;
height: 100%;
}
#parent {
height: 100%;
margin: 0;
border: 0;
}
#child {
position: absolute;
top: 50%;
left: 60%;
right: 0;
bottom: 0;
transform: translate(-50%, -50%);
border: 0;
}
</style>
</head>
<body class="signin">
<div id="parent">
<div id="child"><h4> <strong>登录中...</strong></h4></div>
<div id="validateFalse"></div>
</div>
<script th:inline="javascript"> </script>
<!--[if lte IE 8]><script>window.location.href=ctx+'html/ie.html';</script><![endif]-->
<!-- 全局js -->
<script src="../static/js/jquery.min.js" th:src="@{/js/jquery.min.js}"></script>
<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=4.6.2}"></script>
<script th:inline="javascript">
var ctx = [[@{/}]];
var loginType = [[${loginType}]];
var username = [[${username}]];
var password = [[${password}]];
var rememberMe = "true";
$(function () {
if (loginType == 'wechat') {
$.ajax({
type: "post",
url: ctx + "login",
data: {
"username": username,
"password": password,
"rememberMe": rememberMe,
"loginType": loginType,
},
success: function(r) {
if (r.code == web_status.SUCCESS) {
location.href = ctx + 'index';
} else {
$.modal.closeLoading();
$('.imgcode').click();
$(".code").val("");
$.modal.msg(r.msg);
}
}
});
}
});
</script>
</body>
</html>

View File

@ -2,6 +2,8 @@ package com.ruoyi.framework.shiro.realm;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import com.ruoyi.framework.shiro.util.CustToken;
import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.AuthenticationToken;
@ -86,9 +88,12 @@ public class UserRealm extends AuthorizingRealm
@Override @Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException
{ {
UsernamePasswordToken upToken = (UsernamePasswordToken) token; //UsernamePasswordToken upToken = (UsernamePasswordToken) token;
CustToken upToken= (CustToken) token;
String loginType = upToken.getLoginType();
String username = upToken.getUsername(); String username = upToken.getUsername();
String password = ""; String password = "";
if (upToken.getPassword() != null) if (upToken.getPassword() != null)
{ {
password = new String(upToken.getPassword()); password = new String(upToken.getPassword());
@ -97,7 +102,7 @@ public class UserRealm extends AuthorizingRealm
SysUser user = null; SysUser user = null;
try try
{ {
user = loginService.login(username, password); user = loginService.login(username, password,loginType);
} }
catch (CaptchaException e) catch (CaptchaException e)
{ {

View File

@ -38,26 +38,26 @@ public class SysLoginService
/** /**
* 登录 * 登录
*/ */
public SysUser login(String username, String password) public SysUser login(String username, String password,String loginType)
{ {
// 验证码校验 //如果是企业微信登录则无需验证本密码规则
if (ShiroConstants.CAPTCHA_ERROR.equals(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA))) if(StringUtils.isEmpty(loginType) || !loginType.equals("wechat")) {
{ // 验证码校验
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); if (ShiroConstants.CAPTCHA_ERROR.equals(ServletUtils.getRequest().getAttribute(ShiroConstants.CURRENT_CAPTCHA))) {
throw new CaptchaException(); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
} throw new CaptchaException();
// 用户名或密码为空 错误 }
if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) // 用户名或密码为空 错误
{ if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("not.null")));
throw new UserNotExistsException(); throw new UserNotExistsException();
} }
// 密码如果不在指定范围内 错误 // 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH) || password.length() > UserConstants.PASSWORD_MAX_LENGTH) {
{ AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match"))); throw new UserPasswordNotMatchException();
throw new UserPasswordNotMatchException(); }
} }
// 用户名不在指定范围内 错误 // 用户名不在指定范围内 错误
@ -88,20 +88,22 @@ public class SysLoginService
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.not.exists")));
throw new UserNotExistsException(); throw new UserNotExistsException();
} }
if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.delete")));
throw new UserDeleteException(); throw new UserDeleteException();
} }
if (UserStatus.DISABLE.getCode().equals(user.getStatus())) if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark()))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.blocked", user.getRemark())));
throw new UserBlockedException(); throw new UserBlockedException();
} }
//如果是企业微信登录则无需本地验证密码
passwordService.validate(user, password); if(StringUtils.isEmpty(loginType) || !loginType.equals("wechat")){
passwordService.validate(user, password);
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
recordLoginInfo(user); recordLoginInfo(user);

View File

@ -0,0 +1,20 @@
package com.ruoyi.framework.shiro.util;
import org.apache.shiro.authc.UsernamePasswordToken;
public class CustToken extends UsernamePasswordToken {
private String loginType;// 企业微信wechat
public String getLoginType() {
return loginType;
}
public void setLoginType(String loginType) {
this.loginType = loginType;
}
public CustToken(String username, String password, Boolean rememberMe, String loginType) {
super(username, password);
this.loginType = loginType;
}
}

View File

@ -0,0 +1,112 @@
package com.ruoyi.system.domain;
import java.util.Date;
public class WechatAccessToken {
private Long sid;
private String corpId;
private String agentId;
private String secret;
private String errcode;
private String errmsg;
private String access_token; //access_token
private String expires_in;
private Date getTokenTime;
private String aesKey;
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getCorpId() {
return corpId;
}
public void setCorpId(String corpId) {
this.corpId = corpId;
}
public String getAgentId() {
return agentId;
}
public void setAgentId(String agentId) {
this.agentId = agentId;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getErrcode() {
return errcode;
}
public void setErrcode(String errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public String getAccess_token() {
return access_token;
}
public void setAccess_token(String access_token) {
this.access_token = access_token;
}
public String getExpires_in() {
return expires_in;
}
public void setExpires_in(String expires_in) {
this.expires_in = expires_in;
}
public Date getGetTokenTime() {
return getTokenTime;
}
public void setGetTokenTime(Date getTokenTime) {
this.getTokenTime = getTokenTime;
}
public String getAesKey() {
return aesKey;
}
public void setAesKey(String aesKey) {
this.aesKey = aesKey;
}
@Override
public String toString() {
return "WechatAccessToken{" +
"sid='" + sid + '\'' +
", corpId='" + corpId + '\'' +
", agentId='" + agentId + '\'' +
", secrect='" + secret + '\'' +
", errcode='" + errcode + '\'' +
", errmsg='" + errmsg + '\'' +
", access_token='" + access_token + '\'' +
", expires_in='" + expires_in + '\'' +
", getTokenTime=" + getTokenTime +
", aesKey='" + aesKey + '\'' +
'}';
}
}

View File

@ -0,0 +1,215 @@
package com.ruoyi.system.domain;
import java.util.List;
public class WechatUserInfo {
String errocode; //返回码
String errmsg; //返回码描述
String Userid; //成员UserID
String name; //成员名称
String depatrment; //成员所属部门id列表
String order; //部门内的排序值
String position; //职务信息
String mobile; //手机号码
String gender; //性别0未定义12
String email; //邮箱
String is_leader_in_dept; //在所在的部门内是否为上级
String avatar; //头像Url
String thumb_avatar; //头像缩略图Url
String telephone; //座机
String alias; //别名
String address; //地址
String open_userid; //全局唯一id
String main_department; //主部门
String extattr; //扩展属性
String Status; //激活状态: 1=已激活2=已禁用4=未激活5=退出企业
String qr_code; //员工个人二维码
String external_position; // 对外职务
String external_profile; //成员对外属性
public String getErrocode() {
return errocode;
}
public void setErrocode(String errocode) {
this.errocode = errocode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public String getUserid() {
return Userid;
}
public void setUserid(String userid) {
Userid = userid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDepatrment() {
return depatrment;
}
public void setDepatrment(String depatrment) {
this.depatrment = depatrment;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
public String getPosition() {
return position;
}
public void setPosition(String position) {
this.position = position;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getIs_leader_in_dept() {
return is_leader_in_dept;
}
public void setIs_leader_in_dept(String is_leader_in_dept) {
this.is_leader_in_dept = is_leader_in_dept;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getThumb_avatar() {
return thumb_avatar;
}
public void setThumb_avatar(String thumb_avatar) {
this.thumb_avatar = thumb_avatar;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getOpen_userid() {
return open_userid;
}
public void setOpen_userid(String open_userid) {
this.open_userid = open_userid;
}
public String getMain_department() {
return main_department;
}
public void setMain_department(String main_department) {
this.main_department = main_department;
}
public String getExtattr() {
return extattr;
}
public void setExtattr(String extattr) {
this.extattr = extattr;
}
public String getStatus() {
return Status;
}
public void setStatus(String status) {
Status = status;
}
public String getQr_code() {
return qr_code;
}
public void setQr_code(String qr_code) {
this.qr_code = qr_code;
}
public String getExternal_position() {
return external_position;
}
public void setExternal_position(String external_position) {
this.external_position = external_position;
}
public String getExternal_profile() {
return external_profile;
}
public void setExternal_profile(String external_profile) {
this.external_profile = external_profile;
}
}

View File

@ -126,4 +126,12 @@ public interface SysUserMapper
* 删除Ecology同步过来的用户 * 删除Ecology同步过来的用户
*/ */
public void deleteEcologySyncUser(); public void deleteEcologySyncUser();
/**
* 查询用户列表
*
* @param sysUser 用户信息
* @return 用户信息集合信息
*/
public List<SysUser> selectUserLists(SysUser sysUser);
} }

View File

@ -0,0 +1,67 @@
package com.ruoyi.system.mapper;
import com.ruoyi.system.domain.WechatAccessToken;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
/**
* 企业微信获取Access Token 的Mapper接口
*
* @author Bo
* @date 2021-07-21
*/
public interface WechatAccessTokenMapper
{
/**
* 根据SID查询Access Token
*
* @param sid
* @return 企业微信Access Token信息
*/
public WechatAccessToken selectWechatAccessTokenById(Long sid);
/**
* 查询Access Token
* @param wechatAccessToken
* @return 企业微信Access Token信息
*/
public List<WechatAccessToken> selectWechatAccessTokenList(WechatAccessToken wechatAccessToken);
/**
* 新增Access Token
*
* @param wechatAccessToken Access Token
* @return 结果
*/
public int insertWechatAccessToken(WechatAccessToken wechatAccessToken);
/**
* 修改Access Token
*
* @param wechatAccessToken Access Token
* @return 结果
*/
public int updateWechatAccessToken(WechatAccessToken wechatAccessToken);
/**
* 删除Access Token
*
* @param sid Access TokenID
* @return 结果
*/
public int deleteWechatAccessTokenById(Long sid);
/**
* 批量删除Access Token
*
* @param sids 需要删除的数据ID
* @return 结果
*/
public int deleteWechatAccessTokenByIds(String[] sids);
}

View File

@ -209,4 +209,12 @@ public interface ISysUserService
* Ecology人员信息同步 * Ecology人员信息同步
*/ */
public int syncEcologyUser(String url,String params); public int syncEcologyUser(String url,String params);
/**
* 查询用户列表
*
* @param user 用户信息
* @return 用户信息集合信息
*/
public List<SysUser> selectUserLists(SysUser user);
} }

View File

@ -0,0 +1,9 @@
package com.ruoyi.system.service;
public interface IWechatApiService {
//获取Access Token
public String GetAccessToken();
//根据企业微信登录身份获取本地LoginName
public String GetLoginNameWithWechatCode(String code);
}

View File

@ -540,6 +540,17 @@ public class SysUserServiceImpl implements ISysUserService
return result; return result;
} }
/**
* 查询用户列表
*
* @param user 用户信息
* @return 用户信息集合信息
*/
@Override
public List<SysUser> selectUserLists(SysUser user) {
return userMapper.selectUserLists(user);
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public int userSync(Map<String,String> mapResult){ public int userSync(Map<String,String> mapResult){
//如果接口返回状态码不为200则不做同步处理 //如果接口返回状态码不为200则不做同步处理

View File

@ -0,0 +1,158 @@
package com.ruoyi.system.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.system.domain.WechatAccessToken;
import com.ruoyi.system.mapper.WechatAccessTokenMapper;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.IWechatApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
@Service
public class WechatApiServiceImpl implements IWechatApiService {
@Value("${wechat.corpId}")
private String corpId;
@Value("${wechat.secret}")
private String secret;
@Value("${wechat.agentId}")
private String agentId;
@Autowired
WechatAccessTokenMapper wechatAccessTokenMapper;
@Autowired
IWechatApiService wechatApiService;
@Autowired
private ISysUserService userService;
/**
*
* 获取企业微信Access Token
* @return Access Token
*/
@Override
public String GetAccessToken() {
//获取本地数据库中的Token
WechatAccessToken wat = new WechatAccessToken();
wat.setCorpId(corpId);
wat.setSecret(secret);
List<WechatAccessToken> list= wechatAccessTokenMapper.selectWechatAccessTokenList(wat);
WechatAccessToken returnWat;
//如果数据库中没有对应corpId+corpSecret的数据,或者数据多于一条则从企业微信获取Token并插入数据库
if(list.isEmpty() || list.size() <=0)
{
returnWat= getAccessTokenFromWechat(corpId,secret,agentId);
wechatAccessTokenMapper.insertWechatAccessToken(returnWat);
return returnWat.getAccess_token();
}
//如果数据库中存在多条corpId+corpSecret的数据则全部删除再从企业微信获取Token,并插入数据库
if(list.size()>1 || StringUtils.isEmpty(list.get(0).getAccess_token()))
{
for(WechatAccessToken token:list){
wechatAccessTokenMapper.deleteWechatAccessTokenById(token.getSid());
}
returnWat= getAccessTokenFromWechat(corpId,secret,agentId);
wechatAccessTokenMapper.insertWechatAccessToken(returnWat);
return returnWat.getAccess_token();
}
//如果获取到的数据中Token或更新时间为空或者离过期时间小于1000秒则从企业微信获取Token,并更新数据库
int a= differenceSecond(DateUtils.getNowDate(),list.get(0).getGetTokenTime())-Integer.parseInt(list.get(0).getExpires_in())-1000;
if(StringUtils.isEmpty(list.get(0).getAccess_token()) || list.get(0).getGetTokenTime() ==null
|| differenceSecond(DateUtils.getNowDate(),list.get(0).getGetTokenTime())>Integer.parseInt(list.get(0).getExpires_in())-1000){
returnWat= getAccessTokenFromWechat(corpId,secret,agentId);
returnWat.setSid(list.get(0).getSid());
wechatAccessTokenMapper.updateWechatAccessToken(returnWat);
return returnWat.getAccess_token();
}
//如果以上情况皆不是则返回本地数据库的token
return list.get(0).getAccess_token();
}
//根据corpId与corpSecret获取Token
private WechatAccessToken getAccessTokenFromWechat(String corpId,String secret, String agentId){
String param ="corpid=" + corpId + "&corpsecret=" + secret;
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken";
WechatAccessToken wechatAccessToken= new Gson().fromJson(HttpUtils.sendGet(url,param),WechatAccessToken.class);
wechatAccessToken.setCorpId(corpId);
wechatAccessToken.setSecret(secret);
wechatAccessToken.setAgentId(agentId);
wechatAccessToken.setGetTokenTime(DateUtils.getNowDate());
return wechatAccessToken;
}
//获取相两个日期相差秒数
private int differenceSecond(Date minuendDate, Date subtractionDate ) {
return (int)((minuendDate.getTime() - subtractionDate.getTime()) / 1000);
}
/**
* 根据企业微信登录身份获取本地LoginName
*
* @param code
* @return LoginName
*/
@Override
public String GetLoginNameWithWechatCode(String code)
{
//获取访问用户身份ID
String url="https://qyapi.weixin.qq.com/cgi-bin/user/getuserinfo";
String param = "access_token="+wechatApiService.GetAccessToken()+"&code="+code;
//String userInfo = HttpUtils.sendGet(url,param); //测试已能正常返回UserInfo Json,正式使用时打开
String userInfo = "{\"UserId\":\"359\",\"DeviceId\":\"10000589102865WJ\",\"errcode\":0,\"errmsg\":\"ok\"}"; //为避免去微信获取code麻烦开发调试时打开
JSONObject jsonObjectUserInfo = JSONObject.parseObject(userInfo);
//如果返回码不为0则输出错误信息并返回空值
if ( Integer.parseInt(jsonObjectUserInfo.getString("errcode")) != 0){
System.out.println(jsonObjectUserInfo.getString("errmsg"));
return "";
}
String userId = jsonObjectUserInfo.getString("UserId");
//获取用户邮箱与姓名
url="https://qyapi.weixin.qq.com/cgi-bin/user/get";
param="access_token="+wechatApiService.GetAccessToken()+"&userid="+userId;
String userInfoDetail=HttpUtils.sendGet(url,param); //获取成员信息
JSONObject jsonObjectUserInfoDetail=JSONObject.parseObject(userInfoDetail);
//如果返回码不为0则返回错误信息
if(Integer.parseInt(jsonObjectUserInfoDetail.getString("errcode")) != 0)
{
System.out.println(jsonObjectUserInfo.getString("errmsg"));
return "";
}
String userEmail= jsonObjectUserInfoDetail.getString("email");
String userName= jsonObjectUserInfoDetail.getString("name");
//根据邮箱名+用户名匹配本地用户对应的邮箱名与用户名
SysUser sysUser=new SysUser();
sysUser.setUserName(userName);
sysUser.setEmail(userEmail);
sysUser.setUserType("02"); //只获取从OA同步的用户保持与企业微信一致
List<SysUser> userList= userService.selectUserLists(sysUser);
int count= userList.size();
if(count <= 0){
return ""; //系统里没有用户没有从OA同步 处理逻辑待定
}
if(count > 1){
return ""; //本地数据库存在多个姓名与邮箱相同的记录如何处理
}
String loginName= userList.get(0).getLoginName();
return loginName;
}
}

View File

@ -227,5 +227,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<delete id="deleteEcologySyncUser" > <delete id="deleteEcologySyncUser" >
delete from sys_user where user_type ='02' delete from sys_user where user_type ='02'
</delete> </delete>
<select id="selectUserLists" parameterType="SysUser" resultMap="SysUserResult">
select user_id, dept_id, login_name, user_name, user_type, email, avatar, phonenumber, password, sex, salt, status, del_flag, login_ip, login_date, create_by, create_time, remark from sys_user
where del_flag = '0'
<if test="userName != null and userName != ''">
AND user_name = #{userName}
</if>
<if test="email != null and email != ''">
AND email = #{email}
</if>
<if test="userType != null and userType != ''">
AND user_type = #{userType}
</if>
</select>
</mapper> </mapper>

View File

@ -0,0 +1,92 @@
<?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.system.mapper.WechatAccessTokenMapper">
<resultMap type="WechatAccessToken" id="WechatAccessTokenResult">
<result property="sid" column="sid" />
<result property="corpId" column="corp_id" />
<result property="agentId" column="agent_id" />
<result property="secret" column="secret" />
<result property="errcode" column="errcode" />
<result property="errmsg" column="errmsg" />
<result property="access_token" column="access_token" />
<result property="expires_in" column="expires_in" />
<result property="getTokenTime" column="get_token_time" />
<result property="aesKey" column="aes_key" />
</resultMap>
<sql id="selectWechatAccessTokenVo">
select sid, corp_id, agent_id, secret, errcode, errmsg, access_token, expires_in, get_token_time, aes_key from wechat_access_token
</sql>
<select id="selectWechatAccessTokenList" parameterType="WechatAccessToken" resultMap="WechatAccessTokenResult">
<include refid="selectWechatAccessTokenVo"/>
<where>
<if test="corpId != null and corpId != ''"> and corp_id = #{corpId}</if>
<if test="agentId != null and agentId != ''"> and agent_id = #{agentId}</if>
<if test="secret != null and secret != ''"> and secret = #{secret}</if>
<if test="access_token != null and access_token != ''"> and access_token = #{access_token}</if>
</where>
</select>
<select id="selectWechatAccessTokenById" parameterType="Long" resultMap="WechatAccessTokenResult">
<include refid="selectWechatAccessTokenVo"/>
where sid = #{sid}
</select>
<insert id="insertWechatAccessToken" parameterType="WechatAccessToken" useGeneratedKeys="true" keyProperty="sid">
insert into wechat_access_token
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="corpId != null">corp_id,</if>
<if test="agentId != null">agent_id,</if>
<if test="secret != null">secret,</if>
<if test="errcode != null">errcode,</if>
<if test="errmsg != null">errmsg,</if>
<if test="access_token != null">access_token,</if>
<if test="expires_in != null">expires_in,</if>
<if test="getTokenTime != null">getToken_time,</if>
<if test="aesKey != null">aes_key,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="corpId != null">#{corpId},</if>
<if test="agentId != null">#{agentId},</if>
<if test="secret != null">#{secret},</if>
<if test="errcode != null">#{errcode},</if>
<if test="errmsg != null">#{errmsg},</if>
<if test="access_token != null">#{access_token},</if>
<if test="expires_in != null">#{expires_in},</if>
<if test="getTokenTime != null">#{getTokenTime},</if>
<if test="aesKey != null">#{aesKey},</if>
</trim>
</insert>
<update id="updateWechatAccessToken" parameterType="WechatAccessToken">
update wechat_access_token
<trim prefix="SET" suffixOverrides=",">
<if test="corpId != null">corp_id = #{corpId},</if>
<if test="agentId != null">agent_id = #{agentId},</if>
<if test="secret != null">secret = #{secret},</if>
<if test="errcode != null">errcode = #{errcode},</if>
<if test="errmsg != null">errmsg = #{errmsg},</if>
<if test="access_token != null">access_token = #{access_token},</if>
<if test="expires_in != null">expires_in = #{expires_in},</if>
<if test="getTokenTime != null">get_token_time = #{getTokenTime},</if>
<if test="aesKey != null">aes_key = #{aesKey},</if>
</trim>
where sid = #{sid}
</update>
<delete id="deleteWechatAccessTokenById" parameterType="Long">
delete from wechat_access_token where sid = #{sid}
</delete>
<delete id="deleteWechatAccessTokenByIds" parameterType="String">
delete from wechat_access_token where sid in
<foreach item="sid" collection="array" open="(" separator="," close=")">
#{sid}
</foreach>
</delete>
</mapper>