chenwen 4 jaren geleden
bovenliggende
commit
ccf0f9c75f

+ 12 - 0
common/src/main/java/com/jpsoft/employment/modules/common/dto/MessageResultBuilder.java

@@ -0,0 +1,12 @@
+package com.jpsoft.employment.modules.common.dto;
+
+public class MessageResultBuilder {
+
+    public static <T>  MessageResult<T> ok(T data){
+            return new MessageResult<T>(true,null,data,200);
+    }
+
+    public static <T>  MessageResult<T> error(String msg){
+        return new MessageResult<T>(false,msg,null,500);
+    }
+}

+ 106 - 0
common/src/main/java/com/jpsoft/employment/modules/common/utils/MapUtils.java

@@ -0,0 +1,106 @@
+package com.jpsoft.employment.modules.common.utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang.StringUtils;
+
+
+
+public class MapUtils {
+
+	/**
+	 * 为空串的value设置为null
+	 * @param args
+	 */
+	public static void blankValToNull(Map<String,Object> args){
+		for(String key : args.keySet()){
+			if(args.get(key) instanceof String && StringUtils.isEmpty((String)args.get(key))){
+				args.put(key,null);
+			}
+		}
+	}
+	
+	/**
+	 * 为空串的value设置为null,指定的keys有效
+	 * @param args
+	 */
+    public static void blankValToNull(Map<String,Object> args,String... keys){
+		for(String key : keys){
+			if(args.get(key) instanceof String && StringUtils.isEmpty((String)args.get(key))){
+				args.put(key,null);
+			}
+		}
+	}
+    
+    
+    /**
+     * 字符串时间value转换为Date对象值,指定的keys有效
+     * @param args
+     * @param fields
+     */
+    /*public static void strValToDate(Map<String,Object> args,String... keys){
+		for(String key : keys){
+			if(StringUtils.isNotEmpty((String)args.get(key))){
+				args.put(key,DateUtil.parse((String)args.get(key)));
+			}
+		}
+	}*/
+    
+    /**
+     * 提取部分键值对作为新的Map返回,原Map去掉被提取的键值对
+     * @param <V>
+     * @param srcMap
+     * @param keys
+     * @return
+     */
+    public static <V>  Map<String,V>  trackMap(Map<String,V> srcMap,String... keys){
+		Map<String,V> rtnMap=new HashMap<String,V>(keys.length);
+		for(String key : keys){
+			rtnMap.put(key, srcMap.get(key));
+		}
+		for(String key : keys){
+			srcMap.remove(key);
+		}
+		return rtnMap;
+	}
+	
+    /**
+     * 提取部分键值对作为新的Map返回
+     * @param <V>
+     * @param srcMap
+     * @param keys
+     * @return
+     */
+	public static <V> Map<String,V> clone(Map<String,V> srcMap,String... keys){
+		Map<String,V> rtnMap=new HashMap<String,V>(keys.length);
+		for(String key : keys){
+			rtnMap.put(key, srcMap.get(key));
+		}
+		return rtnMap;
+	}
+	
+	public static Map<String,Object> builder(String... keyVal){
+		if(keyVal==null){
+			return null;
+		}
+		Map<String,Object>  rtnMap=new HashMap<String,Object>();
+		for(int i=0,len=keyVal.length;i<len;i++){
+			rtnMap.put(keyVal[i], (i+1)<len?keyVal[i+1]:null);
+			i+=1;
+		}
+		return rtnMap;
+	}
+	
+	public static Map<String,Object> builder(Object... keyVal){
+		if(keyVal==null){
+			return null;
+		}
+		Map<String,Object>  rtnMap=new HashMap<String,Object>();
+		for(int i=0,len=keyVal.length;i<len;i++){
+			rtnMap.put(keyVal[i].toString(), (i+1)<len?keyVal[i+1]:null);
+			i+=1;
+		}
+		return rtnMap;
+	}
+}

