Ver código fonte

扫码登记

pengjing 10 meses atrás
pai
commit
bf14d44d87
29 arquivos alterados com 699 adições e 69 exclusões
  1. 5 1
      doc/待更新脚本
  2. 2 1
      h5app/public/appconfig.json
  3. 4 0
      h5app/src/App.vue
  4. 13 0
      h5app/src/api/siteUserInfo/index.ts
  5. 28 0
      h5app/src/api/wechat/index.ts
  6. BIN
      h5app/src/assets/icon/wxQrcode.jpg
  7. 3 0
      h5app/src/enums/cacheEnum.ts
  8. 13 4
      h5app/src/store/modules/user.ts
  9. 1 0
      h5app/src/utils/config.ts
  10. 1 1
      h5app/src/utils/request.ts
  11. 10 3
      h5app/src/utils/urlUtils.ts
  12. 49 0
      h5app/src/utils/wechat.ts
  13. 112 4
      h5app/src/views/pages/jobUserInfo/index.vue
  14. 94 17
      h5app/src/views/pages/userQrCode/index.vue
  15. 1 1
      pom.xml
  16. 4 0
      src/main/java/com/hz/employmentsite/AppConfig.java
  17. 1 0
      src/main/java/com/hz/employmentsite/config/WebConfiguration.java
  18. 37 0
      src/main/java/com/hz/employmentsite/config/WxMpConfig.java
  19. 11 17
      src/main/java/com/hz/employmentsite/controller/CommonController.java
  20. 12 3
      src/main/java/com/hz/employmentsite/controller/WxController.java
  21. 20 0
      src/main/java/com/hz/employmentsite/model/PcSiteUser.java
  22. 140 0
      src/main/java/com/hz/employmentsite/model/PcSiteUserExample.java
  23. 23 9
      src/main/java/com/hz/employmentsite/services/impl/WechatServiceImpl.java
  24. 6 0
      src/main/java/com/hz/employmentsite/services/service/WechatService.java
  25. 61 0
      src/main/java/com/hz/employmentsite/util/QrCodeUtils.java
  26. 3 0
      src/main/java/com/hz/employmentsite/vo/user/UserInfoModel.java
  27. 4 2
      src/main/resources/application.yml
  28. 37 5
      src/main/resources/mapping/PcSiteUserMapper.xml
  29. 4 1
      src/main/resources/mapping/cquery/SysUserCQuery.xml

+ 5 - 1
doc/待更新脚本

@@ -42,4 +42,8 @@ INSERT INTO sys_dictionary_item (DictionaryItemID, Code, DictionaryCode, Value,
 INSERT INTO sys_dictionary_item (DictionaryItemID, Code, DictionaryCode, Value, Name, OrderNo, RecordStatus, IsEditable) VALUES ('f06cf371-a77a-11ed-a6c5-7285c2a9999e', '', 'DataRange', 3, '机构', 30, 1, 0);
 INSERT INTO sys_dictionary_item (DictionaryItemID, Code, DictionaryCode, Value, Name, OrderNo, RecordStatus, IsEditable) VALUES ('f06cf371-a77a-11ed-a6c5-7385c2a9999e', '', 'DataRange', 4, '驿站', 40, 1, 0);
 INSERT INTO sys_dictionary_item (DictionaryItemID, Code, DictionaryCode, Value, Name, OrderNo, RecordStatus, IsEditable) VALUES ('f06cf371-a77a-11ed-a6c5-7485c2a9999e', '', 'DataRange', 5, '企业', 50, 1, 0);
-INSERT INTO sys_dictionary_item (DictionaryItemID, Code, DictionaryCode, Value, Name, OrderNo, RecordStatus, IsEditable) VALUES ('f06cf371-a77a-11ed-a6c5-7585c3a9999e', '', 'DataRange', 6, '本人', 60, 1, 0);
+INSERT INTO sys_dictionary_item (DictionaryItemID, Code, DictionaryCode, Value, Name, OrderNo, RecordStatus, IsEditable) VALUES ('f06cf371-a77a-11ed-a6c5-7585c3a9999e', '', 'DataRange', 6, '本人', 60, 1, 0);
+
+-- 2024.4.17
+alter table pc_site_user add UserNo varchar(50) comment '工号';
+alter table pc_site_user add IDCard varchar(100) comment '身份证号';

+ 2 - 1
h5app/public/appconfig.json

@@ -1,3 +1,4 @@
 {
-  "isDev": true
+  "isDev": true,
+  "webSiteUrl": "http://www.bowintek.com/hzyz/mobile/"
 }

+ 4 - 0
h5app/src/App.vue

@@ -8,6 +8,7 @@
 import {IonApp, IonRouterOutlet} from '@ionic/vue';
 import {getCurrentInstance, ref} from "vue";
 import {useUserStore} from "@/store/modules/user";
+import {wxAuth} from "@/utils/wechat";
 
 const {appContext: {config: {globalProperties}}} = getCurrentInstance();
 
@@ -18,6 +19,9 @@ const user = ref(userStore.getUserInfo);
 if (user.value != null) {
   globalProperties.$routeActive = true;
 }
+else{
+  wxAuth();
+}
 
 </script>
 

+ 13 - 0
h5app/src/api/siteUserInfo/index.ts

@@ -11,4 +11,17 @@ export function getSiteUserDataList(){
             isNew: true,
         },
     );
