19 changed files with 1209 additions and 70 deletions
@ -0,0 +1,110 @@ |
|||
## 加密规则 |
|||
|
|||
``` |
|||
1、分解步骤 |
|||
one = md5(CodeString)+md5(AppKey) |
|||
two = md5(one)+AppKey |
|||
therr = md5(two) |
|||
2、合并 |
|||
md5(md5(md5(CodeString)+md5(AppKey))+AppKey) |
|||
``` |
|||
|
|||
## 接口访问规则 |
|||
|
|||
1、以POST方式访问 http://xxxx/empower/gaintoken |
|||
|
|||
#### 参数 |
|||
|
|||
```json |
|||
{ |
|||
"username":"jindie", |
|||
"password":"jindie123" |
|||
} |
|||
``` |
|||
|
|||
| 参数 | 说明 | |
|||
| -------- | ---- | |
|||
| username | 账号 | |
|||
| password | 密码 | |
|||
|
|||
#### 返回值 |
|||
|
|||
```json |
|||
{ |
|||
"code": 0, |
|||
"msg": "成功", |
|||
"data": { |
|||
"token": "6235a9de7109ba50852f3f9d3b3052ae", |
|||
"number": "16534571868477" |
|||
} |
|||
} |
|||
``` |
|||
|
|||
| 参数 | 说明 | | |
|||
| ---- | ------ | -------------------------- | |
|||
| code | | 状态码 | |
|||
| msg | | 信息 | |
|||
| data | | 附加值 | |
|||
| | token | Token(有效时间为180分钟) | |
|||
| | number | 随机数 | |
|||
|
|||
1、以POST方式访问 http://xxxx/接口 |
|||
|
|||
#### Header参数 |
|||
|
|||
| 参数 | 说明 | |
|||
| ------------ | ------------------------------ | |
|||
| token | 获取到得参数 | |
|||
| number | 加密后得随机数(参考加密规则) | |
|||
| Content-Type | 内容类型 | |
|||
| Origin | 站点信息 | |
|||
| User-Agent | 用户代理 | |
|||
|
|||
#### Body参数 (接口需要得添加参数) |
|||
|
|||
```json |
|||
{ |
|||
"page":"1", |
|||
"pagesize":"20" |
|||
} |
|||
``` |
|||
|
|||
| 参数 | 说明 | |
|||
| -------- | -------------- | |
|||
| page | 页码 | |
|||
| pagesize | 每页显示多少条 | |
|||
|
|||
#### 返回值 |
|||
|
|||
```json |
|||
{ |
|||
"code": 0, |
|||
"msg": "成功", |
|||
"data": { |
|||
"count": 20, |
|||
"page": 1, |
|||
"pageSize": 20, |
|||
"total": 1147, |
|||
"list": [] |
|||
} |
|||
} |
|||
``` |
|||
|
|||
| 参数 | 说明 | | |
|||
| ---- | -------- | -------------- | |
|||
| code | | 状态码 | |
|||
| msg | | 信息 | |
|||
| data | | 附加值 | |
|||
| | count | 本页共多少数据 | |
|||
| | page | 当前页码 | |
|||
| | pageSize | 每页显示多少条 | |
|||
| | .... | .... | |
|||
|
|||
#### 认证信息 |
|||
|
|||
| 参数 | 说明 | |
|||
| ---------------- | ------------------------ | |
|||
| UserKey | shuziluanshen | |
|||
| Password | shu@zi#luan$shen | |
|||
| VerificationCode | mingqi_hr | |
|||
| 访问地址 | http://120.224.6.6:39168 | |
|||
@ -0,0 +1,331 @@ |
|||
package administrativeorganization |
|||
|
|||
import ( |
|||
"hr_server/models" |
|||
"hr_server/models/hrmodels" |
|||
"hr_server/overall" |
|||
"hr_server/overall/overallhandle" |
|||
"regexp" |
|||
"sort" |
|||
"strconv" |
|||
|
|||
"github.com/gin-gonic/gin" |
|||
) |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2023-08-22 08:56:17 |
|||
@ 功能: 自定义表单专用行政组织树 |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func (o *OrganizationApi) OrgTreeList(c *gin.Context) { |
|||
var requestData overallhandle.PublicId[int64] |
|||
c.ShouldBindJSON(&requestData) |
|||
var orgContList []hrmodels.OrgCont |
|||
err := overall.CONSTANT_DB_HR.Model(&hrmodels.OrgCont{}).Select("`id`,`name`,`superior`,`sort`,`state`").Where("state = ?", 1).Find(&orgContList).Error |
|||
if err != nil && len(orgContList) < 1 { |
|||
overallhandle.Result(0, "未获取到数据", c) |
|||
return |
|||
} |
|||
var formOrgTreeList []CustomerFormCont |
|||
for _, v := range orgContList { |
|||
if !overallhandle.IsInTrue[int64](v.Id, []int64{281}) { |
|||
var formOrgTreeCont CustomerFormCont |
|||
formOrgTreeCont.Id = v.Id |
|||
formOrgTreeCont.ParentId = v.Superior |
|||
formOrgTreeCont.Name = v.Name |
|||
formOrgTreeCont.Sort = v.Sort |
|||
formOrgTreeCont.Status = v.State |
|||
formOrgTreeCont.Remark = "" |
|||
formOrgTreeList = append(formOrgTreeList, formOrgTreeCont) |
|||
} |
|||
|
|||
} |
|||
sort.Slice(formOrgTreeList, func(i, j int) bool { |
|||
return formOrgTreeList[i].Sort < formOrgTreeList[j].Sort |
|||
}) |
|||
if requestData.Id == 0 { |
|||
requestData.Id = 313 |
|||
} |
|||
govMapThree := GovOrgTreeForm(requestData.Id, formOrgTreeList) |
|||
var snedCont SendOrgTreeAry |
|||
dictAry := overallhandle.MapOutint() |
|||
dictAry[0] = "停用" |
|||
dictAry[1] = "正常" |
|||
snedCont.Dict.Status = dictAry |
|||
snedCont.List = govMapThree |
|||
snedCont.PageInfo.Total = len(formOrgTreeList) |
|||
overallhandle.Result(0, snedCont, c) |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2023-08-22 09:15:59 |
|||
@ 功能: 表单行政组织树 |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func GovOrgTreeForm(parentId int64, govList []CustomerFormCont) (govMap []CustomerFormOrgTree) { |
|||
for i := 0; i < len(govList); i++ { |
|||
if govList[i].ParentId == parentId { |
|||
var govCont CustomerFormOrgTree |
|||
govCont.Id = govList[i].Id |
|||
govCont.ParentId = govList[i].ParentId |
|||
govCont.Name = govList[i].Name |
|||
govCont.Sort = govList[i].Sort |
|||
govCont.Status = govList[i].Status |
|||
govCont.Remark = govList[i].Remark |
|||
govCont.Children = GovOrgTreeForm(govList[i].Id, govList) |
|||
govMap = append(govMap, govCont) |
|||
} |
|||
} |
|||
return |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2023-08-23 09:45:34 |
|||
@ 功能: 自定义表单搜索人员 |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func (o *OrganizationApi) SearchUserList(c *gin.Context) { |
|||
var requestData SearchUserCont |
|||
c.ShouldBindJSON(&requestData) |
|||
if requestData.PageInfo.PageIndex == 0 { |
|||
requestData.PageInfo.PageIndex = 1 |
|||
} |
|||
if requestData.PageInfo.PageSize == 0 { |
|||
requestData.PageInfo.PageSize = 20 |
|||
} |
|||
gormDb := overall.CONSTANT_DB_HR.Model(&models.PersonArchives{}).Select("`id`").Where("`number` NOT LIKE ?", "%W%") |
|||
if requestData.Name != "" { |
|||
gormDb = gormDb.Where("number LIKE ? OR name LIKE ?", "%"+requestData.Name+"%", "%"+requestData.Name+"%") |
|||
} |
|||
if requestData.Department != 0 { |
|||
var sunAry overallhandle.AllSunList[int64] |
|||
sunAry.GetAllSunOrg(requestData.Department) |
|||
sunAry.SunList = append(sunAry.SunList, requestData.Department) |
|||
gormDb = gormDb.Where("admin_org IN ?", sunAry.SunList) |
|||
} |
|||
gormDb = gormDb.Where("emp_type BETWEEN ? AND ?", 1, 10) |
|||
var total int64 |
|||
totalErr := gormDb.Count(&total).Error |
|||
if totalErr != nil { |
|||
total = 0 |
|||
} |
|||
var userList []CustomerFormUser |
|||
var idAry []int64 |
|||
err := gormDb.Order("company ASC,maindeparment ASC,admin_org ASC,position ASC").Limit(requestData.PageInfo.PageSize).Offset(overallhandle.LimitPage(requestData.PageInfo.PageIndex, requestData.PageInfo.PageSize)).Find(&idAry).Error |
|||
if err != nil || len(idAry) < 1 { |
|||
overallhandle.ResultList(0, requestData.PageInfo.PageIndex, requestData.PageInfo.PageSize, total, int64(len(userList)), userList, c) |
|||
return |
|||
} |
|||
var manContList []models.ManCont |
|||
err = overall.CONSTANT_DB_HR.Model(&models.ManCont{}).Select("`id`,`number`,`name`,`icon`,`icon_photo`,`admin_org`,`company`,`maindeparment`,`key`,`mobilephone`").Where("`id` IN ?", idAry).Find(&manContList).Error |
|||
if err != nil || len(manContList) < 1 { |
|||
overallhandle.ResultList(0, requestData.PageInfo.PageIndex, requestData.PageInfo.PageSize, total, int64(len(userList)), userList, c) |
|||
return |
|||
} |
|||
for _, v := range manContList { |
|||
var userCont CustomerFormUser |
|||
userCont.Id = v.Id //id"`
|
|||
userCont.UserKey = strconv.FormatInt(v.Key, 10) //userkey"`
|
|||
userCont.Number = v.Number //number"`
|
|||
userCont.Name = v.Name //name"`
|
|||
userCont.Icon = v.Icon //icon"`
|
|||
if v.Icon == "" && v.IconPhoto != "" { |
|||
userCont.Icon = v.IconPhoto //icon"`
|
|||
} |
|||
var orgIdMap []int64 |
|||
userCont.Company = v.Company //company"`
|
|||
if v.Company != 0 { |
|||
if !overallhandle.IsInTrue[int64](v.Company, orgIdMap) { |
|||
orgIdMap = append(orgIdMap, v.Company) |
|||
} |
|||
// var getSpurDepart models.AdministrativeOrganization
|
|||
// getSpurDepart.GetCont(map[string]interface{}{"`id`": v.Company}, "name")
|
|||
// userCont.CompanyName = getSpurDepart.Name
|
|||
} |
|||
userCont.MainDeparment = v.MainDeparment //maindeparment"`
|
|||
if v.MainDeparment != 0 { |
|||
if !overallhandle.IsInTrue[int64](v.MainDeparment, orgIdMap) { |
|||
orgIdMap = append(orgIdMap, v.MainDeparment) |
|||
} |
|||
// var getSpurDepartMain models.AdministrativeOrganization
|
|||
// getSpurDepartMain.GetCont(map[string]interface{}{"`id`": v.MainDeparment}, "name")
|
|||
// userCont.MainDeparmentName = getSpurDepartMain.Name //maindeparmentname"`
|
|||
} |
|||
userCont.AdminOrg = v.AdminOrg //adminorg"`
|
|||
if v.AdminOrg != 0 { |
|||
if !overallhandle.IsInTrue[int64](v.AdminOrg, orgIdMap) { |
|||
orgIdMap = append(orgIdMap, v.AdminOrg) |
|||
} |
|||
// var orgCont models.AdministrativeOrganization
|
|||
// orgCont.GetCont(map[string]interface{}{"`id`": v.AdminOrg}, "name")
|
|||
// userCont.AdminOrgName = orgCont.Name //adminorgname"`
|
|||
} |
|||
if len(orgIdMap) > 0 { |
|||
var orgAllCont []models.AdministrativeOrganization |
|||
overall.CONSTANT_DB_HR.Model(&models.AdministrativeOrganization{}).Select("`id`,`name`").Where("`id` IN ?", orgIdMap).Find(&orgAllCont) |
|||
if len(orgAllCont) > 0 { |
|||
for _, org := range orgAllCont { |
|||
if org.Id == v.Company { |
|||
userCont.CompanyName = org.Name |
|||
} |
|||
if org.Id == v.MainDeparment { |
|||
userCont.MainDeparmentName = org.Name |
|||
} |
|||
if org.Id == v.AdminOrg { |
|||
userCont.AdminOrgName = org.Name |
|||
} |
|||
} |
|||
} |
|||
} |
|||
userCont.Tel = v.Mobilephone |
|||
userList = append(userList, userCont) |
|||
} |
|||
overallhandle.ResultList(0, requestData.PageInfo.PageIndex, requestData.PageInfo.PageSize, total, int64(len(userList)), userList, c) |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2023-10-09 13:37:43 |
|||
@ 功能:根据选定人员条件查询人员(自定义表单专用) |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func (o *OrganizationApi) SearchUserCustomerFormList(c *gin.Context) { |
|||
var requestData overallhandle.NameOverall |
|||
err := c.ShouldBindJSON(&requestData) |
|||
if err != nil || requestData.Name == "" { |
|||
overallhandle.Result(100, err, c) |
|||
return |
|||
} |
|||
reg1 := regexp.MustCompile(`\(([^)]+)\)`) |
|||
jieguo := reg1.FindAllStringSubmatch(requestData.Name, -1) |
|||
var userNumber []string |
|||
if len(jieguo) > 0 { |
|||
for _, v := range jieguo { |
|||
vLen := len(v) |
|||
if vLen > 0 { |
|||
|
|||
// numInt, _ := strconv.ParseInt(v[vLen-1], 10, 64)
|
|||
// fmt.Printf("%v: %v\n", v, numInt)
|
|||
if !overallhandle.IsInTrue[string](v[vLen-1], userNumber) { |
|||
userNumber = append(userNumber, v[vLen-1]) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
var userList []CustomerFormUser |
|||
if len(userNumber) < 1 { |
|||
overallhandle.Result(0, userList, c) |
|||
} |
|||
var manContList []models.ManCont |
|||
err = overall.CONSTANT_DB_HR.Model(&models.ManCont{}).Select("`id`,`number`,`name`,`icon`,`icon_photo`,`admin_org`,`company`,`maindeparment`,`key`,`mobilephone`").Where("`number` IN ?", userNumber).Find(&manContList).Error |
|||
if err != nil || len(manContList) < 1 { |
|||
overallhandle.Result(0, userList, c) |
|||
return |
|||
} |
|||
for _, v := range manContList { |
|||
var userCont CustomerFormUser |
|||
userCont.Id = v.Id //id"`
|
|||
userCont.UserKey = strconv.FormatInt(v.Key, 10) //userkey"`
|
|||
userCont.Number = v.Number //number"`
|
|||
userCont.Name = v.Name //name"`
|
|||
userCont.Icon = v.Icon //icon"`
|
|||
if v.Icon == "" && v.IconPhoto != "" { |
|||
userCont.Icon = v.IconPhoto //icon"`
|
|||
} |
|||
var orgIdMap []int64 |
|||
userCont.Company = v.Company //company"`
|
|||
if v.Company != 0 { |
|||
if !overallhandle.IsInTrue[int64](v.Company, orgIdMap) { |
|||
orgIdMap = append(orgIdMap, v.Company) |
|||
} |
|||
// var getSpurDepart models.AdministrativeOrganization
|
|||
// getSpurDepart.GetCont(map[string]interface{}{"`id`": v.Company}, "name")
|
|||
// userCont.CompanyName = getSpurDepart.Name
|
|||
} |
|||
userCont.MainDeparment = v.MainDeparment //maindeparment"`
|
|||
if v.MainDeparment != 0 { |
|||
if !overallhandle.IsInTrue[int64](v.MainDeparment, orgIdMap) { |
|||
orgIdMap = append(orgIdMap, v.MainDeparment) |
|||
} |
|||
// var getSpurDepartMain models.AdministrativeOrganization
|
|||
// getSpurDepartMain.GetCont(map[string]interface{}{"`id`": v.MainDeparment}, "name")
|
|||
// userCont.MainDeparmentName = getSpurDepartMain.Name //maindeparmentname"`
|
|||
} |
|||
userCont.AdminOrg = v.AdminOrg //adminorg"`
|
|||
if v.AdminOrg != 0 { |
|||
if !overallhandle.IsInTrue[int64](v.AdminOrg, orgIdMap) { |
|||
orgIdMap = append(orgIdMap, v.AdminOrg) |
|||
} |
|||
// var orgCont models.AdministrativeOrganization
|
|||
// orgCont.GetCont(map[string]interface{}{"`id`": v.AdminOrg}, "name")
|
|||
// userCont.AdminOrgName = orgCont.Name //adminorgname"`
|
|||
} |
|||
if len(orgIdMap) > 0 { |
|||
var orgAllCont []models.AdministrativeOrganization |
|||
overall.CONSTANT_DB_HR.Model(&models.AdministrativeOrganization{}).Select("`id`,`name`").Where("`id` IN ?", orgIdMap).Find(&orgAllCont) |
|||
if len(orgAllCont) > 0 { |
|||
for _, org := range orgAllCont { |
|||
if org.Id == v.Company { |
|||
userCont.CompanyName = org.Name |
|||
} |
|||
if org.Id == v.MainDeparment { |
|||
userCont.MainDeparmentName = org.Name |
|||
} |
|||
if org.Id == v.AdminOrg { |
|||
userCont.AdminOrgName = org.Name |
|||
} |
|||
} |
|||
} |
|||
} |
|||
userCont.Tel = v.Mobilephone |
|||
userList = append(userList, userCont) |
|||
} |
|||
overallhandle.Result(0, userList, c) |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
package workWechat |
|||
|
|||
import ( |
|||
"hr_server/models" |
|||
"hr_server/overall/overallhandle" |
|||
|
|||
"github.com/gin-gonic/gin" |
|||
) |
|||
|
|||
type ApiMethod struct{} |
|||
|
|||
// 微信相关项目入口
|
|||
func (a *ApiMethod) Index(c *gin.Context) { |
|||
outputCont := overallhandle.MapOut() |
|||
outputCont["index"] = "微信相关项目入口" |
|||
overallhandle.Result(0, outputCont, c) |
|||
} |
|||
|
|||
// 微信返回结构体
|
|||
type RevokeMsgSendCallBack struct { |
|||
Errcode int `json:"errcode"` //返回码
|
|||
Errmsg string `json:"errmsg"` //对返回码的文本描述内容
|
|||
} |
|||
|
|||
// 微信返回结构体(Token)
|
|||
type WeChatCallBack struct { |
|||
RevokeMsgSendCallBack |
|||
Accesstoken string `json:"access_token"` |
|||
Expiresin int64 `json:"expires_in"` |
|||
Ticket string `json:"ticket"` |
|||
} |
|||
|
|||
// 获取Token参数
|
|||
type WechatTokanVal struct { |
|||
SystemApp string `json:"system_app"` |
|||
IsAgain int `json:"is_again"` |
|||
} |
|||
|
|||
// 企业微信身份认证
|
|||
type WorkWechatUserAuter struct { |
|||
RevokeMsgSendCallBack |
|||
Userid string `json:"userid"` // 成员UserID。若需要获得用户详情信息,可调用通讯录接口:读取成员。如果是互联企业/企业互联/上下游,则返回的UserId格式如:CorpId/userid
|
|||
UserTicket string `json:"user_ticket"` //成员票据,最大为512字节,有效期为1800s。scope为snsapi_privateinfo,且用户在应用可见范围之内时返回此参数。后续利用该参数可以获取用户信息或敏感信息,参见"获取访问用户敏感信息"。暂时不支持上下游或/企业互联场景
|
|||
OpenId string `json:"openid"` //非企业成员的标识,对当前企业唯一。不超过64字节
|
|||
ExternalUserid string `json:"external_userid"` //外部联系人id,当且仅当用户是企业的客户,且跟进人在应用的可见范围内时返回。如果是第三方应用调用,针对同一个客户,同一个服务商不同应用获取到的id相同
|
|||
} |
|||
|
|||
// 身份认证返回
|
|||
type WechatVerifyIdentity struct { |
|||
UserKey string `json:"userkey"` |
|||
Token string `json:"token"` |
|||
UserInfo models.ManCont `json:"userinfo"` |
|||
} |
|||
@ -0,0 +1,163 @@ |
|||
package workWechat |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"errors" |
|||
"fmt" |
|||
"hr_server/grocerystore" |
|||
"hr_server/overall" |
|||
"hr_server/overall/overallhandle" |
|||
) |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-18 14:11:11 |
|||
@ 功能: 获取token |
|||
@ 参数 |
|||
|
|||
#systemApp 系统 |
|||
#key 身份KEy |
|||
#isAgain 重新授权 1:否,2:是 |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
#token token值 |
|||
#err 状态 |
|||
*/ |
|||
func GainWechatToken(systemApp, key string, isAgain int) (token string, err error) { |
|||
companyId := overall.CONSTANT_CONFIG.WechatCompany.CompanyId |
|||
redisFileKey := fmt.Sprintf("Wechat:Token:%v_%v_%v", companyId, key, overall.CONSTANT_CONFIG.RedisPrefixStr.Alias) |
|||
var secretStr string |
|||
switch systemApp { |
|||
case "kpi": |
|||
redisFileKey = fmt.Sprintf("%v_%v_%v", redisFileKey, systemApp, overall.CONSTANT_CONFIG.WechatKpi.Agentid) |
|||
secretStr = overall.CONSTANT_CONFIG.WechatKpi.Secret |
|||
case "school": |
|||
redisFileKey = fmt.Sprintf("%v_%v_%v", redisFileKey, systemApp, overall.CONSTANT_CONFIG.WechatSchool.Agentid) |
|||
secretStr = overall.CONSTANT_CONFIG.WechatSchool.Secret |
|||
default: |
|||
redisFileKey = fmt.Sprintf("%v_%v", redisFileKey, systemApp) |
|||
} |
|||
redisClient := grocerystore.RunRedis(overall.CONSTANT_REDIS4) //设定redis库
|
|||
if isAgain != 1 { |
|||
token, err = getWechatServer(companyId, secretStr) |
|||
if err != nil { |
|||
return |
|||
} |
|||
redisClient.SetRedisTime(7200) |
|||
redisClient.Set(redisFileKey, token) |
|||
} else { |
|||
isTrue, tokens := redisClient.Get(redisFileKey) |
|||
if isTrue && token != "" { |
|||
err = nil |
|||
token = tokens |
|||
return |
|||
} else { |
|||
token, err = getWechatServer(companyId, secretStr) |
|||
if err != nil { |
|||
return |
|||
} |
|||
redisClient.SetRedisTime(7200) |
|||
redisClient.Set(redisFileKey, token) |
|||
} |
|||
} |
|||
|
|||
return |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-18 14:23:24 |
|||
@ 功能: 获取微信Token(链接微信服务器) |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func getWechatServer(companyId, secretStr string) (token string, err error) { |
|||
getTokenUrl := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%v&corpsecret=%v", companyId, secretStr) |
|||
// getTokenUrl := "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=" + companyId + "&corpsecret=" + secretStr
|
|||
tokenByte := overallhandle.CurlGet(getTokenUrl) |
|||
var callBackCont WeChatCallBack |
|||
err = json.Unmarshal(tokenByte, &callBackCont) |
|||
if err != nil { |
|||
return |
|||
} |
|||
if callBackCont.Errcode != 0 { |
|||
err = errors.New("未能获得到TOKEN!") |
|||
return |
|||
} |
|||
token = callBackCont.Accesstoken |
|||
return |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-18 17:00:54 |
|||
@ 功能: 获取企业的jsapi_ticket 或 获取应用的jsapi_ticket |
|||
@ 参数 |
|||
|
|||
#systemApp 系统 |
|||
#key 身份识别 |
|||
#calss 1:应用,2:企业 |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func GainJsapiTicket(systemApp, key string, class int) (jsApiTickerStr string, err error) { |
|||
|
|||
jsApiTicketRedis := fmt.Sprintf("Wechat:JsapiTicket:%v_%v_%v", systemApp, overall.CONSTANT_CONFIG.RedisPrefixStr.Alias, class) |
|||
redisClient := grocerystore.RunRedis(overall.CONSTANT_REDIS4) |
|||
isTrue, jsApiTickerInfo := redisClient.Get(jsApiTicketRedis) //读取redis数据
|
|||
if isTrue { |
|||
jsApiTickerStr = jsApiTickerInfo |
|||
err = nil |
|||
return |
|||
} else { |
|||
var sendUrlstr string |
|||
//获取token
|
|||
tokenStr, errs := GainWechatToken(systemApp, key, 1) |
|||
if errs != nil { |
|||
err = errs |
|||
return |
|||
} |
|||
if class != 1 { |
|||
sendUrlstr = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=" + tokenStr //获取企业级
|
|||
} else { |
|||
sendUrlstr = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?access_token=" + tokenStr + "&type=agent_config" //获取应用级
|
|||
} |
|||
//获取企业微信jsapi_ticket
|
|||
jsapiTickerMsg := overallhandle.CurlGet(sendUrlstr) |
|||
var callBackCont WeChatCallBack |
|||
err = json.Unmarshal(jsapiTickerMsg, &callBackCont) |
|||
if err != nil { |
|||
return |
|||
} |
|||
if callBackCont.Errcode != 0 { |
|||
return |
|||
} |
|||
jsApiTickerStr = callBackCont.Ticket |
|||
redisClient.SetRedisTime(7200) |
|||
redisClient.Set(jsApiTicketRedis, jsApiTickerStr) |
|||
} |
|||
return |
|||
} |
|||
@ -0,0 +1,350 @@ |
|||
package workWechat |
|||
|
|||
import ( |
|||
"encoding/json" |
|||
"errors" |
|||
"fmt" |
|||
"hr_server/grocerystore" |
|||
"hr_server/overall" |
|||
"hr_server/overall/overallhandle" |
|||
"net/http" |
|||
"net/url" |
|||
"reflect" |
|||
"strconv" |
|||
"strings" |
|||
|
|||
"github.com/gin-gonic/gin" |
|||
) |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-18 15:56:15 |
|||
@ 功能: 获取Token |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func (a *ApiMethod) GainWechatToken(c *gin.Context) { |
|||
var requestData WechatTokanVal |
|||
err := c.ShouldBindJSON(&requestData) |
|||
if err != nil { |
|||
overallhandle.Result(100, err, c) |
|||
return |
|||
} |
|||
host := c.Request.Header.Get("Host") |
|||
userAgent := c.Request.Header.Get("User-Agent") |
|||
wechatTokenStr := fmt.Sprintf("%v_%v", host, userAgent) |
|||
var md5JiaMi overallhandle.Md5Encryption |
|||
md5JiaMi.Md5EncryptionInit(wechatTokenStr) |
|||
md5Token := md5JiaMi.Md5EncryptionAlgorithm() |
|||
token, err := GainWechatToken(requestData.SystemApp, md5Token, requestData.IsAgain) |
|||
if err != nil { |
|||
overallhandle.Result(107, err, c) |
|||
return |
|||
} |
|||
overallhandle.Result(0, token, c) |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-19 16:00:09 |
|||
@ 功能: 获取企业的jsapi_ticket 或 获取应用的jsapi_ticket |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func (a *ApiMethod) WechatJsapiTicket(c *gin.Context) { |
|||
var requestData WechatTokanVal |
|||
err := c.ShouldBindJSON(&requestData) |
|||
if err != nil { |
|||
overallhandle.Result(100, err, c) |
|||
return |
|||
} |
|||
host := c.Request.Header.Get("Host") |
|||
userAgent := c.Request.Header.Get("User-Agent") |
|||
wechatTokenStr := fmt.Sprintf("%v_%v", host, userAgent) |
|||
var md5JiaMi overallhandle.Md5Encryption |
|||
md5JiaMi.Md5EncryptionInit(wechatTokenStr) |
|||
md5Token := md5JiaMi.Md5EncryptionAlgorithm() |
|||
jsApiTicker, err := GainJsapiTicket(requestData.SystemApp, md5Token, requestData.IsAgain) |
|||
if err != nil { |
|||
overallhandle.Result(107, err, c) |
|||
return |
|||
} |
|||
overallhandle.Result(0, jsApiTicker, c) |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-20 08:57:14 |
|||
@ 功能: 获取身份认证 |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func (a *ApiMethod) AuthenticationUser(c *gin.Context) { |
|||
host := c.Request.Header.Get("Host") |
|||
userAgent := c.Request.Header.Get("User-Agent") |
|||
wechatTokenStr := fmt.Sprintf("%v_%v", host, userAgent) |
|||
var md5JiaMi overallhandle.Md5Encryption |
|||
md5JiaMi.Md5EncryptionInit(wechatTokenStr) |
|||
md5Token := md5JiaMi.Md5EncryptionAlgorithm() |
|||
|
|||
systemApp := c.Query("systemapp") |
|||
if systemApp == "" { |
|||
systemApp = "hr" |
|||
} |
|||
isAgain := c.Query("isagain") |
|||
if isAgain == "" { |
|||
isAgain = "1" |
|||
} |
|||
isAgainInt, _ := strconv.Atoi(isAgain) |
|||
if isAgainInt == 0 { |
|||
isAgainInt = 1 |
|||
} |
|||
token, err := GainWechatToken(systemApp, md5Token, isAgainInt) |
|||
if err != nil { |
|||
overallhandle.Result(1, token, c, "身份认证失败") |
|||
return |
|||
} |
|||
var additional []string |
|||
additional = append(additional, fmt.Sprintf("systemapp=%v", systemApp)) |
|||
additional = append(additional, fmt.Sprintf("isagain=%v", isAgainInt)) |
|||
userNum := c.Query("usernum") |
|||
if userNum != "" { |
|||
additional = append(additional, fmt.Sprintf("usernum=%v", userNum)) |
|||
} |
|||
|
|||
urlParameter := strings.Join(additional, "&") |
|||
//重定向身份认证
|
|||
callBackUrl := url.QueryEscape(fmt.Sprintf("%v/kpiapi/wechat/callbackauthuser?%v", overall.CONSTANT_CONFIG.Appsetup.WebUrl, urlParameter)) |
|||
redirectUrl := fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%v&redirect_uri=%v&response_type=code&scope=snsapi_base&state=%v#wechat_redirect", overall.CONSTANT_CONFIG.WechatCompany.CompanyId, callBackUrl, token) |
|||
// formUrl := c.Request.URL.Path
|
|||
// formUrls := c.Request.RequestURI
|
|||
|
|||
// sendData := overallhandle.MapOut()
|
|||
// sendData["formUrl"] = formUrl
|
|||
// sendData["formUrls"] = formUrls
|
|||
// sendData["userNum"] = userNum
|
|||
// sendData["token"] = token
|
|||
// sendData["callBackUrl"] = callBackUrl
|
|||
// sendData["urlParameter"] = urlParameter
|
|||
// sendData["redirectUrl"] = redirectUrl
|
|||
// overallhandle.Result(0, sendData, c)
|
|||
c.Redirect(http.StatusMovedPermanently, redirectUrl) |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-20 13:53:51 |
|||
@ 功能: 企业微信身份回调认证 |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func (a *ApiMethod) CallBackAuthUser(c *gin.Context) { |
|||
code := c.Query("code") |
|||
state := c.Query("state") |
|||
if code == "" || state == "" { |
|||
overallhandle.Result(1, code, c, "未能查询到您的信息!企业微信授权失败!") |
|||
return |
|||
} |
|||
systemApp := c.Query("systemapp") |
|||
if systemApp == "" { |
|||
systemApp = "hr" |
|||
} |
|||
isAgain := c.Query("isagain") |
|||
if isAgain == "" { |
|||
isAgain = "1" |
|||
} |
|||
userNum := c.Query("usernum") |
|||
gainWechatInfo := fmt.Sprintf("https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=%v&code=%v", state, code) |
|||
wechatInfoByte := overallhandle.CurlGet(gainWechatInfo) |
|||
var callBackWechatInfo WorkWechatUserAuter |
|||
err := json.Unmarshal(wechatInfoByte, &callBackWechatInfo) |
|||
if err != nil { |
|||
overallhandle.Result(1, err, c, "未能查询到您的信息!企业微信授权失败!2") |
|||
return |
|||
} |
|||
if callBackWechatInfo.Errcode != 0 { |
|||
|
|||
if callBackWechatInfo.Errcode == 42001 { |
|||
AgainEmpower(c) |
|||
return |
|||
} |
|||
overallhandle.Result(1, callBackWechatInfo, c, "未能查询到您的信息!企业微信授权失败!3") |
|||
return |
|||
} |
|||
var userWechatId string |
|||
if callBackWechatInfo.OpenId != "" { |
|||
userWechatId = callBackWechatInfo.OpenId |
|||
} |
|||
if callBackWechatInfo.Userid != "" { |
|||
userWechatId = callBackWechatInfo.Userid |
|||
} |
|||
if userWechatId == "" { |
|||
overallhandle.Result(1, err, c, "未能查询到您的信息!企业微信授权失败!") |
|||
return |
|||
} |
|||
wechatCont, err := SetUpWechatInfo(code) |
|||
if err != nil { |
|||
overallhandle.Result(1, err, c) |
|||
return |
|||
} |
|||
callBackLoginUrl := fmt.Sprintf("%v/#/?usernum=%v&openid=%v&userkey=%v&token=%v", overall.CONSTANT_CONFIG.Appsetup.WebUrl, userNum, wechatCont.UserInfo.Number, wechatCont.UserKey, wechatCont.Token) |
|||
c.Redirect(http.StatusMovedPermanently, callBackLoginUrl) |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-20 14:06:00 |
|||
@ 功能: 获取登陆人员信息 |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func SetUpWechatInfo(wechatOpenId string) (sendData WechatVerifyIdentity, err error) { |
|||
err = overall.CONSTANT_DB_HR.Where("`wechat` = ? OR `work_wechat` = ?", wechatOpenId, wechatOpenId).First(&sendData.UserInfo).Error |
|||
if err != nil { |
|||
return |
|||
} |
|||
if !overallhandle.IsInTrue[int](sendData.UserInfo.EmpType, []int{1, 3, 4, 5, 6, 7, 8, 9, 10}) { |
|||
err = errors.New("对不起!你没有权限进入!") |
|||
return |
|||
} |
|||
// uuIdVal := overallhandle.OnlyOneNumber(3)
|
|||
userAgent := overall.CONSTANT_CONFIG.Appsetup.AppKey |
|||
var md5JiaMi overallhandle.Md5Encryption |
|||
md5JiaMi.Md5EncryptionInit(userAgent) |
|||
md5Token := md5JiaMi.Md5EncryptionAlgorithm() |
|||
//工号MD5加密
|
|||
var md5JiaMiNumber overallhandle.Md5Encryption |
|||
md5JiaMiNumber.Md5EncryptionInit(sendData.UserInfo.Number) |
|||
sendData.UserKey = md5JiaMiNumber.Md5EncryptionAlgorithm() |
|||
|
|||
sha1Str := fmt.Sprintf("%v%v%v%v", sendData.UserKey, sendData.UserInfo.Number, sendData.UserInfo.Password, md5Token) |
|||
sendData.Token = overallhandle.Sha1Encryption(sha1Str) |
|||
//组成Token字符串进行
|
|||
|
|||
wechatUserToken := fmt.Sprintf("%v%v", sendData.UserKey, sendData.Token) |
|||
var md5JiaMiWechat overallhandle.Md5Encryption |
|||
md5JiaMiWechat.Md5EncryptionInit(wechatUserToken) |
|||
wechatRedisKey := md5JiaMiWechat.Md5EncryptionAlgorithm() |
|||
wechatRedisToekn := fmt.Sprintf("Wechat:UserToken:%v_%v", wechatRedisKey, overall.CONSTANT_CONFIG.RedisPrefixStr.Alias) |
|||
|
|||
saveInfo := overallhandle.MapOut() |
|||
structValue := reflect.ValueOf(sendData.UserInfo) |
|||
structType := structValue.Type() |
|||
for i := 0; i < structValue.NumField(); i++ { |
|||
fieldValue := structValue.Field(i) |
|||
fieldType := structType.Field(i) |
|||
// fmt.Printf("%s: %v\n", fieldType.Name, fieldValue.Interface())
|
|||
saveInfo[fieldType.Name] = fieldValue.Interface() |
|||
} |
|||
redisClient := grocerystore.RunRedis(overall.CONSTANT_REDIS4) //设定redis库
|
|||
redisClient.SetRedisTime(7200) |
|||
redisClient.HashMsetAdd(wechatRedisToekn, saveInfo) |
|||
return |
|||
} |
|||
|
|||
/* |
|||
* |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-01-20 14:03:26 |
|||
@ 功能: 重新授权 |
|||
@ 参数 |
|||
|
|||
# |
|||
|
|||
@ 返回值 |
|||
|
|||
# |
|||
|
|||
@ 方法原型 |
|||
|
|||
# |
|||
*/ |
|||
func AgainEmpower(c *gin.Context) { |
|||
host := c.Request.Header.Get("Host") |
|||
userAgent := c.Request.Header.Get("User-Agent") |
|||
wechatTokenStr := fmt.Sprintf("%v_%v", host, userAgent) |
|||
var md5JiaMi overallhandle.Md5Encryption |
|||
md5JiaMi.Md5EncryptionInit(wechatTokenStr) |
|||
md5Token := md5JiaMi.Md5EncryptionAlgorithm() |
|||
|
|||
systemApp := c.Query("systemapp") |
|||
if systemApp == "" { |
|||
systemApp = "hr" |
|||
} |
|||
isAgain := c.Query("isagain") |
|||
if isAgain == "" { |
|||
isAgain = "1" |
|||
} |
|||
isAgainInt, _ := strconv.Atoi(isAgain) |
|||
if isAgainInt == 0 { |
|||
isAgainInt = 1 |
|||
} |
|||
token, err := GainWechatToken(systemApp, md5Token, isAgainInt) |
|||
if err != nil { |
|||
overallhandle.Result(1, token, c, "身份认证失败") |
|||
return |
|||
} |
|||
var additional []string |
|||
additional = append(additional, fmt.Sprintf("systemapp=%v", systemApp)) |
|||
additional = append(additional, fmt.Sprintf("isagain=%v", isAgainInt)) |
|||
userNum := c.Query("usernum") |
|||
if userNum != "" { |
|||
additional = append(additional, fmt.Sprintf("usernum=%v", userNum)) |
|||
} |
|||
|
|||
urlParameter := strings.Join(additional, "&") |
|||
//重定向身份认证
|
|||
callBackUrl := url.QueryEscape(fmt.Sprintf("%v/kpiapi/wechat/callbackauthuser?%v", overall.CONSTANT_CONFIG.Appsetup.WebUrl, urlParameter)) |
|||
redirectUrl := fmt.Sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%v&redirect_uri=%v&response_type=code&scope=snsapi_base&state=%v#wechat_redirect", overall.CONSTANT_CONFIG.WechatCompany.CompanyId, callBackUrl, token) |
|||
c.Redirect(http.StatusMovedPermanently, redirectUrl) |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
package workwechatrouter |
|||
|
|||
import ( |
|||
"hr_server/api/version1" |
|||
|
|||
"github.com/gin-gonic/gin" |
|||
) |
|||
|
|||
// 微信路由
|
|||
func (a *ApiRouter) RouterGroupPc(router *gin.RouterGroup) { |
|||
apiRouter := router.Group("wechat") |
|||
|
|||
var methodBinding = version1.AppApiInlet.WechatApi |
|||
{ |
|||
apiRouter.GET("", methodBinding.Index) //入口
|
|||
apiRouter.POST("", methodBinding.Index) //入口
|
|||
apiRouter.POST("gainWechatToken", methodBinding.GainWechatToken) //获取Token、
|
|||
apiRouter.POST("wechatJsapiTicket", methodBinding.WechatJsapiTicket) //获取企业的jsapi_ticket 或 获取应用的jsapi_ticket
|
|||
apiRouter.GET("authuser", methodBinding.AuthenticationUser) //获取身份认证
|
|||
apiRouter.GET("wechatCallBack", methodBinding.CallBackAuthUser) //获取身份认证
|
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
package workwechatrouter |
|||
|
|||
type ApiRouter struct{} |
|||
Binary file not shown.
Loading…
Reference in new issue