+ 19 - 0
common/src/main/java/com/jpsoft/employment/modules/job/dto/EducationExpDTO.java

@@ -0,0 +1,19 @@
+package com.jpsoft.employment.modules.job.dto;
+
+import lombok.Data;
+
+@Data
+public class EducationExpDTO {
+    private String id;
+
+    private String name;
+
+    private String timeS;
+
+    private String timeE;
+
+    private String remark;
+
+    private String content;
+
+}

+ 14 - 0
common/src/main/java/com/jpsoft/employment/modules/job/dto/ExpJsonDTO.java

@@ -0,0 +1,14 @@
+package com.jpsoft.employment.modules.job.dto;
+
+import com.sun.corba.se.spi.orbutil.threadpool.Work;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class ExpJsonDTO {
+    private List<WorkExpDTO> workExp;
+    private List<EducationExpDTO> educationExp;
+
+}

+ 19 - 0
common/src/main/java/com/jpsoft/employment/modules/job/dto/WorkExpDTO.java

@@ -0,0 +1,19 @@
+package com.jpsoft.employment.modules.job.dto;
+
+import lombok.Data;
+
+@Data
+public class WorkExpDTO {
+    private String id;
+
+    private String name;
+
+    private String timeS;
+
+    private String timeE;
+
+    private String remark;
+
+    private String content;
+
+}

+ 105 - 0
common/src/main/java/com/jpsoft/employment/modules/job/entity/RecruitmentVO.java

@@ -0,0 +1,105 @@
+package com.jpsoft.employment.modules.job.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+  描述:job_recruitment的VO
+ */
+@Data
+public class RecruitmentVO {
+
+	@ApiModelProperty(value = "ID")
+	private String id;
+
+	@ApiModelProperty(value = "企业ID")
+	private String companyId;
+
+	@ApiModelProperty(value = "标题")
+	private String title;
+
+	@ApiModelProperty(value = "招聘所属地区")
+	private String area;
+
+	@ApiModelProperty(value = "地址")
+	private String address;
+
+	@ApiModelProperty(value = "职位")
+	private String position;
+
+	@ApiModelProperty(value = "职位名称")
+	private String positionName;
+
+	@ApiModelProperty(value = "职位描述")
+	private String positionMessage;
+
+	@ApiModelProperty(value = "任职要求")
+	private String requirements;
+
+
+	@ApiModelProperty(value = "求职人数")
+	private Integer positionNumber;
+
+	@ApiModelProperty(value = "工作年限")
+	private String workYear;
+
+	@ApiModelProperty(value = "学历要求")
+	private String education;
+
+	@ApiModelProperty(value = "性别要求")
+	private String positionSex;
+
+	@ApiModelProperty(value = "性别要求")
+	private Integer readTimes;
+
+	@ApiModelProperty(value = "薪资")
+	private String wageType;
+
+	@ApiModelProperty(value = "是否面议")
+	private Boolean isDiscussPersonally;
+
+	@ApiModelProperty(value = "联系人")
+	private String contactPerson;
+
+	@ApiModelProperty(value = "联系方式")
+	private String tel;
+
+	@ApiModelProperty(value = "状态(关闭,开启等)")
+	private String status;
+
+	@ApiModelProperty(value = "审批状态")
+	private String approveStatus;
+
+	@ApiModelProperty(value = "阅读次数")
+	private Integer readingTimes;
+
+	@ApiModelProperty(value = "收藏次数")
+	private Integer collectionTimes;
+
+	@ApiModelProperty(value = "投递次数")
+	private Integer deliveryTimes;
+
+	@ApiModelProperty(value = "创建人")
+	private String createBy;
+
+	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	@ApiModelProperty(value = "创建时间")
+	private Date createTime;
+
+	@ApiModelProperty(value = "更新人")
+	private String updateBy;
+
+	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	@ApiModelProperty(value = "更新时间")
+	private Date updateTime;
+
+	@ApiModelProperty(value = "是否删除")
+	private Boolean delFlag;
+
+}