+}
+
+export function getUserByID(userId: string) {
+    return request(
+        {
+            url: 'user/getUserInfo',
+            method: 'get',
+            params: {userId:userId},
+        },
+        {
+            isNew: true,
+        }
+    );
 }

+ 28 - 0
h5app/src/api/wechat/index.ts

@@ -0,0 +1,28 @@
+import {request} from "@/utils/request";
+
+export function getOAuthUrl() {
+    return request<object>(
+        {
+            url: 'wx/getOAuthUrl',
+            method: 'get',
+            params: {},
+        },
+        {
+            isNew: true,
+        },
+    );
+}
+
+
+export function getWxOpenId(code:string) {
+    return request<object>(
+        {
+            url: 'wx/getOpenId',
+            method: 'get',
+            params: {code:code},
+        },
+        {
+            isNew: true,
+        },
+    );
+}

BIN
h5app/src/assets/icon/wxQrcode.jpg


+ 3 - 0
h5app/src/enums/cacheEnum.ts

@@ -16,3 +16,6 @@ export const ROLES_KEY = 'MOBILE_ROLES__KEY__';
 export const IS_LOCKSCREEN = 'MOBILE_IS_LOCKSCREEN';
 /** 标签页 */
 export const TABS_ROUTES = 'MOBILE_TABS_ROUTES';
+
+/** 用户token */
+export const ACCESS_OpenId_KEY = 'MOBILE_OpenId';

+ 13 - 4
h5app/src/store/modules/user.ts

@@ -2,7 +2,7 @@ import { defineStore } from 'pinia';
 //import { useWsStore } from './ws';
 import { store } from '@/store';
 import { login } from '@/api/login';
-import {ACCESS_TOKEN_KEY, USER_INFO_KEY} from '@/enums/cacheEnum';
+import {ACCESS_OpenId_KEY, ACCESS_TOKEN_KEY, USER_INFO_KEY} from '@/enums/cacheEnum';
 import { Storage } from '@/utils/Storage';
 import { logout, getInfo, permmenu } from '@/api/account';
 import {oauthLogin} from "@/api/oauth";
