From c3506762f78b9426695d85fdabb4238e9c44b35c Mon Sep 17 00:00:00 2001
From: tgq <gqtan@fowind.com.cn>
Date: Tue, 14 Sep 2021 16:55:39 +0800
Subject: [PATCH] miniapp

---
 ruoyi-admin/pom.xml                           |  13 ++
 .../common/core/domain/model/LoginUser.java   |  23 +++-
 ruoyi-framework/pom.xml                       |   6 +
 .../framework/config/SecurityConfig.java      |   2 +-
 .../web/service/UserDetailsServiceImpl.java   |  25 ++++
 ruoyi-wxapi/pom.xml                           |  33 +++++
 .../java/com/ruoyi/wxapi/domain/WxApp.java    | 124 +++++++++++++++++
 .../com/ruoyi/wxapi/mapper/WxAppMapper.java   |  69 ++++++++++
 .../com/ruoyi/wxapi/mapper/WxUserMapper.java  |  69 ++++++++++
 .../ruoyi/wxapi/service/IWxAppService.java    |  71 ++++++++++
 .../ruoyi/wxapi/service/IWxUserService.java   |  69 ++++++++++
 .../wxapi/service/impl/WxAppServiceImpl.java  | 125 ++++++++++++++++++
 .../wxapi/service/impl/WxUserServiceImpl.java | 107 +++++++++++++++
 .../resources/mapper/wxapi/WxAppMapper.xml    | 101 ++++++++++++++
 .../resources/mapper/wxapi/WxUserMapper.xml   | 123 +++++++++++++++++
 15 files changed, 957 insertions(+), 3 deletions(-)
 create mode 100644 ruoyi-wxapi/pom.xml
 create mode 100644 ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/domain/WxApp.java
 create mode 100644 ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxAppMapper.java
 create mode 100644 ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxUserMapper.java
 create mode 100644 ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxAppService.java
 create mode 100644 ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxUserService.java
 create mode 100644 ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxAppServiceImpl.java
 create mode 100644 ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxUserServiceImpl.java
 create mode 100644 ruoyi-wxapi/src/main/resources/mapper/wxapi/WxAppMapper.xml
 create mode 100644 ruoyi-wxapi/src/main/resources/mapper/wxapi/WxUserMapper.xml

diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 1d1d687b4..72fe7535e 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -61,6 +61,19 @@
             <artifactId>ruoyi-generator</artifactId>
         </dependency>
 
+        <!-- wxJava -->
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-miniapp</artifactId>
+            <version>3.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-wxapi</artifactId>
+            <version>3.7.0</version>
+            <scope>compile</scope>
+        </dependency>
+
     </dependencies>
 
     <build>
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
index 7b1d8966a..8aa523b02 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/model/LoginUser.java
@@ -2,6 +2,8 @@ package com.ruoyi.common.core.domain.model;
 
 import java.util.Collection;
 import java.util.Set;
+
+import com.ruoyi.common.core.domain.entity.WxUser;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.userdetails.UserDetails;
 import com.fasterxml.jackson.annotation.JsonIgnore;
@@ -71,6 +73,11 @@ public class LoginUser implements UserDetails
      */
     private SysUser user;
 
+    /**
+     * 微信用户信息
+     */
+    private WxUser wxUser;
+
     public Long getUserId()
     {
         return userId;
@@ -119,17 +126,21 @@ public class LoginUser implements UserDetails
         this.permissions = permissions;
     }
 
