48 changed files with 5956 additions and 170 deletions
Binary file not shown.
File diff suppressed because it is too large
@ -0,0 +1,448 @@ |
|||||
|
package personnelapi |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
"hr_server/models" |
||||
|
personalitycolor "hr_server/models/personalityColor" |
||||
|
"hr_server/overall" |
||||
|
"hr_server/overall/overallhandle" |
||||
|
"reflect" |
||||
|
"strconv" |
||||
|
"strings" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/gin-gonic/gin" |
||||
|
) |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-20 16:20:09 |
||||
|
@ 功能: 根据工号获取个人档案 |
||||
|
@ 参数 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func (s *StaffApi) PersonnelFiles(c *gin.Context) { |
||||
|
var requestData overallhandle.NmuberOverall |
||||
|
err := c.ShouldBindJSON(&requestData) |
||||
|
if err != nil { |
||||
|
overallhandle.Result(101, requestData, c) |
||||
|
return |
||||
|
} |
||||
|
if requestData.Number == "" { |
||||
|
overallhandle.Result(1, requestData, c, "未知人员!不可查询信息") |
||||
|
return |
||||
|
} |
||||
|
var myInfo models.ManCont |
||||
|
err = myInfo.GetCont(map[string]interface{}{"`number`": requestData.Number}) |
||||
|
if err != nil { |
||||
|
overallhandle.Result(105, err, c) |
||||
|
return |
||||
|
} |
||||
|
saveInfo := overallhandle.MapOut() |
||||
|
structValue := reflect.ValueOf(myInfo) |
||||
|
structType := structValue.Type() |
||||
|
for i := 0; i < structValue.NumField(); i++ { |
||||
|
fieldValue := structValue.Field(i) |
||||
|
fieldType := structType.Field(i) |
||||
|
saveInfo[fieldType.Name] = fieldValue.Interface() |
||||
|
} |
||||
|
if myInfo.Birthday != 0 { |
||||
|
saveInfo["birthdayTime"] = overallhandle.UnixTimeToDay(myInfo.Birthday, 14) //生日
|
||||
|
} |
||||
|
if myInfo.Entrydate != 0 { |
||||
|
saveInfo["EntrydateTime"] = overallhandle.UnixTimeToDay(myInfo.Entrydate, 14) //入职日期
|
||||
|
} |
||||
|
//部门
|
||||
|
if myInfo.MainDeparment != 0 { |
||||
|
var demperMainInfos models.AdministrativeOrganization |
||||
|
demperMainInfos.GetCont(map[string]interface{}{"`id`": myInfo.MainDeparment}, "`name`") |
||||
|
saveInfo["MainDeparmentName"] = demperMainInfos.Name |
||||
|
} |
||||
|
//岗位
|
||||
|
if myInfo.AdminOrg != 0 { |
||||
|
var adminOrg models.AdministrativeOrganization |
||||
|
adminOrg.GetCont(map[string]interface{}{"`id`": myInfo.AdminOrg}, "`name`") |
||||
|
saveInfo["AdminOrgName"] = adminOrg.Name |
||||
|
} |
||||
|
//职务
|
||||
|
if myInfo.Position != 0 { |
||||
|
var postisInfo models.Position |
||||
|
postisInfo.GetCont(map[string]interface{}{"`id`": myInfo.Position}, "`name`", "`person_in_charge`") |
||||
|
saveInfo["PositionName"] = postisInfo.Name |
||||
|
saveInfo["PersonInCharge"] = postisInfo.PersonInCharge |
||||
|
} |
||||
|
if myInfo.Isdoubleworker == 1 { |
||||
|
var doubleWorkerInfo models.DoubleWorker |
||||
|
doubleWorkerInfo.GetCont(map[string]interface{}{"`number`": myInfo.Number, "`state`": 1}, "`name`", "`company`", "`department`", "`position`") |
||||
|
saveInfo["WorkCompany"] = fmt.Sprintf("%v%v%v%v", doubleWorkerInfo.Name, doubleWorkerInfo.Company, doubleWorkerInfo.Department, doubleWorkerInfo.Position) |
||||
|
} else { |
||||
|
saveInfo["WorkCompany"] = "" |
||||
|
} |
||||
|
saveInfo["GenderName"] = overallhandle.GenderStatus(int64(myInfo.Gender)) |
||||
|
saveInfo["ConstellationName"] = overallhandle.StarSign(int64(myInfo.Constellation)) |
||||
|
saveInfo["PolitOutlook"] = overallhandle.PoliticalIdentity(int64(myInfo.PoliticalOutlook)) |
||||
|
saveInfo["Maristatus"] = overallhandle.MaritalStatus(int64(myInfo.Maritalstatus)) |
||||
|
//教育经历
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
saveInfo["EducationalExperience"] = UserEducationalExperience(myInfo.Key) |
||||
|
}() |
||||
|
//工作履历
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
saveInfo["ExternalWork"] = getWorkHistoryList(myInfo.Key) //工作履历
|
||||
|
}() |
||||
|
//集团内工作履历
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
saveInfo["InternalWork"] = getGroupWorkHistoryList(myInfo.Key) //工作履历
|
||||
|
}() |
||||
|
//职称证书
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
AcademicTitle := GainCertificateHonors(myInfo.Key, 1) |
||||
|
saveInfo["AcademicTitle"] = strings.Join(AcademicTitle, ",") //工作履历
|
||||
|
}() |
||||
|
//资格证书
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
Diploma := GainCertificateHonors(myInfo.Key, 2) |
||||
|
saveInfo["Diploma"] = strings.Join(Diploma, ",") //工作履历
|
||||
|
}() |
||||
|
|
||||
|
currentTime := time.Now() |
||||
|
years := currentTime.Year() - 1 |
||||
|
//绩效成绩 Performance score
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
saveInfo["Meritslog"] = GainTimeLangMeritslog(myInfo.Key, years, 2) //工作履历
|
||||
|
}() |
||||
|
//获奖情况
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
saveInfo["Rewards"] = GainRewardsPenalties(myInfo.Key, years, 2, 1) //工作履历
|
||||
|
}() |
||||
|
//惩罚情况
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
saveInfo["Penalties"] = GainRewardsPenalties(myInfo.Key, years, 2, 2) //工作履历
|
||||
|
}() |
||||
|
//性格社彩
|
||||
|
synPro.Add(1) |
||||
|
go func() { |
||||
|
xgsc := GainCharacterColor(myInfo.Number) |
||||
|
saveInfo["CharacterColour"] = strings.Join(xgsc.TestNumber, "、") //工作履历
|
||||
|
}() |
||||
|
synPro.Wait() |
||||
|
overallhandle.Result(0, saveInfo, c) |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-24 08:08:43 |
||||
|
@ 功能: 获取性格色彩 |
||||
|
@ 参数 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func GainCharacterColor(num string) (tpr TestPageColorResult) { |
||||
|
synPro.Done() |
||||
|
var myColor personalitycolor.Charcolortest |
||||
|
err := myColor.GetCont(map[string]interface{}{"`c_states`": 1, "`c_number`": num}) |
||||
|
if err != nil { |
||||
|
return |
||||
|
} |
||||
|
var testPage []TestPageColor |
||||
|
if myColor.TestJson != "" { |
||||
|
json.Unmarshal([]byte(myColor.TestJson), &testPage) |
||||
|
} |
||||
|
GetColorVal := JiSuanColor(testPage) |
||||
|
var ColorStrAry []TestPageColorVal |
||||
|
var redColor TestPageColorVal |
||||
|
redColor.Strval = GetColorVal["RedColor"] |
||||
|
redColor.Name = "红色" |
||||
|
redColor.Setval = 1 |
||||
|
ColorStrAry = append(ColorStrAry, redColor) |
||||
|
var blueColor TestPageColorVal |
||||
|
blueColor.Strval = GetColorVal["BlueColor"] |
||||
|
blueColor.Name = "蓝色" |
||||
|
blueColor.Setval = 1 |
||||
|
ColorStrAry = append(ColorStrAry, blueColor) |
||||
|
var yellowColor TestPageColorVal |
||||
|
yellowColor.Strval = GetColorVal["YellowColor"] |
||||
|
yellowColor.Name = "黄色" |
||||
|
yellowColor.Setval = 1 |
||||
|
ColorStrAry = append(ColorStrAry, yellowColor) |
||||
|
var greenColor TestPageColorVal |
||||
|
greenColor.Strval = GetColorVal["GreenColor"] |
||||
|
greenColor.Name = "绿色" |
||||
|
greenColor.Setval = 1 |
||||
|
ColorStrAry = append(ColorStrAry, greenColor) |
||||
|
var colorAry []int |
||||
|
colorAry = append(colorAry, GetColorVal["RedColor"]) |
||||
|
colorAry = append(colorAry, GetColorVal["BlueColor"]) |
||||
|
colorAry = append(colorAry, GetColorVal["YellowColor"]) |
||||
|
colorAry = append(colorAry, GetColorVal["GreenColor"]) |
||||
|
MaxColor := overallhandle.GetMaxNum[int](colorAry) |
||||
|
for _, v := range ColorStrAry { |
||||
|
if v.Strval == MaxColor { |
||||
|
if !overallhandle.IsInTrue[int](v.Setval, tpr.CheckedVal) { |
||||
|
tpr.CheckedVal = append(tpr.CheckedVal, v.Setval) |
||||
|
} |
||||
|
if !overallhandle.IsInTrue[string](v.Name, tpr.TestNumber) { |
||||
|
tpr.TestNumber = append(tpr.TestNumber, v.Name) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 计算颜色
|
||||
|
func JiSuanColor(testPage []TestPageColor) map[string]int { |
||||
|
if len(testPage) < 1 { |
||||
|
sendDataw := make(map[string]int) |
||||
|
sendDataw["RedColor"] = 0 |
||||
|
sendDataw["BlueColor"] = 0 |
||||
|
sendDataw["YellowColor"] = 0 |
||||
|
sendDataw["GreenColor"] = 0 |
||||
|
return sendDataw |
||||
|
} |
||||
|
A_front_count := 0 |
||||
|
B_front_count := 0 |
||||
|
C_front_count := 0 |
||||
|
D_front_count := 0 |
||||
|
A_after_count := 0 |
||||
|
B_after_count := 0 |
||||
|
C_after_count := 0 |
||||
|
D_after_count := 0 |
||||
|
|
||||
|
for _, v := range testPage { |
||||
|
testNumInt, _ := strconv.Atoi(v.TestNumber) |
||||
|
checkedValInt, _ := strconv.Atoi(v.CheckedVal) |
||||
|
if testNumInt <= 15 { |
||||
|
switch checkedValInt { |
||||
|
case 2: |
||||
|
B_front_count++ |
||||
|
case 3: |
||||
|
C_front_count++ |
||||
|
case 4: |
||||
|
D_front_count++ |
||||
|
default: |
||||
|
A_front_count++ |
||||
|
} |
||||
|
} else { |
||||
|
switch checkedValInt { |
||||
|
case 2: |
||||
|
B_after_count++ |
||||
|
case 3: |
||||
|
C_after_count++ |
||||
|
case 4: |
||||
|
D_after_count++ |
||||
|
default: |
||||
|
A_after_count++ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
RedColor := A_front_count + D_after_count |
||||
|
BlueColor := B_front_count + C_after_count |
||||
|
YellowColor := C_front_count + B_after_count |
||||
|
GreenColor := D_front_count + A_after_count |
||||
|
sendData := make(map[string]int) |
||||
|
sendData["RedColor"] = RedColor |
||||
|
sendData["BlueColor"] = BlueColor |
||||
|
sendData["YellowColor"] = YellowColor |
||||
|
sendData["GreenColor"] = GreenColor |
||||
|
sendData["A_front_count"] = A_front_count |
||||
|
sendData["B_front_count"] = B_front_count |
||||
|
sendData["C_front_count"] = C_front_count |
||||
|
sendData["D_front_count"] = D_front_count |
||||
|
sendData["A_after_count"] = A_after_count |
||||
|
sendData["B_after_count"] = B_after_count |
||||
|
sendData["C_after_count"] = C_after_count |
||||
|
sendData["D_after_count"] = D_after_count |
||||
|
return sendData |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-23 15:42:56 |
||||
|
@ 功能: 奖惩记录 |
||||
|
@ 参数 |
||||
|
|
||||
|
#userKey 人员KEY |
||||
|
#years 当前年 |
||||
|
#duration 倒查几年 |
||||
|
#class 奖励还是惩罚 |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func GainRewardsPenalties(userKey int64, years, duration, class int) map[string]interface{} { |
||||
|
synPro.Done() |
||||
|
sendData := overallhandle.MapOut() |
||||
|
|
||||
|
if duration > 0 { |
||||
|
// fmt.Printf("奖惩记录111111: %v\n", duration)
|
||||
|
for i := duration; i >= 0; i-- { |
||||
|
// fmt.Printf("奖惩记录33333: %v\n", i)
|
||||
|
timeVal := years - i |
||||
|
var allScore []map[string]interface{} |
||||
|
overall.CONSTANT_DB_HR.Model(&models.RewardsPenalties{}).Where("`state` = 1 AND `userkey` = ? AND `years` = ? AND `type` = ?", userKey, timeVal, class).Find(&allScore) |
||||
|
// fmt.Printf("奖惩记录11111: %v\n", err)
|
||||
|
timeValStr := strconv.Itoa(timeVal) |
||||
|
sendData[timeValStr] = allScore |
||||
|
// fmt.Printf("奖惩记录: %s\n", timeValStr)
|
||||
|
} |
||||
|
} else { |
||||
|
var allScore map[string]interface{} |
||||
|
overall.CONSTANT_DB_HR.Model(&models.RewardsPenalties{}).Where("`state` = 1 AND `userkey` = ? AND `years` = ? AND `type` = ?", userKey, years, class).Find(&allScore) |
||||
|
timeValStr := strconv.Itoa(years) |
||||
|
sendData[timeValStr] = allScore |
||||
|
} |
||||
|
return sendData |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-23 15:20:52 |
||||
|
@ 功能: 获取多长时间的绩效 |
||||
|
@ 参数 |
||||
|
|
||||
|
#userKey 人员KEY |
||||
|
#years 当前年 |
||||
|
#duration 倒查几年 |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func GainTimeLangMeritslog(userKey int64, years, duration int) map[string]interface{} { |
||||
|
synPro.Done() |
||||
|
sendData := overallhandle.MapOut() |
||||
|
if duration > 0 { |
||||
|
for i := duration; i >= 0; i-- { |
||||
|
timeVal := years - i |
||||
|
var allScore int64 |
||||
|
overall.CONSTANT_DB_HR.Model(&models.Meritslog{}).Select("SUM(`score`) as scoresum").Where("`status` = 1 AND `userkey` = ? AND `years` = ?", userKey, timeVal).Find(&allScore) |
||||
|
timeValStr := strconv.Itoa(timeVal) |
||||
|
if allScore > 0 { |
||||
|
sendData[timeValStr] = float64(allScore) / 10000 |
||||
|
} else { |
||||
|
sendData[timeValStr] = 0 |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
var allScore int64 |
||||
|
overall.CONSTANT_DB_HR.Model(&models.Meritslog{}).Select("SUM(`score`) as scoresum").Where("`status` = 1 AND `userkey` = ? AND `years` = ?", userKey, years).Find(&allScore) |
||||
|
timeValStr := strconv.Itoa(years) |
||||
|
if allScore > 0 { |
||||
|
sendData[timeValStr] = float64(allScore) / 10000 |
||||
|
} else { |
||||
|
sendData[timeValStr] = 0 |
||||
|
} |
||||
|
} |
||||
|
return sendData |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-23 15:08:44 |
||||
|
@ 功能: 获取证书 |
||||
|
@ 参数 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func GainCertificateHonors(userKey int64, class int) (titleList []string) { |
||||
|
synPro.Done() |
||||
|
overall.CONSTANT_DB_HR.Model(&models.CertificateHonors{}).Select("`title`").Where("`state` = 1 AND `type` = ? AND `userkey` = ?", class, userKey).Find(&titleList) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-23 09:46:31 |
||||
|
@ 功能: 获取教育径路 |
||||
|
@ 参数 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
# |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func UserEducationalExperience(num int64) (eduExper []educatExp) { |
||||
|
defer synPro.Done() |
||||
|
var dowWorkMan []models.PersonnelEducation |
||||
|
err := overall.CONSTANT_DB_HR.Model(&models.PersonnelEducation{}).Select("`id`", "`education`", "`graduation_school`", "`subject`", "`admission_time`", "`graduation_time`", "`level`,`academic_degree`").Where("`state` = 1 AND `key` = ?", num).Order("`level` desc").Find(&dowWorkMan).Error |
||||
|
if err != nil { |
||||
|
return |
||||
|
} |
||||
|
for _, v := range dowWorkMan { |
||||
|
var dwManCont educatExp //
|
||||
|
dwManCont.GraduationSchool = v.GraduationSchool //毕业学校
|
||||
|
dwManCont.Subject = v.Subject //专业
|
||||
|
dwManCont.Education = v.Education //学历
|
||||
|
dwManCont.EducationName = overallhandle.EducationLevel(int64(v.Education)) |
||||
|
if v.AdmissionTime != 0 { |
||||
|
dwManCont.AdmissionTime = overallhandle.UnixTimeToDay(v.AdmissionTime, 14) //入学时间
|
||||
|
} |
||||
|
if v.GraduationTime != 0 { |
||||
|
dwManCont.GraduationTime = overallhandle.UnixTimeToDay(v.GraduationTime, 14) //毕业时间
|
||||
|
} |
||||
|
|
||||
|
dwManCont.AcademicDegree = overallhandle.AcademicDegree(int64(v.AcademicDegree)) //学位
|
||||
|
dwManCont.AcademicDegreeId = v.AcademicDegree |
||||
|
dwManCont.Level = overallhandle.GetXueWeiClass(int64(v.Level)) |
||||
|
dwManCont.LevelId = v.Level //学历类型
|
||||
|
dwManCont.Id = strconv.FormatInt(v.Id, 10) |
||||
|
dwManCont.EducationTypeName = overallhandle.EducationType(int64(v.EducationType)) |
||||
|
eduExper = append(eduExper, dwManCont) |
||||
|
} |
||||
|
|
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,91 @@ |
|||||
|
package workWechat |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/middleware/wxbizjsonmsgcrypt" |
||||
|
"hr_server/middleware/wxbizmsgcrypt" |
||||
|
"hr_server/overall" |
||||
|
) |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-26 08:52:18 |
||||
|
@ 功能: 企业微信加解密-json |
||||
|
@ 参数 |
||||
|
|
||||
|
#token 应用Token |
||||
|
#encodingAesKey 应用Encodingaeskey |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
#wxcpt 初始化加解密类 |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func WechatDecryptJson(systemApp string) (wxcpt *wxbizjsonmsgcrypt.WXBizMsgCrypt) { |
||||
|
var token string |
||||
|
var encodingAesKey string |
||||
|
switch systemApp { |
||||
|
case "kpi": |
||||
|
token = overall.CONSTANT_CONFIG.WechatKpi.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.WechatKpi.Encodingaeskey |
||||
|
case "school": |
||||
|
token = overall.CONSTANT_CONFIG.WechatSchool.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.WechatSchool.Encodingaeskey |
||||
|
case "hr": |
||||
|
token = overall.CONSTANT_CONFIG.EmployeeFile.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.EmployeeFile.Encodingaeskey |
||||
|
case "txl": |
||||
|
token = overall.CONSTANT_CONFIG.AddressBook.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.AddressBook.Encodingaeskey |
||||
|
default: |
||||
|
token = overall.CONSTANT_CONFIG.WechatSchool.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.WechatSchool.Encodingaeskey |
||||
|
} |
||||
|
wxcpt = wxbizjsonmsgcrypt.NewWXBizMsgCrypt(token, encodingAesKey, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, wxbizjsonmsgcrypt.JsonType) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
* |
||||
|
@ 作者: 秦东 |
||||
|
@ 时间: 2024-01-26 09:09:14 |
||||
|
@ 功能: 企业微信加解密-XML |
||||
|
@ 参数 |
||||
|
|
||||
|
#token 应用Token |
||||
|
#encodingAesKey 应用Encodingaeskey |
||||
|
|
||||
|
@ 返回值 |
||||
|
|
||||
|
#wxcpt 初始化加解密类 |
||||
|
|
||||
|
@ 方法原型 |
||||
|
|
||||
|
# |
||||
|
*/ |
||||
|
func WechatDecryptXml(systemApp string) (wxcpt *wxbizmsgcrypt.WXBizMsgCrypt) { |
||||
|
var token string |
||||
|
var encodingAesKey string |
||||
|
switch systemApp { |
||||
|
case "kpi": |
||||
|
token = overall.CONSTANT_CONFIG.WechatKpi.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.WechatKpi.Encodingaeskey |
||||
|
case "school": |
||||
|
token = overall.CONSTANT_CONFIG.WechatSchool.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.WechatSchool.Encodingaeskey |
||||
|
case "hr": |
||||
|
token = overall.CONSTANT_CONFIG.EmployeeFile.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.EmployeeFile.Encodingaeskey |
||||
|
case "txl": |
||||
|
token = overall.CONSTANT_CONFIG.AddressBook.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.AddressBook.Encodingaeskey |
||||
|
default: |
||||
|
token = overall.CONSTANT_CONFIG.WechatSchool.Token |
||||
|
encodingAesKey = overall.CONSTANT_CONFIG.WechatSchool.Encodingaeskey |
||||
|
} |
||||
|
wxcpt = wxbizmsgcrypt.NewWXBizMsgCrypt(token, encodingAesKey, overall.CONSTANT_CONFIG.WechatCompany.CompanyId, wxbizmsgcrypt.XmlType) |
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,65 @@ |
|||||
|
package workWechat |
||||
|
|
||||
|
//获取企业微信部门列表
|
||||
|
type GetWechatOrg struct { |
||||
|
WechatTokanVal |
||||
|
OrgId int `json:"org"` //行政组织ID
|
||||
|
} |
||||
|
|
||||
|
//企业微信更新成员
|
||||
|
type UpdateWechatUserInfo struct { |
||||
|
WechatTokanVal |
||||
|
Info map[string]interface{} `json:"info"` //行政组织ID
|
||||
|
} |
||||
|
|
||||
|
//企业微信回调基础参数
|
||||
|
type CallBackData struct { |
||||
|
MsgSignature string `json:"msg_signature"` |
||||
|
Timestamp string `json:"timestamp"` |
||||
|
Nonce string `json:"nonce"` |
||||
|
Echostr string `json:"echostr"` |
||||
|
ToUserName string `json:"tousername"` |
||||
|
AgentID string `json:"agentid"` |
||||
|
Encrypt string `json:"encrypt"` |
||||
|
DataType string `json:"datatype"` |
||||
|
SystemApp string `json:"systemapp"` |
||||
|
} |
||||
|
|
||||
|
//XML 格式回调
|
||||
|
type XmlMsgCont struct { |
||||
|
ToUsername string `xml:"ToUserName" json:"ToUserName"` |
||||
|
Agentid uint32 `xml:"AgentID" json:"AgentID"` |
||||
|
Encrypt string `xml:"Encrypt" json:"encrypt"` |
||||
|
} |
||||
|
|
||||
|
//返回消息体解密
|
||||
|
type DecryptMsgCont struct { |
||||
|
MsgSignature string `json:"msg_signature"` |
||||
|
Timestamp string `json:"timestamp"` |
||||
|
Nonce string `json:"nonce"` |
||||
|
SystemApp string `json:"systemapp"` |
||||
|
jsonMsgCont |
||||
|
} |
||||
|
type jsonMsgCont struct { |
||||
|
ToUsername string `json:"ToUserName"` |
||||
|
Agentid uint32 `json:"AgentID"` |
||||
|
Encrypt string `json:"encrypt"` |
||||
|
} |
||||
|
|
||||
|
//XML数据解密
|
||||
|
type MsgContentXml struct { |
||||
|
XmlMsgUpdateCont |
||||
|
Content string `xml:"Content" json:"Content"` |
||||
|
Msgid string `xml:"MsgId" json:"MsgId"` |
||||
|
} |
||||
|
|
||||
|
//通用更新切片
|
||||
|
type XmlMsgUpdateCont struct { |
||||
|
ToUsername string `xml:"ToUserName" json:"ToUserName"` |
||||
|
FromUsername string `xml:"FromUserName" json:"FromUserName"` |
||||
|
CreateTime uint32 `xml:"CreateTime" json:"CreateTime"` |
||||
|
MsgType string `xml:"MsgType" json:"MsgType"` |
||||
|
Agentid uint32 `xml:"AgentID" json:"AgentID"` |
||||
|
Event string `xml:"Event" json:"Event"` |
||||
|
EventKey string `xml:"EventKey" json:"EventKey"` |
||||
|
} |
||||
@ -0,0 +1,161 @@ |
|||||
|
# 开发日志 |
||||
|
|
||||
|
## 2024-01-29 |
||||
|
|
||||
|
### 数据库操作 |
||||
|
|
||||
|
#### 1、person_archives 人员主表 |
||||
|
|
||||
|
增加表字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `person_archives` ADD `work_section` bigint unsigned DEFAULT '0' COMMENT '工段'; |
||||
|
``` |
||||
|
|
||||
|
#### 2、personnel_content 人员副表 |
||||
|
|
||||
|
增加表字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `personnel_content` ADD `domicile_type` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '户籍类型'; |
||||
|
ALTER TABLE `personnel_content` ADD `idCardnoLongTerm` int unsigned NOT NULL DEFAULT '2' COMMENT '身份证是否长期有效(1:是;2:否)'; |
||||
|
ALTER TABLE `person_archives` ADD `mobileShortNumber` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '手机小号'; |
||||
|
ALTER TABLE `person_archives` ADD `channel` int unsigned NOT NULL DEFAULT '1' COMMENT '入职渠道(1:社会招聘;2:校园招聘;3:内部推荐)'; |
||||
|
ALTER TABLE `person_archives` ADD `bloodType` varchar(10) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '血型'; |
||||
|
``` |
||||
|
|
||||
|
#### 3、personnel_education 教育经历 |
||||
|
|
||||
|
增加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `personnel_education` ADD `education_type` int unsigned NOT NULL DEFAULT '1' COMMENT '学历类型(1、全日制统招学历;2、成人高考学历;3、自学考试学历;4:开放大学学历;5:网络教育学历)'; |
||||
|
ALTER TABLE `personnel_education` ADD `collegeFaction` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '所属院系'; |
||||
|
ALTER TABLE `personnel_education` ADD `schoolType` int unsigned NOT NULL DEFAULT '0' COMMENT '院校类型(1、私立中学;2:公立中学;3:高职院校;4:民办专科院校;5:公办专科院校;6:民办本科院校;7:公办本科院校;8:”211“工程院校;9:”985“工程院校;10:双一流院校)' |
||||
|
``` |
||||
|
|
||||
|
#### 4、family_members 员工家属 |
||||
|
|
||||
|
增加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `family_members` ADD `workUnitPost` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '工作单位及职务'; |
||||
|
ALTER TABLE `family_members` ADD `isSos` int unsigned NOT NULL DEFAULT '2' COMMENT '是否为紧急联系人(1、是;2:否)'; |
||||
|
``` |
||||
|
|
||||
|
#### 5、double_worker 双职工 |
||||
|
|
||||
|
添加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `double_worker` ADD `workUnit` varchar(100) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '工段'; |
||||
|
ALTER TABLE `double_worker` ADD `workPosit` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '职位'; |
||||
|
ALTER TABLE `double_worker` ADD `levele` varchar(30) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '职等'; |
||||
|
``` |
||||
|
|
||||
|
#### 6、inside_work_history 集团内部工作经历 |
||||
|
|
||||
|
添加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `inside_work_history` ADD `changeType` int unsigned NOT NULL DEFAULT '1' COMMENT '变动类型(1、新入职;2:平调;3:降职;4:升职)'; |
||||
|
ALTER TABLE `inside_work_history` ADD `changeReason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '变动原因'; |
||||
|
ALTER TABLE `inside_work_history` ADD `superiorPosition` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '上级职位'; |
||||
|
ALTER TABLE `inside_work_history` ADD `superiorName` varchar(50) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '上级名称'; |
||||
|
ALTER TABLE `inside_work_history` ADD `subordinates` int unsigned NOT NULL DEFAULT '0' COMMENT '下属人数'; |
||||
|
``` |
||||
|
|
||||
|
#### 7、work_history 工作履历 |
||||
|
|
||||
|
添加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `work_history` ADD `companyNature` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '公司性质'; |
||||
|
ALTER TABLE `work_history` ADD `industry` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '所属行业'; |
||||
|
``` |
||||
|
|
||||
|
#### 8、meritslog 绩效 |
||||
|
|
||||
|
添加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE `work_history` ADD `level` varchar(255) COLLATE utf8mb4_bin DEFAULT '' COMMENT '考核等级'; |
||||
|
``` |
||||
|
|
||||
|
#### 9、rewards_penalties 奖惩 |
||||
|
|
||||
|
添加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE rewards_penalties ADD level int unsigned NOT NULL DEFAULT '1' COMMENT '奖惩级别(1:部门级;2:公司级;3:县级;4:市级;5:省级;6:国家级)'; |
||||
|
ALTER TABLE rewards_penalties ADD rewPunClass int unsigned NOT NULL DEFAULT '1' COMMENT '奖惩类型(1:年终评优;2:表扬;3:嘉奖;4:记功;5:记大功;6:特别奖励;7:批评;8:警告;9:记过;10:记大过;11:降级;12:留用察看;13:开除)'; |
||||
|
``` |
||||
|
|
||||
|
#### 10、political_identity 政治属性 |
||||
|
|
||||
|
添加表 |
||||
|
|
||||
|
``` |
||||
|
CREATE TABLE `political_identity` ( |
||||
|
`userkey` bigint unsigned NOT NULL DEFAULT '0' COMMENT '员工唯一识别符', |
||||
|
`political_outlook` int unsigned NOT NULL DEFAULT '1' COMMENT '政治面貌(1:群众;2:无党派;3:台盟会员;4:九三社员;5:致公党员;6:农工党员;7:民进会员;8:民建会员;9:民盟盟员;10:民革会员,11:共青团员;12:预备党员;13:中共党员)', |
||||
|
`joinTime` bigint NOT NULL DEFAULT '0' COMMENT '加入时间', |
||||
|
`branch` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '所在党支部', |
||||
|
`position` varchar(100) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '党内职务', |
||||
|
`joiningParty` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '入党时所在单位', |
||||
|
`switchToClass` int unsigned NOT NULL DEFAULT '2' COMMENT '组织关系是否转入(1:是;2:否)', |
||||
|
`switchToTime` bigint NOT NULL DEFAULT '0' COMMENT '组织关系转入时间', |
||||
|
`time` bigint unsigned NOT NULL DEFAULT '0', |
||||
|
PRIMARY KEY (`userkey`), |
||||
|
UNIQUE KEY `userkey` (`userkey`) |
||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='政治属性'; |
||||
|
``` |
||||
|
|
||||
|
#### 11、veterans 退役军人信息 |
||||
|
|
||||
|
添加表 |
||||
|
|
||||
|
``` |
||||
|
CREATE TABLE `veterans` ( |
||||
|
`userkey` bigint unsigned NOT NULL DEFAULT '0', |
||||
|
`isRetire` int unsigned NOT NULL DEFAULT '2' COMMENT '是否为退役军人(1:是;2:否)', |
||||
|
`retireNumber` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '退役证编号', |
||||
|
`joinTime` bigint NOT NULL DEFAULT '0' COMMENT '入伍时间', |
||||
|
`retireTime` bigint NOT NULL DEFAULT '0' COMMENT '退伍时间', |
||||
|
`armyUnits` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '参军单位', |
||||
|
`typesOfSoldiers` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '兵种', |
||||
|
`time` bigint unsigned NOT NULL DEFAULT '0', |
||||
|
PRIMARY KEY (`userkey`), |
||||
|
UNIQUE KEY `userkey` (`userkey`) |
||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='老兵信息'; |
||||
|
``` |
||||
|
|
||||
|
#### 12、academictitle 职称 |
||||
|
|
||||
|
添加表 |
||||
|
|
||||
|
``` |
||||
|
CREATE TABLE `academictitle` ( |
||||
|
`id` bigint unsigned NOT NULL, |
||||
|
`types` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '职称级别', |
||||
|
`series` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '职称系列', |
||||
|
`speciality` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '职称专业', |
||||
|
`number` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '资格证书编号', |
||||
|
`time` bigint unsigned NOT NULL DEFAULT '0' COMMENT '生效时间', |
||||
|
`editTime` bigint unsigned NOT NULL DEFAULT '0', |
||||
|
`userKey` bigint unsigned NOT NULL DEFAULT '0' COMMENT '人员唯一识别符', |
||||
|
PRIMARY KEY (`id`), |
||||
|
UNIQUE KEY `id` (`id`), |
||||
|
KEY `userKey` (`userKey`) |
||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='职称'; |
||||
|
``` |
||||
|
|
||||
|
#### 13、certificate_honors 证书 |
||||
|
|
||||
|
添加字段 |
||||
|
|
||||
|
``` |
||||
|
ALTER TABLE rewards_penalties ADD number varchar(255) COLLATE utf8mb4_bin DEFAULT '' COMMENT '证书编号''; |
||||
|
ALTER TABLE rewards_penalties ADD endTime int unsigned NOT NULL DEFAULT '1' COMMENT '奖惩级别(1:部门级;2:公司级;3:县级;4:市级;5:省级;6:国家级)'; |
||||
|
ALTER TABLE rewards_penalties ADD validPeriod int unsigned NOT NULL DEFAULT '1' COMMENT '奖惩级别(1:部门级;2:公司级;3:县级;4:市级;5:省级;6:国家级)'; |
||||
|
``` |
||||
Binary file not shown.
@ -0,0 +1,310 @@ |
|||||
|
package wxbizjsonmsgcrypt |
||||
|
|
||||
|
import ( |
||||
|
"bytes" |
||||
|
"crypto/aes" |
||||
|
"crypto/cipher" |
||||
|
"crypto/sha1" |
||||
|
"encoding/base64" |
||||
|
"encoding/binary" |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
"math/rand" |
||||
|
"sort" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
const letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" |
||||
|
|
||||
|
const ( |
||||
|
ValidateSignatureError int = -40001 |
||||
|
ParseJsonError int = -40002 |
||||
|
ComputeSignatureError int = -40003 |
||||
|
IllegalAesKey int = -40004 |
||||
|
ValidateCorpidError int = -40005 |
||||
|
EncryptAESError int = -40006 |
||||
|
DecryptAESError int = -40007 |
||||
|
IllegalBuffer int = -40008 |
||||
|
EncodeBase64Error int = -40009 |
||||
|
DecodeBase64Error int = -40010 |
||||
|
GenJsonError int = -40011 |
||||
|
IllegalProtocolType int = -40012 |
||||
|
) |
||||
|
|
||||
|
type ProtocolType int |
||||
|
|
||||
|
const ( |
||||
|
JsonType ProtocolType = 1 |
||||
|
) |
||||
|
|
||||
|
type CryptError struct { |
||||
|
ErrCode int |
||||
|
ErrMsg string |
||||
|
} |
||||
|
|
||||
|
func NewCryptError(err_code int, err_msg string) *CryptError { |
||||
|
return &CryptError{ErrCode: err_code, ErrMsg: err_msg} |
||||
|
} |
||||
|
|
||||
|
type WXBizJsonMsg4Recv struct { |
||||
|
Tousername string `json:"tousername"` |
||||
|
Encrypt string `json:"encrypt"` |
||||
|
Agentid string `json:"agentid"` |
||||
|
} |
||||
|
|
||||
|
type WXBizJsonMsg4Send struct { |
||||
|
Encrypt string `json:"encrypt"` |
||||
|
Signature string `json:"msgsignature"` |
||||
|
Timestamp string `json:"timestamp"` |
||||
|
Nonce string `json:"nonce"` |
||||
|
} |
||||
|
|
||||
|
func NewWXBizJsonMsg4Send(encrypt, signature, timestamp, nonce string) *WXBizJsonMsg4Send { |
||||
|
return &WXBizJsonMsg4Send{Encrypt: encrypt, Signature: signature, Timestamp: timestamp, Nonce: nonce} |
||||
|
} |
||||
|
|
||||
|
type ProtocolProcessor interface { |
||||
|
parse(src_data []byte) (*WXBizJsonMsg4Recv, *CryptError) |
||||
|
serialize(msg_send *WXBizJsonMsg4Send) ([]byte, *CryptError) |
||||
|
} |
||||
|
|
||||
|
type WXBizMsgCrypt struct { |
||||
|
token string |
||||
|
encoding_aeskey string |
||||
|
receiver_id string |
||||
|
protocol_processor ProtocolProcessor |
||||
|
} |
||||
|
|
||||
|
type JsonProcessor struct { |
||||
|
} |
||||
|
|
||||
|
func (self *JsonProcessor) parse(src_data []byte) (*WXBizJsonMsg4Recv, *CryptError) { |
||||
|
var msg4_recv WXBizJsonMsg4Recv |
||||
|
err := json.Unmarshal(src_data, &msg4_recv) |
||||
|
if nil != err { |
||||
|
fmt.Println("Unmarshal fail", err) |
||||
|
return nil, NewCryptError(ParseJsonError, "json to msg fail") |
||||
|
} |
||||
|
return &msg4_recv, nil |
||||
|
} |
||||
|
|
||||
|
func (self *JsonProcessor) serialize(msg4_send *WXBizJsonMsg4Send) ([]byte, *CryptError) { |
||||
|
json_msg, err := json.Marshal(msg4_send) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(GenJsonError, err.Error()) |
||||
|
} |
||||
|
|
||||
|
return json_msg, nil |
||||
|
} |
||||
|
|
||||
|
func NewWXBizMsgCrypt(token, encoding_aeskey, receiver_id string, protocol_type ProtocolType) *WXBizMsgCrypt { |
||||
|
var protocol_processor ProtocolProcessor |
||||
|
if protocol_type != JsonType { |
||||
|
panic("unsupport protocal") |
||||
|
} else { |
||||
|
protocol_processor = new(JsonProcessor) |
||||
|
} |
||||
|
|
||||
|
return &WXBizMsgCrypt{token: token, encoding_aeskey: (encoding_aeskey + "="), receiver_id: receiver_id, protocol_processor: protocol_processor} |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) randString(n int) string { |
||||
|
b := make([]byte, n) |
||||
|
for i := range b { |
||||
|
b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))] |
||||
|
} |
||||
|
return string(b) |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) pKCS7Padding(plaintext string, block_size int) []byte { |
||||
|
padding := block_size - (len(plaintext) % block_size) |
||||
|
padtext := bytes.Repeat([]byte{byte(padding)}, padding) |
||||
|
var buffer bytes.Buffer |
||||
|
buffer.WriteString(plaintext) |
||||
|
buffer.Write(padtext) |
||||
|
return buffer.Bytes() |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) pKCS7Unpadding(plaintext []byte, block_size int) ([]byte, *CryptError) { |
||||
|
plaintext_len := len(plaintext) |
||||
|
if nil == plaintext || plaintext_len == 0 { |
||||
|
return nil, NewCryptError(DecryptAESError, "pKCS7Unpadding error nil or zero") |
||||
|
} |
||||
|
if plaintext_len%block_size != 0 { |
||||
|
return nil, NewCryptError(DecryptAESError, "pKCS7Unpadding text not a multiple of the block size") |
||||
|
} |
||||
|
padding_len := int(plaintext[plaintext_len-1]) |
||||
|
return plaintext[:plaintext_len-padding_len], nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) cbcEncrypter(plaintext string) ([]byte, *CryptError) { |
||||
|
aeskey, err := base64.StdEncoding.DecodeString(self.encoding_aeskey) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(DecodeBase64Error, err.Error()) |
||||
|
} |
||||
|
const block_size = 32 |
||||
|
pad_msg := self.pKCS7Padding(plaintext, block_size) |
||||
|
|
||||
|
block, err := aes.NewCipher(aeskey) |
||||
|
if err != nil { |
||||
|
return nil, NewCryptError(EncryptAESError, err.Error()) |
||||
|
} |
||||
|
|
||||
|
ciphertext := make([]byte, len(pad_msg)) |
||||
|
iv := aeskey[:aes.BlockSize] |
||||
|
|
||||
|
mode := cipher.NewCBCEncrypter(block, iv) |
||||
|
|
||||
|
mode.CryptBlocks(ciphertext, pad_msg) |
||||
|
base64_msg := make([]byte, base64.StdEncoding.EncodedLen(len(ciphertext))) |
||||
|
base64.StdEncoding.Encode(base64_msg, ciphertext) |
||||
|
|
||||
|
return base64_msg, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) cbcDecrypter(base64_encrypt_msg string) ([]byte, *CryptError) { |
||||
|
aeskey, err := base64.StdEncoding.DecodeString(self.encoding_aeskey) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(DecodeBase64Error, err.Error()) |
||||
|
} |
||||
|
|
||||
|
encrypt_msg, err := base64.StdEncoding.DecodeString(base64_encrypt_msg) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(DecodeBase64Error, err.Error()) |
||||
|
} |
||||
|
|
||||
|
block, err := aes.NewCipher(aeskey) |
||||
|
if err != nil { |
||||
|
return nil, NewCryptError(DecryptAESError, err.Error()) |
||||
|
} |
||||
|
|
||||
|
if len(encrypt_msg) < aes.BlockSize { |
||||
|
return nil, NewCryptError(DecryptAESError, "encrypt_msg size is not valid") |
||||
|
} |
||||
|
|
||||
|
iv := aeskey[:aes.BlockSize] |
||||
|
|
||||
|
if len(encrypt_msg)%aes.BlockSize != 0 { |
||||
|
return nil, NewCryptError(DecryptAESError, "encrypt_msg not a multiple of the block size") |
||||
|
} |
||||
|
|
||||
|
mode := cipher.NewCBCDecrypter(block, iv) |
||||
|
|
||||
|
mode.CryptBlocks(encrypt_msg, encrypt_msg) |
||||
|
|
||||
|
return encrypt_msg, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) calSignature(timestamp, nonce, data string) string { |
||||
|
sort_arr := []string{self.token, timestamp, nonce, data} |
||||
|
sort.Strings(sort_arr) |
||||
|
var buffer bytes.Buffer |
||||
|
for _, value := range sort_arr { |
||||
|
buffer.WriteString(value) |
||||
|
} |
||||
|
|
||||
|
sha := sha1.New() |
||||
|
sha.Write(buffer.Bytes()) |
||||
|
signature := fmt.Sprintf("%x", sha.Sum(nil)) |
||||
|
return string(signature) |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) ParsePlainText(plaintext []byte) ([]byte, uint32, []byte, []byte, *CryptError) { |
||||
|
const block_size = 32 |
||||
|
plaintext, err := self.pKCS7Unpadding(plaintext, block_size) |
||||
|
if nil != err { |
||||
|
return nil, 0, nil, nil, err |
||||
|
} |
||||
|
|
||||
|
text_len := uint32(len(plaintext)) |
||||
|
if text_len < 20 { |
||||
|
return nil, 0, nil, nil, NewCryptError(IllegalBuffer, "plain is to small 1") |
||||
|
} |
||||
|
random := plaintext[:16] |
||||
|
msg_len := binary.BigEndian.Uint32(plaintext[16:20]) |
||||
|
if text_len < (20 + msg_len) { |
||||
|
return nil, 0, nil, nil, NewCryptError(IllegalBuffer, "plain is to small 2") |
||||
|
} |
||||
|
|
||||
|
msg := plaintext[20 : 20+msg_len] |
||||
|
receiver_id := plaintext[20+msg_len:] |
||||
|
|
||||
|
return random, msg_len, msg, receiver_id, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) VerifyURL(msg_signature, timestamp, nonce, echostr string) ([]byte, *CryptError) { |
||||
|
signature := self.calSignature(timestamp, nonce, echostr) |
||||
|
|
||||
|
if strings.Compare(signature, msg_signature) != 0 { |
||||
|
return nil, NewCryptError(ValidateSignatureError, "signature not equal") |
||||
|
} |
||||
|
|
||||
|
plaintext, err := self.cbcDecrypter(echostr) |
||||
|
if nil != err { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
_, _, msg, receiver_id, err := self.ParsePlainText(plaintext) |
||||
|
if nil != err { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
if len(self.receiver_id) > 0 && strings.Compare(string(receiver_id), self.receiver_id) != 0 { |
||||
|
fmt.Println(string(receiver_id), self.receiver_id, len(receiver_id), len(self.receiver_id)) |
||||
|
return nil, NewCryptError(ValidateCorpidError, "receiver_id is not equil") |
||||
|
} |
||||
|
|
||||
|
return msg, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) EncryptMsg(reply_msg, timestamp, nonce string) ([]byte, *CryptError) { |
||||
|
rand_str := self.randString(16) |
||||
|
var buffer bytes.Buffer |
||||
|
buffer.WriteString(rand_str) |
||||
|
|
||||
|
msg_len_buf := make([]byte, 4) |
||||
|
binary.BigEndian.PutUint32(msg_len_buf, uint32(len(reply_msg))) |
||||
|
buffer.Write(msg_len_buf) |
||||
|
buffer.WriteString(reply_msg) |
||||
|
buffer.WriteString(self.receiver_id) |
||||
|
|
||||
|
tmp_ciphertext, err := self.cbcEncrypter(buffer.String()) |
||||
|
if nil != err { |
||||
|
return nil, err |
||||
|
} |
||||
|
ciphertext := string(tmp_ciphertext) |
||||
|
|
||||
|
signature := self.calSignature(timestamp, nonce, ciphertext) |
||||
|
|
||||
|
msg4_send := NewWXBizJsonMsg4Send(ciphertext, signature, timestamp, nonce) |
||||
|
return self.protocol_processor.serialize(msg4_send) |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) DecryptMsg(msg_signature, timestamp, nonce string, post_data []byte) ([]byte, *CryptError) { |
||||
|
msg4_recv, crypt_err := self.protocol_processor.parse(post_data) |
||||
|
if nil != crypt_err { |
||||
|
return nil, crypt_err |
||||
|
} |
||||
|
|
||||
|
signature := self.calSignature(timestamp, nonce, msg4_recv.Encrypt) |
||||
|
|
||||
|
if strings.Compare(signature, msg_signature) != 0 { |
||||
|
return nil, NewCryptError(ValidateSignatureError, "signature not equal") |
||||
|
} |
||||
|
|
||||
|
plaintext, crypt_err := self.cbcDecrypter(msg4_recv.Encrypt) |
||||
|
if nil != crypt_err { |
||||
|
return nil, crypt_err |
||||
|
} |
||||
|
|
||||
|
_, _, msg, receiver_id, crypt_err := self.ParsePlainText(plaintext) |
||||
|
if nil != crypt_err { |
||||
|
return nil, crypt_err |
||||
|
} |
||||
|
|
||||
|
if len(self.receiver_id) > 0 && strings.Compare(string(receiver_id), self.receiver_id) != 0 { |
||||
|
return nil, NewCryptError(ValidateCorpidError, "receiver_id is not equil") |
||||
|
} |
||||
|
|
||||
|
return msg, nil |
||||
|
} |
||||
@ -0,0 +1,315 @@ |
|||||
|
package wxbizmsgcrypt |
||||
|
|
||||
|
import ( |
||||
|
"bytes" |
||||
|
"crypto/aes" |
||||
|
"crypto/cipher" |
||||
|
"crypto/sha1" |
||||
|
"encoding/base64" |
||||
|
"encoding/binary" |
||||
|
"encoding/xml" |
||||
|
"fmt" |
||||
|
"math/rand" |
||||
|
"sort" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
const letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" |
||||
|
|
||||
|
const ( |
||||
|
ValidateSignatureError int = -40001 |
||||
|
ParseXmlError int = -40002 |
||||
|
ComputeSignatureError int = -40003 |
||||
|
IllegalAesKey int = -40004 |
||||
|
ValidateCorpidError int = -40005 |
||||
|
EncryptAESError int = -40006 |
||||
|
DecryptAESError int = -40007 |
||||
|
IllegalBuffer int = -40008 |
||||
|
EncodeBase64Error int = -40009 |
||||
|
DecodeBase64Error int = -40010 |
||||
|
GenXmlError int = -40010 |
||||
|
ParseJsonError int = -40012 |
||||
|
GenJsonError int = -40013 |
||||
|
IllegalProtocolType int = -40014 |
||||
|
) |
||||
|
|
||||
|
type ProtocolType int |
||||
|
|
||||
|
const ( |
||||
|
XmlType ProtocolType = 1 |
||||
|
) |
||||
|
|
||||
|
type CryptError struct { |
||||
|
ErrCode int |
||||
|
ErrMsg string |
||||
|
} |
||||
|
|
||||
|
func NewCryptError(err_code int, err_msg string) *CryptError { |
||||
|
return &CryptError{ErrCode: err_code, ErrMsg: err_msg} |
||||
|
} |
||||
|
|
||||
|
type WXBizMsg4Recv struct { |
||||
|
Tousername string `xml:"ToUserName"` |
||||
|
Encrypt string `xml:"Encrypt"` |
||||
|
Agentid string `xml:"AgentID"` |
||||
|
} |
||||
|
|
||||
|
type CDATA struct { |
||||
|
Value string `xml:",cdata"` |
||||
|
} |
||||
|
|
||||
|
type WXBizMsg4Send struct { |
||||
|
XMLName xml.Name `xml:"xml"` |
||||
|
Encrypt CDATA `xml:"Encrypt"` |
||||
|
Signature CDATA `xml:"MsgSignature"` |
||||
|
Timestamp string `xml:"TimeStamp"` |
||||
|
Nonce CDATA `xml:"Nonce"` |
||||
|
} |
||||
|
|
||||
|
func NewWXBizMsg4Send(encrypt, signature, timestamp, nonce string) *WXBizMsg4Send { |
||||
|
return &WXBizMsg4Send{Encrypt: CDATA{Value: encrypt}, Signature: CDATA{Value: signature}, Timestamp: timestamp, Nonce: CDATA{Value: nonce}} |
||||
|
} |
||||
|
|
||||
|
type ProtocolProcessor interface { |
||||
|
parse(src_data []byte) (*WXBizMsg4Recv, *CryptError) |
||||
|
serialize(msg_send *WXBizMsg4Send) ([]byte, *CryptError) |
||||
|
} |
||||
|
|
||||
|
type WXBizMsgCrypt struct { |
||||
|
token string |
||||
|
encoding_aeskey string |
||||
|
receiver_id string |
||||
|
protocol_processor ProtocolProcessor |
||||
|
} |
||||
|
|
||||
|
type XmlProcessor struct { |
||||
|
} |
||||
|
|
||||
|
func (self *XmlProcessor) parse(src_data []byte) (*WXBizMsg4Recv, *CryptError) { |
||||
|
var msg4_recv WXBizMsg4Recv |
||||
|
err := xml.Unmarshal(src_data, &msg4_recv) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(ParseXmlError, "xml to msg fail") |
||||
|
} |
||||
|
return &msg4_recv, nil |
||||
|
} |
||||
|
|
||||
|
func (self *XmlProcessor) serialize(msg4_send *WXBizMsg4Send) ([]byte, *CryptError) { |
||||
|
xml_msg, err := xml.Marshal(msg4_send) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(GenXmlError, err.Error()) |
||||
|
} |
||||
|
return xml_msg, nil |
||||
|
} |
||||
|
|
||||
|
func NewWXBizMsgCrypt(token, encoding_aeskey, receiver_id string, protocol_type ProtocolType) *WXBizMsgCrypt { |
||||
|
var protocol_processor ProtocolProcessor |
||||
|
if protocol_type != XmlType { |
||||
|
panic("unsupport protocal") |
||||
|
} else { |
||||
|
protocol_processor = new(XmlProcessor) |
||||
|
} |
||||
|
|
||||
|
return &WXBizMsgCrypt{token: token, encoding_aeskey: (encoding_aeskey + "="), receiver_id: receiver_id, protocol_processor: protocol_processor} |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) randString(n int) string { |
||||
|
b := make([]byte, n) |
||||
|
for i := range b { |
||||
|
b[i] = letterBytes[rand.Int63()%int64(len(letterBytes))] |
||||
|
} |
||||
|
return string(b) |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) pKCS7Padding(plaintext string, block_size int) []byte { |
||||
|
padding := block_size - (len(plaintext) % block_size) |
||||
|
padtext := bytes.Repeat([]byte{byte(padding)}, padding) |
||||
|
var buffer bytes.Buffer |
||||
|
buffer.WriteString(plaintext) |
||||
|
buffer.Write(padtext) |
||||
|
return buffer.Bytes() |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) pKCS7Unpadding(plaintext []byte, block_size int) ([]byte, *CryptError) { |
||||
|
plaintext_len := len(plaintext) |
||||
|
if nil == plaintext || plaintext_len == 0 { |
||||
|
return nil, NewCryptError(DecryptAESError, "pKCS7Unpadding error nil or zero") |
||||
|
} |
||||
|
if plaintext_len%block_size != 0 { |
||||
|
return nil, NewCryptError(DecryptAESError, "pKCS7Unpadding text not a multiple of the block size") |
||||
|
} |
||||
|
padding_len := int(plaintext[plaintext_len-1]) |
||||
|
return plaintext[:plaintext_len-padding_len], nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) cbcEncrypter(plaintext string) ([]byte, *CryptError) { |
||||
|
aeskey, err := base64.StdEncoding.DecodeString(self.encoding_aeskey) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(DecodeBase64Error, err.Error()) |
||||
|
} |
||||
|
const block_size = 32 |
||||
|
pad_msg := self.pKCS7Padding(plaintext, block_size) |
||||
|
|
||||
|
block, err := aes.NewCipher(aeskey) |
||||
|
if err != nil { |
||||
|
return nil, NewCryptError(EncryptAESError, err.Error()) |
||||
|
} |
||||
|
|
||||
|
ciphertext := make([]byte, len(pad_msg)) |
||||
|
iv := aeskey[:aes.BlockSize] |
||||
|
|
||||
|
mode := cipher.NewCBCEncrypter(block, iv) |
||||
|
|
||||
|
mode.CryptBlocks(ciphertext, pad_msg) |
||||
|
base64_msg := make([]byte, base64.StdEncoding.EncodedLen(len(ciphertext))) |
||||
|
base64.StdEncoding.Encode(base64_msg, ciphertext) |
||||
|
|
||||
|
return base64_msg, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) cbcDecrypter(base64_encrypt_msg string) ([]byte, *CryptError) { |
||||
|
aeskey, err := base64.StdEncoding.DecodeString(self.encoding_aeskey) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(DecodeBase64Error, err.Error()) |
||||
|
} |
||||
|
|
||||
|
encrypt_msg, err := base64.StdEncoding.DecodeString(base64_encrypt_msg) |
||||
|
if nil != err { |
||||
|
return nil, NewCryptError(DecodeBase64Error, err.Error()) |
||||
|
} |
||||
|
|
||||
|
block, err := aes.NewCipher(aeskey) |
||||
|
if err != nil { |
||||
|
return nil, NewCryptError(DecryptAESError, err.Error()) |
||||
|
} |
||||
|
|
||||
|
if len(encrypt_msg) < aes.BlockSize { |
||||
|
return nil, NewCryptError(DecryptAESError, "encrypt_msg size is not valid") |
||||
|
} |
||||
|
|
||||
|
iv := aeskey[:aes.BlockSize] |
||||
|
|
||||
|
if len(encrypt_msg)%aes.BlockSize != 0 { |
||||
|
return nil, NewCryptError(DecryptAESError, "encrypt_msg not a multiple of the block size") |
||||
|
} |
||||
|
|
||||
|
mode := cipher.NewCBCDecrypter(block, iv) |
||||
|
|
||||
|
mode.CryptBlocks(encrypt_msg, encrypt_msg) |
||||
|
|
||||
|
return encrypt_msg, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) calSignature(timestamp, nonce, data string) string { |
||||
|
sort_arr := []string{self.token, timestamp, nonce, data} |
||||
|
sort.Strings(sort_arr) |
||||
|
var buffer bytes.Buffer |
||||
|
for _, value := range sort_arr { |
||||
|
buffer.WriteString(value) |
||||
|
} |
||||
|
|
||||
|
sha := sha1.New() |
||||
|
sha.Write(buffer.Bytes()) |
||||
|
signature := fmt.Sprintf("%x", sha.Sum(nil)) |
||||
|
return string(signature) |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) ParsePlainText(plaintext []byte) ([]byte, uint32, []byte, []byte, *CryptError) { |
||||
|
const block_size = 32 |
||||
|
plaintext, err := self.pKCS7Unpadding(plaintext, block_size) |
||||
|
if nil != err { |
||||
|
return nil, 0, nil, nil, err |
||||
|
} |
||||
|
|
||||
|
text_len := uint32(len(plaintext)) |
||||
|
if text_len < 20 { |
||||
|
return nil, 0, nil, nil, NewCryptError(IllegalBuffer, "plain is to small 1") |
||||
|
} |
||||
|
random := plaintext[:16] |
||||
|
msg_len := binary.BigEndian.Uint32(plaintext[16:20]) |
||||
|
if text_len < (20 + msg_len) { |
||||
|
return nil, 0, nil, nil, NewCryptError(IllegalBuffer, "plain is to small 2") |
||||
|
} |
||||
|
|
||||
|
msg := plaintext[20 : 20+msg_len] |
||||
|
receiver_id := plaintext[20+msg_len:] |
||||
|
|
||||
|
return random, msg_len, msg, receiver_id, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) VerifyURL(msg_signature, timestamp, nonce, echostr string) ([]byte, *CryptError) { |
||||
|
signature := self.calSignature(timestamp, nonce, echostr) |
||||
|
|
||||
|
if strings.Compare(signature, msg_signature) != 0 { |
||||
|
return nil, NewCryptError(ValidateSignatureError, "signature not equal") |
||||
|
} |
||||
|
|
||||
|
plaintext, err := self.cbcDecrypter(echostr) |
||||
|
if nil != err { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
_, _, msg, receiver_id, err := self.ParsePlainText(plaintext) |
||||
|
if nil != err { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
if len(self.receiver_id) > 0 && strings.Compare(string(receiver_id), self.receiver_id) != 0 { |
||||
|
fmt.Println(string(receiver_id), self.receiver_id, len(receiver_id), len(self.receiver_id)) |
||||
|
return nil, NewCryptError(ValidateCorpidError, "receiver_id is not equil") |
||||
|
} |
||||
|
|
||||
|
return msg, nil |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) EncryptMsg(reply_msg, timestamp, nonce string) ([]byte, *CryptError) { |
||||
|
rand_str := self.randString(16) |
||||
|
var buffer bytes.Buffer |
||||
|
buffer.WriteString(rand_str) |
||||
|
|
||||
|
msg_len_buf := make([]byte, 4) |
||||
|
binary.BigEndian.PutUint32(msg_len_buf, uint32(len(reply_msg))) |
||||
|
buffer.Write(msg_len_buf) |
||||
|
buffer.WriteString(reply_msg) |
||||
|
buffer.WriteString(self.receiver_id) |
||||
|
|
||||
|
tmp_ciphertext, err := self.cbcEncrypter(buffer.String()) |
||||
|
if nil != err { |
||||
|
return nil, err |
||||
|
} |
||||
|
ciphertext := string(tmp_ciphertext) |
||||
|
|
||||
|
signature := self.calSignature(timestamp, nonce, ciphertext) |
||||
|
|
||||
|
msg4_send := NewWXBizMsg4Send(ciphertext, signature, timestamp, nonce) |
||||
|
return self.protocol_processor.serialize(msg4_send) |
||||
|
} |
||||
|
|
||||
|
func (self *WXBizMsgCrypt) DecryptMsg(msg_signature, timestamp, nonce string, post_data []byte) ([]byte, *CryptError) { |
||||
|
msg4_recv, crypt_err := self.protocol_processor.parse(post_data) |
||||
|
if nil != crypt_err { |
||||
|
return nil, crypt_err |
||||
|
} |
||||
|
|
||||
|
signature := self.calSignature(timestamp, nonce, msg4_recv.Encrypt) |
||||
|
|
||||
|
if strings.Compare(signature, msg_signature) != 0 { |
||||
|
return nil, NewCryptError(ValidateSignatureError, "signature not equal") |
||||
|
} |
||||
|
|
||||
|
plaintext, crypt_err := self.cbcDecrypter(msg4_recv.Encrypt) |
||||
|
if nil != crypt_err { |
||||
|
return nil, crypt_err |
||||
|
} |
||||
|
|
||||
|
_, _, msg, receiver_id, crypt_err := self.ParsePlainText(plaintext) |
||||
|
if nil != crypt_err { |
||||
|
return nil, crypt_err |
||||
|
} |
||||
|
|
||||
|
if len(self.receiver_id) > 0 && strings.Compare(string(receiver_id), self.receiver_id) != 0 { |
||||
|
return nil, NewCryptError(ValidateCorpidError, "receiver_id is not equil") |
||||
|
} |
||||
|
|
||||
|
return msg, nil |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
package models |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/overall" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
// 双职工
|
||||
|
type AcademicTitle struct { |
||||
|
Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:ID"` |
||||
|
Types string `json:"types" gorm:"column:types;type:varchar(255) unsigned;default:'';not null;comment:职称级别"` |
||||
|
Series string `json:"series" gorm:"column:series;type:varchar(255) unsigned;default:'';not null;comment:职称系列"` |
||||
|
Speciality string `json:"speciality" gorm:"column:speciality;type:varchar(255) unsigned;default:'';not null;comment:职称专业"` |
||||
|
Number string `json:"number" gorm:"column:number;type:varchar(255) unsigned;default:'';not null;comment:资格证书编号"` |
||||
|
Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:生效时间"` |
||||
|
EditTime int64 `json:"editTime" gorm:"column:editTime;type:bigint(20) unsigned;default:0;not null;comment:写入时间"` |
||||
|
UserKey int64 `json:"userKey" gorm:"column:userKey;type:bigint(20) unsigned;default:0;not null;comment:人员唯一识别符"` |
||||
|
} |
||||
|
|
||||
|
func (AcademicTitle *AcademicTitle) TableName() string { |
||||
|
return "academictitle" |
||||
|
} |
||||
|
|
||||
|
// 编辑双职工内容
|
||||
|
func (AcademicTitle *AcademicTitle) EiteCont(whereMap interface{}, saveData interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Model(&AcademicTitle).Where(whereMap).Updates(saveData).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 获取双职工内容
|
||||
|
func (cont *AcademicTitle) GetCont(whereMap interface{}, field ...string) (err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
gormDb = gormDb.Where(whereMap) |
||||
|
err = gormDb.First(&cont).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 删除内容
|
||||
|
func (cont *AcademicTitle) DelCont(whereMap interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Where(whereMap).Delete(&cont).Error |
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
package models |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/overall" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
// 证书
|
||||
|
type CertificateHonors struct { |
||||
|
Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:ID"` |
||||
|
Title string `json:"title" gorm:"column:title;type:varchar(30) unsigned;not null;comment:证书/荣誉名称"` |
||||
|
UserKey int64 `json:"userkey" gorm:"column:userkey;type:bigint(20) unsigned;default:0;not null;comment:获得人员"` |
||||
|
Types int `json:"types" gorm:"column:types;type:tinyint(1) unsigned;default:1;not null;comment:类型(1:职称证书;2:资格证书;3:荣誉)` |
||||
|
State int `json:"state" gorm:"column:state;type:tinyint(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)` |
||||
|
IssuingUnit string `json:"issuingUnit" gorm:"column:issuing_unit;type:varchar(255) unsigned;default:'';not null;comment:颁发单位"` |
||||
|
TimeData int64 `json:"timedata" gorm:"column:timedata;type:bigint(20) unsigned;default:0;not null;comment:获得时间"` |
||||
|
Years int `json:"years" gorm:"column:years;type:int(7) unsigned;default:0;not null;comment:年"` |
||||
|
Months int `json:"months" gorm:"column:months;type:int(7) unsigned;default:0;not null;comment:月"` |
||||
|
Number string `json:"number" gorm:"column:number;type:varchar(255) unsigned;not null;comment:证书编号"` |
||||
|
EndTime int64 `json:"endTime" gorm:"column:endTime;type:bigint(20) unsigned;default:0;not null;comment:截止时间"` |
||||
|
ValidPeriod string `json:"validPeriod" gorm:"column:validPeriod;type:varchar(255) unsigned;not null;comment:有效期限"` |
||||
|
} |
||||
|
|
||||
|
func (CertificateHonors *CertificateHonors) TableName() string { |
||||
|
return "certificate_honors" |
||||
|
} |
||||
|
|
||||
|
// 编辑双职工内容
|
||||
|
func (CertificateHonors *CertificateHonors) EiteCont(whereMap interface{}, saveData interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Model(&CertificateHonors).Where(whereMap).Updates(saveData).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 获取双职工内容
|
||||
|
func (cont *CertificateHonors) GetCont(whereMap interface{}, field ...string) (err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
gormDb = gormDb.Where(whereMap) |
||||
|
err = gormDb.First(&cont).Error |
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
package models |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/overall" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
// 绩效考核成绩
|
||||
|
type Meritslog struct { |
||||
|
Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:ID"` |
||||
|
Score int64 `json:"score" gorm:"column:score;type:bigint(20) unsigned;default:0;not null;comment:绩效分数*10000保存"` |
||||
|
UserKey int64 `json:"userkey" gorm:"column:userkey;type:bigint(20) unsigned;default:0;not null;comment:获得人员"` |
||||
|
Status int `json:"status" gorm:"column:status;type:tinyint(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)` |
||||
|
TimeData int64 `json:"timedata" gorm:"column:timedata;type:bigint(20) unsigned;default:0;not null;comment:获得时间"` |
||||
|
Years int `json:"years" gorm:"column:years;type:int(7) unsigned;default:0;not null;comment:年"` |
||||
|
Months int `json:"months" gorm:"column:months;type:int(7) unsigned;default:0;not null;comment:月"` |
||||
|
Level string `json:"level" gorm:"column:level;type:varchar(255);not null;comment:考核等级"` |
||||
|
} |
||||
|
|
||||
|
func (Meritslog *Meritslog) TableName() string { |
||||
|
return "meritslog" |
||||
|
} |
||||
|
|
||||
|
// 编辑双职工内容
|
||||
|
func (Meritslog *Meritslog) EiteCont(whereMap interface{}, saveData interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Model(&Meritslog).Where(whereMap).Updates(saveData).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 获取双职工内容
|
||||
|
func (cont *Meritslog) GetCont(whereMap interface{}, field ...string) (err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
gormDb = gormDb.Where(whereMap) |
||||
|
err = gormDb.First(&cont).Error |
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
package personalitycolor |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/overall" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
// 授权账户
|
||||
|
type Charcolortest struct { |
||||
|
Id int64 `json:"id" gorm:"primaryKey;column:c_id;type:bigint(20) unsigned;not null;comment:Id;index"` |
||||
|
Class int64 `json:"class" gorm:"column:c_class;type:bigint(20) unsigned;default:0;not null;comment:测试试卷类型"` |
||||
|
Types int `json:"types" gorm:"column:c_type;type:tinyint(1) unsigned;default:1;not null;comment:1:内部测试;2:外部测试` |
||||
|
Number string `json:"number" gorm:"column:c_number;type:varchar(10) unsigned;not null;comment:工号"` |
||||
|
Name string `json:"name" gorm:"column:c_name;type:varchar(50) unsigned;not null;comment:姓名"` |
||||
|
Department string `json:"department" gorm:"column:c_department;type:varchar(255) unsigned;not null;comment:部门"` |
||||
|
Tel string `json:"tel" gorm:"column:c_tel;type:varchar(50) unsigned;not null;comment:联系电话"` |
||||
|
Address string `json:"address" gorm:"column:c_address;type:varchar(255) unsigned;not null;comment:联系地址"` |
||||
|
UserJson string `json:"userJson" gorm:"column:c_user_json;type:text unsigned;comment:内部员工详细信息"` |
||||
|
TestJson string `json:"testJson" gorm:"column:c_test_json;type:mediumtext unsigned;comment:试卷答案"` |
||||
|
Time int64 `json:"addtime" gorm:"column:c_add_time;type:bigint(20) unsigned;default:0;not null;comment:写入时间"` |
||||
|
EiteTime int64 `json:"eitetime" gorm:"column:c_eite_time;type:bigint(20) unsigned;default:0;not null;comment:编辑时间"` |
||||
|
State int `json:"state" gorm:"column:c_states;type:tinyint(1) unsigned;default:1;not null;comment:状态(1:有效;2:无效)` |
||||
|
BranchName string `json:"branchName" gorm:"column:c_branch_name;type:varchar(255) unsigned;not null;comment:部门"` |
||||
|
} |
||||
|
|
||||
|
func (Position *Charcolortest) TableName() string { |
||||
|
return "charcolortest" |
||||
|
} |
||||
|
|
||||
|
// 编辑职务分类内容
|
||||
|
func (cont *Charcolortest) EiteCont(whereMap interface{}, saveData map[string]interface{}) (err error) { |
||||
|
err = overall.CONSTANT_Personality_Color.Model(&cont).Where(whereMap).Updates(saveData).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 获取行政组织内容
|
||||
|
func (cont *Charcolortest) GetCont(whereMap interface{}, field ...string) (err error) { |
||||
|
gormDb := overall.CONSTANT_Personality_Color.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
gormDb = gormDb.Where(whereMap) |
||||
|
err = gormDb.First(&cont).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 根据条件获取总数
|
||||
|
func (cont *Charcolortest) CountCont(whereMap interface{}) (countId int64) { |
||||
|
overall.CONSTANT_Personality_Color.Model(&cont).Where(whereMap).Count(&countId) |
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,63 @@ |
|||||
|
package models |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/overall" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
type PoliticalIdentity struct { |
||||
|
Userkey int64 `json:"userkey" gorm:"primaryKey;column:userkey;type:bigint(20) unsigned;not null;comment:员工唯一识别符;"` |
||||
|
PoliticalOutlook int `json:"politicaloutlook" gorm:"column:political_outlook;type:int(3) unsigned;default:1;comment:政治面貌(1:群众;2:无党派;3:台盟会员;4:九三社员;5:致公党员;6:农工党员;7:民进会员;8:民建会员;9:民盟盟员;10:民革会员,11:共青团员;12:预备党员;13:中共党员)"` |
||||
|
JoinTime int64 `json:"joinTime" gorm:"column:joinTime;type:bigint(20) unsigned;default:0;not null;comment:加入时间"` |
||||
|
Branch string `json:"branch" gorm:"column:branch;type:varchar(255) ;comment:所在党支部"` |
||||
|
Bosition string `json:"position" gorm:"column:position;type:varchar(255) ;comment:党内职务"` |
||||
|
JoiningParty string `json:"joiningParty" gorm:"column:joiningParty;type:varchar(255) ;comment:入党时所在单位"` |
||||
|
SwitchToClass int `json:"switchToClass" gorm:"column:switchToClass;type:int(1) unsigned;default:50;not null;comment:组织关系是否转入(1:是;2:否)"` |
||||
|
SwitchToTime int64 `json:"switchToTime" gorm:"column:switchToTime;type:bigint(20) unsigned;default:0;not null;comment:组织关系转入时间"` |
||||
|
Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:创建时间"` |
||||
|
} |
||||
|
|
||||
|
func (PoliticalIdentity *PoliticalIdentity) TableName() string { |
||||
|
return "political_identity" |
||||
|
} |
||||
|
|
||||
|
// 编辑内容
|
||||
|
func (cont *PoliticalIdentity) EiteCont(whereMap interface{}, saveData interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Model(&cont).Where(whereMap).Updates(saveData).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 获取内容
|
||||
|
func (cont *PoliticalIdentity) GetCont(whereMap interface{}, field ...string) (err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
gormDb = gormDb.Where(whereMap) |
||||
|
err = gormDb.First(&cont).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 根据条件获取总数
|
||||
|
func (cont *PoliticalIdentity) CountCont(whereMap interface{}) (countId int64) { |
||||
|
overall.CONSTANT_DB_HR.Model(&cont).Where(whereMap).Count(&countId) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 读取全部信息
|
||||
|
func (cont *PoliticalIdentity) ContMap(whereMap interface{}, field ...string) (countAry []PoliticalIdentity, err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
err = gormDb.Where(whereMap).Find(&countAry).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 删除内容
|
||||
|
func (cont *PoliticalIdentity) DelCont(whereMap interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Where(whereMap).Delete(&cont).Error |
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
package models |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/overall" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
// 证书
|
||||
|
type RewardsPenalties struct { |
||||
|
Id int64 `json:"id" gorm:"primaryKey;column:id;type:bigint(20) unsigned;not null;comment:ID"` |
||||
|
Title string `json:"title" gorm:"column:title;type:varchar(30) unsigned;not null;comment:奖励/处分项目"` |
||||
|
UserKey int64 `json:"userkey" gorm:"column:userkey;type:bigint(20) unsigned;default:0;not null;comment:获得人员"` |
||||
|
Types int `json:"types" gorm:"column:types;type:tinyint(1) unsigned;default:1;not null;comment:类型(1:奖励;2:处分;)` |
||||
|
State int `json:"state" gorm:"column:state;type:tinyint(1) unsigned;default:1;not null;comment:状态(1:启用;2:禁用;3:删除)` |
||||
|
IssuingUnit string `json:"issuingUnit" gorm:"column:issuing_unit;type:varchar(255) unsigned;default:'';not null;comment:颁发单位"` |
||||
|
TimeData int64 `json:"timedata" gorm:"column:timedata;type:bigint(20) unsigned;default:0;not null;comment:获得时间"` |
||||
|
Years int `json:"years" gorm:"column:years;type:int(7) unsigned;default:0;not null;comment:年"` |
||||
|
Months int `json:"months" gorm:"column:months;type:int(7) unsigned;default:0;not null;comment:月"` |
||||
|
Level int `json:"level" gorm:"column:level;type:int(7) unsigned;default:0;not null;comment:奖惩级别(1:部门级;2:公司级;3:县级;4:市级;5:省级;6:国家级)"` |
||||
|
RewPunClass int `json:"rewPunClass" gorm:"column:rewPunClass;type:int(7) unsigned;default:0;not null;comment:奖惩类型(1:年终评优;2:表扬;3:嘉奖;4:记功;5:记大功;6:特别奖励;7:批评;8:警告;9:记过;10:记大过;11:降级;12:留用察看;13:开除)"` |
||||
|
} |
||||
|
|
||||
|
func (RewardsPenalties *RewardsPenalties) TableName() string { |
||||
|
return "rewards_penalties" |
||||
|
} |
||||
|
|
||||
|
// 编辑双职工内容
|
||||
|
func (RewardsPenalties *RewardsPenalties) EiteCont(whereMap interface{}, saveData interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Model(&RewardsPenalties).Where(whereMap).Updates(saveData).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 获取双职工内容
|
||||
|
func (cont *RewardsPenalties) GetCont(whereMap interface{}, field ...string) (err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
gormDb = gormDb.Where(whereMap) |
||||
|
err = gormDb.First(&cont).Error |
||||
|
return |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
package models |
||||
|
|
||||
|
import ( |
||||
|
"hr_server/overall" |
||||
|
"strings" |
||||
|
) |
||||
|
|
||||
|
type Veterans struct { |
||||
|
Userkey int64 `json:"userkey" gorm:"primaryKey;column:userkey;type:bigint(20) unsigned;not null;comment:员工唯一识别符;"` |
||||
|
IsRetire int `json:"isRetire" gorm:"column:isRetire;type:int(1) unsigned;default:50;not null;comment:是否为退役军人(1:是;2:否)"` |
||||
|
RetireNumber string `json:"retireNumber" gorm:"column:retireNumber;type:varchar(255) ;comment:退役证编号"` |
||||
|
JoinTime int64 `json:"joinTime" gorm:"column:joinTime;type:bigint(20) unsigned;default:0;not null;comment:入伍时间"` |
||||
|
RetireTime int64 `json:"retireTime" gorm:"column:retireTime;type:bigint(20) unsigned;default:0;not null;comment:退伍时间"` |
||||
|
ArmyUnits string `json:"armyUnits" gorm:"column:armyUnits;type:varchar(255) ;comment:参军单位"` |
||||
|
TypesOfSoldiers string `json:"typesOfSoldiers" gorm:"column:typesOfSoldiers;type:varchar(255) ;comment:兵种"` |
||||
|
Time int64 `json:"time" gorm:"column:time;type:bigint(20) unsigned;default:0;not null;comment:创建时间"` |
||||
|
} |
||||
|
|
||||
|
func (Veterans *Veterans) TableName() string { |
||||
|
return "veterans" |
||||
|
} |
||||
|
|
||||
|
// 编辑内容
|
||||
|
func (cont *Veterans) EiteCont(whereMap interface{}, saveData interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Model(&cont).Where(whereMap).Updates(saveData).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 获取内容
|
||||
|
func (cont *Veterans) GetCont(whereMap interface{}, field ...string) (err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
gormDb = gormDb.Where(whereMap) |
||||
|
err = gormDb.First(&cont).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 根据条件获取总数
|
||||
|
func (cont *Veterans) CountCont(whereMap interface{}) (countId int64) { |
||||
|
overall.CONSTANT_DB_HR.Model(&cont).Where(whereMap).Count(&countId) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 读取全部信息
|
||||
|
func (cont *Veterans) ContMap(whereMap interface{}, field ...string) (countAry []Veterans, err error) { |
||||
|
gormDb := overall.CONSTANT_DB_HR.Model(&cont) |
||||
|
if len(field) > 0 { |
||||
|
fieldStr := strings.Join(field, ",") |
||||
|
gormDb = gormDb.Select(fieldStr) |
||||
|
} |
||||
|
err = gormDb.Where(whereMap).Find(&countAry).Error |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 删除内容
|
||||
|
func (cont *Veterans) DelCont(whereMap interface{}) (err error) { |
||||
|
err = overall.CONSTANT_DB_HR.Where(whereMap).Delete(&cont).Error |
||||
|
return |
||||
|
} |
||||
Loading…
Reference in new issue