@@ -16,7 +16,8 @@ interface UserState {
   perms: string[];
   menus: API.Menu[];
   userInfo: Partial<API.AdminUserInfo>;
-  timer: any
+  timer: any,
+  openId: string
 }
 
 export const useUserStore = defineStore({
@@ -28,7 +29,8 @@ export const useUserStore = defineStore({
     perms: [],
     menus: [],
     userInfo: Storage.get(USER_INFO_KEY, null),
-    timer: null
+    timer: null,
+    openId:''
   }),
   getters: {
     getToken(): string {
@@ -43,7 +45,9 @@ export const useUserStore = defineStore({
     getUserInfo():Partial<API.AdminUserInfo>{
       return this.userInfo;
     },
-
+    getOpenId(): string {
+      return this.openId;
+    },
   },
   actions: {
     /** 清空token及用户信息 */
@@ -65,6 +69,11 @@ export const useUserStore = defineStore({
       const ex = 7 * 24 * 60 * 60 * 1000;
       Storage.set(USER_INFO_KEY, this.userInfo,ex);
     },
+    setOpenId(openId: string) {
+      this.openId = openId ?? '';
+      const ex = 7 * 24 * 60 * 60 * 1000;
+      Storage.set(ACCESS_OpenId_KEY, this.openId, ex);
+    },
     /** 登录 */
     async login(params: API.LoginParams) {
       try {

+ 1 - 0
h5app/src/utils/config.ts

@@ -5,6 +5,7 @@ const service = axios.create({
 
 export interface ConfigParams  {
     isDev: boolean;
+    webSiteUrl: string
 }
 
 export const getConfig = async <ConfigParams>(

+ 1 - 1
h5app/src/utils/request.ts

@@ -86,7 +86,7 @@ service.interceptors.response.use(
       }
 
       // throw other
-        const error = new Error(res.message || UNKNOWN_ERROR) as Error & { code: any,data:any };
+        const error = new Error(res.message || res.msg || UNKNOWN_ERROR) as Error & { code: any,data:any };
         error.code = res.code;
         error.data=res.data;
         return Promise.reject(error);

+ 10 - 3
h5app/src/utils/urlUtils.ts

@@ -32,20 +32,27 @@ export const uniqueSlash = (path: string) => path.replace(/(https?:\/)|(\/)+/g,
 // Safari 不支持以下正则(反向否定查找) shit!
 // export const uniqueSlash = (path: string) => path.replace(/(?<!:)\/{2,}/g, '/');
 
+
 export function getUrlParams(){
-  // 截取url中的ticket方法
   let url = location.href;
   const theRequest = new Object();
   if (url.indexOf("#/login") != -1) {
     url = url.split("#/login")[0];
   }
   if (url.indexOf("?") != -1) {
-    const paramsUrl = url.split('?')[1];
+    const index = url.indexOf("?");
+    const splits = [url.slice(0,index),url.slice(index+1)];
+    const paramsUrl = splits[1];
     const strs = paramsUrl.split("&");
     for (let i = 0; i < strs.length; i++) {
       // eslint-disable-next-line @typescript-eslint/ban-ts-comment
       // @ts-ignore
-      theRequest[strs[i].split("=")[0]] = strs[i].split("=")[1];
+      const paramsIndex = strs[i].indexOf("=");
+      const paramsSplits = [strs[i].slice(0,paramsIndex),strs[i].slice(paramsIndex+1)];
+
+      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+      // @ts-ignore
+      theRequest[paramsSplits[0]] = paramsSplits[1];
     }
   }
   return theRequest;

+ 49 - 0
h5app/src/utils/wechat.ts

@@ -0,0 +1,49 @@
+import {getUrlParams} from "@/utils/urlUtils";
+import {getOAuthUrl, getWxOpenId} from "@/api/wechat";
+import {useUserStore} from "@/store/modules/user";
+import {alertController, loadingController} from '@ionic/vue';
+
+export function isWechat() {
+    /*return String(navigator.userAgent.toLowerCase().match(/MicroMessenger/i)) === "micromessenger";*/
+    return true;
+}
+
+export async function wxAuth() {
+    const userStore = useUserStore();
+    if (isWechat() && !userStore.getOpenId) {
+        const urlParams = getUrlParams() as any;
+        const code = urlParams["code"];
+        if (!code) {
+            const loading = await loadingController.create({
+                cssClass: 'my-custom-class',
+                message: '微信授权中,请稍后...',
+                duration: 2000,
+            });
+            await loading.present();
+
+            getOAuthUrl().then((res: any) => {
+                if (res) {
+                    window.location.href = res;
+                } else {
+                    presentAlert("微信授权失败!");
+                }
+            });
+        } else {
+            getWxOpenId(code).then((res: any) => {
+                userStore.setOpenId(res);
+            });
+        }
+    }
+}
+
+const presentAlert = async (msg: any) => {
+    const alert = await alertController.create({
+        header: '错误!',
+        message: msg,
+        buttons: [
+            '确定'
+        ],
+    });
+
+    await alert.present();
+}

+ 112 - 4
h5app/src/views/pages/jobUserInfo/index.vue

@@ -1,5 +1,113 @@
 <template>
-  <div>
-    index
-  </div>
-</template>
+  <ion-page class="list-page">
+    <ion-header class="header-theme2">
+      <ion-toolbar>
+        <ion-title>信息登记</ion-title>
+      </ion-toolbar>
+    </ion-header>
+    <ion-content class="qr_content">
+      <div class="bw-vue-form">
+        <div class="form-detail">
+          <ion-label>姓名</ion-label>
+          <ion-text>{{ user.name }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>工号</ion-label>
+          <ion-text>{{ user.userNo }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>身份证号</ion-label>
+          <ion-text>{{ user.IDCard }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>身份</ion-label>
+          <ion-text>驿站工作人员</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>所属驿站</ion-label>
+          <ion-text>{{ user.siteName }}</ion-text>
+        </div>
+      </div>
+      <div class="page_button">
+        <ion-button shape="round" expand="block" @click="onCompany">我是企业</ion-button>
+        <ion-button shape="round" expand="block" @click="onJobUser">我是求职者</ion-button>
+      </div>
+    </ion-content>
+  </ion-page>
+</template>
+<script>
+import {defineComponent, ref} from "vue";
+import {getUrlParams} from "@/utils/urlUtils";
+import {alertController} from "@ionic/vue";
+import {getUserByID} from "@/api/siteUserInfo";
+import {useRouter} from "vue-router";
+import {getWxOpenId} from "@/api/wechat";
+
+
+const presentAlert = async (message) => {
+  const alert = await alertController.create({
+    header: '错误!',
+    message: message,
+    buttons: [
+      '确定'
+    ],
+  });
+
+  await alert.present();
+}
+
+export default defineComponent({
+  name: "jobUserInfoIndex",
+  setup() {
+    const router = useRouter();
+    const user = ref({userNo: '', name: '', IDCard: '', siteName: ''});
+    const urlParams = getUrlParams();
+    const userId = urlParams["userId"];
+    const openId = ref("");
+
+    const getUser = async function () {
+      const reqData = await getUserByID(userId);
+      user.value = reqData;
+    };
+
+    const getOpenId = async function () {
+      const reqData = await getWxOpenId();
+      openId.value = reqData;
+    };
+
+    const onCompany = function () {
+      router.push({path: '/jobUserInfo/companyedit', query: {reload: 1, openId: openId.value}});
+    };
+
+    const onJobUser = function () {
+      router.push({path: '/jobUserInfo/useredit', query: {reload: 1, openId: openId.value}});
+    };
+
+
+    if (!userId) {
+      presentAlert("驿站工作者信息获取失败");
+    } else {
+      getUser();
+    }
+
+    getOpenId();
+
+    return {
+      user,
+      onCompany,
+      onJobUser
+    }
+  }
+});
+</script>
+<style lang="less">
+.page_button {
+  display: flex;
+  justify-content: space-around;
+  padding: 20px;
+
+  ion-button {
+    width: 150px;
+  }
+}
+</style>

+ 94 - 17
h5app/src/views/pages/userQrCode/index.vue

@@ -1,30 +1,78 @@
 <template>
-  <ion-page className="list-page">
-    <ion-header>
+  <ion-page class="list-page">
+    <ion-header class="header-theme2">
       <ion-toolbar>
+        <ion-buttons slot="start">
+          <ion-icon :icon="arrowBackOutline" @click="onBack"></ion-icon>
+        </ion-buttons>
         <ion-title>我的二维码</ion-title>
       </ion-toolbar>
     </ion-header>
-    <ion-content>
-      <div style="display: flex;">
-        <img src="@/assets/icon/wxQrcode.jpg" :style="imgStyle">
-        <img :src="infoQrcodeUrl" :style="imgStyle">
+    <ion-content class="qr_content">
+      <div class="user_qrcode">
+        <div class="qr_item">
+          <img src="@/assets/icon/wxQrcode.jpg" :style="imgStyle">
+          <span>关注公众号</span>
+        </div>
+        <div class="qr_item">
+          <img :src="infoQrcodeUrl" :style="imgStyle">
+          <span>扫码登记</span>
+        </div>
+      </div>
+      <div class="bw-vue-form">
+        <div class="form-detail">
+          <ion-label>姓名</ion-label>
+          <ion-text>{{ user.name }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>工号</ion-label>
+          <ion-text>{{ user.userNo }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>身份证号</ion-label>
+          <ion-text>{{ user.IDCard }}</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>身份</ion-label>
+          <ion-text>驿站工作人员</ion-text>
+        </div>
+        <div class="form-detail">
+          <ion-label>所属驿站</ion-label>
+          <ion-text>{{ user.siteName }}</ion-text>
+        </div>
       </div>
     </ion-content>
   </ion-page>
 </template>
 <script>
-import {defineComponent,ref} from "vue";
+import {defineComponent, ref} from "vue";
+import {useUserStore} from "../../../store/modules/user";
+import {arrowBackOutline} from 'ionicons/icons';
+import {useRouter} from "vue-router";
+import {getConfig} from "../../../utils/config"
+
+const infoQrcodeUrl = ref("");
 
 export default defineComponent({
   name: "qrcode",
   setup() {
-    const browserWidth = ref(0);
-    const infoQrcodeUrl=ref("");
-    infoQrcodeUrl.value="/api/common/getQRCode?code=http://office.bowintek.com:8200/mobile/index.html#/login";
+    const router = useRouter();
+    const userStore = useUserStore();
+    const user = ref(userStore.getUserInfo);
+    const imgStyle = ref({
+      width: '0px',
+      height: '0px',
+    });
+
+
+    const updateBrowserWidth = () => {
+      const browserWidth = window.innerWidth;
+      imgStyle.value.width = (browserWidth - 20) / 2 + 'px';
+      imgStyle.value.height = (browserWidth - 20) / 2 + 'px';
+    }
 
-    function updateBrowserWidth() {
-      browserWidth.value = window.innerWidth;
+    const onBack = () => {
+      router.push('../');
     }
 
     // 设置初始浏览器宽度
@@ -34,15 +82,44 @@ export default defineComponent({
 
     return {
       infoQrcodeUrl,
-      browserWidth,
-      imgStyle:{
-        width:(browserWidth.value-20)/2 + 'px',
-        height:(browserWidth.value-20)/2 + 'px',
-      }
+      imgStyle,
+      user,
+      arrowBackOutline,
+      onBack
     }
+  },
+  mounted() {
+    const userStore = useUserStore();
+    const user = ref(userStore.getUserInfo);
+    getConfig().then((data) => {
+      const qrCodeUrl = data.webSiteUrl + "/jobUserInfo/index?userId=" + user.value.userID;
+      infoQrcodeUrl.value = "/api/common/getQRCode?code=" + qrCodeUrl;
+    }, () => {
+      infoQrcodeUrl.value = "";
+    })
   }
 });
 </script>
 <style lang="less">
+.qr_content {
+  --padding-start: 10px;
+  --padding-end: 10px;
+}
+
+.user_qrcode {
+  display: flex;
+  justify-content: space-between;
+
+  .qr_item {
+    text-align: center;
+  }
+
+  img {
+    padding: 10px;
+  }
+}
 
+.bw-vue-form {
+  padding: 20px 10px 10px 10px;
+}
 </style>

+ 1 - 1
pom.xml

@@ -167,7 +167,7 @@
         <dependency>
             <groupId>com.github.binarywang</groupId>
             <artifactId>weixin-java-mp</artifactId>
-            <version>2.7.0</version>
+            <version>3.7.0</version>
         </dependency>
     </dependencies>
 

+ 4 - 0
src/main/java/com/hz/employmentsite/AppConfig.java

@@ -75,6 +75,10 @@ public class AppConfig {
     public String wxAppSecret;
     @Value("${appconfig.wxconfig.messageTemplateId}")
     public String wxMessageTemplateId;
+    @Value("${appconfig.wxconfig.redirectURI}")
+    public String wxRedirectURI;
+    @Value("${appconfig.wxconfig.accessScope}")
+    public String wxAccessScope;
 
 
 

+ 1 - 0
src/main/java/com/hz/employmentsite/config/WebConfiguration.java

@@ -61,6 +61,7 @@ public class WebConfiguration implements WebMvcConfigurer {
         excludePath.add("/api/oauth/oauthLogin");//单点登录
         excludePath.add("/api/system/file/downFileToUrl/**");  //下载附件
         excludePath.add("/api/common/getQRCode");
+        excludePath.add("/api/user/getUserInfo");
         excludePath.add("/api/wx/**");
         excludePath.add("/static/**");  //静态资源
         excludePath.add("/mobile/**");  //静态资源

+ 37 - 0
src/main/java/com/hz/employmentsite/config/WxMpConfig.java

@@ -0,0 +1,37 @@
+package com.hz.employmentsite.config;
+
+import com.hz.employmentsite.AppConfig;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+@ConditionalOnClass(WxMpService.class)
+public class WxMpConfig {
+    @Autowired
+    private AppConfig appConfig;
+
+    @Bean
+    @ConditionalOnMissingBean
+    public WxMpService wxMpService() {
+        WxMpService wxMpService = new WxMpServiceImpl();
+        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
+
+        return wxMpService;
+    }
+
+    @Bean
+    @ConditionalOnMissingBean
+    public WxMpConfigStorage wxMpConfigStorage(){
+        WxMpDefaultConfigImpl wxMpDefaultConfig = new WxMpDefaultConfigImpl();
+        wxMpDefaultConfig.setAppId(appConfig.wxAppId);
+        wxMpDefaultConfig.setSecret(appConfig.wxAppSecret);
+        return wxMpDefaultConfig;
+    }
+}

+ 11 - 17
src/main/java/com/hz/employmentsite/controller/CommonController.java

@@ -4,18 +4,21 @@ import com.github.pagehelper.PageInfo;
 import com.google.zxing.BarcodeFormat;
 import com.google.zxing.EncodeHintType;
 import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
 import com.google.zxing.client.j2se.MatrixToImageWriter;
 import com.google.zxing.common.BitMatrix;
 import com.hz.employmentsite.filter.exception.BaseResponse;
 import com.hz.employmentsite.filter.exception.RespGenerstor;
 import com.hz.employmentsite.util.ExcelHelper;
 import com.hz.employmentsite.util.JsonMapper;
+import com.hz.employmentsite.util.QrCodeUtils;
 import com.hz.employmentsite.vo.baseSettings.SiteInfoVo;
 import lombok.Data;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -29,6 +32,9 @@ public class CommonController {
     @Autowired
     public JsonMapper jsonMapper;
 
+    @Autowired
+    private QrCodeUtils qrCodeUtils;
+
     @PostMapping(value = "/exportErrorExcel")
     public void exportErrorExcel(HttpServletResponse response,
                                  @RequestBody ResponseErrorExcelVo errorExcelVo) throws Exception {
@@ -74,26 +80,14 @@ public class CommonController {
 
     @ResponseBody
     @GetMapping("/getQRCode")
-    public BaseResponse<String> getQRCode(HttpServletResponse response, @RequestParam("code") String code) {
-        BaseResponse<String> res = new BaseResponse<>();
-        int width = 400, height = 400;
-        String format = "png", character_set = "UTF-8";
+    public void getQRCode(HttpServletResponse response, @RequestParam("code") String code, @RequestParam(required = false) Integer margin) throws IOException, WriterException {
+        String format = "png";
 
         response.setContentType("image/" + format);
 
-        // 设置字符集编码
-        Map<EncodeHintType, Object> hints = new HashMap<>();
-        hints.put(EncodeHintType.CHARACTER_SET, character_set);
-        try {
-            // 生成二维码矩阵
-            BitMatrix bitMatrix = new MultiFormatWriter().encode(code, BarcodeFormat.QR_CODE, width, height, hints);
-            OutputStream os = response.getOutputStream();
-            MatrixToImageWriter.writeToStream(bitMatrix, format, os);
-            RespGenerstor.success(code);
-        } catch (Exception ex) {
-            RespGenerstor.fail("qrcode",ex.getMessage());
-        }
-        return res;
+        OutputStream os = response.getOutputStream();
+
+        qrCodeUtils.getQrCode(os, code, margin);
     }
 
 

+ 12 - 3
src/main/java/com/hz/employmentsite/controller/WxController.java

@@ -3,9 +3,7 @@ package com.hz.employmentsite.controller;
 import com.hz.employmentsite.filter.exception.BaseResponse;
 import com.hz.employmentsite.filter.exception.RespGenerstor;
 import com.hz.employmentsite.services.service.WechatService;
-import com.hz.employmentsite.util.RemoteHelper;
-import me.chanjar.weixin.mp.api.WxMpService;
-import org.apache.commons.collections.map.AbstractMapDecorator;
+import me.chanjar.weixin.common.error.WxErrorException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -36,6 +34,17 @@ public class WxController {
     @Autowired
     private WechatService wechatService;
 
+    @GetMapping("getOAuthUrl")
+    public BaseResponse<String> getOAuthUrl() {
+        return RespGenerstor.success(wechatService.getOAuthUrl(""));
+    }
+
+
+    @GetMapping("getOpenId")
+    public BaseResponse<String> getOpenId(String code) throws WxErrorException {
+        return RespGenerstor.success(wechatService.getOpenId(code));
+    }
+
     @PostMapping("/sentMsg")
     public BaseResponse<String> sentMsg(){
         Map<String,String> data = new HashMap<>();

+ 20 - 0
src/main/java/com/hz/employmentsite/model/PcSiteUser.java

@@ -25,6 +25,10 @@ public class PcSiteUser {
 
     private Date updateTime;
 
+    private String userNo;
+
+    private String IDCard;
+
     public String getSiteUserID() {
         return siteUserID;
     }
@@ -112,4 +116,20 @@ public class PcSiteUser {
     public void setUpdateTime(Date updateTime) {
         this.updateTime = updateTime;
     }
+
+    public String getUserNo() {
+        return userNo;
+    }
+
+    public void setUserNo(String userNo) {
+        this.userNo = userNo == null ? null : userNo.trim();
+    }
+
+    public String getIDCard() {
+        return IDCard;
+    }
+
+    public void setIDCard(String IDCard) {
+        this.IDCard = IDCard == null ? null : IDCard.trim();
+    }
 }

+ 140 - 0
src/main/java/com/hz/employmentsite/model/PcSiteUserExample.java

@@ -834,6 +834,146 @@ public class PcSiteUserExample {
             addCriterion("UpdateTime not between", value1, value2, "updateTime");
             return (Criteria) this;
         }
+
+        public Criteria andUserNoIsNull() {
+            addCriterion("UserNo is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoIsNotNull() {
+            addCriterion("UserNo is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoEqualTo(String value) {
+            addCriterion("UserNo =", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoNotEqualTo(String value) {
+            addCriterion("UserNo <>", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoGreaterThan(String value) {
+            addCriterion("UserNo >", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoGreaterThanOrEqualTo(String value) {
+            addCriterion("UserNo >=", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoLessThan(String value) {
+            addCriterion("UserNo <", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoLessThanOrEqualTo(String value) {
+            addCriterion("UserNo <=", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoLike(String value) {
+            addCriterion("UserNo like", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoNotLike(String value) {
+            addCriterion("UserNo not like", value, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoIn(List<String> values) {
+            addCriterion("UserNo in", values, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoNotIn(List<String> values) {
+            addCriterion("UserNo not in", values, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoBetween(String value1, String value2) {
+            addCriterion("UserNo between", value1, value2, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andUserNoNotBetween(String value1, String value2) {
+            addCriterion("UserNo not between", value1, value2, "userNo");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardIsNull() {
+            addCriterion("IDCard is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardIsNotNull() {
+            addCriterion("IDCard is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardEqualTo(String value) {
+            addCriterion("IDCard =", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardNotEqualTo(String value) {
+            addCriterion("IDCard <>", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardGreaterThan(String value) {
+            addCriterion("IDCard >", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardGreaterThanOrEqualTo(String value) {
+            addCriterion("IDCard >=", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardLessThan(String value) {
+            addCriterion("IDCard <", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardLessThanOrEqualTo(String value) {
+            addCriterion("IDCard <=", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardLike(String value) {
+            addCriterion("IDCard like", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardNotLike(String value) {
+            addCriterion("IDCard not like", value, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardIn(List<String> values) {
+            addCriterion("IDCard in", values, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardNotIn(List<String> values) {
+            addCriterion("IDCard not in", values, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardBetween(String value1, String value2) {
+            addCriterion("IDCard between", value1, value2, "IDCard");
+            return (Criteria) this;
+        }
+
+        public Criteria andIDCardNotBetween(String value1, String value2) {
+            addCriterion("IDCard not between", value1, value2, "IDCard");
+            return (Criteria) this;
+        }
     }
 
     public static class Criteria extends GeneratedCriteria {

+ 23 - 9
src/main/java/com/hz/employmentsite/services/impl/WechatServiceImpl.java

@@ -3,11 +3,12 @@ package com.hz.employmentsite.services.impl;
 import com.hz.employmentsite.AppConfig;
 import com.hz.employmentsite.services.service.WechatService;
 import lombok.extern.slf4j.Slf4j;
-import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
+import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -21,19 +22,30 @@ import java.util.Map;
 public class WechatServiceImpl implements WechatService {
 
     @Autowired
-    AppConfig appConfig;
+    private AppConfig appConfig;
 
+    @Autowired
+    private WxMpService wxMpService;
+
+    private final Logger logger;
+
+    public WechatServiceImpl() {
+        logger = LoggerFactory.getLogger(this.getClass());
+    }
+
+    public String getOAuthUrl(String state) {
+        return wxMpService.oauth2buildAuthorizationUrl(appConfig.wxRedirectURI, appConfig.wxAccessScope, state);
+    }
+
+    @Override
+    public String getOpenId(String code) throws WxErrorException {
+        return wxMpService.oauth2getAccessToken(code).getOpenId();
+    }
 
     @Override
     public Integer sentMsg(String toUserId, Map<String,String> sentData){
         String openId = "";
 
-        WxMpInMemoryConfigStorage wxStorage = new WxMpInMemoryConfigStorage();
-        wxStorage.setAppId(appConfig.wxAppId); //appID
-        wxStorage.setSecret(appConfig.wxAppSecret);//app密钥
-        WxMpService wxMpService = new WxMpServiceImpl();
-        wxMpService.setWxMpConfigStorage(wxStorage);
-
         //数据
         List<WxMpTemplateData> data=new ArrayList<>();
 
@@ -59,4 +71,6 @@ public class WechatServiceImpl implements WechatService {
         return 1;
     }
 
+
+
 }

+ 6 - 0
src/main/java/com/hz/employmentsite/services/service/WechatService.java

@@ -1,9 +1,15 @@
 package com.hz.employmentsite.services.service;
 
+import me.chanjar.weixin.common.error.WxErrorException;
+
 import java.util.Map;
 
 public interface WechatService {
 
+    String getOAuthUrl(String state);
+
     Integer sentMsg(String toUserId, Map<String,String> sentData);
 
+    String getOpenId(String code) throws WxErrorException;
+
 }

+ 61 - 0
src/main/java/com/hz/employmentsite/util/QrCodeUtils.java

@@ -0,0 +1,61 @@
+package com.hz.employmentsite.util;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.WriterException;
+import com.google.zxing.client.j2se.MatrixToImageWriter;
+import com.google.zxing.common.BitMatrix;
+import com.hz.employmentsite.filter.exception.RespGenerstor;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class QrCodeUtils {
+
+    public BitMatrix getQrCode(String code) throws WriterException {
+        int width = 400, height = 400;
+        String character_set = "UTF-8";
+
+        // 设置字符集编码
+        Map<EncodeHintType, Object> hints = new HashMap<>();
+        hints.put(EncodeHintType.CHARACTER_SET, character_set);
+        // 生成二维码矩阵
+        BitMatrix bitMatrix = new MultiFormatWriter().encode(code, BarcodeFormat.QR_CODE, width, height, hints);
+
+        return reduceWhite(bitMatrix,0);
+    }
+
+    public void getQrCode(OutputStream os,String code,Integer margin) throws WriterException, IOException {
+        String format = "png";
+        MatrixToImageWriter.writeToStream(reduceWhite(getQrCode(code),margin == null ? 0 : margin), format, os);
+    }
+
+    /**
+     * 缩小生成二维码白边框(删除白边 重新添加新白边)
+     *
+     * @param matrix
+     * @return
+     */
+    private static BitMatrix reduceWhite(BitMatrix matrix, int margin) {
+        int tempM = margin * 2;
+        int[] rec = matrix.getEnclosingRectangle(); // 获取二维码图案的属性
+        int resWidth = rec[2] + tempM;
+        int resHeight = rec[3] + tempM;
+        BitMatrix resMatrix = new BitMatrix(resWidth, resHeight); // 按照自定义边框生成新的BitMatrix
+        resMatrix.clear();
+        for (int i = margin; i < resWidth - margin; i++) { // 循环,将二维码图案绘制到新的bitMatrix中
+            for (int j = margin; j < resHeight - margin; j++) {
+                if (matrix.get(i - margin + rec[0], j - margin + rec[1])) {
+                    resMatrix.set(i, j);
+                }
+            }
+        }
+        return resMatrix;
+    }
+
+}

+ 3 - 0
src/main/java/com/hz/employmentsite/vo/user/UserInfoModel.java

@@ -25,5 +25,8 @@ public class UserInfoModel {
     public String createBy;
     public Date updateTime;
     public String updateBy;
+    public String userNo;
+    public String IDCard;
+    public String siteName;
 
 }

+ 4 - 2
src/main/resources/application.yml

@@ -118,8 +118,10 @@ appconfig:
     client_id: xxx
     client_secret: xxx
   wxconfig:
-    appId: ''
-    appSecret: ''
+    appId: 'wx74648e2f8589cc94'
+    appSecret: 'c177326e256261175288ef529e44a477'
     messageTemplateId: ''
+    redirectURI: 'http://www.bowintek.com/hzyz/mobile'
+    accessScope: 'snsapi_base'
 
 

+ 37 - 5
src/main/resources/mapping/PcSiteUserMapper.xml

@@ -13,6 +13,8 @@
     <result column="CreateTime" jdbcType="TIMESTAMP" property="createTime" />
     <result column="UpdateBy" jdbcType="VARCHAR" property="updateBy" />
     <result column="UpdateTime" jdbcType="TIMESTAMP" property="updateTime" />
+    <result column="UserNo" jdbcType="VARCHAR" property="userNo" />
+    <result column="IDCard" jdbcType="VARCHAR" property="IDCard" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -74,7 +76,7 @@
   </sql>
   <sql id="Base_Column_List">
     SiteUserID, SiteUserName, UserID, SiteID, Gender, Mobile, RoleID, CreateUserID, CreateTime, 
-    UpdateBy, UpdateTime
+    UpdateBy, UpdateTime, UserNo, IDCard
   </sql>
   <select id="selectByExample" parameterType="com.hz.employmentsite.model.PcSiteUserExample" resultMap="BaseResultMap">
     select
@@ -110,11 +112,13 @@
     insert into pc_site_user (SiteUserID, SiteUserName, UserID, 
       SiteID, Gender, Mobile, 
       RoleID, CreateUserID, CreateTime, 
-      UpdateBy, UpdateTime)
+      UpdateBy, UpdateTime, UserNo, 
+      IDCard)
     values (#{siteUserID,jdbcType=VARCHAR}, #{siteUserName,jdbcType=VARCHAR}, #{userID,jdbcType=VARCHAR}, 
       #{siteID,jdbcType=VARCHAR}, #{gender,jdbcType=INTEGER}, #{mobile,jdbcType=VARCHAR}, 
       #{roleID,jdbcType=INTEGER}, #{createUserID,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 
-      #{updateBy,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP})
+      #{updateBy,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP}, #{userNo,jdbcType=VARCHAR}, 
+      #{IDCard,jdbcType=VARCHAR})
   </insert>
   <insert id="insertSelective" parameterType="com.hz.employmentsite.model.PcSiteUser">
     insert into pc_site_user
@@ -152,6 +156,12 @@
       <if test="updateTime != null">
         UpdateTime,
       </if>
+      <if test="userNo != null">
+        UserNo,
+      </if>
+      <if test="IDCard != null">
+        IDCard,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="siteUserID != null">
@@ -187,6 +197,12 @@
       <if test="updateTime != null">
         #{updateTime,jdbcType=TIMESTAMP},
       </if>
+      <if test="userNo != null">
+        #{userNo,jdbcType=VARCHAR},
+      </if>
+      <if test="IDCard != null">
+        #{IDCard,jdbcType=VARCHAR},
+      </if>
     </trim>
   </insert>
   <select id="countByExample" parameterType="com.hz.employmentsite.model.PcSiteUserExample" resultType="java.lang.Long">
@@ -231,6 +247,12 @@
       <if test="row.updateTime != null">
         UpdateTime = #{row.updateTime,jdbcType=TIMESTAMP},
       </if>
+      <if test="row.userNo != null">
+        UserNo = #{row.userNo,jdbcType=VARCHAR},
+      </if>
+      <if test="row.IDCard != null">
+        IDCard = #{row.IDCard,jdbcType=VARCHAR},
+      </if>
     </set>
     <if test="example != null">
       <include refid="Update_By_Example_Where_Clause" />
@@ -248,7 +270,9 @@
       CreateUserID = #{row.createUserID,jdbcType=VARCHAR},
       CreateTime = #{row.createTime,jdbcType=TIMESTAMP},
       UpdateBy = #{row.updateBy,jdbcType=VARCHAR},
-      UpdateTime = #{row.updateTime,jdbcType=TIMESTAMP}
+      UpdateTime = #{row.updateTime,jdbcType=TIMESTAMP},
+      UserNo = #{row.userNo,jdbcType=VARCHAR},
+      IDCard = #{row.IDCard,jdbcType=VARCHAR}
     <if test="example != null">
       <include refid="Update_By_Example_Where_Clause" />
     </if>
@@ -286,6 +310,12 @@
       <if test="updateTime != null">
         UpdateTime = #{updateTime,jdbcType=TIMESTAMP},
       </if>
+      <if test="userNo != null">
+        UserNo = #{userNo,jdbcType=VARCHAR},
+      </if>
+      <if test="IDCard != null">
+        IDCard = #{IDCard,jdbcType=VARCHAR},
+      </if>
     </set>
     where SiteUserID = #{siteUserID,jdbcType=VARCHAR}
   </update>
@@ -300,7 +330,9 @@
       CreateUserID = #{createUserID,jdbcType=VARCHAR},
       CreateTime = #{createTime,jdbcType=TIMESTAMP},
       UpdateBy = #{updateBy,jdbcType=VARCHAR},
-      UpdateTime = #{updateTime,jdbcType=TIMESTAMP}
+      UpdateTime = #{updateTime,jdbcType=TIMESTAMP},
+      UserNo = #{userNo,jdbcType=VARCHAR},
+      IDCard = #{IDCard,jdbcType=VARCHAR}
     where SiteUserID = #{siteUserID,jdbcType=VARCHAR}
   </update>
 </mapper>

+ 4 - 1
src/main/resources/mapping/cquery/SysUserCQuery.xml

@@ -84,8 +84,11 @@
 
     <select id="selectUserInfo" resultType="com.hz.employmentsite.vo.user.UserInfoModel">
         select theUser.*,dic_userType.Name as UserTypeName,siteUser.SiteID,siteUser.SiteUserName,siteUser.Mobile as UserMobile,
-               siteUser.Gender,dic_genderType.Name as GenderName from sys_user theUser
+               siteUser.Gender,dic_genderType.Name as GenderName
+        ,siteUser.userNo,siteUser.IDCard,site.siteName
+        from sys_user theUser
         left join pc_site_user siteUser on theUser.UserID = siteUser.UserID
+        left join pc_site site on siteUser.SiteID = site.SiteID
         left join (select * from sys_dictionary_item where DictionaryCode ='UserType') dic_userType
         on theUser.UserTypeID = dic_userType.value
         left join (select * from sys_dictionary_item where DictionaryCode ='Gender') dic_genderType