+ 77 - 0
common/src/main/java/com/jpsoft/employment/modules/job/entity/ResumeVO.java

@@ -0,0 +1,77 @@
+package com.jpsoft.employment.modules.job.entity;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+  描述:job_resume的VO类
+ */
+@Data
+public class ResumeVO {
+
+	@ApiModelProperty(value = "ID")
+	private String id;
+
+	@ApiModelProperty(value = "创建人")
+	private String createBy;
+
+	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	@ApiModelProperty(value = "创建时间")
+	private Date createTime;
+
+	@ApiModelProperty(value = "更新人")
+	private String updateBy;
+
+	@DateTimeFormat(pattern="yyyy-MM-dd HH:mm")
+	@JsonFormat(pattern = "yyyy-MM-dd HH:mm",timezone ="GMT+8")
+	@ApiModelProperty(value = "更新时间")
+	private Date updateTime;
+
+	@ApiModelProperty(value = "是否删除")
+	private Boolean delFlag;
+
+	@ApiModelProperty(value = "用户ID")
+	private String jobUserId;
+
+	@ApiModelProperty(value = "性别")
+	private String sex;
+
+	@ApiModelProperty(value = "职位分类")
+	private String positionCategoryId;
+
+	@ApiModelProperty(value = "职位分类名称")
+	private String positionCategoryName;
+
+	@ApiModelProperty(value = "工作经验")
+	private String workExp;
+
+	@ApiModelProperty(value = "学历")
+	private String education;
+
+	@ApiModelProperty(value = "期望薪资")
+	private String dreamMoney;
+
+	@ApiModelProperty(value = "期望工作地点")
+	private String dreamAdd;
+
+	@DateTimeFormat(pattern="yyyy-MM-dd")
+	@JsonFormat(pattern = "yyyy-MM-dd",timezone ="GMT+8")
+	@ApiModelProperty(value = "出生日期")
+	private Date birthday;
+
+	@ApiModelProperty(value = "个人介绍")
+	private String introduction;
+
+
+	@ApiModelProperty(value = "简历状态(开启,审核,等")
+	private String status;
+
+	@ApiModelProperty(value = "审批状态")
+	private String approveStatus;
+
+}

+ 67 - 0
web/src/main/java/com/jpsoft/employment/modules/pay/properties/AliPayProperties.java

@@ -0,0 +1,67 @@
+package com.jpsoft.employment.modules.pay.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-11-26 9:37
+ */
+
+@Data
+@ConfigurationProperties(prefix = "alipay")
+@Component
+public class AliPayProperties {
+
+
+    /**
+     * 支付宝网关
+     */
+    private String serviceUrl;
+
+    /**
+     * 应用appid
+     */
+    private String appId;
+
+    /**
+     * 应用私钥
+     */
+    private String privateKey;
+
+    /**
+     * 支付宝公钥
+     */
+    private String zfbPublicKey;
+
+    /**
+     * 编码
+     */
+    private String inputCharset;
+
+    /**
+     * 服务商id
+     */
+    private String mchId;
+
+    /**
+     * 授权token
+     */
+    private String appAuthToken;
+
+    /**
+     * 加密方式
+     */
+    private String signType;
+
+    /**
+     * 支付回调地址
+     */
+    private String notifyUrl;
+
+    /**
+     * 商品描述
+     */
+    private String body;
+}

+ 68 - 0
web/src/main/java/com/jpsoft/employment/modules/pay/properties/ParkAliPayProperties.java

