35 changed files with 3513 additions and 110 deletions
@ -0,0 +1,183 @@ |
|||||
|
package com.ccsens.tall.bean.po; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class SysWx implements Serializable { |
||||
|
private Long id; |
||||
|
|
||||
|
private Long userId; |
||||
|
|
||||
|
private String openId; |
||||
|
|
||||
|
private String unionId; |
||||
|
|
||||
|
private String nickname; |
||||
|
|
||||
|
private String headImgUrl; |
||||
|
|
||||
|
private Byte sex; |
||||
|
|
||||
|
private String province; |
||||
|
|
||||
|
private String city; |
||||
|
|
||||
|
private String country; |
||||
|
|
||||
|
private String language; |
||||
|
|
||||
|
private String privilege; |
||||
|
|
||||
|
private Date createdAt; |
||||
|
|
||||
|
private Date updatedAt; |
||||
|
|
||||
|
private Byte recStatus; |
||||
|
|
||||
|
private static final long serialVersionUID = 1L; |
||||
|
|
||||
|
public Long getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(Long id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public Long getUserId() { |
||||
|
return userId; |
||||
|
} |
||||
|
|
||||
|
public void setUserId(Long userId) { |
||||
|
this.userId = userId; |
||||
|
} |
||||
|
|
||||
|
public String getOpenId() { |
||||
|
return openId; |
||||
|
} |
||||
|
|
||||
|
public void setOpenId(String openId) { |
||||
|
this.openId = openId == null ? null : openId.trim(); |
||||
|
} |
||||
|
|
||||
|
public String getUnionId() { |
||||
|
return unionId; |
||||
|
} |
||||
|
|
||||
|
public void setUnionId(String unionId) { |
||||
|
this.unionId = unionId == null ? null : unionId.trim(); |
||||
|
} |
||||
|
|
||||
|
public String getNickname() { |
||||
|
return nickname; |
||||
|
} |
||||
|
|
||||
|
public void setNickname(String nickname) { |
||||
|
this.nickname = nickname == null ? null : nickname.trim(); |
||||
|
} |
||||
|
|
||||
|
public String getHeadImgUrl() { |
||||
|
return headImgUrl; |
||||
|
} |
||||
|
|
||||
|
public void setHeadImgUrl(String headImgUrl) { |
||||
|
this.headImgUrl = headImgUrl == null ? null : headImgUrl.trim(); |
||||
|
} |
||||
|
|
||||
|
public Byte getSex() { |
||||
|
return sex; |
||||
|
} |
||||
|
|
||||
|
public void setSex(Byte sex) { |
||||
|
this.sex = sex; |
||||
|
} |
||||
|
|
||||
|
public String getProvince() { |
||||
|
return province; |
||||
|
} |
||||
|
|
||||
|
public void setProvince(String province) { |
||||
|
this.province = province == null ? null : province.trim(); |
||||
|
} |
||||
|
|
||||
|
public String getCity() { |
||||
|
return city; |
||||
|
} |
||||
|
|
||||
|
public void setCity(String city) { |
||||
|
this.city = city == null ? null : city.trim(); |
||||
|
} |
||||
|
|
||||
|
public String getCountry() { |
||||
|
return country; |
||||
|
} |
||||
|
|
||||
|
public void setCountry(String country) { |
||||
|
this.country = country == null ? null : country.trim(); |
||||
|
} |
||||
|
|
||||
|
public String getLanguage() { |
||||
|
return language; |
||||
|
} |
||||
|
|
||||
|
public void setLanguage(String language) { |
||||
|
this.language = language == null ? null : language.trim(); |
||||
|
} |
||||
|
|
||||
|
public String getPrivilege() { |
||||
|
return privilege; |
||||
|
} |
||||
|
|
||||
|
public void setPrivilege(String privilege) { |
||||
|
this.privilege = privilege == null ? null : privilege.trim(); |
||||
|
} |
||||
|
|
||||
|
public Date getCreatedAt() { |
||||
|
return createdAt; |
||||
|
} |
||||
|
|
||||
|
public void setCreatedAt(Date createdAt) { |
||||
|
this.createdAt = createdAt; |
||||
|
} |
||||
|
|
||||
|
public Date getUpdatedAt() { |
||||
|
return updatedAt; |
||||
|
} |
||||
|
|
||||
|
public void setUpdatedAt(Date updatedAt) { |
||||
|
this.updatedAt = updatedAt; |
||||
|
} |
||||
|
|
||||
|
public Byte getRecStatus() { |
||||
|
return recStatus; |
||||
|
} |
||||
|
|
||||
|
public void setRecStatus(Byte recStatus) { |
||||
|
this.recStatus = recStatus; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String toString() { |
||||
|
StringBuilder sb = new StringBuilder(); |
||||
|
sb.append(getClass().getSimpleName()); |
||||
|
sb.append(" ["); |
||||
|
sb.append("Hash = ").append(hashCode()); |
||||
|
sb.append(", id=").append(id); |
||||
|
sb.append(", userId=").append(userId); |
||||
|
sb.append(", openId=").append(openId); |
||||
|
sb.append(", unionId=").append(unionId); |
||||
|
sb.append(", nickname=").append(nickname); |
||||
|
sb.append(", headImgUrl=").append(headImgUrl); |
||||
|
sb.append(", sex=").append(sex); |
||||
|
sb.append(", province=").append(province); |
||||
|
sb.append(", city=").append(city); |
||||
|
sb.append(", country=").append(country); |
||||
|
sb.append(", language=").append(language); |
||||
|
sb.append(", privilege=").append(privilege); |
||||
|
sb.append(", createdAt=").append(createdAt); |
||||
|
sb.append(", updatedAt=").append(updatedAt); |
||||
|
sb.append(", recStatus=").append(recStatus); |
||||
|
sb.append("]"); |
||||
|
return sb.toString(); |
||||
|
} |
||||
|
} |
||||
File diff suppressed because it is too large
@ -0,0 +1,9 @@ |
|||||
|
package com.ccsens.tall.persist.dao; |
||||
|
|
||||
|
import com.ccsens.tall.persist.mapper.SysWxMapper; |
||||
|
import org.springframework.stereotype.Repository; |
||||
|
|
||||
|
@Repository |
||||
|
public interface SysWxDao extends SysWxMapper { |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
package com.ccsens.tall.persist.mapper; |
||||
|
|
||||
|
import com.ccsens.tall.bean.po.SysWx; |
||||
|
import com.ccsens.tall.bean.po.SysWxExample; |
||||
|
import java.util.List; |
||||
|
import org.apache.ibatis.annotations.Param; |
||||
|
|
||||
|
public interface SysWxMapper { |
||||
|
long countByExample(SysWxExample example); |
||||
|
|
||||
|
int deleteByExample(SysWxExample example); |
||||
|
|
||||
|
int deleteByPrimaryKey(Long id); |
||||
|
|
||||
|
int insert(SysWx record); |
||||
|
|
||||
|
int insertSelective(SysWx record); |
||||
|
|
||||
|
List<SysWx> selectByExample(SysWxExample example); |
||||
|
|
||||
|
SysWx selectByPrimaryKey(Long id); |
||||
|
|
||||
|
int updateByExampleSelective(@Param("record") SysWx record, @Param("example") SysWxExample example); |
||||
|
|
||||
|
int updateByExample(@Param("record") SysWx record, @Param("example") SysWxExample example); |
||||
|
|
||||
|
int updateByPrimaryKeySelective(SysWx record); |
||||
|
|
||||
|
int updateByPrimaryKey(SysWx record); |
||||
|
} |
||||
@ -0,0 +1,370 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> |
||||
|
<mapper namespace="com.ccsens.tall.persist.mapper.SysWxMapper"> |
||||
|
<resultMap id="BaseResultMap" type="com.ccsens.tall.bean.po.SysWx"> |
||||
|
<id column="id" jdbcType="BIGINT" property="id" /> |
||||
|
<result column="user_id" jdbcType="BIGINT" property="userId" /> |
||||
|
<result column="open_id" jdbcType="VARCHAR" property="openId" /> |
||||
|
<result column="union_id" jdbcType="VARCHAR" property="unionId" /> |
||||
|
<result column="nickname" jdbcType="VARCHAR" property="nickname" /> |
||||
|
<result column="head_img_url" jdbcType="VARCHAR" property="headImgUrl" /> |
||||
|
<result column="sex" jdbcType="TINYINT" property="sex" /> |
||||
|
<result column="province" jdbcType="VARCHAR" property="province" /> |
||||
|
<result column="city" jdbcType="VARCHAR" property="city" /> |
||||
|
<result column="country" jdbcType="VARCHAR" property="country" /> |
||||
|
<result column="language" jdbcType="VARCHAR" property="language" /> |
||||
|
<result column="privilege" jdbcType="VARCHAR" property="privilege" /> |
||||
|
<result column="created_at" jdbcType="TIMESTAMP" property="createdAt" /> |
||||
|
<result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" /> |
||||
|
<result column="rec_status" jdbcType="TINYINT" property="recStatus" /> |
||||
|
</resultMap> |
||||
|
<sql id="Example_Where_Clause"> |
||||
|
<where> |
||||
|
<foreach collection="oredCriteria" item="criteria" separator="or"> |
||||
|
<if test="criteria.valid"> |
||||
|
<trim prefix="(" prefixOverrides="and" suffix=")"> |
||||
|
<foreach collection="criteria.criteria" item="criterion"> |
||||
|
<choose> |
||||
|
<when test="criterion.noValue"> |
||||
|
and ${criterion.condition} |
||||
|
</when> |
||||
|
<when test="criterion.singleValue"> |
||||
|
and ${criterion.condition} #{criterion.value} |
||||
|
</when> |
||||
|
<when test="criterion.betweenValue"> |
||||
|
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} |
||||
|
</when> |
||||
|
<when test="criterion.listValue"> |
||||
|
and ${criterion.condition} |
||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=","> |
||||
|
#{listItem} |
||||
|
</foreach> |
||||
|
</when> |
||||
|
</choose> |
||||
|
</foreach> |
||||
|
</trim> |
||||
|
</if> |
||||
|
</foreach> |
||||
|
</where> |
||||
|
</sql> |
||||
|
<sql id="Update_By_Example_Where_Clause"> |
||||
|
<where> |
||||
|
<foreach collection="example.oredCriteria" item="criteria" separator="or"> |
||||
|
<if test="criteria.valid"> |
||||
|
<trim prefix="(" prefixOverrides="and" suffix=")"> |
||||
|
<foreach collection="criteria.criteria" item="criterion"> |
||||
|
<choose> |
||||
|
<when test="criterion.noValue"> |
||||
|
and ${criterion.condition} |
||||
|
</when> |
||||
|
<when test="criterion.singleValue"> |
||||
|
and ${criterion.condition} #{criterion.value} |
||||
|
</when> |
||||
|
<when test="criterion.betweenValue"> |
||||
|
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} |
||||
|
</when> |
||||
|
<when test="criterion.listValue"> |
||||
|
and ${criterion.condition} |
||||
|
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=","> |
||||
|
#{listItem} |
||||
|
</foreach> |
||||
|
</when> |
||||
|
</choose> |
||||
|
</foreach> |
||||
|
</trim> |
||||
|
</if> |
||||
|
</foreach> |
||||
|
</where> |
||||
|
</sql> |
||||
|
<sql id="Base_Column_List"> |
||||
|
id, user_id, open_id, union_id, nickname, head_img_url, sex, province, city, country, |
||||
|
language, privilege, created_at, updated_at, rec_status |
||||
|
</sql> |
||||
|
<select id="selectByExample" parameterType="com.ccsens.tall.bean.po.SysWxExample" resultMap="BaseResultMap"> |
||||
|
select |
||||
|
<if test="distinct"> |
||||
|
distinct |
||||
|
</if> |
||||
|
<include refid="Base_Column_List" /> |
||||
|
from t_sys_wx |
||||
|
<if test="_parameter != null"> |
||||
|
<include refid="Example_Where_Clause" /> |
||||
|
</if> |
||||
|
<if test="orderByClause != null"> |
||||
|
order by ${orderByClause} |
||||
|
</if> |
||||
|
</select> |
||||
|
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"> |
||||
|
select |
||||
|
<include refid="Base_Column_List" /> |
||||
|
from t_sys_wx |
||||
|
where id = #{id,jdbcType=BIGINT} |
||||
|
</select> |
||||
|
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long"> |
||||
|
delete from t_sys_wx |
||||
|
where id = #{id,jdbcType=BIGINT} |
||||
|
</delete> |
||||
|
<delete id="deleteByExample" parameterType="com.ccsens.tall.bean.po.SysWxExample"> |
||||
|
delete from t_sys_wx |
||||
|
<if test="_parameter != null"> |
||||
|
<include refid="Example_Where_Clause" /> |
||||
|
</if> |
||||
|
</delete> |
||||
|
<insert id="insert" parameterType="com.ccsens.tall.bean.po.SysWx"> |
||||
|
insert into t_sys_wx (id, user_id, open_id, |
||||
|
union_id, nickname, head_img_url, |
||||
|
sex, province, city, |
||||
|
country, language, privilege, |
||||
|
created_at, updated_at, rec_status |
||||
|
) |
||||
|
values (#{id,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{openId,jdbcType=VARCHAR}, |
||||
|
#{unionId,jdbcType=VARCHAR}, #{nickname,jdbcType=VARCHAR}, #{headImgUrl,jdbcType=VARCHAR}, |
||||
|
#{sex,jdbcType=TINYINT}, #{province,jdbcType=VARCHAR}, #{city,jdbcType=VARCHAR}, |
||||
|
#{country,jdbcType=VARCHAR}, #{language,jdbcType=VARCHAR}, #{privilege,jdbcType=VARCHAR}, |
||||
|
#{createdAt,jdbcType=TIMESTAMP}, #{updatedAt,jdbcType=TIMESTAMP}, #{recStatus,jdbcType=TINYINT} |
||||
|
) |
||||
|
</insert> |
||||
|
<insert id="insertSelective" parameterType="com.ccsens.tall.bean.po.SysWx"> |
||||
|
insert into t_sys_wx |
||||
|
<trim prefix="(" suffix=")" suffixOverrides=","> |
||||
|
<if test="id != null"> |
||||
|
id, |
||||
|
</if> |
||||
|
<if test="userId != null"> |
||||
|
user_id, |
||||
|
</if> |
||||
|
<if test="openId != null"> |
||||
|
open_id, |
||||
|
</if> |
||||
|
<if test="unionId != null"> |
||||
|
union_id, |
||||
|
</if> |
||||
|
<if test="nickname != null"> |
||||
|
nickname, |
||||
|
</if> |
||||
|
<if test="headImgUrl != null"> |
||||
|
head_img_url, |
||||
|
</if> |
||||
|
<if test="sex != null"> |
||||
|
sex, |
||||
|
</if> |
||||
|
<if test="province != null"> |
||||
|
province, |
||||
|
</if> |
||||
|
<if test="city != null"> |
||||
|
city, |
||||
|
</if> |
||||
|
<if test="country != null"> |
||||
|
country, |
||||
|
</if> |
||||
|
<if test="language != null"> |
||||
|
language, |
||||
|
</if> |
||||
|
<if test="privilege != null"> |
||||
|
privilege, |
||||
|
</if> |
||||
|
<if test="createdAt != null"> |
||||
|
created_at, |
||||
|
</if> |
||||
|
<if test="updatedAt != null"> |
||||
|
updated_at, |
||||
|
</if> |
||||
|
<if test="recStatus != null"> |
||||
|
rec_status, |
||||
|
</if> |
||||
|
</trim> |
||||
|
<trim prefix="values (" suffix=")" suffixOverrides=","> |
||||
|
<if test="id != null"> |
||||
|
#{id,jdbcType=BIGINT}, |
||||
|
</if> |
||||
|
<if test="userId != null"> |
||||
|
#{userId,jdbcType=BIGINT}, |
||||
|
</if> |
||||
|
<if test="openId != null"> |
||||
|
#{openId,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="unionId != null"> |
||||
|
#{unionId,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="nickname != null"> |
||||
|
#{nickname,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="headImgUrl != null"> |
||||
|
#{headImgUrl,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="sex != null"> |
||||
|
#{sex,jdbcType=TINYINT}, |
||||
|
</if> |
||||
|
<if test="province != null"> |
||||
|
#{province,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="city != null"> |
||||
|
#{city,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="country != null"> |
||||
|
#{country,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="language != null"> |
||||
|
#{language,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="privilege != null"> |
||||
|
#{privilege,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="createdAt != null"> |
||||
|
#{createdAt,jdbcType=TIMESTAMP}, |
||||
|
</if> |
||||
|
<if test="updatedAt != null"> |
||||
|
#{updatedAt,jdbcType=TIMESTAMP}, |
||||
|
</if> |
||||
|
<if test="recStatus != null"> |
||||
|
#{recStatus,jdbcType=TINYINT}, |
||||
|
</if> |
||||
|
</trim> |
||||
|
</insert> |
||||
|
<select id="countByExample" parameterType="com.ccsens.tall.bean.po.SysWxExample" resultType="java.lang.Long"> |
||||
|
select count(*) from t_sys_wx |
||||
|
<if test="_parameter != null"> |
||||
|
<include refid="Example_Where_Clause" /> |
||||
|
</if> |
||||
|
</select> |
||||
|
<update id="updateByExampleSelective" parameterType="map"> |
||||
|
update t_sys_wx |
||||
|
<set> |
||||
|
<if test="record.id != null"> |
||||
|
id = #{record.id,jdbcType=BIGINT}, |
||||
|
</if> |
||||
|
<if test="record.userId != null"> |
||||
|
user_id = #{record.userId,jdbcType=BIGINT}, |
||||
|
</if> |
||||
|
<if test="record.openId != null"> |
||||
|
open_id = #{record.openId,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.unionId != null"> |
||||
|
union_id = #{record.unionId,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.nickname != null"> |
||||
|
nickname = #{record.nickname,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.headImgUrl != null"> |
||||
|
head_img_url = #{record.headImgUrl,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.sex != null"> |
||||
|
sex = #{record.sex,jdbcType=TINYINT}, |
||||
|
</if> |
||||
|
<if test="record.province != null"> |
||||
|
province = #{record.province,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.city != null"> |
||||
|
city = #{record.city,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.country != null"> |
||||
|
country = #{record.country,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.language != null"> |
||||
|
language = #{record.language,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.privilege != null"> |
||||
|
privilege = #{record.privilege,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="record.createdAt != null"> |
||||
|
created_at = #{record.createdAt,jdbcType=TIMESTAMP}, |
||||
|
</if> |
||||
|
<if test="record.updatedAt != null"> |
||||
|
updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}, |
||||
|
</if> |
||||
|
<if test="record.recStatus != null"> |
||||
|
rec_status = #{record.recStatus,jdbcType=TINYINT}, |
||||
|
</if> |
||||
|
</set> |
||||
|
<if test="_parameter != null"> |
||||
|
<include refid="Update_By_Example_Where_Clause" /> |
||||
|
</if> |
||||
|
</update> |
||||
|
<update id="updateByExample" parameterType="map"> |
||||
|
update t_sys_wx |
||||
|
set id = #{record.id,jdbcType=BIGINT}, |
||||
|
user_id = #{record.userId,jdbcType=BIGINT}, |
||||
|
open_id = #{record.openId,jdbcType=VARCHAR}, |
||||
|
union_id = #{record.unionId,jdbcType=VARCHAR}, |
||||
|
nickname = #{record.nickname,jdbcType=VARCHAR}, |
||||
|
head_img_url = #{record.headImgUrl,jdbcType=VARCHAR}, |
||||
|
sex = #{record.sex,jdbcType=TINYINT}, |
||||
|
province = #{record.province,jdbcType=VARCHAR}, |
||||
|
city = #{record.city,jdbcType=VARCHAR}, |
||||
|
country = #{record.country,jdbcType=VARCHAR}, |
||||
|
language = #{record.language,jdbcType=VARCHAR}, |
||||
|
privilege = #{record.privilege,jdbcType=VARCHAR}, |
||||
|
created_at = #{record.createdAt,jdbcType=TIMESTAMP}, |
||||
|
updated_at = #{record.updatedAt,jdbcType=TIMESTAMP}, |
||||
|
rec_status = #{record.recStatus,jdbcType=TINYINT} |
||||
|
<if test="_parameter != null"> |
||||
|
<include refid="Update_By_Example_Where_Clause" /> |
||||
|
</if> |
||||
|
</update> |
||||
|
<update id="updateByPrimaryKeySelective" parameterType="com.ccsens.tall.bean.po.SysWx"> |
||||
|
update t_sys_wx |
||||
|
<set> |
||||
|
<if test="userId != null"> |
||||
|
user_id = #{userId,jdbcType=BIGINT}, |
||||
|
</if> |
||||
|
<if test="openId != null"> |
||||
|
open_id = #{openId,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="unionId != null"> |
||||
|
union_id = #{unionId,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="nickname != null"> |
||||
|
nickname = #{nickname,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="headImgUrl != null"> |
||||
|
head_img_url = #{headImgUrl,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="sex != null"> |
||||
|
sex = #{sex,jdbcType=TINYINT}, |
||||
|
</if> |
||||
|
<if test="province != null"> |
||||
|
province = #{province,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="city != null"> |
||||
|
city = #{city,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="country != null"> |
||||
|
country = #{country,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="language != null"> |
||||
|
language = #{language,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="privilege != null"> |
||||
|
privilege = #{privilege,jdbcType=VARCHAR}, |
||||
|
</if> |
||||
|
<if test="createdAt != null"> |
||||
|
created_at = #{createdAt,jdbcType=TIMESTAMP}, |
||||
|
</if> |
||||
|
<if test="updatedAt != null"> |
||||
|
updated_at = #{updatedAt,jdbcType=TIMESTAMP}, |
||||
|
</if> |
||||
|
<if test="recStatus != null"> |
||||
|
rec_status = #{recStatus,jdbcType=TINYINT}, |
||||
|
</if> |
||||
|
</set> |
||||
|
where id = #{id,jdbcType=BIGINT} |
||||
|
</update> |
||||
|
<update id="updateByPrimaryKey" parameterType="com.ccsens.tall.bean.po.SysWx"> |
||||
|
update t_sys_wx |
||||
|
set user_id = #{userId,jdbcType=BIGINT}, |
||||
|
open_id = #{openId,jdbcType=VARCHAR}, |
||||
|
union_id = #{unionId,jdbcType=VARCHAR}, |
||||
|
nickname = #{nickname,jdbcType=VARCHAR}, |
||||
|
head_img_url = #{headImgUrl,jdbcType=VARCHAR}, |
||||
|
sex = #{sex,jdbcType=TINYINT}, |
||||
|
province = #{province,jdbcType=VARCHAR}, |
||||
|
city = #{city,jdbcType=VARCHAR}, |
||||
|
country = #{country,jdbcType=VARCHAR}, |
||||
|
language = #{language,jdbcType=VARCHAR}, |
||||
|
privilege = #{privilege,jdbcType=VARCHAR}, |
||||
|
created_at = #{createdAt,jdbcType=TIMESTAMP}, |
||||
|
updated_at = #{updatedAt,jdbcType=TIMESTAMP}, |
||||
|
rec_status = #{recStatus,jdbcType=TINYINT} |
||||
|
where id = #{id,jdbcType=BIGINT} |
||||
|
</update> |
||||
|
</mapper> |
||||
@ -0,0 +1,151 @@ |
|||||
|
package com.ccsens.util.bean.wx.dto; |
||||
|
|
||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; |
||||
|
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
@Data |
||||
|
@JacksonXmlRootElement(localName = "xml") |
||||
|
public class WxGzhAction { |
||||
|
@Data |
||||
|
private static class ScanCodeInfo{ |
||||
|
@JacksonXmlProperty(localName = "ScanType") |
||||
|
private String scanType; |
||||
|
@JacksonXmlProperty(localName = "ScanResult") |
||||
|
private String scanResult; |
||||
|
}; |
||||
|
|
||||
|
@Data |
||||
|
private static class SendPicsInfo{ |
||||
|
@Data |
||||
|
private static class Item{ |
||||
|
@JacksonXmlProperty(localName = "PicMd5Sum") |
||||
|
private String picMd5Sum; |
||||
|
} |
||||
|
@JacksonXmlProperty(localName = "Count") |
||||
|
private Integer count; |
||||
|
@JacksonXmlProperty(localName = "PicList") |
||||
|
private List<Item> picList; |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
private static class SendLocationInfo{ |
||||
|
@JacksonXmlProperty(localName = "Location_X") |
||||
|
private String x; |
||||
|
@JacksonXmlProperty(localName = "Location_Y") |
||||
|
private String y; |
||||
|
@JacksonXmlProperty(localName = "Scale") |
||||
|
private String scale; |
||||
|
@JacksonXmlProperty(localName = "Label") |
||||
|
private String label; |
||||
|
@JacksonXmlProperty(localName = "Poiname") |
||||
|
private String poiname; |
||||
|
} |
||||
|
|
||||
|
@JacksonXmlProperty(localName = "FromUserName") |
||||
|
private String openId; |
||||
|
@JacksonXmlProperty(localName = "ToUserName") |
||||
|
private String gzhId; |
||||
|
@JacksonXmlProperty(localName = "CreateTime") |
||||
|
private Long createTime; |
||||
|
@JacksonXmlProperty(localName = "MsgType") |
||||
|
private String msgType; |
||||
|
|
||||
|
/** |
||||
|
* MsgType: Text (Content,MsgId) |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "Content") |
||||
|
private String content; |
||||
|
@JacksonXmlProperty(localName = "MsgId") |
||||
|
private String msgId; |
||||
|
/** |
||||
|
* MsgType: image (PicUrl,MediaId,MsgId) |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "PicUrl") |
||||
|
private String picUrl; |
||||
|
@JacksonXmlProperty(localName = "MediaId") |
||||
|
private String mediaId; |
||||
|
/** |
||||
|
* MsgType: voice (MediaId,Format,MsgId) |
||||
|
* Recognition: 开通语音识别后生效 |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "Format") |
||||
|
private String format; |
||||
|
@JacksonXmlProperty(localName = "Recognition") |
||||
|
private String recognition; |
||||
|
|
||||
|
/** |
||||
|
* MsgType: video/shortvideo(MediaId,ThumbMediaId,MsgId) |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "ThumbMediaId") |
||||
|
private String thumbMediaId; |
||||
|
/** |
||||
|
* MsgType: location(Location_x,Location_y,Scale,Label,MsgId) |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "Location_X") |
||||
|
private String x; |
||||
|
@JacksonXmlProperty(localName = "Location_Y") |
||||
|
private String y; |
||||
|
@JacksonXmlProperty(localName = "Scale") |
||||
|
private String scale; |
||||
|
@JacksonXmlProperty(localName = "Label") |
||||
|
private String label; |
||||
|
/** |
||||
|
* MsgType: link(Title,Description,Url,MsgId) |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "Title") |
||||
|
private String title; |
||||
|
@JacksonXmlProperty(localName = "Description") |
||||
|
private String description; |
||||
|
@JacksonXmlProperty(localName = "Url") |
||||
|
private String url; |
||||
|
|
||||
|
/** |
||||
|
* MsgType: event |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "Event") |
||||
|
private String event; |
||||
|
@JacksonXmlProperty(localName = "EventKey") |
||||
|
private String eventKey; |
||||
|
|
||||
|
/** |
||||
|
* Event: subscribe/SCAN |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "Ticket") |
||||
|
private String ticket; |
||||
|
/** |
||||
|
* Event: Location |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "Latitude") |
||||
|
private String latitude; |
||||
|
@JacksonXmlProperty(localName = "Longitude") |
||||
|
private String longitude; |
||||
|
@JacksonXmlProperty(localName = "Precision") |
||||
|
private String precision; |
||||
|
|
||||
|
/** |
||||
|
* Event: VIEW/view_miniprogram |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "MenuId") |
||||
|
private String menuId; |
||||
|
/** |
||||
|
* Event: scancode_push/scancode_waitmsg |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "ScanCodeInfo") |
||||
|
private ScanCodeInfo scanCodeInfo; |
||||
|
/** |
||||
|
* Event: pic_sysphoto/pic_photo_or_album/pic_weixin |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "SendPicsInfo") |
||||
|
private SendPicsInfo sendPicsInfo; |
||||
|
/** |
||||
|
* Event: location_select |
||||
|
*/ |
||||
|
@JacksonXmlProperty(localName = "SendLocationInfo") |
||||
|
private SendLocationInfo sendLocationInfo; |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
@Data |
||||
|
public class WxAccessToken extends WxBaseEntity{ |
||||
|
@JsonProperty("access_token") |
||||
|
private String accessToken; |
||||
|
@JsonProperty("expires_in") |
||||
|
private Long expiresIn; |
||||
|
@JsonIgnore |
||||
|
private Long createdAt; |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
@Data |
||||
|
public class WxBaseEntity { |
||||
|
private Integer errcode; |
||||
|
private String errmsg; |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
|
||||
|
public enum WxGzhAuthType { |
||||
|
//基本授权类型,静默,只能获取openId
|
||||
|
SNSAPI_BASE("snsapi_base"), |
||||
|
//信息授权类型,弹出提示框,可以获取openId,unionId,nickanme,city等用户信息
|
||||
|
SNSAPI_USERINFO("snsapi_userinfo"); |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
private String text; |
||||
|
|
||||
|
private WxGzhAuthType(String text){ |
||||
|
this.text = text; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,97 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import cn.hutool.core.collection.CollectionUtil; |
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import com.fasterxml.jackson.annotation.JsonValue; |
||||
|
import lombok.Builder; |
||||
|
import lombok.Data; |
||||
|
import lombok.Getter; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
@Data |
||||
|
public class WxGzhMenu { |
||||
|
public enum ButtonType{ |
||||
|
//点击推事件
|
||||
|
CLICK("click"), |
||||
|
//跳转URL
|
||||
|
VIEW("view"), |
||||
|
//小程序
|
||||
|
MINIPROGRAM("miniprogram"), |
||||
|
//扫码推事件
|
||||
|
SCANCODE_PUSH("scancode_push"), |
||||
|
//扫码推事件且弹出“消息接收中”提示框
|
||||
|
SCANCODE_WAITMSG("scancode_waitmsg"), |
||||
|
//弹出系统拍照发图
|
||||
|
PIC_SYSPHOTO("pic_sysphoto"), |
||||
|
//弹出拍照或者相册发图
|
||||
|
PIC_PHOTO_OR_ALBUM("pic_photo_or_album"), |
||||
|
//弹出微信相册发图器
|
||||
|
PIC_WEIXIN("pic_weixin"), |
||||
|
//弹出地理位置选择器
|
||||
|
LOCATION_SELECT("location_select"), |
||||
|
//下发消息(除文本消息)
|
||||
|
MEDIA_ID("media_id"), |
||||
|
//跳转图文消息URL
|
||||
|
VIEW_LIMITED("view_limited"); |
||||
|
|
||||
|
@JsonValue |
||||
|
private String text; |
||||
|
|
||||
|
ButtonType(String text){ |
||||
|
this.text = text; |
||||
|
} |
||||
|
} |
||||
|
@Builder(toBuilder = true) |
||||
|
@Getter |
||||
|
public static class Button{ |
||||
|
/** |
||||
|
* 必须 |
||||
|
*/ |
||||
|
private ButtonType type; |
||||
|
/** |
||||
|
* 必须 |
||||
|
*/ |
||||
|
private String name; |
||||
|
/** |
||||
|
* click等点击类型必须 |
||||
|
*/ |
||||
|
private String key; |
||||
|
/** |
||||
|
* view、miniprogram类型必须 |
||||
|
*/ |
||||
|
private String url; |
||||
|
/** |
||||
|
* media_id类型和view_limited类型必须 |
||||
|
*/ |
||||
|
@JsonProperty("media_id") |
||||
|
private String mediaId; |
||||
|
/** |
||||
|
* miniprogram类型必须 |
||||
|
*/ |
||||
|
private String appid; |
||||
|
private String pagepath; |
||||
|
/** |
||||
|
* optional |
||||
|
*/ |
||||
|
@JsonProperty("sub_button") |
||||
|
private List<Button> subButton; |
||||
|
} |
||||
|
@JsonProperty("button") |
||||
|
private List<Button> buttons; |
||||
|
|
||||
|
public static WxGzhMenu newInstance(){ |
||||
|
return new WxGzhMenu(); |
||||
|
} |
||||
|
|
||||
|
public WxGzhMenu add(Button button){ |
||||
|
if(buttons == null){ |
||||
|
buttons = CollectionUtil.newArrayList(); |
||||
|
} |
||||
|
buttons.add(button); |
||||
|
return this; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,53 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
public enum WxGzhMsgEvent { |
||||
|
/** |
||||
|
* 关注/取消关注事件 |
||||
|
*/ |
||||
|
SUBSCRIBE("subscribe"),UNSUBSCRIBE("unsubscribe"), |
||||
|
/** |
||||
|
* 扫描带参数(公众号)二维码事件 |
||||
|
* 未关注:产生Event: SUBSCRIBE EventKey: qrscene_xxx |
||||
|
* 已关注:产生Event: Scan EventKey: scene_value |
||||
|
*/ |
||||
|
SCAN("SCAN"), |
||||
|
/** |
||||
|
* 上报地理位置事件 |
||||
|
*/ |
||||
|
LOCATION("LOCATION"), |
||||
|
/** |
||||
|
* 自定义菜单事件 |
||||
|
*/ |
||||
|
//点击菜单拉取消息时的事件推送
|
||||
|
CLICK("CLICK"), |
||||
|
//点击菜单跳转链接时的事件推送
|
||||
|
VIEW("VIEW"), |
||||
|
//扫码推事件的事件推送
|
||||
|
SCANCODE_PUSH("scancode_push"), |
||||
|
//扫码推事件且弹出“消息接收中”提示框的事件推送
|
||||
|
SCANCODE_WAITMSG("scancode_waitmsg"), |
||||
|
//弹出系统拍照发图的事件推送
|
||||
|
PIC_SYSPHOTO("pic_sysphoto"), |
||||
|
//弹出拍照或者相册发图的事件推送
|
||||
|
PIC_PHOTO_OR_ALBUM("pic_photo_or_album"), |
||||
|
//弹出微信相册发图器的事件推送
|
||||
|
PIC_WEIXIN("pic_weixin"), |
||||
|
//弹出地理位置选择器的事件推送
|
||||
|
LOCATION_SELECT("location_select"), |
||||
|
//点击菜单跳转小程序的事件推送
|
||||
|
VIEW_MINIPROGRAM("view_miniprogram"); |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
private String text; |
||||
|
|
||||
|
private WxGzhMsgEvent(String text){ |
||||
|
this.text = text; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,34 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import lombok.Getter; |
||||
|
import lombok.Setter; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
public enum WxGzhMsgType { |
||||
|
/** |
||||
|
* 1.普通消息 |
||||
|
*/ |
||||
|
//1.1 文本消息
|
||||
|
TEXT("text"), |
||||
|
IMAGE("image"), |
||||
|
VOICE("voice"), |
||||
|
VIDEO("video"), |
||||
|
SHORTVIDEO("shortvideo"), |
||||
|
LOCATION("location"), |
||||
|
LINK("link"), |
||||
|
|
||||
|
/** |
||||
|
* 2.事件推送 |
||||
|
*/ |
||||
|
EVENT("event"); |
||||
|
|
||||
|
@Getter |
||||
|
@Setter |
||||
|
private String text; |
||||
|
|
||||
|
private WxGzhMsgType(String text){ |
||||
|
this.text = text; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonIgnore; |
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
@Data |
||||
|
public class WxOauth2AccessToken extends WxBaseEntity{ |
||||
|
@JsonProperty("access_token") |
||||
|
private String accessToken; |
||||
|
@JsonProperty("expires_in") |
||||
|
private int expiresIn; |
||||
|
@JsonProperty("refresh_token") |
||||
|
private String refreshToken; |
||||
|
@JsonProperty("openid") |
||||
|
private String openId; |
||||
|
@JsonProperty("scope") |
||||
|
private String scope; |
||||
|
@JsonProperty("unionid") |
||||
|
private String unionId; |
||||
|
@JsonIgnore |
||||
|
private Long createdAt; |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonProperty; |
||||
|
import lombok.Data; |
||||
|
|
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
@Data |
||||
|
public class WxOauth2UserInfo extends WxBaseEntity{ |
||||
|
@JsonProperty("openid") |
||||
|
private String openId; |
||||
|
|
||||
|
@JsonProperty("nickname") |
||||
|
private String nickname; |
||||
|
|
||||
|
@JsonProperty("sex") |
||||
|
private int sex; |
||||
|
|
||||
|
@JsonProperty("province") |
||||
|
private String province; |
||||
|
|
||||
|
@JsonProperty("city") |
||||
|
private String city; |
||||
|
|
||||
|
@JsonProperty("country") |
||||
|
private String country; |
||||
|
|
||||
|
@JsonProperty("headimgurl") |
||||
|
private String headImgUrl; |
||||
|
|
||||
|
@JsonProperty("privilege") |
||||
|
private List<String> privilegeList; |
||||
|
|
||||
|
@JsonProperty("unionid") |
||||
|
private String unionId; |
||||
|
|
||||
|
@JsonProperty("language") |
||||
|
private String language; |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
package com.ccsens.util.bean.wx.po; |
||||
|
|
||||
|
import com.fasterxml.jackson.annotation.JsonValue; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
|
||||
|
public enum WxOperation { |
||||
|
/** |
||||
|
* 创建公众号底部菜单 |
||||
|
*/ |
||||
|
CREATE_MENU("CreateMenu"); |
||||
|
|
||||
|
@JsonValue |
||||
|
private String text; |
||||
|
|
||||
|
WxOperation(String text){ |
||||
|
this.text = text; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
package com.ccsens.util.exception; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
public class BusinessException extends BaseException { |
||||
|
private String type = "BusinessError"; |
||||
|
|
||||
|
public BusinessException(){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public BusinessException(Integer errcode, String errmsg){ |
||||
|
super(errcode,errmsg); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
package com.ccsens.util.exception; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
@Data |
||||
|
public class WxException extends BaseException{ |
||||
|
private String type = "WxError"; |
||||
|
|
||||
|
public WxException(){ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public WxException(Integer errcode, String errmsg){ |
||||
|
super(errcode,errmsg); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,300 @@ |
|||||
|
package com.ccsens.util.wx; |
||||
|
|
||||
|
import cn.hutool.core.lang.Console; |
||||
|
import cn.hutool.core.util.StrUtil; |
||||
|
import cn.hutool.core.util.URLUtil; |
||||
|
import cn.hutool.http.HttpRequest; |
||||
|
|
||||
|
import com.ccsens.util.DateUtil; |
||||
|
import com.ccsens.util.JacksonUtil; |
||||
|
import com.ccsens.util.WebConstant; |
||||
|
import com.ccsens.util.bean.wx.po.*; |
||||
|
import com.ccsens.util.exception.BaseException; |
||||
|
import com.ccsens.util.exception.BusinessException; |
||||
|
import com.ccsens.util.exception.WxException; |
||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||
|
import org.slf4j.Logger; |
||||
|
import org.slf4j.LoggerFactory; |
||||
|
|
||||
|
import java.io.IOException; |
||||
|
import java.security.MessageDigest; |
||||
|
import java.util.Arrays; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
public class WxGzhUtil { |
||||
|
private static final Logger logger = LoggerFactory.getLogger(WxGzhUtil.class); |
||||
|
/** |
||||
|
* 全局唯一accessToken |
||||
|
*/ |
||||
|
private static WxAccessToken globalWxAccessToken; |
||||
|
/** |
||||
|
* accessToken 过期提前10分钟刷新 |
||||
|
*/ |
||||
|
private static final Integer ACCESS_TOKEN_RESERVED_SECONDS = 10 * 60; |
||||
|
|
||||
|
private static final String URL_LOGIN |
||||
|
= "https://api.weixin.qq.com/sns/jscode2session?appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=%4$s"; |
||||
|
private static final String URL_GET_ACCESS_TOKEN |
||||
|
= "https://api.weixin.qq.com/cgi-bin/token?grant_type=%1$s&appid=%2$s&secret=%3$s"; |
||||
|
private static final String URL_GET_WX_CODE_A |
||||
|
= "https://api.weixin.qq.com/wxa/getwxacode?access_token=%1$s"; |
||||
|
private static final String URL_GET_WX_CODE_B |
||||
|
= "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%1$s"; |
||||
|
private static final String URL_GET_WX_CODE_C |
||||
|
= "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%1$s"; |
||||
|
private static final String URL_PREPARE_PAY |
||||
|
= "https://api.mch.weixin.qq.com/pay/unifiedorder"; |
||||
|
private static final String URL_PAY_TO_USR_WX |
||||
|
= "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; |
||||
|
private static final String URL_PAY_TO_USR_BANK |
||||
|
= "https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank"; |
||||
|
private static final String URL_CREATE_MENU |
||||
|
= " https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%1$s"; |
||||
|
private static final String URL_QUERY_MENU |
||||
|
= "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=%1$s"; |
||||
|
private static final String GZH_AUTH_URL |
||||
|
= "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%1$s&redirect_uri=%2$s&response_type=code&scope=%3$s&state=STATE#wechat_redirect"; |
||||
|
private static final String URL_GET_OAUTH2_ACCESS_TOKEN |
||||
|
= "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%1$s&secret=%2$s&code=%3$s&grant_type=authorization_code"; |
||||
|
private static final String URL_GET_OAUTH2_USERINFO |
||||
|
= "https://api.weixin.qq.com/sns/userinfo?access_token=%1$s&openid=%2$s"; |
||||
|
private static final String APPID = "wx7af1bf1e14facf82"; |
||||
|
private static final String SECRET = "a6613fae11b497639c0224b820aaf6d9"; |
||||
|
|
||||
|
private static final String APPID_H5 = "wxd1842e073e0e6d91"; |
||||
|
private static final String SECRET_H5 = "96d69b79039caf92a2abafa999880cad"; |
||||
|
|
||||
|
private static final String TOKEN = "nNzkL9KkZUOIS8uU"; |
||||
|
private static final String ENCODING_AES_KEY = "MQEXG7grhRNsARbUzem6OwnGr2ZW9o5jsauNqaQWOuu"; |
||||
|
private static final String MCHID = ""; |
||||
|
private static final String KEY = ""; |
||||
|
|
||||
|
private static String appId(WebConstant.IDENTIFY_TYPE identifyType){ |
||||
|
switch (identifyType){ |
||||
|
case Wx_H5: |
||||
|
return APPID_H5; |
||||
|
case OAUTH2_Wx: |
||||
|
|
||||
|
default: |
||||
|
return APPID; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static String secret(WebConstant.IDENTIFY_TYPE identifyType){ |
||||
|
switch (identifyType){ |
||||
|
case Wx_H5: |
||||
|
return SECRET_H5; |
||||
|
case OAUTH2_Wx: |
||||
|
|
||||
|
default: |
||||
|
return SECRET; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 数组转字符串 |
||||
|
*/ |
||||
|
private static String arrayToString(String[] arr) { |
||||
|
StringBuilder bf = new StringBuilder(); |
||||
|
for (String s : arr) { |
||||
|
bf.append(s); |
||||
|
} |
||||
|
return bf.toString(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* sha1加密 |
||||
|
*/ |
||||
|
private static String sha1Encode(String sourceString) { |
||||
|
String resultString = null; |
||||
|
try { |
||||
|
MessageDigest md = MessageDigest.getInstance("SHA-1"); |
||||
|
resultString = byte2hexString(md.digest(sourceString.getBytes())); |
||||
|
} catch (Exception ex) { |
||||
|
ex.printStackTrace(); |
||||
|
} |
||||
|
return resultString; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 字节数组转字符串 |
||||
|
*/ |
||||
|
private static String byte2hexString(byte[] bytes) { |
||||
|
StringBuilder buf = new StringBuilder(bytes.length * 2); |
||||
|
for (byte aByte : bytes) { |
||||
|
if (((int) aByte & 0xff) < 0x10) { |
||||
|
buf.append("0"); |
||||
|
} |
||||
|
buf.append(Long.toString((int) aByte & 0xff, 16)); |
||||
|
} |
||||
|
return buf.toString().toUpperCase(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 公众号接入验证 |
||||
|
* @param signature signature |
||||
|
* @param timestamp timestamp |
||||
|
* @param nonce nonce |
||||
|
* @param echostr echostr |
||||
|
* @return true or false |
||||
|
*/ |
||||
|
public static boolean checkSignature(String signature,String timestamp,String nonce,String echostr){ |
||||
|
if(StrUtil.isEmpty(signature) || StrUtil.isEmpty(timestamp) || StrUtil.isEmpty(nonce) || StrUtil.isEmpty(echostr)){ |
||||
|
return false; |
||||
|
} |
||||
|
String[] tmpArr = { TOKEN, timestamp, nonce }; |
||||
|
Arrays.sort(tmpArr); |
||||
|
String sign = sha1Encode( arrayToString(tmpArr)); |
||||
|
Console.log("sign:{} , signature: {}",sign,signature); |
||||
|
if (sign.equalsIgnoreCase(signature)) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取Access_token |
||||
|
*/ |
||||
|
public static String getAccessToken() throws BaseException { |
||||
|
if(globalWxAccessToken == null || |
||||
|
globalWxAccessToken.getCreatedAt() + globalWxAccessToken.getExpiresIn() |
||||
|
>= DateUtil.currentSeconds() - ACCESS_TOKEN_RESERVED_SECONDS){ |
||||
|
WxAccessToken wxAccessToken = null; |
||||
|
String url = String.format(URL_GET_ACCESS_TOKEN,"client_credential",SECRET); |
||||
|
String response = HttpRequest.get(url).execute().body(); |
||||
|
Console.log("getAccessToken: {}",response); |
||||
|
try { |
||||
|
if(StrUtil.isEmpty(response) || null == (wxAccessToken = JacksonUtil.jsonToBean(response, WxAccessToken.class))) { |
||||
|
throw new BusinessException(-1,"the response of HttpRequest is empty."); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
throw new BusinessException(-1,e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
if(null != wxAccessToken.getErrcode()){ |
||||
|
throw new WxException(wxAccessToken.getErrcode(),wxAccessToken.getErrmsg()); |
||||
|
} |
||||
|
if (StrUtil.isEmpty(wxAccessToken.getAccessToken())) { |
||||
|
throw new BusinessException(-1,"can't find the access_token attribute."); |
||||
|
} |
||||
|
globalWxAccessToken = wxAccessToken; |
||||
|
globalWxAccessToken.setCreatedAt(DateUtil.currentSeconds()); |
||||
|
} |
||||
|
return globalWxAccessToken.getAccessToken(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询微信公众号底部菜单 |
||||
|
*/ |
||||
|
public static String queryMenu() throws BaseException { |
||||
|
String url = String.format(URL_QUERY_MENU,getAccessToken()); |
||||
|
String menuString = HttpRequest.get(url).execute().body(); |
||||
|
Console.log("url:{}, menuString: {}",url,menuString); |
||||
|
return menuString; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 创建微信公众号底部菜单 |
||||
|
*/ |
||||
|
public static void createMenu(WxGzhMenu gzhMenu) throws BaseException { |
||||
|
String url = String.format(URL_CREATE_MENU,getAccessToken()); |
||||
|
String menuString = null; |
||||
|
try { |
||||
|
menuString = JacksonUtil.beanToJson(gzhMenu); |
||||
|
Console.log(menuString); |
||||
|
} catch (JsonProcessingException e) { |
||||
|
e.printStackTrace(); |
||||
|
throw new BusinessException(-1,e.getMessage()); |
||||
|
} |
||||
|
String response = HttpRequest.post(url).body(menuString).execute().body(); |
||||
|
if(StrUtil.isEmpty(response)){ |
||||
|
throw new BusinessException(-1,"the response of HttpRequest is empty."); |
||||
|
} |
||||
|
Map<String,Object> map = null; |
||||
|
try { |
||||
|
map = JacksonUtil.jsonToMap(response); |
||||
|
} catch (IOException e) { |
||||
|
throw new BusinessException(-1,e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
Object errcode = map.get("errcode"); |
||||
|
if(errcode == null || ((Integer)errcode) != 0) { |
||||
|
throw new WxException((Integer)errcode,(String)map.get("errmsg")); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static String getAuthedUrl(String url, WxGzhAuthType wxGzhAuthType){ |
||||
|
return String.format(GZH_AUTH_URL,APPID, URLUtil.encode(url),wxGzhAuthType.getText()); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取网页授权凭证 |
||||
|
* @param code OAuth2授权码 |
||||
|
* @return WxOauth2AccessToken |
||||
|
*/ |
||||
|
public static WxOauth2AccessToken getOauth2AccessToken(WebConstant.IDENTIFY_TYPE identifyType,String code) throws BaseException { |
||||
|
WxOauth2AccessToken wxOauth2AccessToken = null; |
||||
|
String url = String.format(URL_GET_OAUTH2_ACCESS_TOKEN,appId(identifyType),secret(identifyType),code); |
||||
|
String response = HttpRequest.get(url).execute().body(); |
||||
|
Console.log("url: {}\nresponse: {}",url,response); |
||||
|
try { |
||||
|
if(StrUtil.isEmpty(response) || null == (wxOauth2AccessToken = JacksonUtil.jsonToBean(response,WxOauth2AccessToken.class))) { |
||||
|
throw new BusinessException(-1,"the response of HttpRequest is empty."); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
throw new BusinessException(-1,e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
if(null != wxOauth2AccessToken.getErrcode()){ |
||||
|
throw new WxException(wxOauth2AccessToken.getErrcode(),wxOauth2AccessToken.getErrmsg()); |
||||
|
} |
||||
|
if (StrUtil.isEmpty(wxOauth2AccessToken.getAccessToken())) { |
||||
|
throw new BusinessException(-1,"can't find the access_token attribute."); |
||||
|
} |
||||
|
wxOauth2AccessToken.setCreatedAt(DateUtil.currentSeconds()); |
||||
|
return wxOauth2AccessToken; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 通过网页授权获取用户信息 |
||||
|
* |
||||
|
* @param accessToken 网页授权接口调用凭证 |
||||
|
* @param openId 用户标识 |
||||
|
* @return SNSUserInfo |
||||
|
*/ |
||||
|
public static WxOauth2UserInfo getOauth2UserInfo(String accessToken, String openId) throws BaseException { |
||||
|
WxOauth2UserInfo wxOauth2UserInfo = null; |
||||
|
String url = String.format(URL_GET_OAUTH2_USERINFO,accessToken,openId); |
||||
|
String response = HttpRequest.get(url).execute().body(); |
||||
|
Console.log("url: {}\nresponse: {}",url,response); |
||||
|
try { |
||||
|
if(StrUtil.isEmpty(response) || null == (wxOauth2UserInfo = JacksonUtil.jsonToBean(response,WxOauth2UserInfo.class))) { |
||||
|
throw new BusinessException(-1,"the response of HttpRequest is empty."); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
throw new BusinessException(-1,e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
if(null != wxOauth2UserInfo.getErrcode()){ |
||||
|
throw new WxException(wxOauth2UserInfo.getErrcode(),wxOauth2UserInfo.getErrmsg()); |
||||
|
} |
||||
|
if (StrUtil.isEmpty(wxOauth2UserInfo.getOpenId())) { |
||||
|
throw new BusinessException(-1,"can't find the openid attribute."); |
||||
|
} |
||||
|
return wxOauth2UserInfo; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 通过网页授权code拉取用户信息,封装了getOauth2AccessToken和getOauth2UserInfo(accessToken,openId) |
||||
|
* @param code 网页授权码 |
||||
|
* @return WxOauth2UserInfo |
||||
|
* @throws BaseException 异常 |
||||
|
*/ |
||||
|
public static WxOauth2UserInfo getOauth2UserInfo(WebConstant.IDENTIFY_TYPE identifyType,String code) throws BaseException { |
||||
|
WxOauth2AccessToken wxOauth2AccessToken = getOauth2AccessToken(identifyType,code); |
||||
|
return getOauth2UserInfo(wxOauth2AccessToken.getAccessToken(),wxOauth2AccessToken.getOpenId()); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,406 @@ |
|||||
|
package com.ccsens.util.wx; |
||||
|
|
||||
|
import cn.hutool.core.util.ObjectUtil; |
||||
|
import cn.hutool.core.util.StrUtil; |
||||
|
import cn.hutool.http.HttpRequest; |
||||
|
|
||||
|
import com.ccsens.util.HttpsUtil; |
||||
|
import com.ccsens.util.JacksonUtil; |
||||
|
import com.ccsens.util.WebConstant; |
||||
|
import com.ccsens.util.exception.BusinessException; |
||||
|
import com.ccsens.util.exception.WxException; |
||||
|
import lombok.Data; |
||||
|
import org.apache.commons.codec.digest.DigestUtils; |
||||
|
|
||||
|
import java.io.ByteArrayInputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.io.UnsupportedEncodingException; |
||||
|
import java.net.ConnectException; |
||||
|
import java.util.*; |
||||
|
|
||||
|
@Data |
||||
|
class GetUserInfoException extends RuntimeException{ |
||||
|
private int code; |
||||
|
public GetUserInfoException(int code,String message){ |
||||
|
super(message); |
||||
|
this.code = code; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Data |
||||
|
class PayException extends RuntimeException{ |
||||
|
private int code; |
||||
|
public PayException(int code,String message){ |
||||
|
super(message); |
||||
|
this.code = code; |
||||
|
} |
||||
|
|
||||
|
public PayException(String message){ |
||||
|
super(message); |
||||
|
this.code = -1; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @author __zHangSan |
||||
|
*/ |
||||
|
public class WxXcxUtil { |
||||
|
|
||||
|
/** |
||||
|
* 被Jasckson使用的内部类 必须是static的 |
||||
|
*/ |
||||
|
public static class WechatUser { |
||||
|
public String openid; |
||||
|
public String session_key; |
||||
|
public String unionid; |
||||
|
public Integer errcode; |
||||
|
public String errmsg; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get wx code |
||||
|
*/ |
||||
|
public static class WechatCode{ |
||||
|
public String scene; |
||||
|
public String page; |
||||
|
public Integer width; |
||||
|
public Boolean auto_color; |
||||
|
public Boolean line_color; |
||||
|
public Boolean is_hyaline; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Prepare pay |
||||
|
*/ |
||||
|
public static class PreparePayBean{ |
||||
|
public String appid;//小程序ID
|
||||
|
public String mch_id;//商户号
|
||||
|
public String device_info;//设备号
|
||||
|
public String nonce_str;//随机字符串
|
||||
|
public String sign;//签名
|
||||
|
public String sign_type; //签名类型
|
||||
|
public String body;//商品描述
|
||||
|
public String detail;//商品详情
|
||||
|
public String attach;//附加数据
|
||||
|
public String out_trade_no;//商户订单号
|
||||
|
public String fee_type;//货币类型
|
||||
|
public Integer total_fee; //金额(分)
|
||||
|
public String spbill_create_ip;//终端IP
|
||||
|
public String time_start;//交易起始时间
|
||||
|
public String time_expire;//交易结束时间
|
||||
|
public String goods_tag;//商品标记
|
||||
|
public String notify_url;//通知地址
|
||||
|
public String trade_type;//交易类型
|
||||
|
public String product_id;//商品id
|
||||
|
public String limit_pay;//指定支付方式
|
||||
|
public String openid;//用户标识
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Prepare pay result |
||||
|
*/ |
||||
|
public static class PreparePayResultBean{ |
||||
|
public String return_code; |
||||
|
public String return_msg; |
||||
|
public String result_code; |
||||
|
public String prepay_id; |
||||
|
public String err_code; |
||||
|
public String err_code_des; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Prepare pay resign |
||||
|
*/ |
||||
|
public static class PreparePayReSignBean{ |
||||
|
public String nonceStr; |
||||
|
public String _package; |
||||
|
public long timeStamp; |
||||
|
public String paySign; |
||||
|
public String signType; |
||||
|
} |
||||
|
|
||||
|
private static final String URL_LOGIN |
||||
|
= "https://api.weixin.qq.com/sns/jscode2session?appid=%1$s&secret=%2$s&js_code=%3$s&grant_type=%4$s"; |
||||
|
private static final String URL_GET_ACCESS_TOKEN |
||||
|
= "https://api.weixin.qq.com/cgi-bin/token?grant_type=%1$s&appid=%2$s&secret=%3$s"; |
||||
|
private static final String URL_GET_WX_CODE_A |
||||
|
= "https://api.weixin.qq.com/wxa/getwxacode?access_token=%1$s"; |
||||
|
private static final String URL_GET_WX_CODE_B |
||||
|
= "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%1$s"; |
||||
|
private static final String URL_GET_WX_CODE_C |
||||
|
= "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=%1$s"; |
||||
|
private static final String URL_PREPARE_PAY |
||||
|
= "https://api.mch.weixin.qq.com/pay/unifiedorder"; |
||||
|
private static final String URL_PAY_TO_USR_WX |
||||
|
= "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; |
||||
|
private static final String URL_PAY_TO_USR_BANK |
||||
|
= "https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank"; |
||||
|
private static final String URL_CREATE_MENU |
||||
|
= " https://api.weixin.qq.com/cgi-bin/menu/create?access_token=%1$s"; |
||||
|
|
||||
|
private static final String appid = "wx7af1bf1e14facf82"; |
||||
|
private static final String secret = "a6613fae11b497639c0224b820aaf6d9"; |
||||
|
private static final String mchid = ""; |
||||
|
private static final String key = ""; |
||||
|
|
||||
|
/** |
||||
|
* 小程序登陆,根据code获取用户信息(openid,sessionKey,) |
||||
|
* @param code |
||||
|
* @return |
||||
|
* @throws ConnectException |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static WechatUser getUserInfo(String code) throws Exception { |
||||
|
WechatUser wechatUser = null; |
||||
|
String url = String.format(URL_LOGIN, appid, secret, code, "authorization_code"); |
||||
|
String response = HttpRequest.get(url).execute().body(); |
||||
|
try { |
||||
|
if(StrUtil.isEmpty(response) || null == (wechatUser = JacksonUtil.jsonToBean(response, WechatUser.class))) { |
||||
|
throw new BusinessException(-1,"the response of HttpRequest is empty."); |
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
throw new BusinessException(-1,e.getMessage()); |
||||
|
} |
||||
|
|
||||
|
if(null != wechatUser.errcode){ |
||||
|
throw new WxException(wechatUser.errcode, wechatUser.errmsg); |
||||
|
} |
||||
|
return wechatUser; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 获取小程序二维码/小程序码 |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static void getWxCode(String page,String scene,String path) throws Exception { |
||||
|
String url = String.format(URL_GET_WX_CODE_B, WxGzhUtil.getAccessToken()); |
||||
|
|
||||
|
WechatCode wechatCode = new WechatCode(); |
||||
|
wechatCode.page = page; |
||||
|
wechatCode.scene = scene; |
||||
|
|
||||
|
String postStr = JacksonUtil.beanToJson(wechatCode); |
||||
|
System.out.println(postStr); |
||||
|
|
||||
|
HttpsUtil.httpsRequest(url,"POST",postStr,path); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 统一下单 |
||||
|
*/ |
||||
|
public static PreparePayReSignBean preparePay(String openid,String out_trade_no,String body,int total_fee,String spbill_create_ip, |
||||
|
String notify_url) throws Exception { |
||||
|
PreparePayBean preparePayBean = new PreparePayBean(); |
||||
|
preparePayBean.appid = appid; |
||||
|
preparePayBean.mch_id = mchid; |
||||
|
preparePayBean.openid = openid; |
||||
|
preparePayBean.total_fee = total_fee; |
||||
|
preparePayBean.out_trade_no = out_trade_no; |
||||
|
//以utf-8编码放入paymentPo,微信支付要求字符编码统一采用UTF-8字符编码
|
||||
|
preparePayBean.body = new String(body.getBytes("ISO-8859-1"),"UTF-8"); |
||||
|
//preparePayBean.body = new String("小程序-充值");
|
||||
|
preparePayBean.spbill_create_ip = spbill_create_ip; |
||||
|
preparePayBean.notify_url = notify_url; |
||||
|
preparePayBean.trade_type = "JSAPI"; |
||||
|
preparePayBean.nonce_str = createNonceStr(); |
||||
|
|
||||
|
// 把请求参数打包成数组
|
||||
|
Map<String,Object> sParaTemp = new HashMap(); |
||||
|
sParaTemp.put("appid", preparePayBean.appid); |
||||
|
sParaTemp.put("mch_id", preparePayBean.mch_id); |
||||
|
sParaTemp.put("openid", preparePayBean.openid); |
||||
|
sParaTemp.put("total_fee",preparePayBean.total_fee + ""); |
||||
|
sParaTemp.put("out_trade_no", preparePayBean.out_trade_no); |
||||
|
sParaTemp.put("body", preparePayBean.body); |
||||
|
sParaTemp.put("spbill_create_ip", preparePayBean.spbill_create_ip); |
||||
|
sParaTemp.put("notify_url",preparePayBean.notify_url); |
||||
|
sParaTemp.put("trade_type", preparePayBean.trade_type); |
||||
|
sParaTemp.put("nonce_str", preparePayBean.nonce_str); |
||||
|
|
||||
|
preparePayBean.sign = createSign(sParaTemp); |
||||
|
|
||||
|
String reqrXml = JacksonUtil.beanToXml(preparePayBean,"xml"); |
||||
|
String respXml = HttpsUtil.httpsRequest(URL_PREPARE_PAY,"POST",reqrXml); |
||||
|
|
||||
|
System.out.println("---------------PreparePay Request Xml-----------------"); |
||||
|
System.out.println(reqrXml); |
||||
|
System.out.println("---------------PreparePay Response Xml-----------------"); |
||||
|
System.out.println(respXml); |
||||
|
System.out.println("---------------PreparePay end-----------------"); |
||||
|
|
||||
|
PreparePayResultBean resultBean = null; |
||||
|
PreparePayReSignBean reSignBean = new PreparePayReSignBean(); |
||||
|
resultBean = JacksonUtil.xmlToBean(new ByteArrayInputStream(respXml.getBytes()),PreparePayResultBean.class); |
||||
|
|
||||
|
if(ObjectUtil.isNull(resultBean)) { |
||||
|
throw new PayException("PreparePay 返回的resultBean为空"); |
||||
|
} |
||||
|
if(!StrUtil.isEmpty(resultBean.return_code) |
||||
|
&& !StrUtil.isEmpty(resultBean.result_code)){ |
||||
|
if(resultBean.result_code.equals("SUCCESS") && resultBean.return_code.equals(resultBean.result_code)){ |
||||
|
reSignBean.nonceStr = createNonceStr(); |
||||
|
reSignBean._package = "prepay_id="+resultBean.prepay_id; |
||||
|
reSignBean.timeStamp = System.currentTimeMillis() / 1000; |
||||
|
reSignBean.signType = "MD5"; |
||||
|
|
||||
|
// 把请求参数打包成数组
|
||||
|
sParaTemp = new HashMap(); |
||||
|
sParaTemp.put("appId", appid); |
||||
|
sParaTemp.put("package", reSignBean._package); |
||||
|
sParaTemp.put("nonceStr", reSignBean.nonceStr); |
||||
|
sParaTemp.put("signType", reSignBean.signType); |
||||
|
sParaTemp.put("timeStamp",reSignBean.timeStamp + ""); |
||||
|
|
||||
|
reSignBean.paySign = createSign(sParaTemp); |
||||
|
|
||||
|
return reSignBean; |
||||
|
}else{ |
||||
|
throw new PayException("[" + resultBean.err_code + "]" |
||||
|
+ resultBean.err_code_des); |
||||
|
} |
||||
|
}else { |
||||
|
throw new PayException(resultBean.return_msg); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Create Sign |
||||
|
* @param sParaTemp |
||||
|
* @return |
||||
|
*/ |
||||
|
public static String createSign(Map<String,Object> sParaTemp){ |
||||
|
// 除去数组中的空值和签名参数
|
||||
|
Map sPara = paraFilter(sParaTemp); |
||||
|
// 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
|
||||
|
String prestr = createLinkString(sPara); |
||||
|
//MD5运算生成签名
|
||||
|
String sign = sign(prestr, key, "utf-8").toUpperCase(); |
||||
|
return sign; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 除去数组中的空值和签名参数 |
||||
|
* @param sArray 签名参数组 |
||||
|
* @return 去掉空值与签名参数后的新签名参数组 |
||||
|
*/ |
||||
|
private static Map paraFilter(Map<String,Object> sArray) { |
||||
|
Map result = new HashMap(); |
||||
|
if (sArray == null || sArray.size() <= 0) { |
||||
|
return result; |
||||
|
} |
||||
|
for (String key : sArray.keySet()) { |
||||
|
String value = "" + sArray.get(key); |
||||
|
if (StrUtil.isEmpty(value) || key.equalsIgnoreCase("sign") || key.equalsIgnoreCase("sign_type")) { |
||||
|
continue; |
||||
|
} |
||||
|
result.put(key, value); |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 把数组所有元素排序,并按照“参数=参数值”的模式用“&”字符拼接成字符串 |
||||
|
* @param params 需要排序并参与字符拼接的参数组 |
||||
|
* @return 拼接后字符串 |
||||
|
*/ |
||||
|
private static String createLinkString(Map<String,String> params) { |
||||
|
List<String> keys = new ArrayList<String>(params.keySet()); |
||||
|
Collections.sort(keys); |
||||
|
StringBuilder prestr = new StringBuilder(); |
||||
|
for (int i = 0; i < keys.size(); i++) { |
||||
|
String key = keys.get(i); |
||||
|
String value = params.get(key); |
||||
|
if (i == keys.size() - 1) { |
||||
|
prestr.append(key).append("=").append(value); |
||||
|
} else { |
||||
|
prestr.append(key).append("=").append(value).append("&"); |
||||
|
} |
||||
|
} |
||||
|
return prestr.toString(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 签名字符串 |
||||
|
* @param text 需要签名的字符串 |
||||
|
* @param key 密钥 |
||||
|
* @param input_charset 编码格式 |
||||
|
* @return 签名结果 |
||||
|
*/ |
||||
|
private static String sign(String text, String key, String input_charset) { |
||||
|
text = text + "&key=" + key; |
||||
|
return DigestUtils.md5Hex(getContentBytes(text, input_charset)); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* getContentBytes |
||||
|
*/ |
||||
|
private static byte[] getContentBytes(String content, String charset) { |
||||
|
if (charset == null || "".equals(charset)) { |
||||
|
return content.getBytes(); |
||||
|
} |
||||
|
try { |
||||
|
return content.getBytes(charset); |
||||
|
} catch (UnsupportedEncodingException e) { |
||||
|
throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static String createNonceStr(){ |
||||
|
return UUID.randomUUID().toString().replace("-",""); |
||||
|
} |
||||
|
|
||||
|
public static Map<String,Object> payToUsrWx( |
||||
|
String partner_trade_no,String openid,int total_fee,String desc,String spbill_create_ip) |
||||
|
throws Exception{ |
||||
|
final String SUCCESS = "SUCCESS"; |
||||
|
//1.构造请求字符串
|
||||
|
Map<String,Object> reqMap = new HashMap<>(); |
||||
|
reqMap.put("mch_appid",appid); |
||||
|
reqMap.put("mchid",mchid); |
||||
|
//reqMap.put("device_info",null); //不能添加空字段,Jackson会生成闭包xml <device_info/>导致签名失败
|
||||
|
reqMap.put("nonce_str",createNonceStr()); |
||||
|
reqMap.put("partner_trade_no",partner_trade_no); |
||||
|
reqMap.put("openid",openid); |
||||
|
reqMap.put("check_name","NO_CHECK"); |
||||
|
//reqMap.put("re_user_name",null);
|
||||
|
reqMap.put("amount",total_fee + ""); |
||||
|
reqMap.put("desc",desc); |
||||
|
reqMap.put("spbill_create_ip",spbill_create_ip); |
||||
|
reqMap.put("sign",createSign(reqMap)); |
||||
|
|
||||
|
//2.发送付款请求
|
||||
|
String reqrXml = JacksonUtil.mapToXml(reqMap,"xml"); |
||||
|
String respXml = HttpsUtil.httpsRequest(URL_PAY_TO_USR_WX,"POST",reqrXml, |
||||
|
WebConstant.PATH_WX_CRET,mchid); |
||||
|
System.out.println("---------------PayToUsrWx Request Xml-----------------"); |
||||
|
System.out.println(reqrXml); |
||||
|
System.out.println("---------------PayToUsrWx Response Xml-----------------"); |
||||
|
System.out.println(respXml); |
||||
|
System.out.println("---------------PayToUsrWx end-----------------"); |
||||
|
|
||||
|
//3.判断成功失败
|
||||
|
Map<String,Object> respMap = JacksonUtil.xmlToMap(new ByteArrayInputStream(respXml.getBytes())); |
||||
|
String return_code,result_code; |
||||
|
return_code = (String)respMap.get("return_code"); |
||||
|
result_code = (String)respMap.get("result_code"); |
||||
|
|
||||
|
if(!StrUtil.isEmpty(return_code) && !StrUtil.isEmpty(result_code)){ |
||||
|
if(return_code.equals(SUCCESS) && return_code.equals(result_code)){ |
||||
|
return respMap; |
||||
|
}else{ |
||||
|
throw new PayException("[" + respMap.get("err_code") + "]" |
||||
|
+ respMap.get("err_code_des")); |
||||
|
} |
||||
|
}else { |
||||
|
throw new PayException((String) respMap.get("return_msg")); |
||||
|
} |
||||
|
//return null;
|
||||
|
} |
||||
|
|
||||
|
public static Map<String,String> payToUsrBank(){ |
||||
|
//Fix Me
|
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue