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