@@ -0,0 +1,68 @@
+package com.jpsoft.employment.modules.pay.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2020-4-16 15:05
+ */
+@Data
+@ConfigurationProperties(prefix = "parkalipay")
+@Component
+public class ParkAliPayProperties {
+
+    /**
+     * 支付宝网关
+     */
+    private String serviceUrl;
+
+    /**
+     * 应用appid
+     */
+    private String appId;
+
+    /**
+     * 应用私钥
+     */
+    private String privateKey;
+
+    /**
+     * 支付宝公钥
+     */
+    private String zfbPublicKey;
+
+    /**
+     * 编码
+     */
+    private String inputCharset;
+
+    /**
+     * 服务商id
+     */
+    private String mchId;
+
+    /**
+     * 授权token
+     */
+    private String appAuthToken;
+
+    /**
+     * 加密方式
+     */
+    private String signType;
+
+    /**
+     * 支付回调地址
+     */
+    private String notifyUrl;
+
+    /**
+     * 商品描述
+     */
+    private String body;
+
+    private String format;
+
+}

+ 71 - 0
web/src/main/java/com/jpsoft/employment/modules/pay/properties/WxJpsoftProperties.java

@@ -0,0 +1,71 @@
+package com.jpsoft.employment.modules.pay.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-11-26 9:35
+ */
+
+@Data
+@ConfigurationProperties(prefix = "wx.jpsoft")
+@Component
+public class WxJpsoftProperties {
+
+    /**
+     * 设置微信公众号或者小程序等的appid
+     */
+    private String appId;
+
+    /**
+     * 设置微信公众号或者小程序等的appSecret
+     */
+    private String appSecret;
+
+    /**
+     * 微信支付商户号
+     */
+    private String mchId;
+
+    /**
+     * 微信支付商户密钥
+     */
+    private String mchKey;
+
+    /**
+     * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除
+     */
+    private String subAppId;
+
+    /**
+     * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除
+     */
+    private String subMchId;
+
+    /**
+     * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定
+     */
+    private String keyPath;
+
+    /**
+     * 回调地址
+     */
+    private String notifyUrl;
+
+    /**
+     * 发起ip
+     */
+    private String ip;
+
+    /**
+     * 商品描述
+     */
+    private String body;
+
+    /**
+     * 页面跳转标识
+     */
+    private String urlKey;
+}

+ 71 - 0
web/src/main/java/com/jpsoft/employment/modules/pay/properties/WxPayProperties.java

@@ -0,0 +1,71 @@
+package com.jpsoft.employment.modules.pay.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-11-26 9:35
+ */
+
+@Data
+@ConfigurationProperties(prefix = "wx.pay")
+@Component
+public class WxPayProperties {
+
+    /**
+     * 设置微信公众号或者小程序等的appid
+     */
+    private String appId;
+
+    /**
+     * 设置微信公众号或者小程序等的appSecret
+     */
+    private String appSecret;
+
+    /**
+     * 微信支付商户号
+     */
+    private String mchId;
+
+    /**
+     * 微信支付商户密钥
+     */
+    private String mchKey;
+
+    /**
+     * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除
+     */
+    private String subAppId;
+
+    /**
+     * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除
+     */
+    private String subMchId;
+
+    /**
+     * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定
+     */
+    private String keyPath;
+
+    /**
+     * 回调地址
+     */
+    private String notifyUrl;
+
+    /**
+     * 发起ip
+     */
+    private String ip;
+
+    /**
+     * 商品描述
+     */
+    private String body;
+
+    /**
+     * 前端页面url
+     */
+    private String portalUrl;
+}

+ 85 - 0
web/src/main/java/com/jpsoft/employment/modules/wechat/callback/EventCallback.java