+    public LoginUser(WxUser wxUser){
+        this.wxUser = wxUser;
+    }
+
     @JsonIgnore
     @Override
     public String getPassword()
     {
-        return user.getPassword();
+        return user!=null ? user.getPassword() : wxUser.getPassword();
     }
 
     @Override
     public String getUsername()
     {
-        return user.getUserName();
+        return user!=null ? user.getUserName() : wxUser.getOpenId();
     }
 
     /**
@@ -258,6 +269,14 @@ public class LoginUser implements UserDetails
         this.user = user;
     }
 
+    public WxUser getWxUser() {
+        return wxUser;
+    }
+
+    public void setWxUser(WxUser wxUser) {
+        this.wxUser = wxUser;
+    }
+
     @Override
     public Collection<? extends GrantedAuthority> getAuthorities()
     {
diff --git a/ruoyi-framework/pom.xml b/ruoyi-framework/pom.xml
index 0eea3ce11..c70ae3566 100644
--- a/ruoyi-framework/pom.xml
+++ b/ruoyi-framework/pom.xml
@@ -58,6 +58,12 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-system</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-wxapi</artifactId>
+            <version>3.7.0</version>
+            <scope>compile</scope>
+        </dependency>
 
     </dependencies>
 
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index bd3622901..9563b3ed8 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -97,7 +97,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/register", "/captchaImage").anonymous()
+                .antMatchers("/login", "/register", "/captchaImage", "/api/wx/login").anonymous()
                 .antMatchers(
                         HttpMethod.GET,
                         "/",
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
index 575bd8d80..93f2dab43 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/UserDetailsServiceImpl.java
@@ -1,5 +1,8 @@
 package com.ruoyi.framework.web.service;
 
+import com.ruoyi.common.core.domain.entity.WxUser;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.wxapi.service.IWxUserService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,9 +33,31 @@ public class UserDetailsServiceImpl implements UserDetailsService
     @Autowired
     private SysPermissionService permissionService;
 
+    @Autowired
+    private IWxUserService wxUserService;
+
     @Override
     public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
     {
+        if (StringUtils.isNotEmpty(username) && username.startsWith("wx_openid_")){
+            String openId = username.replace("wx_openid_", "");
+            WxUser wxUser = wxUserService.selectWxUserByOpenId(openId);
+            wxUser.setPassword(SecurityUtils.encryptPassword(wxUser.getOpenId()));
+            if (StringUtils.isNull(wxUser))
+            {
+                log.info("登录用户:{} 不存在.", openId);
+                throw new ServiceException("登录用户不存在");
+            }
+            else if ("3".equals(wxUser.getStatus()))
+            {
+                log.info("登录用户:{} 已被停用.", openId);
+                throw new ServiceException("对不起,您的账号已停用");
+            }
+
+            return new LoginUser(wxUser);
+        }
+
+
         SysUser user = userService.selectUserByUserName(username);
         if (StringUtils.isNull(user))
         {
diff --git a/ruoyi-wxapi/pom.xml b/ruoyi-wxapi/pom.xml
new file mode 100644
index 000000000..307c7c990
--- /dev/null
+++ b/ruoyi-wxapi/pom.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>ruoyi</artifactId>
+        <groupId>com.ruoyi</groupId>
+        <version>3.7.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-wxapi</artifactId>
+
+    <description>
+        wxapi系统模块
+    </description>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-miniapp</artifactId>
+            <version>3.8.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.ruoyi</groupId>
+            <artifactId>ruoyi-common</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file
diff --git a/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/domain/WxApp.java b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/domain/WxApp.java
new file mode 100644
index 000000000..37c43da31
--- /dev/null
+++ b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/domain/WxApp.java
@@ -0,0 +1,124 @@
+package com.ruoyi.wxapi.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 小程序设置对象 wx_app
+ * 
+ * @author tgq
+ * @date 2021-09-01
+ */
+public class WxApp extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** id */
+    private Long id;
+
+    /** 小程序代号 */
+    @Excel(name = "小程序代号")
+    private String appCode;
+
+    /** 小程序名称 */
+    @Excel(name = "小程序名称")
+    private String appName;
+
+    /** 小程序id */
+    @Excel(name = "小程序id")
+    private String appId;
+
+    /** 小程序secret */
+    private String secret;
+
+    /** 服务器域名 */
+    @Excel(name = "服务器域名")
+    private String apiDomain;
+
+    /** 状态(1:正常,2:停用) */
+    @Excel(name = "状态(1:正常,2:停用)")
+    private String status;
+
+    public void setId(Long id) 
+    {
+        this.id = id;
+    }
+
+    public Long getId() 
+    {
+        return id;
+    }
+    public void setAppCode(String appCode) 
+    {
+        this.appCode = appCode;
+    }
+
+    public String getAppCode() 
+    {
+        return appCode;
+    }
+    public void setAppName(String appName) 
+    {
+        this.appName = appName;
+    }
+
+    public String getAppName() 
+    {
+        return appName;
+    }
+    public void setAppId(String appId) 
+    {
+        this.appId = appId;
+    }
+
+    public String getAppId() 
+    {
+        return appId;
+    }
+    public void setSecret(String secret) 
+    {
+        this.secret = secret;
+    }
+
+    public String getSecret() 
+    {
+        return secret;
+    }
+    public void setApiDomain(String apiDomain) 
+    {
+        this.apiDomain = apiDomain;
+    }
+
+    public String getApiDomain() 
+    {
+        return apiDomain;
+    }
+    public void setStatus(String status) 
+    {
+        this.status = status;
+    }
+
+    public String getStatus() 
+    {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("id", getId())
+            .append("appCode", getAppCode())
+            .append("appName", getAppName())
+            .append("appId", getAppId())
+            .append("secret", getSecret())
+            .append("apiDomain", getApiDomain())
+            .append("status", getStatus())
+            .append("createBy", getCreateBy())
+            .append("createTime", getCreateTime())
+            .append("updateBy", getUpdateBy())
+            .append("updateTime", getUpdateTime())
+            .toString();
+    }
+}
diff --git a/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxAppMapper.java b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxAppMapper.java
new file mode 100644
index 000000000..345410616
--- /dev/null
+++ b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxAppMapper.java
@@ -0,0 +1,69 @@
+package com.ruoyi.wxapi.mapper;
+
+import java.util.List;
+import com.ruoyi.wxapi.domain.WxApp;
+
+/**
+ * 小程序设置Mapper接口
+ * 
+ * @author tgq
+ * @date 2021-09-01
+ */
+public interface WxAppMapper 
+{
+    /**
+     * 查询小程序设置
+     * 
+     * @param id 小程序设置主键
+     * @return 小程序设置
+     */
+    public WxApp selectWxAppById(Long id);
+
+    /**
+     * 查询小程序设置
+     *
+     * @param code 小程序code
+     * @return 小程序设置
+     */
+    public WxApp selectWxAppByCode(String code);
+
+    /**
+     * 查询小程序设置列表
+     * 
+     * @param wxApp 小程序设置
+     * @return 小程序设置集合
+     */
+    public List<WxApp> selectWxAppList(WxApp wxApp);
+
+    /**
+     * 新增小程序设置
+     * 
+     * @param wxApp 小程序设置
+     * @return 结果
+     */
+    public int insertWxApp(WxApp wxApp);
+
+    /**
+     * 修改小程序设置
+     * 
+     * @param wxApp 小程序设置
+     * @return 结果
+     */
+    public int updateWxApp(WxApp wxApp);
+
+    /**
+     * 删除小程序设置
+     * 
+     * @param id 小程序设置主键
+     * @return 结果
+     */
+    public int deleteWxAppById(Long id);
+
+    /**
+     * 批量删除小程序设置
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteWxAppByIds(Long[] ids);
+}
diff --git a/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxUserMapper.java b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxUserMapper.java
new file mode 100644
index 000000000..d2457f24f
--- /dev/null
+++ b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/mapper/WxUserMapper.java
@@ -0,0 +1,69 @@
+package com.ruoyi.wxapi.mapper;
+
+import java.util.List;
+import com.ruoyi.common.core.domain.entity.WxUser;
+
+/**
+ * 小程序用户Mapper接口
+ * 
+ * @author tgq
+ * @date 2021-09-01
+ */
+public interface WxUserMapper 
+{
+    /**
+     * 查询小程序用户
+     * 
+     * @param id 小程序用户主键
+     * @return 小程序用户
+     */
+    public WxUser selectWxUserById(Long id);
+
+    /**
+     * 查询小程序用户
+     *
+     * @param openId 小程序用户openId
+     * @return 小程序用户
+     */
+    public WxUser selectWxUserByOpenId(String openId);
+
+    /**
+     * 查询小程序用户列表
+     * 
+     * @param wxUser 小程序用户
+     * @return 小程序用户集合
+     */
+    public List<WxUser> selectWxUserList(WxUser wxUser);
+
+    /**
+     * 新增小程序用户
+     * 
+     * @param wxUser 小程序用户
+     * @return 结果
+     */
+    public int insertWxUser(WxUser wxUser);
+
+    /**
+     * 修改小程序用户
+     * 
+     * @param wxUser 小程序用户
+     * @return 结果
+     */
+    public int updateWxUser(WxUser wxUser);
+
+    /**
+     * 删除小程序用户
+     * 
+     * @param id 小程序用户主键
+     * @return 结果
+     */
+    public int deleteWxUserById(Long id);
+
+    /**
+     * 批量删除小程序用户
+     * 
+     * @param ids 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteWxUserByIds(Long[] ids);
+}
diff --git a/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxAppService.java b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxAppService.java
new file mode 100644
index 000000000..f82cff611
--- /dev/null
+++ b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxAppService.java
@@ -0,0 +1,71 @@
+package com.ruoyi.wxapi.service;
+
+import java.util.List;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import com.ruoyi.wxapi.domain.WxApp;
+
+/**
+ * 小程序设置Service接口
+ * 
+ * @author tgq
+ * @date 2021-09-01
+ */
+public interface IWxAppService 
+{
+    /**
+     * 查询小程序设置
+     * 
+     * @param id 小程序设置主键
+     * @return 小程序设置
+     */
+    public WxApp selectWxAppById(Long id);
+
+    /**
+     * 查询小程序设置列表
+     * 
+     * @param wxApp 小程序设置
+     * @return 小程序设置集合
+     */
+    public List<WxApp> selectWxAppList(WxApp wxApp);
+
+    /**
+     * 新增小程序设置
+     * 
+     * @param wxApp 小程序设置
+     * @return 结果
+     */
+    public int insertWxApp(WxApp wxApp);
+
+    /**
+     * 修改小程序设置
+     * 
+     * @param wxApp 小程序设置
+     * @return 结果
+     */
+    public int updateWxApp(WxApp wxApp);
+
+    /**
+     * 批量删除小程序设置
+     * 
+     * @param ids 需要删除的小程序设置主键集合
+     * @return 结果
+     */
+    public int deleteWxAppByIds(Long[] ids);
+
+    /**
+     * 删除小程序设置信息
+     * 
+     * @param id 小程序设置主键
+     * @return 结果
+     */
+    public int deleteWxAppById(Long id);
+
+    /**
+     * 获取微信小程序服务
+     *
+     * @param code 小程序code
+     * @return 结果
+     */
+    public WxMaService getMaService(String code);
+}
diff --git a/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxUserService.java b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxUserService.java
new file mode 100644
index 000000000..0586eeaf4
--- /dev/null
+++ b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/IWxUserService.java
@@ -0,0 +1,69 @@
+package com.ruoyi.wxapi.service;
+
+import java.util.List;
+import com.ruoyi.common.core.domain.entity.WxUser;
+
+/**
+ * 小程序用户Service接口
+ * 
+ * @author tgq
+ * @date 2021-09-01
+ */
+public interface IWxUserService 
+{
+    /**
+     * 查询小程序用户
+     * 
+     * @param id 小程序用户主键
+     * @return 小程序用户
+     */
+    public WxUser selectWxUserById(Long id);
+
+    /**
+     * 查询小程序用户
+     *
+     * @param openId 小程序用户openId
+     * @return 小程序用户
+     */
+    public WxUser selectWxUserByOpenId(String openId);
+
+    /**
+     * 查询小程序用户列表
+     * 
+     * @param wxUser 小程序用户
+     * @return 小程序用户集合
+     */
+    public List<WxUser> selectWxUserList(WxUser wxUser);
+
+    /**
+     * 新增小程序用户
+     * 
+     * @param wxUser 小程序用户
+     * @return 结果
+     */
+    public int insertWxUser(WxUser wxUser);
+
+    /**
+     * 修改小程序用户
+     * 
+     * @param wxUser 小程序用户
+     * @return 结果
+     */
+    public int updateWxUser(WxUser wxUser);
+
+    /**
+     * 批量删除小程序用户
+     * 
+     * @param ids 需要删除的小程序用户主键集合
+     * @return 结果
+     */
+    public int deleteWxUserByIds(Long[] ids);
+
+    /**
+     * 删除小程序用户信息
+     * 
+     * @param id 小程序用户主键
+     * @return 结果
+     */
+    public int deleteWxUserById(Long id);
+}
diff --git a/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxAppServiceImpl.java b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxAppServiceImpl.java
new file mode 100644
index 000000000..4dcb988c8
--- /dev/null
+++ b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxAppServiceImpl.java
@@ -0,0 +1,125 @@
+package com.ruoyi.wxapi.service.impl;
+
+import java.util.List;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
+import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.wxapi.mapper.WxAppMapper;
+import com.ruoyi.wxapi.domain.WxApp;
+import com.ruoyi.wxapi.service.IWxAppService;
+
+/**
+ * 小程序设置Service业务层处理
+ * 
+ * @author tgq
+ * @date 2021-09-01
+ */
+@Service
+public class WxAppServiceImpl implements IWxAppService 
+{
+    @Autowired
+    private WxAppMapper wxAppMapper;
+
+    /**
+     * 查询小程序设置
+     * 
+     * @param id 小程序设置主键
+     * @return 小程序设置
+     */
+    @Override
+    public WxApp selectWxAppById(Long id)
+    {
+        return wxAppMapper.selectWxAppById(id);
+    }
+
+    /**
+     * 查询小程序设置列表
+     * 
+     * @param wxApp 小程序设置
+     * @return 小程序设置
+     */
+    @Override
+    public List<WxApp> selectWxAppList(WxApp wxApp)
+    {
+        return wxAppMapper.selectWxAppList(wxApp);
+    }
+
+    /**
+     * 新增小程序设置
+     * 
+     * @param wxApp 小程序设置
+     * @return 结果
+     */
+    @Override
+    public int insertWxApp(WxApp wxApp)
+    {
+        wxApp.setCreateTime(DateUtils.getNowDate());
+        return wxAppMapper.insertWxApp(wxApp);
+    }
+
+    /**
+     * 修改小程序设置
+     * 
+     * @param wxApp 小程序设置
+     * @return 结果
+     */
+    @Override
+    public int updateWxApp(WxApp wxApp)
+    {
+        wxApp.setUpdateTime(DateUtils.getNowDate());
+        return wxAppMapper.updateWxApp(wxApp);
+    }
+
+    /**
+     * 批量删除小程序设置
+     * 
+     * @param ids 需要删除的小程序设置主键
+     * @return 结果
+     */
+    @Override
+    public int deleteWxAppByIds(Long[] ids)
+    {
+        return wxAppMapper.deleteWxAppByIds(ids);
+    }
+
+    /**
+     * 删除小程序设置信息
+     * 
+     * @param id 小程序设置主键
+     * @return 结果
+     */
+    @Override
+    public int deleteWxAppById(Long id)
+    {
+        return wxAppMapper.deleteWxAppById(id);
+    }
+
+
+    /**
+     * 获取微信小程序服务
+     *
+     * @param code 小程序code
+     * @return 结果
+     */
+    @Override
+    public WxMaService getMaService(String code) {
+        WxApp wxApp = wxAppMapper.selectWxAppByCode(code);
+        if (wxApp == null) {
+            throw new IllegalArgumentException(String.format("未找到对应appcode=[%s]的配置,请核实!", code));
+        }
+        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
+        config.setAppid(wxApp.getAppId());
+        config.setSecret(wxApp.getSecret());
+//        config.setToken(null);
+//        config.setAesKey(null);
+//        config.setMsgDataFormat(null);
+
+        WxMaService service = new WxMaServiceImpl();
+        service.setWxMaConfig(config);
+        return service;
+    }
+}
diff --git a/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxUserServiceImpl.java b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxUserServiceImpl.java
new file mode 100644
index 000000000..dd3eb1afa
--- /dev/null
+++ b/ruoyi-wxapi/src/main/java/com/ruoyi/wxapi/service/impl/WxUserServiceImpl.java
@@ -0,0 +1,107 @@
+package com.ruoyi.wxapi.service.impl;
+
+import java.util.List;
+import com.ruoyi.common.utils.DateUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.wxapi.mapper.WxUserMapper;
+import com.ruoyi.common.core.domain.entity.WxUser;
+import com.ruoyi.wxapi.service.IWxUserService;
+
+/**
+ * 小程序用户Service业务层处理
+ * 
+ * @author tgq
+ * @date 2021-09-01
+ */
+@Service
+public class WxUserServiceImpl implements IWxUserService 
+{
+    @Autowired
+    private WxUserMapper wxUserMapper;
+
+    /**
+     * 查询小程序用户
+     * 
+     * @param id 小程序用户主键
+     * @return 小程序用户
+     */
+    @Override
+    public WxUser selectWxUserById(Long id)
+    {
+        return wxUserMapper.selectWxUserById(id);
+    }
+
+    /**
+     * 查询小程序用户
+     *
+     * @param openId 小程序用户openId
+     * @return 小程序用户
+     */
+    @Override
+    public WxUser selectWxUserByOpenId(String openId) {
+        return wxUserMapper.selectWxUserByOpenId(openId);
+    }
+
+    /**
+     * 查询小程序用户列表
+     * 
+     * @param wxUser 小程序用户
+     * @return 小程序用户
+     */
+    @Override
+    public List<WxUser> selectWxUserList(WxUser wxUser)
+    {
+        return wxUserMapper.selectWxUserList(wxUser);
+    }
+
+    /**
+     * 新增小程序用户
+     * 
+     * @param wxUser 小程序用户
+     * @return 结果
+     */
+    @Override
+    public int insertWxUser(WxUser wxUser)
+    {
+        wxUser.setCreateTime(DateUtils.getNowDate());
+        return wxUserMapper.insertWxUser(wxUser);
+    }
+
+    /**
+     * 修改小程序用户
+     * 
+     * @param wxUser 小程序用户
+     * @return 结果
+     */
+    @Override
+    public int updateWxUser(WxUser wxUser)
+    {
+        wxUser.setUpdateTime(DateUtils.getNowDate());
+        return wxUserMapper.updateWxUser(wxUser);
+    }
+
+    /**
+     * 批量删除小程序用户
+     * 
+     * @param ids 需要删除的小程序用户主键
+     * @return 结果
+     */
+    @Override
+    public int deleteWxUserByIds(Long[] ids)
+    {
+        return wxUserMapper.deleteWxUserByIds(ids);
+    }
+
+    /**
+     * 删除小程序用户信息
+     * 
+     * @param id 小程序用户主键
+     * @return 结果
+     */
+    @Override
+    public int deleteWxUserById(Long id)
+    {
+        return wxUserMapper.deleteWxUserById(id);
+    }
+}
diff --git a/ruoyi-wxapi/src/main/resources/mapper/wxapi/WxAppMapper.xml b/ruoyi-wxapi/src/main/resources/mapper/wxapi/WxAppMapper.xml
new file mode 100644
index 000000000..309f0ca9b
--- /dev/null
+++ b/ruoyi-wxapi/src/main/resources/mapper/wxapi/WxAppMapper.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.wxapi.mapper.WxAppMapper">
+    
+    <resultMap type="WxApp" id="WxAppResult">
+        <result property="id"    column="id"    />
+        <result property="appCode"    column="app_code"    />
+        <result property="appName"    column="app_name"    />
+        <result property="appId"    column="app_id"    />
+        <result property="secret"    column="secret"    />
+        <result property="apiDomain"    column="api_domain"    />
+        <result property="status"    column="status"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectWxAppVo">
+        select id, app_code, app_name, app_id, secret, api_domain, status, create_by, create_time, update_by, update_time from wx_app
+    </sql>
+
+    <select id="selectWxAppList" parameterType="WxApp" resultMap="WxAppResult">
+        <include refid="selectWxAppVo"/>
+        <where>  
+            <if test="appCode != null  and appCode != ''"> and app_code like concat('%', #{appCode}, '%')</if>
+            <if test="appName != null  and appName != ''"> and app_name like concat('%', #{appName}, '%')</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+        </where>
+    </select>
+    
+    <select id="selectWxAppById" parameterType="Long" resultMap="WxAppResult">
+        <include refid="selectWxAppVo"/>
+        where id = #{id}
+    </select>
+
+    <select id="selectWxAppByCode" parameterType="String" resultMap="WxAppResult">
+        <include refid="selectWxAppVo"/>
+        where app_code = #{code}
+    </select>
+
+    <insert id="insertWxApp" parameterType="WxApp">
+        insert into wx_app
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="id != null">id,</if>
+            <if test="appCode != null">app_code,</if>
+            <if test="appName != null">app_name,</if>
+            <if test="appId != null">app_id,</if>
+            <if test="secret != null">secret,</if>
+            <if test="apiDomain != null">api_domain,</if>
+            <if test="status != null">status,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="id != null">#{id},</if>
+            <if test="appCode != null">#{appCode},</if>
+            <if test="appName != null">#{appName},</if>
+            <if test="appId != null">#{appId},</if>
+            <if test="secret != null">#{secret},</if>
+            <if test="apiDomain != null">#{apiDomain},</if>
+            <if test="status != null">#{status},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateWxApp" parameterType="WxApp">
+        update wx_app
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="appCode != null">app_code = #{appCode},</if>
+            <if test="appName != null">app_name = #{appName},</if>
+            <if test="appId != null">app_id = #{appId},</if>
+            <if test="secret != null">secret = #{secret},</if>
+            <if test="apiDomain != null">api_domain = #{apiDomain},</if>
+            <if test="status != null">status = #{status},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteWxAppById" parameterType="Long">
+        delete from wx_app where id = #{id}
+    </delete>
+
+    <delete id="deleteWxAppByIds" parameterType="String">
+        delete from wx_app where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-wxapi/src/main/resources/mapper/wxapi/WxUserMapper.xml b/ruoyi-wxapi/src/main/resources/mapper/wxapi/WxUserMapper.xml
new file mode 100644
index 000000000..91569c902
--- /dev/null
+++ b/ruoyi-wxapi/src/main/resources/mapper/wxapi/WxUserMapper.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.wxapi.mapper.WxUserMapper">
+    
+    <resultMap type="WxUser" id="WxUserResult">
+        <result property="id"    column="id"    />
+        <result property="unionId"    column="union_id"    />
+        <result property="openId"    column="open_id"    />
+        <result property="nickName"    column="nick_name"    />
+        <result property="name"    column="name"    />
+        <result property="status"    column="status"    />
+        <result property="avatarUrl"    column="avatar_url"    />
+        <result property="gender"    column="gender"    />
+        <result property="country"    column="country"    />
+        <result property="province"    column="province"    />
+        <result property="city"    column="city"    />
+        <result property="mobile"    column="mobile"    />
+        <result property="appId"    column="app_id"    />
+        <result property="createBy"    column="create_by"    />
+        <result property="createTime"    column="create_time"    />
+        <result property="updateBy"    column="update_by"    />
+        <result property="updateTime"    column="update_time"    />
+    </resultMap>
+
+    <sql id="selectWxUserVo">
+        select id, union_id, open_id, nick_name, name, status, avatar_url, gender, country, province, city, mobile, app_id, create_by, create_time, update_by, update_time from wx_user
+    </sql>
+
+    <select id="selectWxUserList" parameterType="WxUser" resultMap="WxUserResult">
+        <include refid="selectWxUserVo"/>
+        <where>  
+            <if test="nickName != null  and nickName != ''"> and nick_name like concat('%', #{nickName}, '%')</if>
+            <if test="name != null  and name != ''"> and name like concat('%', #{name}, '%')</if>
+            <if test="status != null  and status != ''"> and status = #{status}</if>
+        </where>
+    </select>
+    
+    <select id="selectWxUserById" parameterType="Long" resultMap="WxUserResult">
+        <include refid="selectWxUserVo"/>
+        where id = #{id}
+    </select>
+
+    <select id="selectWxUserByOpenId" parameterType="String" resultMap="WxUserResult">
+        <include refid="selectWxUserVo"/>
+        where open_id = #{openId}
+    </select>
+
+    <insert id="insertWxUser" parameterType="WxUser" useGeneratedKeys="true" keyProperty="id">
+        insert into wx_user
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="unionId != null">union_id,</if>
+            <if test="openId != null and openId != ''">open_id,</if>
+            <if test="nickName != null and nickName != ''">nick_name,</if>
+            <if test="name != null and name != ''">name,</if>
+            <if test="status != null and status != ''">status,</if>
+            <if test="avatarUrl != null">avatar_url,</if>
+            <if test="gender != null">gender,</if>
+            <if test="country != null">country,</if>
+            <if test="province != null">province,</if>
+            <if test="city != null">city,</if>
+            <if test="mobile != null">mobile,</if>
+            <if test="appId != null">app_id,</if>
+            <if test="createBy != null">create_by,</if>
+            <if test="createTime != null">create_time,</if>
+            <if test="updateBy != null">update_by,</if>
+            <if test="updateTime != null">update_time,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="unionId != null">#{unionId},</if>
+            <if test="openId != null and openId != ''">#{openId},</if>
+            <if test="nickName != null and nickName != ''">#{nickName},</if>
+            <if test="name != null and name != ''">#{name},</if>
+            <if test="status != null and status != ''">#{status},</if>
+            <if test="avatarUrl != null">#{avatarUrl},</if>
+            <if test="gender != null">#{gender},</if>
+            <if test="country != null">#{country},</if>
+            <if test="province != null">#{province},</if>
+            <if test="city != null">#{city},</if>
+            <if test="mobile != null">#{mobile},</if>
+            <if test="appId != null">#{appId},</if>
+            <if test="createBy != null">#{createBy},</if>
+            <if test="createTime != null">#{createTime},</if>
+            <if test="updateBy != null">#{updateBy},</if>
+            <if test="updateTime != null">#{updateTime},</if>
+         </trim>
+    </insert>
+
+    <update id="updateWxUser" parameterType="WxUser">
+        update wx_user
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="unionId != null">union_id = #{unionId},</if>
+            <if test="openId != null and openId != ''">open_id = #{openId},</if>
+            <if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
+            <if test="name != null and name != ''">name = #{name},</if>
+            <if test="status != null and status != ''">status = #{status},</if>
+            <if test="avatarUrl != null">avatar_url = #{avatarUrl},</if>
+            <if test="gender != null">gender = #{gender},</if>
+            <if test="country != null">country = #{country},</if>
+            <if test="province != null">province = #{province},</if>
+            <if test="city != null">city = #{city},</if>
+            <if test="mobile != null">mobile = #{mobile},</if>
+            <if test="appId != null">app_id = #{appId},</if>
+            <if test="createBy != null">create_by = #{createBy},</if>
+            <if test="createTime != null">create_time = #{createTime},</if>
+            <if test="updateBy != null">update_by = #{updateBy},</if>
+            <if test="updateTime != null">update_time = #{updateTime},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteWxUserById" parameterType="Long">
+        delete from wx_user where id = #{id}
+    </delete>
+
+    <delete id="deleteWxUserByIds" parameterType="String">
+        delete from wx_user where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file