修改环境配置
This commit is contained in:
25
doc/info.txt
Normal file
25
doc/info.txt
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
我发一下服务器的信息:
|
||||
grow.xxzzu.com
|
||||
47.92.6.215
|
||||
mysql 和 linux 的密码都是
|
||||
gywj@1qaz@WSX
|
||||
|
||||
数据库使用
|
||||
sys_manager
|
||||
测试存储过程可以使用 :
|
||||
proc_DS01E_enterprise_info
|
||||
|
||||
当前,ms_muster 数据库 未更新,等开发模式确定后,一起逐一更新数据结构
|
||||
|
||||
小象智租 微信 开发者ID(AppID)
|
||||
AppID:wx08196c4219236ab5
|
||||
AppSecret:9a131c53016eb64e1f55161326307bbf
|
||||
|
||||
appId:wx08196c4219236ab5
|
||||
授权回调域:grow.xxzzu.com
|
||||
|
||||
|
||||
微信开放平台:(open.weixin.qq.com)
|
||||
注册邮箱:jcjytbkt@126.com
|
||||
密码:xx-621588+-
|
30
doc/xxzzu.conf
Normal file
30
doc/xxzzu.conf
Normal file
@ -0,0 +1,30 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name grow.xxzzu.com;
|
||||
|
||||
location ^~ /system {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
|
||||
location ~ .*\.(js|css)?$ {
|
||||
expires 12h;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
location / {
|
||||
index index.html index index.htm;
|
||||
alias /www/muster-ui;
|
||||
}
|
||||
|
||||
location ^~ /common/ {
|
||||
proxy_pass http://127.0.0.1:8081;
|
||||
}
|
||||
|
||||
#文件资源映射路径
|
||||
location /profile {
|
||||
alias /www/muster/upload;
|
||||
access_log off;
|
||||
log_not_found off;
|
||||
}
|
||||
|
||||
}
|
@ -73,6 +73,17 @@
|
||||
<artifactId>muster-generator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 逻辑模块-->
|
||||
<dependency>
|
||||
<groupId>com.muster</groupId>
|
||||
<artifactId>muster-logic</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.muster.common.config.RuoYiConfig;
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.common.constant.Constants;
|
||||
import com.muster.common.core.domain.AjaxResult;
|
||||
import com.muster.common.utils.StringUtils;
|
||||
@ -46,7 +46,7 @@ public class CommonController
|
||||
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
|
||||
}
|
||||
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
|
||||
String filePath = RuoYiConfig.getDownloadPath() + fileName;
|
||||
String filePath = MusterConfig.getDownloadPath() + fileName;
|
||||
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("multipart/form-data");
|
||||
@ -73,7 +73,7 @@ public class CommonController
|
||||
try
|
||||
{
|
||||
// 上传文件路径
|
||||
String filePath = RuoYiConfig.getUploadPath();
|
||||
String filePath = MusterConfig.getUploadPath();
|
||||
// 上传并返回新文件名称
|
||||
String fileName = FileUploadUtils.upload(filePath, file);
|
||||
String url = serverConfig.getUrl() + fileName;
|
||||
@ -95,7 +95,7 @@ public class CommonController
|
||||
public void resourceDownload(String name, HttpServletRequest request, HttpServletResponse response) throws Exception
|
||||
{
|
||||
// 本地资源路径
|
||||
String localPath = RuoYiConfig.getProfile();
|
||||
String localPath = MusterConfig.getProfile();
|
||||
// 数据库资源地址
|
||||
String downloadPath = localPath + StringUtils.substringAfter(name, Constants.RESOURCE_PREFIX);
|
||||
// 下载名称
|
||||
|
@ -0,0 +1,165 @@
|
||||
package com.muster.web.controller.common;
|
||||
|
||||
|
||||
import com.muster.common.constant.WxConsts;
|
||||
import com.muster.common.core.controller.BaseController;
|
||||
import com.muster.common.core.domain.AjaxResult;
|
||||
import com.muster.common.utils.StringUtils;
|
||||
import com.muster.common.utils.file.MimeTypeUtils;
|
||||
import com.muster.common.utils.uuid.IdUtils;
|
||||
import com.muster.web.controller.muster.weixin.QrCodeUtils;
|
||||
import com.muster.web.controller.muster.weixin.WeChatService;
|
||||
import com.muster.web.controller.muster.weixin.WeiXinCommonUtil;
|
||||
import com.muster.web.controller.muster.weixin.WeiXinOauth2Token;
|
||||
import com.muster.web.controller.muster.weixin.WeiXinUserInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @ClassName WeiXinController
|
||||
* @Description TOOD
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 14:29
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
@RestController
|
||||
@Api(value = "微信相关操作管理", description = "微信相关操作管理", tags = {"微信相关操作管理"})
|
||||
@RequestMapping("/system/wechat")
|
||||
public class WeChatController extends BaseController {
|
||||
|
||||
@Value("${wx.open.appid}")
|
||||
private String wxMapAppid;
|
||||
|
||||
@Value("${wx.open.appsecret}")
|
||||
private String wxMapAppsecret;
|
||||
|
||||
@Value("${wx.open.callback_url}")
|
||||
private String wxMapCallbackUrl;
|
||||
|
||||
@Autowired
|
||||
private WeChatService weChatService;
|
||||
|
||||
@GetMapping("/callback")
|
||||
@ApiOperation("微信回调接口")
|
||||
@ApiImplicitParams(value = {
|
||||
@ApiImplicitParam(name = "redirectUri", value = "跳转url", dataType = "String"),
|
||||
@ApiImplicitParam(name = "code", value = "微信授权的Code", dataType = "String")
|
||||
})
|
||||
public void callback(HttpServletResponse response, HttpServletRequest request,
|
||||
@RequestParam("redirectUri") String redirectUri,
|
||||
@RequestParam(value = "code", required = false) String code,
|
||||
@RequestParam("state") String state) throws IOException {
|
||||
String redirectUrl = String.format("%s?code=%s&state=%s", redirectUri , code, state);
|
||||
response.sendRedirect(redirectUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* <1>用户访问微信网页版,此时微信服务器会为其生成一个全局唯一的UUID。然后这个UUID就 回调路径wxMapCallbackUrl的后面,
|
||||
* 此时该操作并没有和用户有交互,所以该ID仅仅是个唯一字符串而已,系统并不知道该ID会和哪个用户相绑定。
|
||||
如果此时你不断地刷新,你会发现每次的ID都会发生过变化。感兴趣的可以自己手动来抓包,这里就不做示范了。
|
||||
注意:此时服务器和你网页还会建立一个长连接(websocket),为了节约系统资源,如果一段时间不扫描,便会超时。返回状态为408。
|
||||
|
||||
<2>用户扫描PC端的二维码,然后用户和服务创建一个长链接(websocket)判断当前状态,并且。这个步骤的目的是为了获取起生成的全局唯一UUID,进行前端状态变化。
|
||||
|
||||
<3>用户如果此时授权,则会像系统发送一条请求,并且将UUID和code一块发送过去,然后根据code获取微信用户信息,看系统是否存在该用户,不存在,则将微信用户信息保存,然后让用户取绑定账号
|
||||
<4> 如果用户输入的账号也不存在,则需要用户开通账号(开通账号方式分为自己注册和要求管理员开通),
|
||||
4.1 如果自己注册,则开始走注册流程,走注册流程的话,审核流程通过之后,然后重新扫码绑定。
|
||||
4.2 如果需要管理员开通账号,开通账号之后,首次扫码登录或者微信授权登录都需要重新绑定一次
|
||||
|
||||
<5>系统受到这一步的目的是将UUIIDI和用户账号(或token)绑定在一起,因为二者都是唯一,便可以确定唯一的对应关系。
|
||||
处理完该关系后,系统会向PC端反馈消息,这个UUID对应的用户是A,然后网页便可请求加载A的微信信息和资料
|
||||
|
||||
*/
|
||||
|
||||
@GetMapping("/wxQrMapCode")
|
||||
@ApiOperation("获取微信公众号二维码")
|
||||
@ApiImplicitParams(value = {
|
||||
@ApiImplicitParam(name = "width",value = "图片宽度",dataType = "Integer"),
|
||||
@ApiImplicitParam(name = "height",value = "图片高度",dataType = "Integer")
|
||||
})
|
||||
public AjaxResult wxQrMapCode(@RequestParam(value = "width", required = false, defaultValue = "100") int width,
|
||||
@RequestParam(value = "height", required = false, defaultValue = "100") int height) {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
// 唯一标识
|
||||
String uuid = IdUtils.simpleUUID();
|
||||
// //将uuid带到回调地址上,判断当前用户是否使用了
|
||||
String authorizeUrl = WeiXinCommonUtil.getAuthorizeUrl(wxMapAppid, String.format(wxMapCallbackUrl,uuid), WxConsts.QrConnectScope.SNSAPI_LOGIN, null);
|
||||
String qrCodeBasePicture = QrCodeUtils.getQrCodeBasePicture(authorizeUrl, width, height, MimeTypeUtils.getExtension(MimeTypeUtils.IMAGE_PNG));
|
||||
ajax.put("img", qrCodeBasePicture);
|
||||
ajax.put("uuid",uuid);
|
||||
return ajax;
|
||||
}
|
||||
|
||||
@PostMapping("/user-info")
|
||||
@ApiOperation("通过authorizeCode获取微信用户信息,并进行判断,让前端根据返回的参数去判断")
|
||||
@ApiImplicitParam(name = "authorizeCode",value = "微信授权authorizeCode",dataType = "String")
|
||||
public AjaxResult getWeChatCode(@RequestParam("authorizeCode") String authorizeCode,
|
||||
@RequestParam("state") String state,
|
||||
@RequestParam("appId") String appId,
|
||||
@RequestParam("bizId") String bizId){
|
||||
if(StringUtils.isNotNull(authorizeCode)){
|
||||
WeiXinOauth2Token oauth2AccessToken = WeiXinCommonUtil.getOauth2AccessToken(authorizeCode, wxMapAppid, wxMapAppsecret);
|
||||
if(StringUtils.isNotNull(oauth2AccessToken)){
|
||||
if(oauth2AccessToken.getErrcode()==0){
|
||||
// String refreshToken = oauth2AccessToken.getRefreshToken();
|
||||
String accessToken = oauth2AccessToken.getAccessToken();
|
||||
String openId = oauth2AccessToken.getOpenId();
|
||||
// //校验授权token是否有效,false则取刷新token
|
||||
// boolean b = WeiXinCommonUtil.validateToken(refreshToken, wxMapAppid);
|
||||
// if(!b){
|
||||
// refreshToken = WeiXinCommonUtil.getRefreshToken(wxMapAppid, refreshToken);
|
||||
// }
|
||||
|
||||
WeiXinUserInfo userInfo = WeiXinCommonUtil.getUserInfo(accessToken, openId);
|
||||
boolean loginFlag = weChatService.login(userInfo, appId, bizId);
|
||||
if (loginFlag) {
|
||||
|
||||
return AjaxResult.success(userInfo);
|
||||
}
|
||||
|
||||
|
||||
//先拿openId去库里查找微信信息标
|
||||
// BWxOpenUser bWxOpenUser = ibWxOpenUserService.selectByOpenId(openId);
|
||||
// // 如果没有则获取微信用户信息,插入数据库
|
||||
// if(StringUtils.isNull(bWxOpenUser)){
|
||||
// //获取微信用户信息
|
||||
// WeiXinUserInfo userInfo = WeiXinCommonUtil.getUserInfo(refreshToken, openId);
|
||||
// if(StringUtils.isNotNull(userInfo) && userInfo.getErrcode()==0){
|
||||
// ibWxOpenUserService.saveWxOpenUser(userInfo);
|
||||
// }
|
||||
// }else {
|
||||
// return AjaxResult.success(openId);
|
||||
// }
|
||||
//如果有则判断userId有没有,如果userId为0或者null,则返回让用户绑定账号。如果有,则使用userId查询sys_user标,将user_name和password查找到,使用loginService登录判断
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return AjaxResult.error("登录异常,请重试");
|
||||
|
||||
}else {
|
||||
return AjaxResult.error("参数不合法,请传入授权码");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/pushToWeb/{uuid}")
|
||||
public AjaxResult pushToWeb(@PathVariable String uuid){
|
||||
//TODO 写逻辑
|
||||
return AjaxResult.success();
|
||||
}
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.muster.web.controller.muster;
|
||||
|
||||
|
||||
import com.muster.common.constant.Constants;
|
||||
import com.muster.common.constant.WxConsts;
|
||||
import com.muster.common.core.domain.AjaxResult;
|
||||
import com.muster.framework.web.service.SysLoginService;
|
||||
import com.muster.web.controller.muster.weixin.WeChatService;
|
||||
import com.muster.web.controller.muster.weixin.WeiXinUserInfo;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
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.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* @ClassName WeiXinController
|
||||
* @Description TOOD
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 14:29
|
||||
* @Version 1.0
|
||||
**/
|
||||
@Controller
|
||||
@Api(value = "微信相关操作管理", description = "微信相关操作管理", tags = {"微信相关操作管理"})
|
||||
@RequestMapping("/system/weixin")
|
||||
public class WeiXinController {
|
||||
|
||||
@Autowired
|
||||
private WeChatService weChatService;
|
||||
|
||||
@Autowired
|
||||
private SysLoginService loginService;
|
||||
|
||||
private String prefix = "weixin";
|
||||
|
||||
@GetMapping("/redirect")
|
||||
public String user()
|
||||
{
|
||||
return prefix + "/redirect";
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
@ResponseBody
|
||||
@ApiOperation("子系统通过微信登录")
|
||||
@ApiImplicitParam(name = "子系统通过微信登录",value = "子系统通过微信登录", dataTypeClass = WeiXinUserInfo.class)
|
||||
public AjaxResult login(@RequestBody WeiXinUserInfo weiXinUserInfo) {
|
||||
|
||||
boolean loginFlag = weChatService.login(weiXinUserInfo);
|
||||
|
||||
if (loginFlag) {
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
String token = loginService.login(WxConsts.Account.SHRIO_USERNAME, WxConsts.Account.SHRIO_PASSWORD);
|
||||
|
||||
ajax.put(Constants.TOKEN, token);
|
||||
return ajax;
|
||||
|
||||
}
|
||||
return AjaxResult.error("微信扫码登录失败,请重试");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName JsApiTicket
|
||||
* @Description TOOD 获取授权页ticket 获取的ticket和有效期
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 10:39
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
public class JsApiTicket {
|
||||
|
||||
// 接口访问凭证
|
||||
private String ticket;
|
||||
// 凭证有效期,单位:秒
|
||||
private int expiresIn;
|
||||
|
||||
public String getTicket() {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
public void setTicket(String ticket) {
|
||||
this.ticket = ticket;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public void setExpiresIn(int expiresIn) {
|
||||
this.expiresIn = expiresIn;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* @ClassName MyX509TrustManager
|
||||
* @Description TOOD
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 10:47
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
|
||||
public class MyX509TrustManager implements X509TrustManager {
|
||||
@Override
|
||||
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public X509Certificate[] getAcceptedIssuers() {
|
||||
return new X509Certificate[0];
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
|
||||
import cn.hutool.extra.qrcode.QrCodeUtil;
|
||||
import com.muster.common.utils.sign.Base64;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
/**
|
||||
* @ClassName QrCodeUtils
|
||||
* @Description TOOD 生成二维码图片
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 13:57
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
|
||||
public class QrCodeUtils {
|
||||
|
||||
/**
|
||||
* 生成二维码方法返回到流
|
||||
* @author guoconglin
|
||||
* @date 2020/4/10 13:44
|
||||
* @param: [url 访问链接, width 图片宽, height 图片高, mimeType 类型比图png\jpg, resp]
|
||||
* @return: void
|
||||
*/
|
||||
public static void getQrcode(String url,int width,int height,String mimeType, HttpServletResponse resp) throws Exception {
|
||||
QrCodeUtil.generate(url,width,height, mimeType,resp.getOutputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成base64图片
|
||||
* @author guoconglin
|
||||
* @date 2020/4/10 13:49
|
||||
* @param: [url 访问链接, width 图片宽, height 图片高, mimeType 类型比图png\jpg]
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
public static String getQrCodeBasePicture(String url,int width,int height,String mimeType){
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
QrCodeUtil.generate(url,width,height,mimeType,stream);
|
||||
String base64EnCode = Base64.encode(stream.toByteArray());
|
||||
return base64EnCode;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @ClassName SignUtil
|
||||
* @Description TOOD 微信签名
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 13:17
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
|
||||
public class SignUtil {
|
||||
|
||||
public static Map<String, String> sign(String jsapi_ticket, String url) {
|
||||
Map<String, String> ret = new HashMap<String, String>();
|
||||
String nonce_str = create_nonce_str();
|
||||
String timestamp = create_timestamp();
|
||||
String string1;
|
||||
String signature = "";
|
||||
|
||||
//注意这里参数名必须全部小写,且必须有序
|
||||
string1 = "jsapi_ticket=" + jsapi_ticket +
|
||||
"&noncestr=" + nonce_str +
|
||||
"×tamp=" + timestamp +
|
||||
"&url=" + url;
|
||||
System.out.println(string1);
|
||||
|
||||
try
|
||||
{
|
||||
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
|
||||
crypt.reset();
|
||||
crypt.update(string1.getBytes("UTF-8"));
|
||||
signature = byteToHex(crypt.digest());
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
ret.put("url", url);
|
||||
ret.put("jsapi_ticket", jsapi_ticket);
|
||||
ret.put("nonceStr", nonce_str);
|
||||
ret.put("timestamp", timestamp);
|
||||
ret.put("signature", signature);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static String byteToHex(final byte[] hash) {
|
||||
Formatter formatter = new Formatter();
|
||||
for (byte b : hash)
|
||||
{
|
||||
formatter.format("%02x", b);
|
||||
}
|
||||
String result = formatter.toString();
|
||||
formatter.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String create_nonce_str() {
|
||||
return UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
private static String create_timestamp() {
|
||||
return Long.toString(System.currentTimeMillis() / 1000);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName Token
|
||||
* @Description TOOD 获取的token 和有效时间
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 10:40
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
public class Token {
|
||||
|
||||
// 接口访问凭证
|
||||
private String accessToken;
|
||||
// 凭证有效期,单位:秒
|
||||
private int expiresIn;
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public void setExpiresIn(int expiresIn) {
|
||||
this.expiresIn = expiresIn;
|
||||
}
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
import com.muster.common.utils.StringUtils;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* @ClassName URIUtil
|
||||
* @Description TOOD 网站转码
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 12:50
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
|
||||
public class URIUtil {
|
||||
|
||||
private static final String ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()";
|
||||
|
||||
public static String encodeURIComponent(String input) {
|
||||
if (StringUtils.isEmpty(input)) {
|
||||
return input;
|
||||
}
|
||||
|
||||
int l = input.length();
|
||||
StringBuilder o = new StringBuilder(l * 3);
|
||||
try {
|
||||
for (int i = 0; i < l; i++) {
|
||||
String e = input.substring(i, i + 1);
|
||||
if (ALLOWED_CHARS.indexOf(e) == -1) {
|
||||
byte[] b = e.getBytes("utf-8");
|
||||
o.append(getHex(b));
|
||||
continue;
|
||||
}
|
||||
o.append(e);
|
||||
}
|
||||
return o.toString();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
private static String getHex(byte buf[]) {
|
||||
StringBuilder o = new StringBuilder(buf.length * 3);
|
||||
for (int i = 0; i < buf.length; i++) {
|
||||
int n = buf[i] & 0xff;
|
||||
o.append("%");
|
||||
if (n < 0x10) {
|
||||
o.append("0");
|
||||
}
|
||||
o.append(Long.toString(n, 16).toUpperCase());
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,19 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-08.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
public interface WeChatService {
|
||||
|
||||
int query(final String openId);
|
||||
|
||||
boolean login(final WeiXinUserInfo userInfo);
|
||||
|
||||
boolean login(final WeiXinUserInfo userInfo, String appId, String bizId);
|
||||
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.common.constant.WxConsts;
|
||||
import com.muster.logic.DbLogicService;
|
||||
import com.muster.logic.model.ProcedureResult;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-11.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
@Component
|
||||
public class WeChatServiceImpl implements WeChatService{
|
||||
|
||||
private DbLogicService storedProcedure;
|
||||
|
||||
/** 微信用户 */
|
||||
public final static String PROC_DU02A_USER_LOGIN = "proc_DU02A_user_login";
|
||||
public final static String PROC_DU02C_USER_CREATE = "proc_DU02C_user_create";
|
||||
@Autowired
|
||||
WeChatServiceImpl (DbLogicService storedProcedure) {
|
||||
this.storedProcedure = storedProcedure;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int query(final String openId) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean login(final WeiXinUserInfo userInfo) {
|
||||
return this.login(userInfo, MusterConfig.getAppId(), MusterConfig.getBizId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean login(final WeiXinUserInfo userInfo, String appId, String bizId) {
|
||||
// 创建账号
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("01_acc_type", WxConsts.Account.TYPE);
|
||||
params.put("02_username", userInfo.getWxOpenid());
|
||||
params.put("03_password", WxConsts.Account.PASSWORD);
|
||||
params.put("04_userip", "0.0.0.0");
|
||||
params.put("appId", appId);
|
||||
params.put("bizId", bizId);
|
||||
|
||||
int createRes = this.create(params);
|
||||
if (createRes > 0) {
|
||||
int loginRes = this.login(params);
|
||||
return loginRes > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int create( final Map<String, Object> params) {
|
||||
Map<String, Object> p = new HashMap<>(params);
|
||||
p.put("05_json", "{}");
|
||||
ProcedureResult createRes = storedProcedure.exec(PROC_DU02C_USER_CREATE, p);
|
||||
return createRes.getRes();
|
||||
}
|
||||
|
||||
private int login(final Map<String, Object> params) {
|
||||
ProcedureResult loginRes = storedProcedure.exec(PROC_DU02A_USER_LOGIN, params);
|
||||
return loginRes.getRes();
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName WechatQRCode
|
||||
* @Description TOOD 二维码参数
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 13:29
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
public class WechatQRCode {
|
||||
|
||||
// 获取的二维码
|
||||
private String ticket;
|
||||
// 二维码的有效时间,单位为秒,最大不超过2592000(即30天)
|
||||
private int expire_seconds;
|
||||
// 二维码图片解析后的地址
|
||||
private String url;
|
||||
|
||||
public String getTicket() {
|
||||
return ticket;
|
||||
}
|
||||
|
||||
public void setTicket(String ticket) {
|
||||
this.ticket = ticket;
|
||||
}
|
||||
|
||||
public int getExpire_seconds() {
|
||||
return expire_seconds;
|
||||
}
|
||||
|
||||
public void setExpire_seconds(int expire_seconds) {
|
||||
this.expire_seconds = expire_seconds;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
@ -0,0 +1,641 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
import com.alibaba.fastjson.JSONException;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.muster.common.utils.StringUtils;
|
||||
import com.muster.common.utils.http.HttpUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.URL;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName WeiXinCommonUtil
|
||||
* @Description TOOD 微信通用工具类
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 10:38
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
|
||||
public class WeiXinCommonUtil {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(WeiXinCommonUtil.class);
|
||||
|
||||
|
||||
private static Map<String, JsApiTicket> weixinCache = new HashMap<String, JsApiTicket>();
|
||||
|
||||
private static Map<String, Token> tokenCache = new HashMap<String, Token>();
|
||||
|
||||
// 临时二维码
|
||||
private static final String QR_SCENE = "QR_SCENE";
|
||||
// 永久二维码
|
||||
private static final String QR_LIMIT_SCENE = "QR_LIMIT_SCENE";
|
||||
// 永久二维码(字符串)
|
||||
private static final String QR_LIMIT_STR_SCENE = "QR_LIMIT_STR_SCENE";
|
||||
// 创建二维码
|
||||
private static final String create_ticket_path = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=%s";
|
||||
// 通过ticket换取二维码
|
||||
private static final String showqrcode_path = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=%s";
|
||||
|
||||
// 凭证获取(GET)
|
||||
public static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||
/**
|
||||
* 长链接转短链接接口
|
||||
*/
|
||||
public static final String SHORTURL_API_URL = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=%s";
|
||||
/**
|
||||
* 获取access_token
|
||||
*/
|
||||
public static final String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
|
||||
|
||||
/**
|
||||
* 获得jsapi_ticket
|
||||
*/
|
||||
public static final String GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
|
||||
|
||||
/**
|
||||
* 通过access token获得jsapi_ticket
|
||||
*/
|
||||
public static final String TOKEN_GET_JSAPI_TICKET_URL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
|
||||
|
||||
/**
|
||||
* 用code换取oauth2的access token
|
||||
*/
|
||||
public static final String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code";
|
||||
/**
|
||||
* 刷新oauth2的access token
|
||||
*/
|
||||
public static final String OAUTH2_REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%s&grant_type=refresh_token&refresh_token=%s";
|
||||
/**
|
||||
* 用oauth2获取用户信息
|
||||
*/
|
||||
public static final String OAUTH2_USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=%s";
|
||||
/**
|
||||
* 验证oauth2的access token是否有效
|
||||
*/
|
||||
public static final String OAUTH2_VALIDATE_TOKEN_URL = "https://api.weixin.qq.com/sns/auth?access_token=%s&openid=%s";
|
||||
/**
|
||||
* 获取微信服务器IP地址
|
||||
*/
|
||||
public static final String GET_CALLBACK_IP_URL = "https://api.weixin.qq.com/cgi-bin/getcallbackip";
|
||||
/**
|
||||
* 第三方使用网站应用授权登录的url
|
||||
*/
|
||||
public static final String QRCONNECT_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
|
||||
/**
|
||||
* oauth2授权的url连接
|
||||
*/
|
||||
public static final String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
|
||||
|
||||
/**
|
||||
* 获取公众号的自动回复规则
|
||||
*/
|
||||
public static final String GET_CURRENT_AUTOREPLY_INFO_URL = "https://api.weixin.qq.com/cgi-bin/get_current_autoreply_info";
|
||||
|
||||
/**
|
||||
* 公众号调用或第三方平台帮公众号调用对公众号的所有api调用(包括第三方帮其调用)次数进行清零
|
||||
*/
|
||||
public static final String CLEAR_QUOTA_URL = "https://api.weixin.qq.com/cgi-bin/clear_quota";
|
||||
|
||||
/**
|
||||
* 通过openId 获取公众号用户详细信息
|
||||
*/
|
||||
public static final String OAUTH2_USERINFO_URLS = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=%s";
|
||||
|
||||
/**
|
||||
* 公众号发送模板消息链接
|
||||
*/
|
||||
public static final String SEND_MP_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取接口访问凭证
|
||||
* @author guoconglin
|
||||
* @date 2020/4/10 10:44
|
||||
* @param: [appId 微信平台开账号的appId, appSecret 微信开放平台开账号后的appSecret]
|
||||
* @return: com.sanqi.common.utils.weixin.Token
|
||||
*/
|
||||
public static Token getToken(String appId,String appSecret) {
|
||||
Token token = null;
|
||||
String requestUrl = String.format(TOKEN_URL,appId,appSecret);
|
||||
// 发起GET请求获取凭证
|
||||
JSONObject jsonObject = httpsRequest(requestUrl, "GET", null);
|
||||
LOG.info("获取token jsonObject jsonObject:{}", jsonObject);
|
||||
if (null != jsonObject) {
|
||||
try {
|
||||
token = new Token();
|
||||
token.setAccessToken(jsonObject.getString("access_token"));
|
||||
token.setExpiresIn(jsonObject.getIntValue("expires_in"));
|
||||
} catch (JSONException e) {
|
||||
token = null;
|
||||
// 获取token失败
|
||||
LOG.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getIntValue("errcode"), jsonObject.getString("errmsg"));
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新token
|
||||
* @param appId 微信平台开的唯一标识
|
||||
* @param accessToken token
|
||||
* @return
|
||||
*/
|
||||
public static String getRefreshToken(String appId,String accessToken){
|
||||
String refreshToken = String.format(OAUTH2_REFRESH_TOKEN_URL,appId,accessToken);
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证token是否有效
|
||||
* @param refreshToken 刷新获取到的新token
|
||||
* @param appId 微信平台开的唯一标识
|
||||
* @return
|
||||
*/
|
||||
public static boolean validateToken(String refreshToken,String appId){
|
||||
String refreshTokenUrl = String.format(OAUTH2_VALIDATE_TOKEN_URL,refreshToken,appId);
|
||||
JSONObject jsonObject = httpsRequest(refreshTokenUrl, "GET", null);
|
||||
if(jsonObject != null){
|
||||
//TODO需要判断
|
||||
int errcode = jsonObject.getIntValue("errcode");
|
||||
if(errcode == 0){ //则证明有效
|
||||
return true;
|
||||
}else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取微信授权页面链接
|
||||
* @param appId 微信平台开的唯一标识
|
||||
* @param redirectURI 回调地址
|
||||
* @param scope
|
||||
* @param state
|
||||
* @return
|
||||
*/
|
||||
public static String getAuthorizeUrl(String appId,String redirectURI, String scope, String state){
|
||||
String authorizeUrl = String.format(QRCONNECT_URL,appId,URIUtil.encodeURIComponent(redirectURI),scope, StringUtils.trimToEmpty(state));
|
||||
return authorizeUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用code换取oauth2的access token
|
||||
* @author guoconglin
|
||||
* @date 2020/4/10 12:55
|
||||
* @param: [code, appId 微信平台唯一识别appId, appSecret 微信平台唯一识别appSecret]
|
||||
* @return: com.sanqi.common.utils.weixin.WeiXinOauth2Token
|
||||
*/
|
||||
public static WeiXinOauth2Token getOauth2AccessToken(String code,String appId,String appSecret){
|
||||
WeiXinOauth2Token weixinOauth2Token = new WeiXinOauth2Token();
|
||||
String getTokenUrl = String.format(OAUTH2_ACCESS_TOKEN_URL, appId, appSecret, code);
|
||||
JSONObject jsonObject = httpsRequest(getTokenUrl, "GET", null);
|
||||
LOG.info("获取网页授权凭证 jsonObject:{}",jsonObject);
|
||||
if (null != jsonObject) {
|
||||
if(jsonObject.getIntValue("errcode") == 0){
|
||||
weixinOauth2Token.setAccessToken(jsonObject.getString("access_token"));
|
||||
weixinOauth2Token.setExpiresIn(jsonObject.getIntValue("expires_in"));
|
||||
weixinOauth2Token.setRefreshToken(jsonObject.getString("refresh_token"));
|
||||
weixinOauth2Token.setOpenId(jsonObject.getString("openid"));
|
||||
weixinOauth2Token.setScope(jsonObject.getString("scope"));
|
||||
weixinOauth2Token.setErrcode(jsonObject.getIntValue("errcode"));
|
||||
weixinOauth2Token.setErrmsg(jsonObject.getString("errmsg"));
|
||||
weixinOauth2Token.setUnionId(jsonObject.containsKey("unionid")?jsonObject.getString("unionid"):null);
|
||||
LOG.info("获取网页授权凭证成功 weixinOauth2Token:{}",weixinOauth2Token);
|
||||
}else {
|
||||
int errorCode = jsonObject.getIntValue("errcode");
|
||||
String errorMsg = jsonObject.getString("errmsg");
|
||||
weixinOauth2Token.setErrcode(errorCode);
|
||||
weixinOauth2Token.setErrmsg(errorMsg);
|
||||
LOG.error("获取网页授权凭证失败 errcode:{} errmsg:{}", errorCode, errorMsg);
|
||||
}
|
||||
}
|
||||
return weixinOauth2Token;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 通过网页授权获取用户信息
|
||||
* @author guoconglin
|
||||
* @date 2020/4/10 13:00
|
||||
* @param: [accessToken 获取的token, openId 用户的openId]
|
||||
* @return: com.sanqi.common.utils.weixin.WeiXinUserInfo
|
||||
*/
|
||||
public static WeiXinUserInfo getUserInfo(String accessToken, String openId){
|
||||
WeiXinUserInfo weixinUserInfo = new WeiXinUserInfo();
|
||||
String userInfoUrl = String.format(OAUTH2_USERINFO_URL, accessToken, openId, "zh_CN");
|
||||
JSONObject jsonObject = httpsRequest(userInfoUrl, "GET", null);
|
||||
LOG.info("jsonObject:{}",jsonObject);
|
||||
LOG.info("jsonObject:{}",jsonObject.getIntValue("subscribe"));
|
||||
if (null != jsonObject) {
|
||||
try {
|
||||
if(jsonObject.getIntValue("errcode") == 0){
|
||||
// 用户的标识
|
||||
if(jsonObject.containsKey("openid")){
|
||||
weixinUserInfo.setWxOpenid(jsonObject.getString("openid"));
|
||||
}
|
||||
if(jsonObject.containsKey("subscribe")){
|
||||
// 关注状态(1是关注,0是未关注),未关注时获取不到其余信息
|
||||
int subscribe = jsonObject.getIntValue("subscribe");
|
||||
weixinUserInfo.setSubscribe(subscribe);
|
||||
}
|
||||
// 用户关注时间
|
||||
if(jsonObject.containsKey("subscribe_time")){
|
||||
weixinUserInfo.setSubscribeTime(jsonObject.getString("subscribe_time"));
|
||||
}
|
||||
// 昵称
|
||||
if(jsonObject.containsKey("nickname")){
|
||||
weixinUserInfo.setNickName(jsonObject.getString("nickname"));
|
||||
}
|
||||
// 用户的性别(1是男性,2是女性,0是未知)
|
||||
if(jsonObject.containsKey("sex")){
|
||||
weixinUserInfo.setSex(jsonObject.getIntValue("sex"));
|
||||
}
|
||||
// 用户所在国家
|
||||
if(jsonObject.containsKey("country")){
|
||||
weixinUserInfo.setCountry(jsonObject.getString("country"));
|
||||
}
|
||||
// 用户所在省份
|
||||
if(jsonObject.containsKey("province")){
|
||||
weixinUserInfo.setProvince(jsonObject.getString("province"));
|
||||
}
|
||||
// 用户所在城市
|
||||
if(jsonObject.containsKey("city")){
|
||||
weixinUserInfo.setCity(jsonObject.getString("city"));
|
||||
}
|
||||
// 用户的语言,简体中文为zh_CN
|
||||
if(jsonObject.containsKey("language")){
|
||||
weixinUserInfo.setLanguage(jsonObject.getString("language"));
|
||||
}
|
||||
// 用户头像
|
||||
if(jsonObject.containsKey("headimgurl")){
|
||||
weixinUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
|
||||
}
|
||||
//unionid
|
||||
if(jsonObject.containsKey("unionid")){
|
||||
weixinUserInfo.setUnionId(jsonObject.getString("unionid"));
|
||||
}
|
||||
int errorCode = jsonObject.getIntValue("errcode");
|
||||
String errorMsg = jsonObject.getString("errmsg");
|
||||
weixinUserInfo.setErrcode(errorCode);
|
||||
weixinUserInfo.setErrmsg(errorMsg);
|
||||
LOG.info("获取用户信息成功 weixinUserInfo:{}", weixinUserInfo);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
int errorCode = jsonObject.getIntValue("errcode");
|
||||
String errorMsg = jsonObject.getString("errmsg");
|
||||
weixinUserInfo.setErrcode(errorCode);
|
||||
weixinUserInfo.setErrmsg(errorMsg);
|
||||
LOG.error("获取用户信息失败 errcode:{} errmsg:{}", errorCode, errorMsg);
|
||||
}
|
||||
}
|
||||
return weixinUserInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建调用jsapi时所需要的签名
|
||||
* @author guoconglin
|
||||
* @date 2020/4/10 13:19
|
||||
* @param: [url, mpAppId, mpSecret]
|
||||
* @return: com.sanqi.common.utils.weixin.WxJsapiSignature
|
||||
*/
|
||||
public static WxJsapiSignature createJsapiSignature(String url,String mpAppId,String mpSecret) throws ParseException {
|
||||
LOG.info("创建调用jsapi时所需要的签名 url:{} ",url);
|
||||
String token_str = null;
|
||||
Token token = tokenCache.get("accessToken");
|
||||
if(StringUtils.isNotNull(token)){
|
||||
int expiresIn = token.getExpiresIn();
|
||||
Calendar ever = Calendar.getInstance();
|
||||
Date date = new Date(expiresIn*1000L);
|
||||
ever.setTime(date);
|
||||
Calendar current = Calendar.getInstance();
|
||||
if(ever.after(current)){
|
||||
token_str = token.getAccessToken();
|
||||
LOG.info("获取的accessToken:{}",token_str);
|
||||
}else {
|
||||
token_str = getWxJsapiTokenStr(mpAppId, mpSecret);
|
||||
}
|
||||
}else{
|
||||
token_str = getWxJsapiTokenStr(mpAppId, mpSecret);
|
||||
}
|
||||
WxJsapiSignature wxJsapiSignature = null;
|
||||
String ticket_str = null;
|
||||
LOG.info("weixinCache:{}",weixinCache);
|
||||
JsApiTicket jsApiTicket = weixinCache.get("ticket");
|
||||
LOG.info("获取jsApiTicket成功 jsApiTicket:{}", jsApiTicket);
|
||||
if(jsApiTicket != null){
|
||||
int expiresIn = jsApiTicket.getExpiresIn();
|
||||
Calendar ever = Calendar.getInstance();
|
||||
Date date = new Date(expiresIn*1000L);
|
||||
ever.setTime(date);
|
||||
Calendar current = Calendar.getInstance();
|
||||
if(ever.after(current)) {
|
||||
ticket_str = jsApiTicket.getTicket();
|
||||
LOG.info("获取jsApiTicket成功 ticket_str:{}", ticket_str);
|
||||
}else{
|
||||
String ticketUrl = String.format(TOKEN_GET_JSAPI_TICKET_URL,token_str);
|
||||
JSONObject jsonObject = httpsRequest(ticketUrl, "GET", null);
|
||||
if(jsonObject != null){
|
||||
try {
|
||||
ticket_str = jsonObject.getString("ticket");
|
||||
JsApiTicket jsApiTicket1 = new JsApiTicket();
|
||||
weixinCache.remove("ticket");
|
||||
jsApiTicket1.setTicket(jsonObject.getString("ticket"));
|
||||
LOG.info("获取jticket的值为: ticket:{}",jsonObject.getString("ticket"));
|
||||
jsApiTicket1.setExpiresIn(jsonObject.getIntValue("expires_in"));
|
||||
weixinCache.put("ticket", jsApiTicket1);
|
||||
} catch (JSONException e) {
|
||||
token = null;
|
||||
// 获取jsApiTicket失败
|
||||
LOG.error("获取jsApiTicket失败 errcode:{} errmsg:{}", jsonObject.getIntValue("errcode"), jsonObject.getString("errmsg"));
|
||||
}
|
||||
}
|
||||
}
|
||||
Map<String, String> sign = SignUtil.sign(ticket_str, url);
|
||||
wxJsapiSignature = new WxJsapiSignature();
|
||||
wxJsapiSignature.setAppId(mpAppId);
|
||||
wxJsapiSignature.setNonceStr(sign.get("nonceStr"));
|
||||
wxJsapiSignature.setTimestamp(Long.parseLong(sign.get("timestamp")));
|
||||
wxJsapiSignature.setSignature(sign.get("signature"));
|
||||
LOG.info("获取jsApiTicket成功 wxJsapiSignature:{}", wxJsapiSignature);
|
||||
}else{
|
||||
String ticketUrl = String.format(TOKEN_GET_JSAPI_TICKET_URL,token_str);
|
||||
JSONObject jsonObject = httpsRequest(ticketUrl, "GET", null);
|
||||
LOG.info("jsonObject 请求jsonObject:{}",jsonObject);
|
||||
if(jsonObject != null){
|
||||
try {
|
||||
JsApiTicket jsApiTicket1 = new JsApiTicket();
|
||||
weixinCache.remove("ticket");
|
||||
jsApiTicket1.setTicket(jsonObject.getString("ticket"));
|
||||
jsApiTicket1.setExpiresIn(jsonObject.getIntValue("expires_in"));
|
||||
weixinCache.put("ticket", jsApiTicket1);
|
||||
LOG.info("获取ticket成功 ========= ticket:{}", jsApiTicket1);
|
||||
Map<String, String> sign = SignUtil.sign(jsApiTicket1.getTicket(), url);
|
||||
wxJsapiSignature = new WxJsapiSignature();
|
||||
wxJsapiSignature.setAppId(mpAppId);
|
||||
wxJsapiSignature.setNonceStr(sign.get("nonceStr"));
|
||||
wxJsapiSignature.setTimestamp(Long.parseLong(sign.get("timestamp")));
|
||||
wxJsapiSignature.setSignature(sign.get("signature"));
|
||||
LOG.info("获取jsApiTicket成功 ========= wxJsapiSignature:{}", wxJsapiSignature);
|
||||
} catch (JSONException e) {
|
||||
token = null;
|
||||
// 获取jsApiTicket失败
|
||||
LOG.error("获取jsApiTicket失败 errcode:{} errmsg:{}", jsonObject.getIntValue("errcode"), jsonObject.getString("errmsg"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return wxJsapiSignature;
|
||||
}
|
||||
|
||||
private static String getWxJsapiTokenStr(String mpAppId,String mpSecret){
|
||||
String token_str = null;
|
||||
Token token = getToken(mpAppId, mpSecret);
|
||||
LOG.info("获取的token1:{}",token);
|
||||
if(StringUtils.isNotNull(token)){
|
||||
token_str = token.getAccessToken();
|
||||
tokenCache.remove("accessToken");
|
||||
tokenCache.put("accessToken",token);
|
||||
}else{
|
||||
LOG.info("失败{} {}");
|
||||
}
|
||||
LOG.info("获取的第二次accessToken:{}",token_str);
|
||||
return token_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建临时带参数二维码
|
||||
* @param accessToken
|
||||
* @expireSeconds 该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。
|
||||
* @param sceneId 场景Id
|
||||
* @return
|
||||
*/
|
||||
public static String createTempTicket(String accessToken, String expireSeconds, int sceneId) {
|
||||
WechatQRCode wxQRCode = null;
|
||||
Map<String,Integer> intMap = new HashMap<String,Integer>();
|
||||
intMap.put("scene_id",sceneId);
|
||||
Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
|
||||
mapMap.put("scene", intMap);
|
||||
//
|
||||
Map<String,Object> paramsMap = new HashMap<String,Object>();
|
||||
paramsMap.put("expire_seconds", expireSeconds);
|
||||
paramsMap.put("action_name", QR_SCENE);
|
||||
paramsMap.put("action_info", mapMap);
|
||||
String data = new Gson().toJson(paramsMap);
|
||||
System.out.println("创建临时带参数二维码参数"+data);
|
||||
String requestUrl = String.format(create_ticket_path,accessToken);
|
||||
data = HttpUtils.sendPost( requestUrl, data);
|
||||
System.out.println("创建临时带参数二维码返回结果"+data);
|
||||
try {
|
||||
wxQRCode = new Gson().fromJson(data, WechatQRCode.class);
|
||||
} catch (JsonSyntaxException e) {
|
||||
wxQRCode = null;
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.out.println("创建临时带参数二维码返回转换对象"+wxQRCode);
|
||||
return wxQRCode==null?null:wxQRCode.getUrl();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建永久二维码(数字)
|
||||
* @param accessToken
|
||||
* @param sceneId 场景Id
|
||||
* @return
|
||||
*/
|
||||
public static String createForeverTicket(String accessToken, int sceneId) {
|
||||
|
||||
//output data
|
||||
Map<String,Integer> intMap = new HashMap<String,Integer>();
|
||||
intMap.put("scene_id",sceneId);
|
||||
Map<String,Map<String,Integer>> mapMap = new HashMap<String,Map<String,Integer>>();
|
||||
mapMap.put("scene", intMap);
|
||||
//
|
||||
Map<String,Object> paramsMap = new HashMap<String,Object>();
|
||||
paramsMap.put("action_name", QR_LIMIT_SCENE);
|
||||
paramsMap.put("action_info", mapMap);
|
||||
String data = new Gson().toJson(paramsMap);
|
||||
System.out.println("创建临时带参数二维码参数"+data);
|
||||
String requestUrl = String.format(create_ticket_path,accessToken);
|
||||
data = HttpUtils.sendPost( requestUrl, data);
|
||||
System.out.println("创建临时带参数二维码返回结果"+data);
|
||||
WechatQRCode wxQRCode = null;
|
||||
try {
|
||||
wxQRCode = new Gson().fromJson(data, WechatQRCode.class);
|
||||
} catch (JsonSyntaxException e) {
|
||||
wxQRCode = null;
|
||||
e.printStackTrace();
|
||||
}
|
||||
return wxQRCode==null?null:wxQRCode.getTicket();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建永久二维码(字符串)
|
||||
*
|
||||
* @param accessToken
|
||||
* @param sceneStr 场景str
|
||||
* @return
|
||||
*/
|
||||
public static String createForeverStrTicket(String accessToken, String sceneStr){
|
||||
//output data
|
||||
Map<String,String> intMap = new HashMap<String,String>();
|
||||
intMap.put("scene_str",sceneStr);
|
||||
Map<String,Map<String,String>> mapMap = new HashMap<String,Map<String,String>>();
|
||||
mapMap.put("scene", intMap);
|
||||
|
||||
Map<String,Object> paramsMap = new HashMap<String,Object>();
|
||||
paramsMap.put("action_name", QR_LIMIT_STR_SCENE);
|
||||
paramsMap.put("action_info", mapMap);
|
||||
String data = new Gson().toJson(paramsMap);
|
||||
System.out.println("创建临时带参数二维码参数"+data);
|
||||
String requestUrl = String.format(create_ticket_path,accessToken);
|
||||
data = HttpUtils.sendPost( requestUrl, data);
|
||||
System.out.println("创建临时带参数二维码返回结果"+data);
|
||||
WechatQRCode wxQRCode = null;
|
||||
try {
|
||||
wxQRCode = new Gson().fromJson(data, WechatQRCode.class);
|
||||
} catch (JsonSyntaxException e) {
|
||||
wxQRCode = null;
|
||||
}
|
||||
return wxQRCode==null?null:wxQRCode.getTicket();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取二维码ticket后,通过ticket换取二维码图片展示
|
||||
* @param ticket
|
||||
* @return
|
||||
*/
|
||||
public static String showQrcode(String ticket){
|
||||
System.out.println("通过ticket换取二维码图片展示参数==="+ticket);
|
||||
String s = null;
|
||||
try {
|
||||
s = HttpUtils.sendGet(String.format(showqrcode_path,urlEncodeUTF8(ticket)),"");
|
||||
System.out.println("通过ticket换取二维码图片展示参数==="+s);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* URL编码(utf-8)
|
||||
*
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static String urlEncodeUTF8(String source) {
|
||||
String result = source;
|
||||
try {
|
||||
result = java.net.URLEncoder.encode(source, "utf-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 长链接生成短链接
|
||||
* @param longUrl 长链接地址
|
||||
* @param accessToken token令牌
|
||||
* @return
|
||||
*/
|
||||
public static String Long2Short(String longUrl,String accessToken){
|
||||
Map<String,Object> paramsMap = new HashMap<String,Object>();
|
||||
paramsMap.put("action", "long2short");
|
||||
paramsMap.put("long_url", longUrl);
|
||||
String data = new Gson().toJson(paramsMap);
|
||||
String requestUrl = String.format(SHORTURL_API_URL,accessToken);
|
||||
data = HttpUtils.sendPost(requestUrl,data);
|
||||
JSONObject jsonObject = JSONObject.parseObject(data);
|
||||
return jsonObject.getString("short_url");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 发送https请求
|
||||
*
|
||||
* @param requestUrl 请求地址
|
||||
* @param requestMethod 请求方式(GET、POST)
|
||||
* @param outputStr 提交的数据
|
||||
* @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)
|
||||
*/
|
||||
public static JSONObject httpsRequest(String requestUrl, String requestMethod, String outputStr) {
|
||||
JSONObject jsonObject = null;
|
||||
try {
|
||||
// 创建SSLContext对象,并使用我们指定的信任管理器初始化
|
||||
TrustManager[] tm = { new MyX509TrustManager() };
|
||||
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
|
||||
sslContext.init(null, tm, new java.security.SecureRandom());
|
||||
// 从上述SSLContext对象中得到SSLSocketFactory对象
|
||||
SSLSocketFactory ssf = sslContext.getSocketFactory();
|
||||
|
||||
URL url = new URL(requestUrl);
|
||||
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
|
||||
conn.setSSLSocketFactory(ssf);
|
||||
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setUseCaches(false);
|
||||
// 设置请求方式(GET/POST)
|
||||
conn.setRequestMethod(requestMethod);
|
||||
|
||||
// 当outputStr不为null时向输出流写数据
|
||||
if (null != outputStr) {
|
||||
OutputStream outputStream = conn.getOutputStream();
|
||||
// 注意编码格式
|
||||
outputStream.write(outputStr.getBytes("UTF-8"));
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
// 从输入流读取返回内容
|
||||
InputStream inputStream = conn.getInputStream();
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
|
||||
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
|
||||
String str = null;
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
while ((str = bufferedReader.readLine()) != null) {
|
||||
buffer.append(str);
|
||||
}
|
||||
|
||||
// 释放资源
|
||||
bufferedReader.close();
|
||||
inputStreamReader.close();
|
||||
inputStream.close();
|
||||
conn.disconnect();
|
||||
jsonObject = JSONObject.parseObject(buffer.toString());
|
||||
} catch (ConnectException ce) {
|
||||
LOG.error("连接超时:{}", ce);
|
||||
} catch (Exception e) {
|
||||
LOG.error("https请求异常:{}", e);
|
||||
}
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,96 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName WeiXinOauth2Token
|
||||
* @Description TOOD 微信授权
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 10:13
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
public class WeiXinOauth2Token {
|
||||
|
||||
// 网页授权接口调用凭证
|
||||
private String accessToken;
|
||||
// 凭证有效时长
|
||||
private int expiresIn;
|
||||
// 用于刷新凭证
|
||||
private String refreshToken;
|
||||
// 用户标识
|
||||
private String openId;
|
||||
// 用户授权作用域
|
||||
private String scope;
|
||||
|
||||
//unionId
|
||||
private String unionId;
|
||||
|
||||
//错误码
|
||||
private int errcode;
|
||||
//错误信息
|
||||
private String errmsg;
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public int getExpiresIn() {
|
||||
return expiresIn;
|
||||
}
|
||||
|
||||
public void setExpiresIn(int expiresIn) {
|
||||
this.expiresIn = expiresIn;
|
||||
}
|
||||
|
||||
public String getRefreshToken() {
|
||||
return refreshToken;
|
||||
}
|
||||
|
||||
public void setRefreshToken(String refreshToken) {
|
||||
this.refreshToken = refreshToken;
|
||||
}
|
||||
|
||||
public String getOpenId() {
|
||||
return openId;
|
||||
}
|
||||
|
||||
public void setOpenId(String openId) {
|
||||
this.openId = openId;
|
||||
}
|
||||
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public String getUnionId() {
|
||||
return unionId;
|
||||
}
|
||||
|
||||
public void setUnionId(String unionId) {
|
||||
this.unionId = unionId;
|
||||
}
|
||||
|
||||
public int getErrcode() {
|
||||
return errcode;
|
||||
}
|
||||
|
||||
public void setErrcode(int errcode) {
|
||||
this.errcode = errcode;
|
||||
}
|
||||
|
||||
public String getErrmsg() {
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
public void setErrmsg(String errmsg) {
|
||||
this.errmsg = errmsg;
|
||||
}
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
|
||||
/**
|
||||
* @ClassName WeiXinUserInfo
|
||||
* @Description TOOD
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 12:59
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
public class WeiXinUserInfo {
|
||||
|
||||
// 用户的标识
|
||||
private String wxOpenid;
|
||||
// 关注状态(1是关注,0是未关注),未关注时获取不到其余信息
|
||||
private int subscribe;
|
||||
// 用户关注时间,为时间戳。如果用户曾多次关注,则取最后关注时间
|
||||
private String subscribeTime;
|
||||
// 昵称
|
||||
private String nickName;
|
||||
// 用户的性别(1是男性,2是女性,0是未知)
|
||||
private int sex;
|
||||
// 用户所在国家
|
||||
private String country;
|
||||
// 用户所在省份
|
||||
private String province;
|
||||
// 用户所在城市
|
||||
private String city;
|
||||
// 用户的语言,简体中文为zh_CN
|
||||
private String language;
|
||||
// 用户头像
|
||||
private String headImgUrl;
|
||||
|
||||
//用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的
|
||||
private String unionId;
|
||||
|
||||
//错误码
|
||||
private int errcode;
|
||||
//错误信息
|
||||
private String errmsg;
|
||||
|
||||
public String getWxOpenid() {
|
||||
return wxOpenid;
|
||||
}
|
||||
|
||||
public void setWxOpenid(String wxOpenid) {
|
||||
this.wxOpenid = wxOpenid;
|
||||
}
|
||||
|
||||
public int getSubscribe() {
|
||||
return subscribe;
|
||||
}
|
||||
|
||||
public void setSubscribe(int subscribe) {
|
||||
this.subscribe = subscribe;
|
||||
}
|
||||
|
||||
public String getSubscribeTime() {
|
||||
return subscribeTime;
|
||||
}
|
||||
|
||||
public void setSubscribeTime(String subscribeTime) {
|
||||
this.subscribeTime = subscribeTime;
|
||||
}
|
||||
|
||||
public String getNickName() {
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName) {
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public int getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public void setSex(int sex) {
|
||||
this.sex = sex;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public void setProvince(String province) {
|
||||
this.province = province;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
public String getHeadImgUrl() {
|
||||
return headImgUrl;
|
||||
}
|
||||
|
||||
public void setHeadImgUrl(String headImgUrl) {
|
||||
this.headImgUrl = headImgUrl;
|
||||
}
|
||||
|
||||
public String getUnionId() {
|
||||
return unionId;
|
||||
}
|
||||
|
||||
public void setUnionId(String unionId) {
|
||||
this.unionId = unionId;
|
||||
}
|
||||
|
||||
public int getErrcode() {
|
||||
return errcode;
|
||||
}
|
||||
|
||||
public void setErrcode(int errcode) {
|
||||
this.errcode = errcode;
|
||||
}
|
||||
|
||||
public String getErrmsg() {
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
public void setErrmsg(String errmsg) {
|
||||
this.errmsg = errmsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("WeiXinUserInfo{");
|
||||
sb.append("wxOpenid='").append(wxOpenid).append('\'');
|
||||
sb.append(", subscribe=").append(subscribe);
|
||||
sb.append(", subscribeTime='").append(subscribeTime).append('\'');
|
||||
sb.append(", nickName='").append(nickName).append('\'');
|
||||
sb.append(", sex=").append(sex);
|
||||
sb.append(", country='").append(country).append('\'');
|
||||
sb.append(", province='").append(province).append('\'');
|
||||
sb.append(", city='").append(city).append('\'');
|
||||
sb.append(", language='").append(language).append('\'');
|
||||
sb.append(", headImgUrl='").append(headImgUrl).append('\'');
|
||||
sb.append(", unionId='").append(unionId).append('\'');
|
||||
sb.append(", errcode=").append(errcode);
|
||||
sb.append(", errmsg='").append(errmsg).append('\'');
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
package com.muster.web.controller.muster.weixin;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @ClassName WxJsapiSignature
|
||||
* @Description TOOD
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 13:14
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
public class WxJsapiSignature implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -1116808193154384804L;
|
||||
|
||||
/**
|
||||
* 公众号的唯一标识
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 生成签名的随机串
|
||||
*/
|
||||
private String nonceStr;
|
||||
|
||||
/**
|
||||
* 生成签名的时间戳
|
||||
*/
|
||||
private long timestamp;
|
||||
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
private String url;
|
||||
|
||||
/**
|
||||
* 签名
|
||||
*/
|
||||
private String signature;
|
||||
|
||||
public static long getSerialVersionUID() {
|
||||
return serialVersionUID;
|
||||
}
|
||||
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
public void setAppId(String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
public String getNonceStr() {
|
||||
return nonceStr;
|
||||
}
|
||||
|
||||
public void setNonceStr(String nonceStr) {
|
||||
this.nonceStr = nonceStr;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(long timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public void setSignature(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.muster.common.annotation.Log;
|
||||
import com.muster.common.config.RuoYiConfig;
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.common.core.controller.BaseController;
|
||||
import com.muster.common.core.domain.AjaxResult;
|
||||
import com.muster.common.core.domain.entity.SysUser;
|
||||
@ -111,7 +111,7 @@ public class SysProfileController extends BaseController
|
||||
if (!file.isEmpty())
|
||||
{
|
||||
LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
|
||||
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
|
||||
String avatar = FileUploadUtils.upload(MusterConfig.getAvatarPath(), file);
|
||||
if (userService.updateUserAvatar(loginUser.getUsername(), avatar))
|
||||
{
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
|
@ -6,7 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import com.muster.common.config.RuoYiConfig;
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
@ -32,7 +32,7 @@ public class SwaggerConfig
|
||||
{
|
||||
/** 系统基础配置 */
|
||||
@Autowired
|
||||
private RuoYiConfig ruoyiConfig;
|
||||
private MusterConfig ruoyiConfig;
|
||||
|
||||
/** 是否开启swagger */
|
||||
@Value("${swagger.enabled}")
|
||||
|
11
muster-admin/src/main/resources/application-dev.yml
Normal file
11
muster-admin/src/main/resources/application-dev.yml
Normal file
@ -0,0 +1,11 @@
|
||||
muster:
|
||||
# 文件路径 示例( Windows配置D:/muster/uploadPath,Linux配置 /home/muster/uploadPath)
|
||||
profile: /Users/liujiangtao/project/mishang/muster-vue
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8080
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
12
muster-admin/src/main/resources/application-prod.yml
Normal file
12
muster-admin/src/main/resources/application-prod.yml
Normal file
@ -0,0 +1,12 @@
|
||||
muster:
|
||||
# 文件路径 示例( Windows配置D:/muster/uploadPath,Linux配置 /home/muster/uploadPath)
|
||||
profile: /www/muster/upload
|
||||
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8081
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /prod-api
|
@ -5,11 +5,9 @@ muster:
|
||||
# 版本
|
||||
version: 3.0.0
|
||||
# 版权年份
|
||||
copyrightYear: 2019
|
||||
copyrightYear: 2020
|
||||
# 实例演示开关
|
||||
demoEnabled: true
|
||||
# 文件路径 示例( Windows配置D:/muster/uploadPath,Linux配置 /home/muster/uploadPath)
|
||||
profile: /Users/liujiangtao/project/mishang/muster-vue
|
||||
# 获取ip地址开关
|
||||
addressEnabled: false
|
||||
# 验证码类型 math 数组计算 char 字符验证
|
||||
@ -17,11 +15,6 @@ muster:
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 8080
|
||||
servlet:
|
||||
# 应用的访问路径
|
||||
context-path: /
|
||||
tomcat:
|
||||
# tomcat的URI编码
|
||||
uri-encoding: UTF-8
|
||||
@ -107,7 +100,7 @@ swagger:
|
||||
# 是否开启swagger
|
||||
enabled: true
|
||||
# 请求前缀
|
||||
pathMapping: /dev-api
|
||||
pathMapping: /prod-api
|
||||
|
||||
# 防止XSS攻击
|
||||
xss:
|
||||
@ -117,3 +110,14 @@ xss:
|
||||
excludes: /system/notice/*
|
||||
# 匹配链接
|
||||
urlPatterns: /system/*,/monitor/*,/tool/*
|
||||
|
||||
#微信
|
||||
wx:
|
||||
#微信开放平台
|
||||
open:
|
||||
#开放平台appid
|
||||
appid: wx08196c4219236ab5
|
||||
#开放平台appsecret
|
||||
appsecret: 9a131c53016eb64e1f55161326307bbf
|
||||
#回调地址
|
||||
callback_url: http://grow.xxzzu.com/system/wechat/callback
|
||||
|
@ -119,6 +119,12 @@
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--Hutool工具-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
|
||||
*/
|
||||
@Component
|
||||
@ConfigurationProperties(prefix = "muster")
|
||||
public class RuoYiConfig
|
||||
public class MusterConfig
|
||||
{
|
||||
/** 项目名称 */
|
||||
private String name;
|
||||
@ -30,6 +30,10 @@ public class RuoYiConfig
|
||||
/** 获取地址开关 */
|
||||
private static boolean addressEnabled;
|
||||
|
||||
private static String appId;
|
||||
|
||||
private static String bizId;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
@ -77,7 +81,7 @@ public class RuoYiConfig
|
||||
|
||||
public void setProfile(String profile)
|
||||
{
|
||||
RuoYiConfig.profile = profile;
|
||||
MusterConfig.profile = profile;
|
||||
}
|
||||
|
||||
public static boolean isAddressEnabled()
|
||||
@ -87,7 +91,7 @@ public class RuoYiConfig
|
||||
|
||||
public void setAddressEnabled(boolean addressEnabled)
|
||||
{
|
||||
RuoYiConfig.addressEnabled = addressEnabled;
|
||||
MusterConfig.addressEnabled = addressEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,4 +117,40 @@ public class RuoYiConfig
|
||||
{
|
||||
return getProfile() + "/upload";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets appId.
|
||||
*
|
||||
* @return the appId
|
||||
*/
|
||||
public static String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets appId.
|
||||
*
|
||||
* @param appId the appId
|
||||
*/
|
||||
public void setAppId(final String appId) {
|
||||
MusterConfig.appId = appId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets bizId.
|
||||
*
|
||||
* @return the bizId
|
||||
*/
|
||||
public static String getBizId() {
|
||||
return bizId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bizId.
|
||||
*
|
||||
* @param bizId the bizId
|
||||
*/
|
||||
public void setBizId(final String bizId) {
|
||||
MusterConfig.bizId = bizId;
|
||||
}
|
||||
}
|
270
muster-common/src/main/java/com/muster/common/constant/WxConsts.java
Executable file
270
muster-common/src/main/java/com/muster/common/constant/WxConsts.java
Executable file
@ -0,0 +1,270 @@
|
||||
package com.muster.common.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName WxConsts
|
||||
* @Description TOOD 微信开发所使用到的常量类.
|
||||
* @Author guoconglin
|
||||
* @DATE 2020/4/10 14:01
|
||||
* @Version 1.0
|
||||
**/
|
||||
|
||||
|
||||
public class WxConsts {
|
||||
|
||||
/**
|
||||
* 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型.
|
||||
*/
|
||||
public static class XmlMsgType {
|
||||
public static final String TEXT = "text";
|
||||
public static final String IMAGE = "image";
|
||||
public static final String VOICE = "voice";
|
||||
public static final String SHORTVIDEO = "shortvideo";
|
||||
public static final String VIDEO = "video";
|
||||
public static final String NEWS = "news";
|
||||
public static final String MUSIC = "music";
|
||||
public static final String LOCATION = "location";
|
||||
public static final String LINK = "link";
|
||||
public static final String EVENT = "event";
|
||||
public static final String DEVICE_TEXT = "device_text";
|
||||
public static final String DEVICE_EVENT = "device_event";
|
||||
public static final String DEVICE_STATUS = "device_status";
|
||||
public static final String HARDWARE = "hardware";
|
||||
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
|
||||
}
|
||||
|
||||
/**
|
||||
* 主动发送消息(即客服消息)的消息类型.
|
||||
*/
|
||||
public static class KefuMsgType {
|
||||
/**
|
||||
* 文本消息.
|
||||
*/
|
||||
public static final String TEXT = "text";
|
||||
/**
|
||||
* 图片消息.
|
||||
*/
|
||||
public static final String IMAGE = "image";
|
||||
/**
|
||||
* 语音消息.
|
||||
*/
|
||||
public static final String VOICE = "voice";
|
||||
|
||||
/**
|
||||
* 图文链接.
|
||||
*/
|
||||
public static final String LINK = "link";
|
||||
/**
|
||||
/**
|
||||
* 视频消息.
|
||||
*/
|
||||
public static final String VIDEO = "video";
|
||||
/**
|
||||
* 音乐消息.
|
||||
*/
|
||||
public static final String MUSIC = "music";
|
||||
/**
|
||||
* 图文消息(点击跳转到外链).
|
||||
*/
|
||||
public static final String NEWS = "news";
|
||||
/**
|
||||
* 图文消息(点击跳转到图文消息页面).
|
||||
*/
|
||||
public static final String MPNEWS = "mpnews";
|
||||
/**
|
||||
* 发送文件(CP专用).
|
||||
*/
|
||||
public static final String FILE = "file";
|
||||
/**
|
||||
* 文本卡片消息(CP专用).
|
||||
*/
|
||||
public static final String TEXTCARD = "textcard";
|
||||
/**
|
||||
* 卡券消息.
|
||||
*/
|
||||
public static final String WXCARD = "wxcard";
|
||||
/**
|
||||
* 转发到客服的消息.
|
||||
*/
|
||||
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
|
||||
}
|
||||
|
||||
/**
|
||||
* 表示是否是保密消息,0表示否,1表示是,默认0.
|
||||
*/
|
||||
public static class KefuMsgSafe {
|
||||
public static final String NO = "0";
|
||||
public static final String YES = "1";
|
||||
}
|
||||
|
||||
public static class Account {
|
||||
public static final int TYPE = 2;
|
||||
public static final String PASSWORD = "123456";
|
||||
|
||||
public static final String SHRIO_USERNAME = "admin";
|
||||
public static final String SHRIO_PASSWORD = "admin123";
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 群发消息的消息类型.
|
||||
*/
|
||||
public static class MassMsgType {
|
||||
public static final String MPNEWS = "mpnews";
|
||||
public static final String TEXT = "text";
|
||||
public static final String VOICE = "voice";
|
||||
public static final String IMAGE = "image";
|
||||
public static final String MPVIDEO = "mpvideo";
|
||||
}
|
||||
|
||||
/**
|
||||
* 群发消息后微信端推送给服务器的反馈消息.
|
||||
*/
|
||||
public static class MassMsgStatus {
|
||||
public static final String SEND_SUCCESS = "send success";
|
||||
public static final String SEND_FAIL = "send fail";
|
||||
public static final String ERR_10001 = "err(10001)";
|
||||
public static final String ERR_20001 = "err(20001)";
|
||||
public static final String ERR_20004 = "err(20004)";
|
||||
public static final String ERR_20002 = "err(20002)";
|
||||
public static final String ERR_20006 = "err(20006)";
|
||||
public static final String ERR_20008 = "err(20008)";
|
||||
public static final String ERR_20013 = "err(20013)";
|
||||
public static final String ERR_22000 = "err(22000)";
|
||||
public static final String ERR_21000 = "err(21000)";
|
||||
|
||||
/**
|
||||
* 群发反馈消息代码所对应的文字描述.
|
||||
*/
|
||||
public static final Map<String, String> STATUS_DESC = new HashMap<>();
|
||||
|
||||
static {
|
||||
STATUS_DESC.put(SEND_SUCCESS, "发送成功");
|
||||
STATUS_DESC.put(SEND_FAIL, "发送失败");
|
||||
STATUS_DESC.put(ERR_10001, "涉嫌广告");
|
||||
STATUS_DESC.put(ERR_20001, "涉嫌政治");
|
||||
STATUS_DESC.put(ERR_20004, "涉嫌社会");
|
||||
STATUS_DESC.put(ERR_20002, "涉嫌色情");
|
||||
STATUS_DESC.put(ERR_20006, "涉嫌违法犯罪");
|
||||
STATUS_DESC.put(ERR_20008, "涉嫌欺诈");
|
||||
STATUS_DESC.put(ERR_20013, "涉嫌版权");
|
||||
STATUS_DESC.put(ERR_22000, "涉嫌互推_互相宣传");
|
||||
STATUS_DESC.put(ERR_21000, "涉嫌其他");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信端推送过来的事件类型.
|
||||
*/
|
||||
public static class EventType {
|
||||
public static final String SUBSCRIBE = "subscribe";
|
||||
public static final String UNSUBSCRIBE = "unsubscribe";
|
||||
public static final String SCAN = "SCAN";
|
||||
public static final String LOCATION = "LOCATION";
|
||||
public static final String CLICK = "CLICK";
|
||||
public static final String VIEW = "VIEW";
|
||||
public static final String MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH";
|
||||
public static final String SCANCODE_PUSH = "scancode_push";
|
||||
public static final String SCANCODE_WAITMSG = "scancode_waitmsg";
|
||||
public static final String PIC_SYSPHOTO = "pic_sysphoto";
|
||||
public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album";
|
||||
public static final String PIC_WEIXIN = "pic_weixin";
|
||||
public static final String LOCATION_SELECT = "location_select";
|
||||
public static final String TEMPLATE_SEND_JOB_FINISH = "TEMPLATESENDJOBFINISH";
|
||||
public static final String ENTER_AGENT = "enter_agent";
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传多媒体(临时素材)文件的类型.
|
||||
*/
|
||||
public static class MediaFileType {
|
||||
public static final String IMAGE = "image";
|
||||
public static final String VOICE = "voice";
|
||||
public static final String VIDEO = "video";
|
||||
public static final String THUMB = "thumb";
|
||||
public static final String FILE = "file";
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义菜单的按钮类型.
|
||||
*/
|
||||
public static class MenuButtonType {
|
||||
/**
|
||||
* 点击推事件.
|
||||
*/
|
||||
public static final String CLICK = "click";
|
||||
/**
|
||||
* 跳转URL.
|
||||
*/
|
||||
public static final String VIEW = "view";
|
||||
/**
|
||||
* 跳转到小程序.
|
||||
*/
|
||||
public static final String MINIPROGRAM = "miniprogram";
|
||||
/**
|
||||
* 扫码推事件.
|
||||
*/
|
||||
public static final String SCANCODE_PUSH = "scancode_push";
|
||||
/**
|
||||
* 扫码推事件且弹出“消息接收中”提示框.
|
||||
*/
|
||||
public static final String SCANCODE_WAITMSG = "scancode_waitmsg";
|
||||
/**
|
||||
* 弹出系统拍照发图.
|
||||
*/
|
||||
public static final String PIC_SYSPHOTO = "pic_sysphoto";
|
||||
/**
|
||||
* 弹出拍照或者相册发图.
|
||||
*/
|
||||
public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album";
|
||||
/**
|
||||
* 弹出微信相册发图器.
|
||||
*/
|
||||
public static final String PIC_WEIXIN = "pic_weixin";
|
||||
/**
|
||||
* 弹出地理位置选择器.
|
||||
*/
|
||||
public static final String LOCATION_SELECT = "location_select";
|
||||
/**
|
||||
* 下发消息(除文本消息).
|
||||
*/
|
||||
public static final String MEDIA_ID = "media_id";
|
||||
/**
|
||||
* 跳转图文消息URL.
|
||||
*/
|
||||
public static final String VIEW_LIMITED = "view_limited";
|
||||
}
|
||||
|
||||
/**
|
||||
* oauth2网页授权的scope.
|
||||
*/
|
||||
public static class OAuth2Scope {
|
||||
/**
|
||||
* 不弹出授权页面,直接跳转,只能获取用户openid.
|
||||
*/
|
||||
public static final String SNSAPI_BASE = "snsapi_base";
|
||||
/**
|
||||
* 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息.
|
||||
*/
|
||||
public static final String SNSAPI_USERINFO = "snsapi_userinfo";
|
||||
}
|
||||
|
||||
/**
|
||||
* 网页应用登录授权作用域.
|
||||
*/
|
||||
public static class QrConnectScope {
|
||||
public static final String SNSAPI_LOGIN = "snsapi_login";
|
||||
}
|
||||
|
||||
/**
|
||||
* 永久素材类型.
|
||||
*/
|
||||
public static class MaterialType {
|
||||
public static final String NEWS = "news";
|
||||
public static final String VOICE = "voice";
|
||||
public static final String IMAGE = "image";
|
||||
public static final String VIDEO = "video";
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.muster.common.config.RuoYiConfig;
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.common.constant.Constants;
|
||||
import com.muster.common.exception.file.FileNameLengthLimitExceededException;
|
||||
import com.muster.common.exception.file.FileSizeLimitExceededException;
|
||||
@ -33,7 +33,7 @@ public class FileUploadUtils
|
||||
/**
|
||||
* 默认上传的地址
|
||||
*/
|
||||
private static String defaultBaseDir = RuoYiConfig.getProfile();
|
||||
private static String defaultBaseDir = MusterConfig.getProfile();
|
||||
|
||||
public static void setDefaultBaseDir(String defaultBaseDir)
|
||||
{
|
||||
@ -144,7 +144,7 @@ public class FileUploadUtils
|
||||
|
||||
private static final String getPathFileName(String uploadDir, String fileName) throws IOException
|
||||
{
|
||||
int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
|
||||
int dirLastIndex = MusterConfig.getProfile().length() + 1;
|
||||
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
|
||||
String pathFileName = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + fileName;
|
||||
return pathFileName;
|
||||
|
@ -3,7 +3,7 @@ package com.muster.common.utils.ip;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.muster.common.config.RuoYiConfig;
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.common.constant.Constants;
|
||||
import com.muster.common.utils.StringUtils;
|
||||
import com.muster.common.utils.http.HttpUtils;
|
||||
@ -31,7 +31,7 @@ public class AddressUtils
|
||||
{
|
||||
return "内网IP";
|
||||
}
|
||||
if (RuoYiConfig.isAddressEnabled())
|
||||
if (MusterConfig.isAddressEnabled())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -46,7 +46,7 @@ import com.muster.common.annotation.Excel;
|
||||
import com.muster.common.annotation.Excel.ColumnType;
|
||||
import com.muster.common.annotation.Excel.Type;
|
||||
import com.muster.common.annotation.Excels;
|
||||
import com.muster.common.config.RuoYiConfig;
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.common.core.domain.AjaxResult;
|
||||
import com.muster.common.core.text.Convert;
|
||||
import com.muster.common.exception.CustomException;
|
||||
@ -739,7 +739,7 @@ public class ExcelUtil<T>
|
||||
*/
|
||||
public String getAbsoluteFile(String filename)
|
||||
{
|
||||
String downloadPath = RuoYiConfig.getDownloadPath() + filename;
|
||||
String downloadPath = MusterConfig.getDownloadPath() + filename;
|
||||
File desc = new File(downloadPath);
|
||||
if (!desc.getParentFile().exists())
|
||||
{
|
||||
|
@ -9,7 +9,7 @@ import org.springframework.web.filter.CorsFilter;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import com.muster.common.config.RuoYiConfig;
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.common.constant.Constants;
|
||||
import com.muster.framework.interceptor.RepeatSubmitInterceptor;
|
||||
|
||||
@ -28,7 +28,7 @@ public class ResourcesConfig implements WebMvcConfigurer
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry)
|
||||
{
|
||||
/** 本地文件上传路径 */
|
||||
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
|
||||
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + MusterConfig.getProfile() + "/");
|
||||
|
||||
/** swagger配置 */
|
||||
registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
|
||||
|
@ -1,12 +1,5 @@
|
||||
package com.muster.framework.web.service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.muster.common.constant.Constants;
|
||||
import com.muster.common.core.domain.model.LoginUser;
|
||||
import com.muster.common.core.redis.RedisCache;
|
||||
@ -17,6 +10,14 @@ import com.muster.common.exception.user.UserPasswordNotMatchException;
|
||||
import com.muster.common.utils.MessageUtils;
|
||||
import com.muster.framework.manager.AsyncManager;
|
||||
import com.muster.framework.manager.factory.AsyncFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
@ -59,13 +60,26 @@ public class SysLoginService
|
||||
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
|
||||
throw new CaptchaException();
|
||||
}
|
||||
return this.login(username, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部登录验证
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return 结果
|
||||
*/
|
||||
public String login(String username, String password)
|
||||
{
|
||||
|
||||
// 用户验证
|
||||
Authentication authentication = null;
|
||||
try
|
||||
{
|
||||
// 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
|
||||
authentication = authenticationManager
|
||||
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
|
||||
.authenticate(new UsernamePasswordAuthenticationToken(username, password));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -200,7 +200,7 @@ public class GenUtils
|
||||
*/
|
||||
public static String replaceText(String text)
|
||||
{
|
||||
return RegExUtils.replaceAll(text, "(?:表|若依)", "");
|
||||
return RegExUtils.replaceAll(text, "(?:表|muster)", "");
|
||||
}
|
||||
|
||||
/**
|
||||
|
23
muster-logic/pom.xml
Normal file
23
muster-logic/pom.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?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>muster</artifactId>
|
||||
<groupId>com.muster</groupId>
|
||||
<version>3.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>muster-logic</artifactId>
|
||||
<version>3.0.0</version>
|
||||
|
||||
<dependencies>
|
||||
<!-- 核心模块-->
|
||||
<dependency>
|
||||
<groupId>com.muster</groupId>
|
||||
<artifactId>muster-framework</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
150
muster-logic/src/main/java/com/muster/logic/BO/DaoContext.java
Normal file
150
muster-logic/src/main/java/com/muster/logic/BO/DaoContext.java
Normal file
@ -0,0 +1,150 @@
|
||||
package com.muster.logic.BO;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-04.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
public class DaoContext {
|
||||
|
||||
public DaoContext() {
|
||||
}
|
||||
|
||||
public DaoContext(final String appId, final String bizId, final String uhId, final int userId, final int token) {
|
||||
this.appId = appId;
|
||||
this.bizId = bizId;
|
||||
this.uhId = uhId;
|
||||
this.userId = userId;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统级设定appid
|
||||
*/
|
||||
private String appId = "10001";
|
||||
|
||||
/**
|
||||
* 系统级设定bizid 原则上 fx_bizid>0 时,将无权注册企业
|
||||
*/
|
||||
private String bizId = "0";
|
||||
|
||||
/**
|
||||
* 用户操作的终端硬件参数
|
||||
*/
|
||||
private String uhId = "test";
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private int userId = 1;
|
||||
|
||||
/**
|
||||
* 用户token
|
||||
*/
|
||||
private int token = 1;
|
||||
|
||||
/**
|
||||
* Gets appId.
|
||||
*
|
||||
* @return the appId
|
||||
*/
|
||||
public String getAppId() {
|
||||
return appId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets appId.
|
||||
*
|
||||
* @param appId the appId
|
||||
*/
|
||||
public void setAppId(final String appId) {
|
||||
this.appId = appId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets bizId.
|
||||
*
|
||||
* @return the bizId
|
||||
*/
|
||||
public String getBizId() {
|
||||
return bizId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bizId.
|
||||
*
|
||||
* @param bizId the bizId
|
||||
*/
|
||||
public void setBizId(final String bizId) {
|
||||
this.bizId = bizId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets uhId.
|
||||
*
|
||||
* @return the uhId
|
||||
*/
|
||||
public String getUhId() {
|
||||
return uhId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets uhId.
|
||||
*
|
||||
* @param uhId the uhId
|
||||
*/
|
||||
public void setUhId(final String uhId) {
|
||||
this.uhId = uhId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets userId.
|
||||
*
|
||||
* @return the userId
|
||||
*/
|
||||
public int getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets userId.
|
||||
*
|
||||
* @param userId the userId
|
||||
*/
|
||||
public void setUserId(final int userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets token.
|
||||
*
|
||||
* @return the token
|
||||
*/
|
||||
public int getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets token.
|
||||
*
|
||||
* @param token the token
|
||||
*/
|
||||
public void setToken(final int token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("DaoContext{");
|
||||
sb.append("appId='").append(appId).append('\'');
|
||||
sb.append(", bizId='").append(bizId).append('\'');
|
||||
sb.append(", uhId='").append(uhId).append('\'');
|
||||
sb.append(", userId=").append(userId);
|
||||
sb.append(", token=").append(token);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-04.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
package com.muster.logic.BO;
|
@ -0,0 +1,39 @@
|
||||
package com.muster.logic;
|
||||
|
||||
|
||||
import com.muster.common.config.MusterConfig;
|
||||
import com.muster.logic.BO.DaoContext;
|
||||
import org.slf4j.MDC;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-05.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
public class DaoContextUtils {
|
||||
|
||||
public static DaoContext createContext() {
|
||||
String hid = MDC.get("hid");
|
||||
int userId = Integer.valueOf(MDC.get("userId"));
|
||||
int token = Integer.valueOf(MDC.get("token"));
|
||||
String appId = MusterConfig.getAppId();
|
||||
String bizId = MusterConfig.getBizId();
|
||||
return new DaoContext(appId, bizId, hid, userId, token);
|
||||
}
|
||||
|
||||
public static DaoContext createContext(final Map<String, Object> params) {
|
||||
String hid = MDC.get("hid");
|
||||
int userId = Integer.valueOf(MDC.get("userId"));
|
||||
int token = Integer.valueOf(MDC.get("token"));
|
||||
String appId = String.valueOf(params.getOrDefault("appId", MusterConfig.getAppId()));
|
||||
String bizId = String.valueOf(params.getOrDefault("bizId", MusterConfig.getBizId()));
|
||||
params.remove("appId");
|
||||
params.remove("bizId");
|
||||
return new DaoContext(appId, bizId, hid, userId, token);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.muster.logic;
|
||||
|
||||
import com.muster.logic.model.ProcedureResult;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-04.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
public interface DbLogicService {
|
||||
|
||||
/**
|
||||
* @param procedureName 存储过程名称,从 ProcedureNameConstants 获取
|
||||
* @param params 存储过程参数
|
||||
* @return 返回结果集
|
||||
*/
|
||||
ProcedureResult exec(final String procedureName, final Map<String, Object> params);
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package com.muster.logic;
|
||||
|
||||
import com.muster.logic.BO.DaoContext;
|
||||
import com.muster.logic.model.ProcedureResult;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-04.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
@Service
|
||||
public class DbLogicServiceImpl implements DbLogicService {
|
||||
|
||||
Logger log = LoggerFactory.getLogger(DbLogicServiceImpl.class);
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private final static int OUPUT_INDEX = 6;
|
||||
|
||||
@Autowired
|
||||
DbLogicServiceImpl(@Qualifier("masterDataSource") DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcedureResult exec(final String procedureName, final Map<String, Object> params) {
|
||||
ProcedureResult result = new ProcedureResult();
|
||||
DaoContext context = DaoContextUtils.createContext(params);
|
||||
String sql = this.createProcedure(procedureName, params.size());
|
||||
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
CallableStatement cs = conn.prepareCall(sql)) {
|
||||
|
||||
// 设置上下文参数
|
||||
this.setContext(cs, context);
|
||||
// 设置业务参数
|
||||
this.setParams(cs, params);
|
||||
|
||||
cs.registerOutParameter(6, Types.INTEGER);
|
||||
cs.execute();
|
||||
|
||||
int res = cs.getInt(OUPUT_INDEX);
|
||||
result.setRes(res);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("{}, {}, {}, {}", procedureName, context.toString(), params, res);
|
||||
}
|
||||
List<Map<String, Object>> list = this.getResult(cs);
|
||||
result.setResult(list);
|
||||
|
||||
} catch (SQLException e) {
|
||||
log.error("{}, {}, {}", procedureName, context.toString(), params, e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> getResult(final CallableStatement cs) {
|
||||
List<Map<String, Object>> list = new ArrayList<>();
|
||||
try (ResultSet rs = cs.getResultSet();) {
|
||||
if (Objects.isNull(rs)) {
|
||||
return list;
|
||||
}
|
||||
ResultSetMetaData rsmd = rs.getMetaData();
|
||||
int columnCount = rsmd.getColumnCount();
|
||||
while (rs.next()) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
for (int i = 1; i <= columnCount; i++) {
|
||||
String name = rsmd.getColumnName(i);
|
||||
String type = rsmd.getColumnClassName(i);
|
||||
Object value = null;
|
||||
if ("java.lang.String".equals(type)) {
|
||||
value = rs.getString(i);
|
||||
} else if ("java.lang.Integer".equals(type)) {
|
||||
value = rs.getInt(i);
|
||||
} else if ("java.sql.Date".equals(type)) {
|
||||
value = rs.getDate(i);
|
||||
} else if ("java.math.BigDecimal".equals(type)) {
|
||||
value = rs.getBigDecimal(i);
|
||||
} else if ("java.lang.Boolean".equals(type)) {
|
||||
value = rs.getBoolean(i);
|
||||
} else if ("java.lang.Long".equals(type)) {
|
||||
value = rs.getLong(i);
|
||||
} else if ("java.sql.Timestamp".equals(type)) {
|
||||
value = rs.getTimestamp(i);
|
||||
}
|
||||
map.put(name, value);
|
||||
}
|
||||
|
||||
list.add(map);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void setParams(final CallableStatement cs, final Map<String, Object> params) {
|
||||
int index = 7;
|
||||
List<String> keys = params.keySet().stream().sorted().collect(Collectors.toList());
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
setParam(cs, params, keys.get(i), index);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
private void setParam(final CallableStatement cs, final Map<String, Object> params, final String key,
|
||||
final int index) {
|
||||
Object v = params.get(key);
|
||||
|
||||
try {
|
||||
if (v instanceof String) {
|
||||
cs.setString(index, v.toString());
|
||||
} else if (v instanceof Integer) {
|
||||
cs.setInt(index, Integer.valueOf(v.toString()));
|
||||
} else if (v instanceof Double) {
|
||||
cs.setDouble(index, Double.valueOf(v.toString()));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setContext(final CallableStatement cs, final DaoContext context) throws SQLException {
|
||||
cs.setString(1, context.getAppId());
|
||||
cs.setString(2, context.getBizId());
|
||||
cs.setString(3, context.getUhId());
|
||||
cs.setInt(4, context.getUserId());
|
||||
cs.setInt(5, context.getToken());
|
||||
}
|
||||
|
||||
private String createProcedure(final String name, final int size) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
str.append(" ,?");
|
||||
}
|
||||
|
||||
return String.format(procedureTemplate, name, str.toString());
|
||||
}
|
||||
|
||||
private final static String procedureTemplate = "call %s(?, ?, ?, ?, ?, ?%s)";
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.muster.logic.model;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-04.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
public class ProcedureResult {
|
||||
|
||||
private int res;
|
||||
|
||||
private List<Map<String, Object>> result;
|
||||
|
||||
/**
|
||||
* Gets res.
|
||||
*
|
||||
* @return the res
|
||||
*/
|
||||
public int getRes() {
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets res.
|
||||
*
|
||||
* @param res the res
|
||||
*/
|
||||
public void setRes(final int res) {
|
||||
this.res = res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets result.
|
||||
*
|
||||
* @return the result
|
||||
*/
|
||||
public List<Map<String, Object>> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets result.
|
||||
*
|
||||
* @param result the result
|
||||
*/
|
||||
public void setResult(final List<Map<String, Object>> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder("ProcedureResult{");
|
||||
sb.append("res=").append(res);
|
||||
sb.append(", result=").append(result);
|
||||
sb.append('}');
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-04.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
package com.muster.logic.model;
|
@ -0,0 +1,9 @@
|
||||
/**
|
||||
* Description
|
||||
* <p>
|
||||
* </p>
|
||||
* DATE 2020-07-04.
|
||||
*
|
||||
* @author 刘江涛.
|
||||
*/
|
||||
package com.muster.logic;
|
@ -1,8 +1,8 @@
|
||||
{
|
||||
"name": "muster",
|
||||
"version": "3.0.0",
|
||||
"description": "若依管理系统",
|
||||
"author": "若依",
|
||||
"description": "Muster管理系统",
|
||||
"author": "MUster",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve --open",
|
||||
|
@ -1,31 +1,31 @@
|
||||
module.exports = {
|
||||
title: '若依管理系统',
|
||||
|
||||
/**
|
||||
* 是否系统布局配置
|
||||
*/
|
||||
showSettings: false,
|
||||
|
||||
/**
|
||||
* 是否显示 tagsView
|
||||
*/
|
||||
tagsView: true,
|
||||
|
||||
/**
|
||||
* 是否固定头部
|
||||
*/
|
||||
fixedHeader: false,
|
||||
|
||||
/**
|
||||
* 是否显示logo
|
||||
*/
|
||||
sidebarLogo: true,
|
||||
|
||||
/**
|
||||
* @type {string | array} 'production' | ['production', 'development']
|
||||
* @description Need show err logs component.
|
||||
* The default is only used in the production env
|
||||
* If you want to also use it in dev, you can pass ['production', 'development']
|
||||
*/
|
||||
errorLog: 'production'
|
||||
}
|
||||
module.exports = {
|
||||
title: 'Muster管理系统',
|
||||
|
||||
/**
|
||||
* 是否系统布局配置
|
||||
*/
|
||||
showSettings: false,
|
||||
|
||||
/**
|
||||
* 是否显示 tagsView
|
||||
*/
|
||||
tagsView: true,
|
||||
|
||||
/**
|
||||
* 是否固定头部
|
||||
*/
|
||||
fixedHeader: false,
|
||||
|
||||
/**
|
||||
* 是否显示logo
|
||||
*/
|
||||
sidebarLogo: true,
|
||||
|
||||
/**
|
||||
* @type {string | array} 'production' | ['production', 'development']
|
||||
* @description Need show err logs component.
|
||||
* The default is only used in the production env
|
||||
* If you want to also use it in dev, you can pass ['production', 'development']
|
||||
*/
|
||||
errorLog: 'production'
|
||||
}
|
||||
|
86
muster.sh
Executable file
86
muster.sh
Executable file
@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
|
||||
AppName=muster-admin.jar
|
||||
|
||||
#JVM参数
|
||||
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
|
||||
APP_HOME=`pwd`
|
||||
LOG_PATH=$APP_HOME/logs/$AppName.log
|
||||
|
||||
if [ "$1" = "" ];
|
||||
then
|
||||
echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$AppName" = "" ];
|
||||
then
|
||||
echo -e "\033[0;31m 未输入应用名 \033[0m"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
function start()
|
||||
{
|
||||
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
|
||||
|
||||
if [ x"$PID" != x"" ]; then
|
||||
echo "$AppName is running..."
|
||||
else
|
||||
nohup java -jar $JVM_OPTS target/$AppName > /dev/null 2>&1 &
|
||||
echo "Start $AppName success..."
|
||||
fi
|
||||
}
|
||||
|
||||
function stop()
|
||||
{
|
||||
echo "Stop $AppName"
|
||||
|
||||
PID=""
|
||||
query(){
|
||||
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`
|
||||
}
|
||||
|
||||
query
|
||||
if [ x"$PID" != x"" ]; then
|
||||
kill -TERM $PID
|
||||
echo "$AppName (pid:$PID) exiting..."
|
||||
while [ x"$PID" != x"" ]
|
||||
do
|
||||
sleep 1
|
||||
query
|
||||
done
|
||||
echo "$AppName exited."
|
||||
else
|
||||
echo "$AppName already stopped."
|
||||
fi
|
||||
}
|
||||
|
||||
function restart()
|
||||
{
|
||||
stop
|
||||
sleep 2
|
||||
start
|
||||
}
|
||||
|
||||
function status()
|
||||
{
|
||||
PID=`ps -ef |grep java|grep $AppName|grep -v grep|wc -l`
|
||||
if [ $PID != 0 ];then
|
||||
echo "$AppName is running..."
|
||||
else
|
||||
echo "$AppName is not running..."
|
||||
fi
|
||||
}
|
||||
|
||||
case $1 in
|
||||
start)
|
||||
start;;
|
||||
stop)
|
||||
stop;;
|
||||
restart)
|
||||
restart;;
|
||||
status)
|
||||
status;;
|
||||
*)
|
||||
|
||||
esac
|
25
pom.xml
25
pom.xml
@ -30,6 +30,8 @@
|
||||
<poi.version>3.17</poi.version>
|
||||
<velocity.version>1.7</velocity.version>
|
||||
<jwt.version>0.9.0</jwt.version>
|
||||
<hutool.version>5.2.1</hutool.version>
|
||||
<gson.version>2.8.5</gson.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
@ -181,6 +183,28 @@
|
||||
<version>${muster.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- 逻辑模块 -->
|
||||
<dependency>
|
||||
<groupId>com.muster</groupId>
|
||||
<artifactId>muster-logic</artifactId>
|
||||
<version>${muster.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--Hutool工具-->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
@ -191,6 +215,7 @@
|
||||
<module>muster-quartz</module>
|
||||
<module>muster-generator</module>
|
||||
<module>muster-common</module>
|
||||
<module>muster-logic</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
@ -23,16 +23,16 @@ create table sys_dept (
|
||||
-- ----------------------------
|
||||
-- 初始化-部门表数据
|
||||
-- ----------------------------
|
||||
insert into sys_dept values(100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(100, 0, '0', '若依科技', 0, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(101, 100, '0,100', '深圳总公司', 1, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(102, 100, '0,100', '长沙分公司', 2, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(103, 101, '0,100,101', '研发部门', 1, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(104, 101, '0,100,101', '市场部门', 2, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(105, 101, '0,100,101', '测试部门', 3, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(106, 101, '0,100,101', '财务部门', 4, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(107, 101, '0,100,101', '运维部门', 5, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(108, 102, '0,100,102', '市场部门', 1, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
insert into sys_dept values(109, 102, '0,100,102', '财务部门', 2, 'muster', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00');
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
@ -65,8 +65,8 @@ create table sys_user (
|
||||
-- ----------------------------
|
||||
-- 初始化-用户信息表数据
|
||||
-- ----------------------------
|
||||
insert into sys_user values(1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2018-03-16 11-33-00', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '管理员');
|
||||
insert into sys_user values(2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2018-03-16 11-33-00', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '测试员');
|
||||
insert into sys_user values(1, 103, 'admin', 'muster', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2018-03-16 11-33-00', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '管理员');
|
||||
insert into sys_user values(2, 105, 'ry', 'muster', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2018-03-16 11-33-00', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '测试员');
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
|
Reference in New Issue
Block a user