@@ -0,0 +1,85 @@
+package com.jpsoft.employment.modules.wechat.callback;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.util.EntityUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@Data
+public class EventCallback {
+    private String code;
+    private String callbackUrl;
+    private String message;
+
+    public EventCallback(){
+
+    }
+
+    public EventCallback(String code, String callbackUrl){
+        this.code = code;
+        this.callbackUrl = callbackUrl;
+//        this.message = message;
+    }
+
+    public boolean process(String wechatId, String openId, String eventKey){
+        boolean result = false;
+
+        try {
+            StringBuilder urlBuilder = new StringBuilder();
+
+            urlBuilder.append(this.callbackUrl);
+
+            HttpPost httpPost = new HttpPost(urlBuilder.toString());
+
+            RequestConfig requestConfig = RequestConfig.custom()
+                    .setSocketTimeout(5000)
+                    .setConnectTimeout(5000)
+                    .setConnectionRequestTimeout(5000)
+                    .build();
+
+            CloseableHttpClient httpClient = HttpClientBuilder.create()
+                    .setDefaultRequestConfig(requestConfig)
+                    .build();
+
+            List<NameValuePair> list = new ArrayList<NameValuePair>();
+            list.add(new BasicNameValuePair("eventKey", eventKey));
+            list.add(new BasicNameValuePair("wechatId", wechatId));
+            list.add(new BasicNameValuePair("openId", openId));
+
+            UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
+            httpPost.setEntity(entity);
+
+            HttpResponse res = httpClient.execute(httpPost);
+
+            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+                String content = EntityUtils.toString(res.getEntity());
+                this.setMessage(content);
+
+                result = true;
+            }
+            else{
+                this.setMessage("发送请求到业务平台失败!");
+            }
+        }
+        catch (Exception ex){
+            log.error(ex.getMessage(),ex);
+
+            result = false;
+            this.setMessage(ex.getMessage());
+        }
+
+        return result;
+    }
+}

+ 419 - 0
web/src/main/java/com/jpsoft/employment/modules/wechat/controller/WxController.java

@@ -0,0 +1,419 @@
+package com.jpsoft.employment.modules.wechat.controller;
+
+import cn.hutool.core.date.DateUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.TypeReference;
+import com.alipay.api.domain.CompanyInfo;
+import com.jpsoft.employment.config.WxConfig;
+import com.jpsoft.employment.modules.common.dto.MessageResult;
+import com.jpsoft.employment.modules.common.service.impl.RedisServiceImpl;
+import com.jpsoft.employment.modules.common.utils.Generator.CaptchaUtilA;
+import com.jpsoft.employment.modules.common.utils.Generator.CircleCaptchaA;
+import com.jpsoft.employment.modules.common.utils.SMSUtil;
+import com.jpsoft.employment.modules.common.utils.Sign;
+import com.jpsoft.employment.modules.common.utils.WeixinUtil;
+import com.jpsoft.employment.modules.job.entity.JobUser;
+import com.jpsoft.employment.modules.job.service.JobUserService;
+import com.jpsoft.employment.modules.pay.properties.WxPayProperties;
+import com.jpsoft.employment.modules.sys.entity.User;
+import com.jpsoft.employment.modules.sys.service.UserService;
+import com.jpsoft.employment.modules.wechat.callback.EventCallback;
+import com.jpsoft.employment.modules.wechat.entity.AccessToken;
+import com.jpsoft.employment.modules.wechat.vo.UserInfo;
+import com.sun.corba.se.impl.protocol.giopmsgheaders.ReplyMessage;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.ValueOperations;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * @author 墨鱼_mo
+ * @date 2019-12-3 15:08
+ */
+
+@Slf4j
+@RequestMapping("/wechat")
+@RestController
+public class WxController {
+
+
+    @Autowired
+    private WxConfig wxConfig;
+
+
+    @Autowired
+    private ValueOperations<String, Object> valueOperations;
+
+    @Autowired
+    private RedisServiceImpl redisService;
+
+    @Autowired
+    private WxPayProperties wxPayProperties;
+
+    @Autowired
+    private JobUserService jobUserService;
+
+    @Autowired
+    private UserService userService;
+
+    @ApiOperation(value = "获取微信配置")
+    @GetMapping(value = "/getConfig")
+    public MessageResult getConfig(String url) {
+
+        int code = 200;
+        String message = "获取成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+            AccessToken token = WeixinUtil.getAccessToken(wxPayProperties.getAppId(), wxPayProperties.getAppSecret());
+
+            Map<String, String> wxMap = Sign.sign(WeixinUtil.getJsAPI(token.getToken()), url);
+
+            wxMap.put("appId", wxPayProperties.getAppId());
+
+            log.warn(JSONObject.toJSONString(wxMap));
+
+            HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+            dataMap.put("wxConfig", wxMap);
+
+            data = dataMap;
+        } catch (Exception ex) {
+            log.error(ex.getMessage(),ex);
+
+            code = 500;
+            result = false;
+            message = "系统错误";
+        }
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @ApiOperation(value = "获取微信code")
+    @PostMapping(value = "findWechatUrl")
+    public MessageResult findWechatUrl(@RequestBody String url) {
+
+        String newpath = WeixinUtil.getCodeRequest(wxPayProperties.getAppId(), url, "snsapi_userinfo");
+
+        HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+        dataMap.put("wechatUrl", newpath);
+
+        return new MessageResult(true, "获取成功", dataMap, 200);
+    }
+
+    @ApiOperation(value = "获取公众号用户信息")
+    @GetMapping(value = "findUserInfo/{code}")
+    public MessageResult findUserInfo(@PathVariable String code) {
+        try {
+            log.warn("code=" + code);
+            log.warn("appId=" + wxPayProperties.getAppId());
+            log.warn("appSecret=" + wxPayProperties.getAppSecret());
+
+            AccessToken at = WeixinUtil.getAccessToken(wxPayProperties.getAppId(), wxPayProperties.getAppSecret(), code);
+
+
+            if (at != null && StringUtils.isNotBlank(at.getOpenid())) {
+                String openId = at.getOpenid();
+                System.out.println("openId:" + openId);
+
+                UserInfo userInfo = WeixinUtil.getUserInfo(openId, at.getToken());
+
+                HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+                dataMap.put("userInfo", userInfo);
+
+                return new MessageResult(true, "获取微信信息成功", userInfo, 200);
+
+            } else {
+                return new MessageResult(false, "获取微信信息失败", "", 400);
+            }
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            return new MessageResult(false, "系统错误", "", 500);
+        }
+    }
+
+    @GetMapping(value = "getAppId/{id}")
+    @ResponseBody
+    public MessageResult getAppId(@PathVariable("id") String id) {
+
+        int code = 200;
+        String message = "获取成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+
+            HashMap<String, Object> wxMap = new HashMap<>();
+
+            wxMap.put("appId", wxPayProperties.getAppId());
+
+            HashMap<String, Object> dataMap = new HashMap<String, Object>();
+
+            dataMap.put("wxConfig", wxMap);
+
+            data = dataMap;
+
+        } catch (Exception ex) {
+            code = 500;
+            message = "系统错误";
+            result = false;
+        }
+
+        return new MessageResult(result, message, data, code);
+    }
+
+    @ApiOperation(value = "获取图片验证码信息")
+    @GetMapping("/getVerifyPic")
+    public MessageResult getVerifyPic(String openId, HttpServletResponse response) {
+        int code = 200;
+        String message = "获取验证码成功";
+        Object data = "";
+        boolean result = true;
+
+        try {
+
+            if (StringUtils.isBlank(openId)) {
+                throw new Exception("openId为空");
+            }
+
+            CircleCaptchaA captcha = CaptchaUtilA.createCircleCaptcha(200, 100, 4, 0);
+            captcha.write(response.getOutputStream());
+            String verifyPic = captcha.getCode();
+            redisService.put("code", openId, verifyPic, 120);
+
+
+            response.getOutputStream().close();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            code = 500;
+            message = e.getMessage();
+            result = false;
+        }
+
+        return new MessageResult(result, message, data, code);
+    }
+
+
+    @ApiOperation(value = "管理员绑定微信openid")
+    @PostMapping(value = "/bindWechat")
+    public MessageResult<String> bindWechat(String eventKey,String openId){
+        MessageResult<String> messageResult = new MessageResult<>();
+
+        try{
+            String[] arr = eventKey.split(",");
+
+            String userId = arr[1];
+            User user = userService.get(userId);
+
+            if (user!=null) {
+                user.setOpenId(openId);
+                user.setUpdateTime(new Date());
+                user.setUpdateBy(userId);
+                userService.update(user);
+            }
+            else{
+                throw new Exception("用户不存在!");
+            }
+
+            messageResult.setMessage(user.getUserName() + "绑定微信成功!");
+            messageResult.setResult(true);
+        }
+        catch (Exception ex){
+            messageResult.setResult(false);
+            messageResult.setMessage(ex.getMessage());
+
+            log.error(ex.getMessage(),ex);
+        }
+
+        return messageResult;
+    }
+
+    @ApiOperation(value = "用户绑定微信openid")
+    @PostMapping(value = "/bindPersonWechat")
+    public MessageResult<String> bindPersonWechat(String eventKey,String openId){
+        MessageResult<String> messageResult = new MessageResult<>();
+
+        try{
+            String[] arr = eventKey.split(",");
+
+            String userId = arr[1];
+            String phone = arr[2];
+
+            JobUser jobUser = jobUserService.get(userId);
+
+            //多传一个电话号码避免,测试环境和正式环境混淆
+            if (jobUser!=null) {
+                if(jobUser.getTel().equals(phone)) {
+                    jobUser.setOpenId(openId);
+                    jobUser.setUpdateTime(new Date());
+                    jobUser.setUpdateBy(userId);
+                    jobUserService.update(jobUser);
+                }
+                else{
+                    throw new Exception("用户手机号错误!");
+                }
+            }
+            else{
+                throw new Exception("用户不存在!");
+            }
+
+            messageResult.setMessage(jobUser.getRealName() + "绑定微信成功!");
+            messageResult.setResult(true);
+        }
+        catch (Exception ex){
+            messageResult.setResult(false);
+            messageResult.setMessage(ex.getMessage());
+
+            log.error(ex.getMessage(),ex);
+        }
+
+        return messageResult;
+    }
+
+    @ApiOperation(value = "验证服务器地址的有效性")
+    @GetMapping("/get")
+    @ResponseBody
+    public String index(@RequestParam(defaultValue = "") String signature,
+                        @RequestParam(defaultValue = "") String timestamp,
+                        @RequestParam(defaultValue = "") String nonce,
+                        @RequestParam(defaultValue = "") String echostr) {
+        log.warn("signature=" + signature);
+        log.warn("timestamp=" + timestamp);
+        log.warn("nonce=" + nonce);
+        log.warn("echostr=" + echostr);
+
+        if (WeixinUtil.checkSignature(wxConfig.getToken(), signature, timestamp, nonce)) {
+            return echostr;
+        } else {
+            return "index";
+        }
+    }
+
+
+    @ResponseBody
+    @ApiOperation(value = "创建二维码")
+    @PostMapping("/qrcode/create")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "expire_seconds", paramType = "query", required = true, value = "该二维码有效时间,以秒为单位。 最大不超过2592000(即30天),此字段如果不填,则默认有效期为30秒。"),
+            @ApiImplicitParam(name = "action_name", paramType = "query", required = true, value = "二维码类型,QR_SCENE为临时的整型参数值,QR_STR_SCENE为临时的字符串参数值,QR_LIMIT_SCENE为永久的整型参数值,QR_LIMIT_STR_SCENE为永久的字符串参数值"),
+            @ApiImplicitParam(name = "scene_id", paramType = "query", value = "场景值ID,临时二维码时为32位非0整型,永久二维码时最大值为100000(目前参数只支持1--100000)"),
+            @ApiImplicitParam(name = "scene_str", paramType = "query", value = "场景值ID(字符串形式的ID),字符串类型,长度限制为1到64")
+    })
+    public cn.hutool.json.JSONObject createQrcode(@RequestParam(name = "expire_seconds", defaultValue = "300") long expireSeconds,
+                                                  @RequestParam(name = "action_name", defaultValue = "QR_STR_SCENE") String actionName,
+                                                  @RequestParam(name = "scene_id", required = false) String sceneId,
+                                                  @RequestParam(name = "scene_str", required = false) String sceneStr) {
+        cn.hutool.json.JSONObject resultObj = new cn.hutool.json.JSONObject();
+
+        try {
+            StringBuilder urlBuilder = new StringBuilder();
+            AccessToken accessToken = WeixinUtil.getAccessToken(wxConfig.getAppId(), wxConfig.getAppSecret());
+
+            urlBuilder.append(wxConfig.getCreateQrCodeUrl())
+                    .append("?access_token=")
+                    .append(URLEncoder.encode(accessToken.getToken(), "UTF-8"));
+
+            cn.hutool.json.JSONObject jsonObject = new cn.hutool.json.JSONObject();
+            jsonObject.put("expire_seconds", expireSeconds);
+            jsonObject.put("action_name", actionName);
+
+            cn.hutool.json.JSONObject actionInfo = new cn.hutool.json.JSONObject();
+            cn.hutool.json.JSONObject scene = new cn.hutool.json.JSONObject();
+
+            StringBuilder keyBuilder = new StringBuilder();
+
+            keyBuilder.append(accessToken);
+
+            if (StringUtils.isNotEmpty(sceneId)) {
+                scene.put("scene_id", sceneId);
+                keyBuilder.append(sceneId);
+            }
+
+            if (StringUtils.isNotEmpty(sceneStr)) {
+                scene.put("scene_str", sceneStr);
+                keyBuilder.append(sceneStr);
+            }
+
+            String qrcodeUrl = (String) valueOperations.get("QRCODE_" + keyBuilder.toString());
+
+            if (StringUtils.isNotEmpty(qrcodeUrl)) {
+                resultObj.put("data", qrcodeUrl);
+                resultObj.put("result", true);
+            } else {
+                actionInfo.put("scene", scene);
+
+                jsonObject.put("action_info", actionInfo);
+
+                StringEntity entity = new StringEntity(jsonObject.toString(), "utf-8");
+
+                entity.setContentType("application/json");//发送json数据需要设置contentType
+
+                HttpPost httpPost = new HttpPost(urlBuilder.toString());
+                CloseableHttpClient httpClient = HttpClientBuilder.create().build();
+
+                httpPost.setEntity(entity);
+
+                HttpResponse res = httpClient.execute(httpPost);
+
+                if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
+                    String content = EntityUtils.toString(res.getEntity());// 返回json格式:
+                    cn.hutool.json.JSONObject ret = new cn.hutool.json.JSONObject(content);
+
+                    if (ret.containsKey("errcode")) {
+                        resultObj.put("result", false);
+                        resultObj.put("message", ret.getStr("errmsg"));
+                        resultObj.put("code", ret.getInt("errcode"));
+                    } else {
+                        String ticket = ret.getStr("ticket");
+                        long expire_seconds = ret.getLong("expire_seconds");
+
+                        qrcodeUrl = wxConfig.getShowQrCodeUrl() + "?ticket=" + URLEncoder.encode(ticket, "UTF-8");
+
+                        valueOperations.set("QRCODE_" + keyBuilder, qrcodeUrl, expire_seconds - 5, TimeUnit.SECONDS);
+
+                        resultObj.put("data", qrcodeUrl);
+                        resultObj.put("result", true);
+                    }
+                } else {
+                    resultObj.put("result", false);
+                    resultObj.put("message", "weixin服务器未正常返回!");
+                }
+            }
+        } catch (Exception ex) {
+            log.error(ex.getMessage(), ex);
+
+            resultObj.put("message", ex.getMessage());
+            resultObj.put("result", false);
+        }
+
+        return resultObj;
+    }
+}