cxzhang 3 tahun lalu
induk
melakukan
59a6b3b367

+ 27 - 31
controllers/base_auth.go

@@ -17,12 +17,12 @@ import (
 // BaseAuth 需要授权token的基类
 type BaseAuth struct {
 	BaseCommon
-	AdminWx *custom.AdminWx                  `description:"管理员信息"`
-	Token   string                           `description:"用户token"`
+	AdminWx *custom.AdminWx `description:"管理员信息"`
+	Token   string          `description:"用户token"`
 
-	StartSize int	`description:"开始数量"`
-	StartPage int	`description:"开始页码"`
-	PageSize int	`description:"每页数量"`
+	StartSize int `description:"开始数量"`
+	StartPage int `description:"开始页码"`
+	PageSize  int `description:"每页数量"`
 }
 
 func (c *BaseAuth) Prepare() {
@@ -30,7 +30,7 @@ func (c *BaseAuth) Prepare() {
 	signData := make(map[string]string)
 	method := c.Ctx.Input.Method()
 
-	var pageSize,currentIndex int
+	var pageSize, currentIndex int
 	switch method {
 	case "GET":
 		//requestBody = c.Ctx.Request.RequestURI
@@ -48,8 +48,8 @@ func (c *BaseAuth) Prepare() {
 		switch contentType {
 		case "multipart/form-data":
 			//文件最大5M
-			err := c.Ctx.Request.ParseMultipartForm(- int64(5<<20))
-			if err != nil{
+			err := c.Ctx.Request.ParseMultipartForm(-int64(5 << 20))
+			if err != nil {
 				c.FailWithMessage(fmt.Sprintf("获取参数失败,%v", err))
 				//response.FailWithMessage(fmt.Sprintf("获取参数失败,%v", err), c)
 				//c.Abort()
@@ -57,7 +57,7 @@ func (c *BaseAuth) Prepare() {
 			}
 		default:
 			err := c.Ctx.Request.ParseForm()
-			if err != nil{
+			if err != nil {
 				c.FailWithMessage(fmt.Sprintf("获取参数失败,%v", err))
 				return
 			}
@@ -72,7 +72,7 @@ func (c *BaseAuth) Prepare() {
 		pageSize = utils.PageSize20
 	}
 	//如果超过最大分页数,那么就是按照最大分页数返回
-	if pageSize > utils.PageMaxSize{
+	if pageSize > utils.PageMaxSize {
 		pageSize = utils.PageMaxSize
 	}
 	if currentIndex <= 0 {
@@ -83,13 +83,12 @@ func (c *BaseAuth) Prepare() {
 	c.PageSize = pageSize
 	c.StartPage = currentIndex
 
-
 	ip := c.Ctx.Input.IP()
 
 	//获取签名秘钥
 	//key := global.GVA_CONFIG.SignKey.Agent
 	////签名校验
-	err := checkSign(signData,ip)
+	err := checkSign(signData, ip)
 	if err != nil {
 		c.SignError(fmt.Sprintf("签名校验失败,%v", err))
 		return
@@ -99,7 +98,7 @@ func (c *BaseAuth) Prepare() {
 }
 
 //将请求传入的数据格式转换成签名需要的格式
-func convertParam(params map[string][]string)(signData map[string]string)  {
+func convertParam(params map[string][]string) (signData map[string]string) {
 	signData = make(map[string]string)
 	for key := range params {
 		signData[key] = params[key][0]
@@ -107,38 +106,37 @@ func convertParam(params map[string][]string)(signData map[string]string)  {
 	return signData
 }
 
-
 //请求参数签名校验
-func checkSign(postData map[string]string,ip string) (err error){
+func checkSign(postData map[string]string, ip string) (err error) {
 	isSandbox := postData["is_sandbox"]
 	//如果是测试环境,且是沙箱环境的话,那么绕过测试
 	if utils.RunMode == "debug" && isSandbox != "" {
 		return
 	}
 
-	appid :=postData["appid"]
+	appid := postData["appid"]
 	if appid == "" {
 		err = errors.New("参数异常,缺少appid")
 		return
 	}
-	openApiUserInfo,tmpErr:= open_api_user.GetByAppid(appid)
-	if tmpErr != nil{
-		if tmpErr.Error() == utils.ErrNoRow(){
+	openApiUserInfo, tmpErr := open_api_user.GetByAppid(appid)
+	if tmpErr != nil {
+		if tmpErr.Error() == utils.ErrNoRow() {
 			err = errors.New("appid异常,请联系管理员")
-		}else{
+		} else {
 			err = errors.New("系统异常,请联系管理员")
 		}
 		return
 	}
 
-	if openApiUserInfo == nil{
+	if openApiUserInfo == nil {
 		err = errors.New("系统异常,请联系管理员")
 		return
 	}
 	//如果有ip限制,那么就添加ip
-	if openApiUserInfo.Ip != ""{
-		if !strings.Contains(openApiUserInfo.Ip,ip){
-			err = errors.New(fmt.Sprintf("无权限访问该接口,ip:%v,请联系管理员",ip))
+	if openApiUserInfo.Ip != "" {
+		if !strings.Contains(openApiUserInfo.Ip, ip) {
+			err = errors.New(fmt.Sprintf("无权限访问该接口,ip:%v,请联系管理员", ip))
 			return
 		}
 	}
@@ -156,15 +154,15 @@ func checkSign(postData map[string]string,ip string) (err error){
 	if postData["timestamp"] == "" {
 		err = errors.New("参数异常,缺少时间戳")
 		return
-	}else{
-		timeUnix := time.Now().Unix()	//当前格林威治时间,int64类型
+	} else {
+		timeUnix := time.Now().Unix() //当前格林威治时间,int64类型
 		//将接口传入的时间做转换
 		timestamp, timeErr := strconv.ParseInt(postData["timestamp"], 10, 64)
-		if timeErr != nil{
+		if timeErr != nil {
 			err = errors.New("参数异常,时间戳格式异常")
 			return
 		}
-		if math.Abs(float64(timeUnix - timestamp)) > 300 {
+		if math.Abs(float64(timeUnix-timestamp)) > 300 {
 			err = errors.New("当前时间异常,请调整设备时间与北京时间一致")
 			return
 		}
@@ -189,13 +187,11 @@ func checkSign(postData map[string]string,ip string) (err error){
 	//3,全转小写(md5(拼装的字符串后+分配给你的app_secret))
 	//sign := strings.ToLower(fmt.Sprintf("%x", md5.Sum([]byte(strings.Trim(signStr, "&")+key))))
 
-
 	//md5.Sum([]byte(signStr+"key="+key))  这是md5加密出来后的每个字符的ascall码,需要再转换成对应的字符
 	//3,全转大写(md5(拼装的字符串后+分配给你的app_secret))
 	sign := strings.ToUpper(fmt.Sprintf("%x", md5.Sum([]byte(signStr+"secret="+openApiUserInfo.Secret))))
-
 	if sign != ownSign {
-		utils.ApiLog.Println(fmt.Sprintf("签名校验异常,签名字符串:%v;服务端签名值:%v",signStr,sign))
+		utils.ApiLog.Println(fmt.Sprintf("签名校验异常,签名字符串:%v;服务端签名值:%v", signStr, sign))
 		return errors.New("签名校验异常,请核实签名")
 	}
 	return nil

+ 12 - 0
controllers/company_user.go

@@ -26,6 +26,12 @@ type CompanyUser struct {
 // @Success 200 {object} company_user.UserReportListResp
 // @router /user_report_list [get]
 func (c *CompanyUser) GetUserReportList() {
+	//appid权限校验
+	appid := c.GetString("appid", "")
+	if utils.RunMode == "release" && appid != "CQWx3EqDLNk7bVHo" {
+		c.FailWithMessage("无权限")
+		return
+	}
 	mobile := c.GetString("mobile", "")
 	email := c.GetString("email", "")
 	startDate := c.GetString("start_date", "")
@@ -204,6 +210,12 @@ func (c *CompanyUser) GetUserReportListV2() {
 // @Success 200 {object} []logic.UserView
 // @router /view_total_list [get]
 func (c *CompanyUser) GetUserReportViewTotalList() {
+	//appid权限校验
+	appid := c.GetString("appid", "")
+	if utils.RunMode == "release" && appid != "CQWx3EqDLNk7bVHo" {
+		c.FailWithMessage("无权限")
+		return
+	}
 	list, err := logic.GetUserViewTotal()
 	if err != nil {
 		c.FailWithMessage("获取失败")

+ 243 - 0
controllers/report.go

@@ -0,0 +1,243 @@
+package controllers
+
+import (
+	"fmt"
+	tables "hongze/hongze_open_api/models/tables/report"
+	"hongze/hongze_open_api/models/tables/wx_user"
+	"hongze/hongze_open_api/utils"
+	"rdluck_tools/common"
+	"strconv"
+	"time"
+)
+
+// 报告模块
+type ReportController struct {
+	BaseAuth
+}
+
+// @Title 获取报告列表接口
+// @Description 获取报告列表
+// @Param   _page_size   query   int  true       "每页数据条数"
+// @Param   _page   query   int  true       "当前页页码,从1开始"
+// @Param   report_type   query   string  true       "类型 day:晨报 、week :周报、two_week:双周报 、month:月报、other :点评 (默认为day:晨报) "
+// @Param   keyword   query   string  true       "搜索关键词"
+// @Param   mobile   query   string  true       "用户手机号(加密后的)"
+// @Success 200 {object} report.ReportListResp
+// @router /list [get]
+func (c *ReportController) ListReport() {
+	pageSize, _ := c.GetInt("_page_size")
+	currentIndex, _ := c.GetInt("_page")
+	keyWord := c.GetString("keyword")
+	reportType := c.GetString("report_type")
+	mobile := c.GetString("mobile")
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+	if mobile == "" {
+		c.FailWithMessage("mobile 必传")
+		return
+	}
+	var dateTxt = []byte(mobile)
+	resultDe := utils.DesBase64Decrypt(dateTxt)
+	deMobile := string(resultDe)
+	if deMobile == "" {
+		c.FailWithMessage("手机号加密格式错误")
+		return
+	}
+	totalFicc, err := tables.GetUserReportFiccCount(deMobile)
+	if err != nil {
+		c.FailWithMessage("获取失败")
+		return
+	}
+	if totalFicc < 1 {
+		c.FailWithMessage("用户不存在")
+		return
+	}
+	var condition string
+	var pars []interface{}
+	condition = ` AND  enabled = 1 `
+	if keyWord != "" {
+		condition += ` AND  research_report_name LIKE '%` + keyWord + `%'`
+	}
+	//day:晨报 、week :周报、two_week:双周报 、month:月报、other :点评
+	if reportType != "week" && reportType != "two_week" && reportType != "month" && reportType != "other" {
+		reportType = "day"
+	}
+	if reportType != "" {
+		condition += ` AND type = ? `
+		pars = append(pars, reportType)
+	}
+	total, err := tables.GetReportListCount(condition, pars)
+	if err != nil {
+		c.FailWithMessage("获取失败")
+		return
+	}
+	list, err := tables.GetReportList(condition, pars, startSize, pageSize)
+	if err != nil {
+		c.FailWithMessage("获取失败")
+		return
+	}
+
+	nonceStr := common.GetRandString(10)
+	timeUnix := strconv.FormatInt(time.Now().Unix(), 10)
+	if len(list) > 0 {
+		for k, v := range list {
+			postData := make(map[string]string)
+			reportId := strconv.Itoa(v.ResearchReportId)
+			parameter := "mobile=" + mobile + "&research_report_id=" + reportId + "&nonce_str=" + nonceStr + "&timestamp=" + timeUnix
+			postData["mobile"] = mobile
+			postData["research_report_id"] = reportId
+			postData["appid"] = utils.ReportAppid
+			postData["nonce_str"] = nonceStr
+			postData["timestamp"] = timeUnix
+			sign := utils.GetSign(postData)
+			list[k].HttpUrl = utils.ResearchReportUrl + "report/getReportInfo?" + parameter + "&sign=" + sign
+		}
+	}
+	page := utils.GetPaging(currentIndex, pageSize, total)
+	resp := tables.ReportListResp{
+		List:   list,
+		Paging: page,
+	}
+	c.OkDetailed(resp, "获取成功")
+}
+
+//func init() {
+//	var pwd = []byte("15557270714,13253777798")
+//	//services.Dojiami()
+//	result := utils.DesBase64Encrypt(pwd)
+//	fmt.Println(string(result))
+//	var dateTxt = []byte("Tl8zwzgQNbEYPUvXleA/XQ==")
+//	resultDe := utils.DesBase64Decrypt(dateTxt)
+//	fmt.Println(string(resultDe))
+//	//fmt.Println(resultStr)
+//	//map[appid:XVuGlcyEEVNYVWx6 nonce_str:PsI0pAxDS4 research_report_id:1550 timestamp:1642522516]
+//	//map[appid:XVuGlcyEEVNYVWx6 mobile:Tl8zwzgQNbEYPUvXleA/XQ== nonce_str:PsI0pAxDS4 research_report_id:1550 sign:0FFE4F38D4394EA72A947A8ADDAD4996 timestamp:1642522516]
+//
+//	fmt.Println("加密解密")
+//}
+
+// @Title 获取报告列表接口
+// @Description 获取报告列表
+// @Param research_report_id query int true "报告ID"
+// @Param   mobile   query   string  true       "用户手机号(加密后的)"
+// @Success 200 {object} report.ResearchReportInfo
+// @router /getReportInfo [get]
+func (c *ReportController) GetReportInfo() {
+	researchReportId, _ := c.GetInt("research_report_id")
+	mobile := c.GetString("mobile")
+	if researchReportId < 1 {
+		c.FailWithMessage("请传入报告id")
+		return
+	}
+	if mobile == "" {
+		c.FailWithMessage("mobile 必传")
+		return
+	}
+
+	var dateTxt = []byte(mobile)
+	resultDe := utils.DesBase64Decrypt(dateTxt)
+	deMobile := string(resultDe)
+	if deMobile == "" {
+		c.FailWithMessage("手机号加密格式错误")
+		return
+	}
+	totalFicc, err := tables.GetUserReportFiccCount(deMobile)
+	if err != nil {
+		c.FailWithMessage("获取失败")
+		return
+	}
+	if totalFicc < 1 {
+		c.FailWithMessage("用户不存在")
+		return
+	}
+	userInfo, err := wx_user.GetWxUserByMobileStr(deMobile)
+	if err != nil {
+		c.FailWithMessage("找不到该用户")
+		return
+	}
+	reportInfo, hasPermission, err := tables.GetResearchReportInfo(researchReportId, userInfo.UserId)
+	if err != nil {
+		fmt.Println(err)
+		c.FailWithMessage("获取报告失败")
+		return
+	}
+	if !hasPermission {
+		c.FailWithMessage("无权限")
+		return
+	}
+	nonceStr := common.GetRandString(10)
+	timeUnix := strconv.FormatInt(time.Now().Unix(), 10)
+	if len(reportInfo.ResearchReportTypeList) > 1 {
+		for k, v := range reportInfo.ResearchReportTypeList {
+			postData := make(map[string]string)
+			reportId := strconv.Itoa(int(v.ResearchReportTypeId))
+			parameter := "mobile=" + mobile + "&ResearchReportTypeId=" + reportId + "&appid=" + utils.ReportAppid + "&nonce_str=" + nonceStr + "&timestamp=" + timeUnix
+			postData["mobile"] = mobile
+			postData["ResearchReportTypeId"] = reportId
+			postData["appid"] = utils.ReportAppid
+			postData["nonce_str"] = nonceStr
+			postData["timestamp"] = timeUnix
+			sign := utils.GetSign(postData)
+			reportInfo.ResearchReportTypeList[k].HttpUrl = utils.ResearchReportUrl + "report/getReportChapterInfo?" + parameter + "&sign=" + sign
+		}
+	}
+	c.OkDetailed(reportInfo, "获取成功")
+}
+
+// @Title 获取报告列表接口
+// @Description 获取报告列表
+// @Param ResearchReportTypeId query int true "章节ID"
+// @Param   mobile   query   string  false       "用户手机号(加密后的)"
+// @Success 200 {object} report.ResearchReportTypeContentInfo
+// @router /getReportChapterInfo [get]
+func (c *ReportController) GetResearchReportChapter() {
+	researchReportTypeId, _ := c.GetInt("ResearchReportTypeId")
+	mobile := c.GetString("mobile")
+	if researchReportTypeId < 1 {
+		c.FailWithMessage("请传入章节id")
+		return
+	}
+	if mobile == "" {
+		c.FailWithMessage("mobile 必传")
+		return
+	}
+	var dateTxt = []byte(mobile)
+	resultDe := utils.DesBase64Decrypt(dateTxt)
+	deMobile := string(resultDe)
+	if deMobile == "" {
+		c.FailWithMessage("手机号加密格式错误")
+		return
+	}
+	totalFicc, err := tables.GetUserReportFiccCount(deMobile)
+	if err != nil {
+		c.FailWithMessage("获取失败")
+		return
+	}
+	if totalFicc < 1 {
+		c.FailWithMessage("用户不存在")
+		return
+	}
+	userInfo, err := wx_user.GetWxUserByMobileStr(deMobile)
+	if err != nil {
+		c.FailWithMessage("找不到该用户")
+		return
+	}
+
+	reportInfo, hasPermission, err := tables.GetResearchReportTypeContentInfo(uint64(researchReportTypeId), uint64(userInfo.UserId))
+	if err != nil {
+		fmt.Println(err)
+		c.FailWithMessage("获取报告失败")
+		return
+	}
+	if !hasPermission {
+		c.FailWithMessage("无权限")
+		return
+	}
+	c.OkDetailed(reportInfo, "获取成功")
+}

+ 56 - 0
models/tables/company_report_permission/company_report_permission.go

@@ -0,0 +1,56 @@
+package company_report_permission
+
+import "time"
+
+// CompanyReportPermission 客户权限表
+type CompanyReportPermission struct {
+	CompanyReportPermissionID uint64    `gorm:"primaryKey;column:company_report_permission_id;type:bigint(20) unsigned;not null" json:"-"`         // 主键
+	CompanyID                 int64     `gorm:"uniqueIndex:uni_key;column:company_id;type:bigint(20);default:0" json:"companyId"`                  // 客户id
+	ReportPermissionID        int64     `gorm:"column:report_permission_id;type:bigint(20)" json:"reportPermissionId"`                             // 报告权限id
+	CreatedTime               time.Time `gorm:"index:created_time;column:created_time;type:datetime;default:CURRENT_TIMESTAMP" json:"createdTime"` // 创建时间
+	LastUpdatedTime           time.Time `gorm:"index:last_updated_time;column:last_updated_time;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"lastUpdatedTime"`
+	ChartPermissionID         int       `gorm:"uniqueIndex:uni_key;column:chart_permission_id;type:int(11);default:0" json:"chartPermissionId"` // 大分类ID
+	StartDate                 time.Time `gorm:"column:start_date;type:date" json:"startDate"`                                                   // 权限开始日期
+	EndDate                   time.Time `gorm:"column:end_date;type:date" json:"endDate"`                                                       // 权限结束日期
+	ProductID                 int       `gorm:"index:idx_product_id;column:product_id;type:int(11);default:0" json:"productId"`                 // 产品id
+	ProductName               string    `gorm:"column:product_name;type:varchar(20);default:''" json:"productName"`                             // 产品名称
+	ModifyTime                time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`                                             // 修改时间
+	CompanyContractID         int       `gorm:"column:company_contract_id;type:int(11);default:0" json:"companyContractId"`                     // 合同id
+	Status                    string    `gorm:"column:status;type:enum('正式','试用','关闭','永续','潜在')" json:"status"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *CompanyReportPermission) TableName() string {
+	return "company_report_permission"
+}
+
+// CompanyReportPermissionColumns get sql column name.获取数据库列名
+var CompanyReportPermissionColumns = struct {
+	CompanyReportPermissionID string
+	CompanyID                 string
+	ReportPermissionID        string
+	CreatedTime               string
+	LastUpdatedTime           string
+	ChartPermissionID         string
+	StartDate                 string
+	EndDate                   string
+	ProductID                 string
+	ProductName               string
+	ModifyTime                string
+	CompanyContractID         string
+	Status                    string
+}{
+	CompanyReportPermissionID: "company_report_permission_id",
+	CompanyID:                 "company_id",
+	ReportPermissionID:        "report_permission_id",
+	CreatedTime:               "created_time",
+	LastUpdatedTime:           "last_updated_time",
+	ChartPermissionID:         "chart_permission_id",
+	StartDate:                 "start_date",
+	EndDate:                   "end_date",
+	ProductID:                 "product_id",
+	ProductName:               "product_name",
+	ModifyTime:                "modify_time",
+	CompanyContractID:         "company_contract_id",
+	Status:                    "status",
+}

+ 154 - 0
models/tables/company_report_permission/custom_query.go

@@ -0,0 +1,154 @@
+package company_report_permission
+
+import (
+	"fmt"
+	"rdluck_tools/orm"
+	"strings"
+	"time"
+)
+
+type ReportChapterTypeIdList struct {
+	ReportChapterTypeId uint64
+}
+
+type ResearchReportTypeInfo struct {
+	ResearchReportTypeTitle string `json:"research_report_type_title" description:"研究报告标题"`
+	BannerUrl               string `json:"banner_url" description:"banner url"`
+	ReportChapterTypeName   string `json:"report_chapter_type_name" description:"章节名称"`
+	ResearchReportID        uint64 `orm:"column(research_report_id)";json:"research_report_id" description:"报告id"`
+	ResearchReportTypeID    uint64 `orm:"column(research_report_type_id)";json:"research_report_type_id" description:"研究报告id"`
+	TypeID                  int    `orm:"column(type_id)";json:"type_id" description:"分类id"`
+	ReportChapterTypeId     uint64 `json:"report_chapter_type_id" description:"章节名称"`
+}
+
+type ResearchReportTypeList struct {
+	ResearchReportTypeId    uint64    ` description:"章节ID"`
+	ResearchReportId        uint64    ` description:"研究报告id"`
+	ResearchReportTypeTitle string    `description:"研究报告标题"`
+	TypeId                  int       `description:"分类id"`
+	Edit                    int8      `description:"是否编辑过"`
+	Trend                   string    `description:"趋势观点"`
+	ReportChapterTypeKey    string    `description:"章节key"`
+	ReportChapterTypeThumb  string    `description:"H5展示的图片"`
+	BannerUrl               string    `description:"banner显示图片"`
+	ReportChapterTypeName   string    `description:"报告章节类型名称"`
+	Sort                    int       `description:"排序字段"`
+	EditImgUrl              string    `description:"管理后台编辑时选用的图"`
+	PauseStartTime          time.Time `description:"暂停开始日期"`
+	PauseEndTime            time.Time `description:"暂停结束日期"`
+	LastUpdatedTime         time.Time `description:"最后更新时间"`
+	HttpUrl                 string    `json:"http_url",description:"报告详情"`
+}
+
+//GetResearchReportType 获取研究报告的章节详情
+func GetResearchReportType(researchReportId uint64, userId int, reportType string) (list []*ResearchReportTypeList, err error) {
+	var condition string
+	//whereVals := make([]interface{}, 0)
+
+	//如果是周报,并且是H5页面
+	if "week" == reportType && userId > 0 {
+		condition += ` and rrt.edit=1 `
+		reportChapterTypeList, tmpErr := GetReportVarietyList(userId, reportType)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		if len(reportChapterTypeList) > 0 {
+			reportChapterTypeIdList := make([]string, 0)
+			for _, v := range reportChapterTypeList {
+				reportChapterTypeIdList = append(reportChapterTypeIdList, fmt.Sprint(v.ReportChapterTypeId))
+			}
+			condition += ` and rct.report_chapter_type_id in (` + strings.Join(reportChapterTypeIdList, ",") + `) `
+			//whereVals = append(whereVals, strings.Join(reportChapterTypeIdList, ","))
+
+		}
+	}
+
+	if strings.Contains("day,week", reportType) {
+		condition += ` and rct.is_show=1 `
+	}
+
+	sql := `select
+	rrt.research_report_type_id,
+	rrt.research_report_id,
+	rrt.research_report_type_title,
+	rrt.type_id,
+	rrt.edit,
+	rrt.trend,
+	rct.report_chapter_type_key,
+	rct.report_chapter_type_thumb,
+	rct.banner_url,
+	rct.report_chapter_type_name,
+	rct.sort,
+	rct.edit_img_url,
+	rct.pause_start_time,
+	rct.pause_end_time,
+	rrt.last_updated_time
+	from research_report_type rrt
+	left JOIN  report_chapter_type rct on rct.report_chapter_type_id  = rrt.type_id
+	where rrt.research_report_id  = ? `
+	sql += condition
+	sql += ` order by rct.sort,rrt.research_report_type_id `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, researchReportId).QueryRows(&list)
+	return
+}
+
+type PermissionName struct {
+	ChartPermissionName string
+	ResearchType        string
+}
+
+//权限
+// GetReportVarietyList
+func GetReportVarietyList(userId int, reportType string) (list []*ReportChapterTypeIdList, err error) {
+	o := orm.NewOrm()
+	var condition string
+	//whereVals := make([]interface{}, 0)
+	if reportType != "" {
+		condition += ` and cpcm.research_type = '` + reportType + `' `
+		//whereVals = append(whereVals, reportType)
+	}
+	sql := ` SELECT cpcm.report_chapter_type_id FROM company_report_permission crp
+            INNER JOIN  chart_permission_chapter_mapping cpcm ON crp.chart_permission_id = cpcm.chart_permission_id
+            INNER JOIN wx_user wu ON wu.company_id = crp.company_id
+            WHERE wu.user_id = ? `
+	sql += condition
+	sql += ` GROUP BY cpcm.report_chapter_type_id `
+	_, err = o.Raw(sql, userId).QueryRows(&list)
+	return
+}
+
+type ResearchReportTypeContent struct {
+	ResearchReportTypeTitle     string
+	ResearchReportTypeContentId int       `json:"research_report_type_content_id" description:"研究报告内容id"`
+	ResearchReportTypeId        int       `json:"research_report_id" description:"报告id"`
+	Sort                        int       `json:"sort" description:"排序"`
+	ContentType                 string    `json:"content_type" description:"内容分类类型"`
+	Content                     string    `json:"content" description:"内容"`
+	ImgUrl                      string    `json:"img_url" description:"图片路径"`
+	CreatedTime                 time.Time `json:"created_time" description:"创建时间"`
+	LastUpdatedTime             time.Time `json:"last_updated_time" description:"最近一次更新时间"`
+}
+
+// GetResearchReportTypeContentList 获取研究报告章节详情
+func GetResearchReportTypeContentList(researchReportTypeId uint64) (items []*ResearchReportTypeContent, err error) {
+	o := orm.NewOrm()
+	sql := `select rrt.research_report_type_title,rrtc.*,rrt.research_report_type_id
+from research_report_type rrt
+inner join research_report_type_content rrtc on rrtc.research_report_type_id = rrt.research_report_type_id
+where rrt.research_report_type_id = ? `
+	_, err = o.Raw(sql, researchReportTypeId).QueryRows(&items)
+	return
+}
+
+// GetResearchReportTypeInfo 获取研究报告类型详情
+func GetResearchReportTypeInfo(researchReportTypeId uint64) (item *ResearchReportTypeInfo, err error) {
+	sql := ` select rrt.research_report_type_title,rct.banner_url,rct.report_chapter_type_name,rrt.research_report_id,rrt.research_report_type_id,rrt.type_id,rct.report_chapter_type_name,rct.report_chapter_type_id
+            from research_report_type rrt
+            left join report_chapter_type rct on rct.report_chapter_type_id = rrt.type_id
+            where rrt.research_report_type_id =? limit 1`
+	o := orm.NewOrm()
+	err = o.Raw(sql, researchReportTypeId).QueryRow(&item)
+	return
+}

+ 6 - 6
models/tables/open_api_user/open_api_user.go

@@ -5,12 +5,12 @@ import (
 )
 
 type OpenApiUser struct {
-	Appid                 string    `orm:"column(appid);pk" json:"appid" description:"开放平台appid"`
-	Secret               string `orm:"column(secret);" json:"secret" description:"开放平台秘钥"`
-	Ip                string `orm:"column(ip);" json:"ip" description:"限制请求来源ip,多个ip用英文,隔开"`
-	Remark                string `orm:"column(remark);" json:"remark" description:"备注信息"`
-	CreateTime             string `orm:"column(create_time);" json:"create_time" description:"创建时间"`
-	ModifyTime         string `orm:"column(modify_time);" json:"modify_time" description:"最近一次更新时间"`
+	Appid      string `orm:"column(appid);pk" json:"appid" description:"开放平台appid"`
+	Secret     string `orm:"column(secret);" json:"secret" description:"开放平台秘钥"`
+	Ip         string `orm:"column(ip);" json:"ip" description:"限制请求来源ip,多个ip用英文,隔开"`
+	Remark     string `orm:"column(remark);" json:"remark" description:"备注信息"`
+	CreateTime string `orm:"column(create_time);" json:"create_time" description:"创建时间"`
+	ModifyTime string `orm:"column(modify_time);" json:"modify_time" description:"最近一次更新时间"`
 }
 
 // GetByAppid 根据appid获取开放api用户信息

+ 216 - 0
models/tables/report/report.go

@@ -0,0 +1,216 @@
+package report
+
+import (
+	"hongze/hongze_open_api/models/tables/company_report_permission"
+	"hongze/hongze_open_api/utils"
+	"rdluck_tools/orm"
+	"time"
+)
+
+type ReportList struct {
+	ResearchReportId   int    `json:"research_report_id",orm:"column(research_report_id)";description:"报告Id"`
+	ResearchReportName string `json:"research_report_name",orm:"column(research_report_name)"description:"标题"`
+	Periods            int    `json:"periods",description:"期数"`
+	ResearchReportDate string `json:"research_report_date",description:"发布时间"`
+	HttpUrl            string `json:"http_url",description:"报告详情"`
+}
+
+type ReportListResp struct {
+	List   []*ReportList     `description:"列表"  json:"list"`
+	Paging *utils.PagingItem `description:"分页数据" json:"paging"`
+}
+
+type ResearchReportInfo struct {
+	ResearchReportInfo            *ResearchReport                                        `json:"research_report_info"`
+	ResearchReportTypeList        []*company_report_permission.ResearchReportTypeList    `json:"research_report_type_list"`
+	HasMenu                       int                                                    `json:"has_menu"`
+	ResearchReportTypeContentList []*company_report_permission.ResearchReportTypeContent `description:"报告详情"`
+}
+
+// ResearchReport 研究报告表
+type ResearchReport struct {
+	//ResearchReportID    uint64    `gorm:"primaryKey;column:research_report_id;type:bigint(20) unsigned;not null" json:"-"`                       // 研究报告id
+	ResearchReportID    uint64    `orm:"column(research_report_id)";description:"报告Id"`                                                                               // 研究报告id
+	ResearchReportName  string    `gorm:"index:research_report_name;column:research_report_name;type:varchar(128)" json:"researchReportName";description:"研究报告名称"`    // 研究报告名称
+	ResearchReportTitle string    `gorm:"index:research_report_title;column:research_report_title;type:varchar(128)" json:"researchReportTitle";description:"研究报告标题"` // 研究报告标题
+	ResearchReportImg   string    `gorm:"column:research_report_img;type:varchar(128)" json:"researchReportImg";description:"报告缩略图URL"`                               // 报告缩略图URL
+	ResearchReportDate  time.Time `gorm:"column:research_report_date;type:date;not null" json:"researchReportDate";description:"报告日期"`                                // 报告日期
+	Type                string    `gorm:"column:type;type:varchar(32);default:day" json:"type";description:"day 晨报  week 周报 twoweek双周报 month 月报"`                     // day 晨报  week 周报 twoweek双周报 month 月报
+	Author              string    `gorm:"column:author;type:varchar(100)" json:"author";description:"报告作者"`                                                           // 报告作者
+	ReportVariety       string    `gorm:"column:report_variety;type:varchar(30)" json:"reportVariety";description:"研究报告的品种,双周报和月报有标识"`                                // 研究报告的品种,双周报和月报有标识
+	IsHasMenu           int8      `gorm:"column:is_has_menu;type:tinyint(1);default:0" json:"isHasMenu";description:"报告Id"`                                           // 报告是否含有目录
+	IsSendedMsg         int8      `gorm:"column:is_sended_msg;type:tinyint(1);default:0" json:"isSendedMsg";description:"报告是否含有目录"`                                   // 是否发送过模板消息
+	Periods             int       `gorm:"column:periods;type:int(8)" json:"periods";description:"期数"`                                                                 // 期数
+	Status              string    `gorm:"column:status;type:varchar(20);not null" json:"status";description:"状态,draft:草稿"`                                            // 状态,draft:草稿,
+	Enabled             int8      `gorm:"index:enabled;column:enabled;type:tinyint(1);default:1" json:"enabled";description:"报告状态"`                                   // 报告状态
+	CreatedTime         time.Time `gorm:"index:created_time;column:created_time;type:datetime;default:CURRENT_TIMESTAMP" json:"createdTime";description:"创建时间"`       // 创建时间
+	LastUpdatedTime     time.Time `gorm:"index:last_updated_time;column:last_updated_time;type:timestamp;not null;default:CURRENT_TIMESTAMP" json:"lastUpdatedTime";description:"修改时间"`
+	Viewers             int       `gorm:"column:viewers;type:int(8);default:0" json:"viewers";description:"H5观看用户数"` // H5观看用户数
+}
+
+type ResearchReportTypeContent struct {
+	ResearchReportTypeTitle     string
+	ResearchReportTypeContentId int       `json:"research_report_type_content_id" description:"研究报告内容id"`
+	ResearchReportTypeId        int       `json:"research_report_id" description:"报告id"`
+	Sort                        int       `json:"sort" description:"排序"`
+	ContentType                 string    `json:"content_type" description:"内容分类类型"`
+	Content                     string    `json:"content" description:"内容"`
+	ImgUrl                      string    `json:"img_url" description:"图片路径"`
+	CreatedTime                 time.Time `json:"created_time" description:"创建时间"`
+	LastUpdatedTime             time.Time `json:"last_updated_time" description:"最近一次更新时间"`
+}
+
+func GetReportListCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+
+	sql := `SELECT COUNT(1) AS count  FROM research_report WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func GetReportList(condition string, pars []interface{}, startSize, pageSize int) (items []*ReportList, err error) {
+	o := orm.NewOrm()
+	//产品权限
+
+	sql := `SELECT * FROM research_report WHERE 1=1`
+	if condition != "" {
+		sql += condition
+	}
+	sql += `ORDER BY  periods DESC LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items)
+	return
+}
+
+//GetResearchReportInfo 获取报告详情
+func GetResearchReportInfo(researchReportId, userId int) (result ResearchReportInfo, hasPermission bool, err error) {
+	//获取报告详情
+	reportInfo, err := GetByResearchReportId(researchReportId)
+	if err != nil {
+		return
+	}
+	reportType := reportInfo.Type
+	//这些个报告需要做权限校验
+
+	if utils.InArray(reportInfo.Type, []string{"month", "two_week", "other"}) {
+		list, tmpErr := company_report_permission.GetReportVarietyList(userId, reportType)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		for _, v := range list {
+			if reportInfo.ResearchReportID == v.ReportChapterTypeId {
+				hasPermission = true
+				break
+			}
+		}
+		if !hasPermission {
+			return
+		}
+	} else {
+		hasPermission = true
+	}
+	researchReportTypeList := make([]*company_report_permission.ResearchReportTypeList, 0)
+	tmpResearchReportTypeList, err := company_report_permission.GetResearchReportType(reportInfo.ResearchReportID, userId, reportInfo.Type)
+	if err != nil {
+		return
+	}
+	reportDate := reportInfo.ResearchReportDate
+	for _, v := range tmpResearchReportTypeList {
+		if reportDate.Before(v.PauseStartTime) || reportDate.After(v.PauseEndTime) {
+			researchReportTypeList = append(researchReportTypeList, v)
+		}
+	}
+	result = ResearchReportInfo{
+		ResearchReportInfo:     reportInfo,
+		ResearchReportTypeList: researchReportTypeList,
+		HasMenu:                1,
+	}
+	if len(researchReportTypeList) <= 0 {
+
+	} else if len(researchReportTypeList) == 1 {
+		//只有一个章节,即没有目录的时候,需要直接返回章节详情
+		result.HasMenu = 0
+		researchReportTypeContent, tmpErr := company_report_permission.GetResearchReportTypeContentList(researchReportTypeList[0].ResearchReportTypeId)
+		if tmpErr != nil {
+			return
+		}
+		result.ResearchReportTypeContentList = researchReportTypeContent
+	}
+	return
+}
+
+// GetPermissionNameByReportId
+func GetByResearchReportId(researchReportid int) (item *ResearchReport, err error) {
+	sql := `SELECT * FROM research_report WHERE research_report_id = ?`
+	o := orm.NewOrm()
+	err = o.Raw(sql, researchReportid).QueryRow(&item)
+	return
+}
+
+type ResearchReportTypeContentInfo struct {
+	ResearchReportTypeInfo        *company_report_permission.ResearchReportTypeInfo      `json:"research_report_type_info"`
+	Add                           int                                                    `json:"add"`
+	ResearchReportTypeContentList []*company_report_permission.ResearchReportTypeContent `description:"报告详情" json:"research_report_type_content_list"`
+}
+
+// GetResearchReportTypeContentInfo 获取报告章节详情
+func GetResearchReportTypeContentInfo(researchReportTypeId, userId uint64) (result ResearchReportTypeContentInfo, hasPermission bool, err error) {
+	//获取章节详情
+	researchReportTypeContentList, err := company_report_permission.GetResearchReportTypeContentList(researchReportTypeId)
+	if err != nil {
+		return
+	}
+	researchReportTypeInfo, err := company_report_permission.GetResearchReportTypeInfo(researchReportTypeId)
+	if err != nil {
+		return
+	}
+	//获取报告详情
+	reportInfo, err := GetByResearchReportId(int(researchReportTypeInfo.ResearchReportID))
+	if err != nil {
+		return
+	}
+	reportType := reportInfo.Type
+	//这些个报告需要做权限校验
+	if utils.InArray(reportInfo.Type, []string{"week", "month", "two_week", "other"}) {
+		list, tmpErr := company_report_permission.GetReportVarietyList(int(userId), reportType)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		if reportInfo.Type == "week" {
+			//周报校验章节是否在权限内
+			for _, v := range list {
+				if researchReportTypeInfo.ReportChapterTypeId == v.ReportChapterTypeId {
+					hasPermission = true
+					break
+				}
+			}
+		} else {
+			//双周报和月报校验 类型是否在权限内
+			for _, v := range list {
+				if reportInfo.ResearchReportID == v.ReportChapterTypeId {
+					hasPermission = true
+					break
+				}
+			}
+		}
+		if !hasPermission {
+			return
+		}
+	} else {
+		hasPermission = true
+	}
+	add := 1
+	if len(researchReportTypeContentList) > 0 {
+		add = 0
+	}
+	result = ResearchReportTypeContentInfo{
+		ResearchReportTypeContentList: researchReportTypeContentList,
+		ResearchReportTypeInfo:        researchReportTypeInfo,
+		Add:                           add,
+	}
+	return
+}

+ 15 - 0
models/tables/report/user_report_power.go

@@ -0,0 +1,15 @@
+package report
+
+import (
+	"rdluck_tools/orm"
+)
+
+func GetUserReportFiccCount(mobile string) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(1) as count
+			FROM company_report_permission crp
+			INNER JOIN wx_user wu ON wu.company_id = crp.company_id 
+			WHERE wu.mobile IN (` + mobile + `) AND crp.product_id = 1 AND status IN  ('正式','试用','永续') `
+	err = o.Raw(sql).QueryRow(&count)
+	return
+}

+ 1 - 1
models/tables/user_view_statistics/user_view_statistics.go

@@ -30,7 +30,7 @@ func GetUserViewListByDate(dayStr string) (list []*UserViewMobileTotalSlice, err
 	o := orm.NewOrm()
 	sql := `SELECT mobile,sum(view_num) total
 			FROM user_view_statistics
-			WHERE 1=1 and date >= ? group by mobile`
+			WHERE 1=1 and date >= ? and mobile !="" group by mobile`
 	_, err = o.Raw(sql, dayStr).QueryRows(&list)
 	return
 }

+ 13 - 4
models/tables/wx_user/wx_user.go

@@ -54,10 +54,10 @@ func GetOpenIdListByMobile(mobile, openIdStr string) (items []*OpenIdList, err e
 }
 
 type WxUserItem struct {
-	UserId int
-	RealName string
-	Mobile string
-	Email string
+	UserId      int
+	RealName    string
+	Mobile      string
+	Email       string
 	CompanyName string
 }
 
@@ -78,3 +78,12 @@ func GetWxUserByEmail(email string) (item *WxUserItem, err error) {
 	err = orm.NewOrm().Raw(sql, email).QueryRow(&item)
 	return
 }
+
+// GetWxUserByMobile 根据手机号获取用户信息
+func GetWxUserByMobileStr(mobile string) (item *WxUserItem, err error) {
+	sql := `SELECT a.user_id,a.real_name,a.mobile,b.company_name FROM wx_user AS a 
+          INNER JOIN company AS b ON a.company_id = b.company_id 
+          WHERE a.mobile IN (` + mobile + `) LIMIT 1 `
+	err = orm.NewOrm().Raw(sql).QueryRow(&item)
+	return
+}

+ 5 - 0
routers/router.go

@@ -28,6 +28,11 @@ func init() {
 				&controllers.CompanyUser{},
 			),
 		),
+		web.NSNamespace("/report",
+			web.NSInclude(
+				&controllers.ReportController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 50 - 1
utils/common.go

@@ -12,6 +12,7 @@ import (
 	"image/png"
 	"math"
 	"math/rand"
+	"net"
 	"os"
 	"os/exec"
 	"regexp"
@@ -690,4 +691,52 @@ func StrTimeToTime(strTime string) time.Time {
 	loc, _ := time.LoadLocation("Local") //重要:获取时区
 	resultTime, _ := time.ParseInLocation(timeLayout, strTime, loc)
 	return resultTime
-}
+}
+
+// InArray 是否在切片(数组/map)中含有该值,目前只支持:string、int 、 int64,其他都是返回false
+func InArray(needle interface{}, hyStack interface{}) bool {
+	switch key := needle.(type) {
+	case string:
+		for _, item := range hyStack.([]string) {
+			if key == item {
+				return true
+			}
+		}
+	case int:
+		for _, item := range hyStack.([]int) {
+			if key == item {
+				return true
+			}
+		}
+	case int64:
+		for _, item := range hyStack.([]int64) {
+			if key == item {
+				return true
+			}
+		}
+	default:
+		return false
+	}
+	return false
+}
+
+func GetLocalIP() (ip string, err error) {
+	addrs, err := net.InterfaceAddrs()
+	if err != nil {
+		return
+	}
+	for _, addr := range addrs {
+		ipAddr, ok := addr.(*net.IPNet)
+		if !ok {
+			continue
+		}
+		if ipAddr.IP.IsLoopback() {
+			continue
+		}
+		if !ipAddr.IP.IsGlobalUnicast() {
+			continue
+		}
+		return ipAddr.IP.String(), nil
+	}
+	return
+}

+ 27 - 7
utils/config.go

@@ -21,13 +21,14 @@ var (
 var ApiLog *log.Log
 
 var (
-	Bucketname       string = "hongze"
-	Endpoint         string
-	Imghost          string = "https://hongze.oss-accelerate.aliyuncs.com/"
-	Upload_dir       string = "static/images/"
-	Upload_Audio_Dir string = "static/audio/"
-	AccessKeyId      string = "LTAIFMZYQhS2BTvW"
-	AccessKeySecret  string = "12kk1ptCHoGWedhBnKRVW5hRJzq9Fq"
+	Bucketname        string = "hongze"
+	Endpoint          string
+	Imghost           string = "https://hongze.oss-accelerate.aliyuncs.com/"
+	Upload_dir        string = "static/images/"
+	Upload_Audio_Dir  string = "static/audio/"
+	AccessKeyId       string = "LTAIFMZYQhS2BTvW"
+	AccessKeySecret   string = "12kk1ptCHoGWedhBnKRVW5hRJzq9Fq"
+	ResearchReportUrl        = "" //全局加密KEY
 )
 
 func init() {
@@ -36,6 +37,23 @@ func init() {
 		panic("配置文件读取run_mode错误 " + err.Error())
 	}
 	RunMode = tmpRunMode
+	fmt.Println("RunMode:", RunMode)
+	if RunMode == "" {
+		localIp, err := GetLocalIP()
+		fmt.Println("localIp:", localIp)
+		if localIp == "10.0.0.123" {
+			RunMode = "debug"
+		} else {
+			RunMode = "release"
+		}
+		fmt.Println("RunMode:", RunMode)
+		configPath := `/home/code/config/hongze_open_api/conf/app.conf`
+		fmt.Println("configPath:", configPath)
+		err = web.LoadAppConfig("ini", configPath)
+		if err != nil {
+			fmt.Println("web.LoadAppConfig Err:" + err.Error())
+		}
+	}
 	fmt.Println(RunMode, "模式")
 	config, err := web.AppConfig.GetSection(RunMode)
 	if err != nil {
@@ -60,8 +78,10 @@ func init() {
 	if RunMode == "release" {
 		logDir := `/data/rdlucklog/hongze_open_api`
 		ApiLog = log.Init("20060102.api", logDir)
+		ResearchReportUrl = "http://8.136.199.33:8608/api/"
 	} else {
 		ApiLog = log.Init("20060102.api")
+		ResearchReportUrl = "http://8.136.199.33:8608/api/"
 	}
 }
 

+ 7 - 1
utils/constants.go

@@ -16,7 +16,7 @@ const (
 	PageSize10            = 10
 	PageSize20            = 20
 	PageSize30            = 30
-	PageMaxSize            = 100	//每页最大数据数
+	PageMaxSize           = 100 //每页最大数据数
 )
 
 const (
@@ -91,3 +91,9 @@ const (
 
 var PermissionFiccClassifyArr = [...]string{"宏观经济", "化工产业", "黑色产业", "有色产业"}
 var PermissionAllClassifyArr = [...]string{"宏观经济", "化工产业", "黑色产业", "有色产业", "权益"}
+
+const (
+	key          = "zDeESsxsXuionhqSLZYHWcDJ"         //全局加密KEY
+	ReportAppid  = "APPIDFwujYAMHqlNojIYPFhvEjFdPysz" //Appid
+	ReportSecret = "SecretPHAvGg9AIqBRGXGc2vVtxfl4DD" //AppSecret
+)

+ 187 - 0
utils/des3.go

@@ -0,0 +1,187 @@
+//加密工具类,用了3des和base64
+package utils
+
+import (
+	"bytes"
+	"crypto/cipher"
+	"crypto/des"
+	"encoding/base64"
+	"encoding/hex"
+	"errors"
+	"strings"
+)
+
+//des3 + base64 encrypt
+func DesBase64Encrypt(origData []byte) []byte {
+	result, err := TripleDesEncrypt(origData, []byte(key))
+	if err != nil {
+		panic(err)
+	}
+	return []byte(base64.StdEncoding.EncodeToString(result))
+}
+
+func DesBase64Decrypt(crypted []byte) []byte {
+	result, _ := base64.StdEncoding.DecodeString(string(crypted))
+	remain := len(result) % 8
+	if remain > 0 {
+		mod := 8 - remain
+		for i := 0; i < mod; i++ {
+			result = append(result, 0)
+		}
+	}
+	origData, err := TripleDesDecrypt(result, []byte(key))
+	if err != nil {
+		panic(err)
+	}
+	return origData
+}
+
+// 3DES加密
+func TripleDesEncrypt(origData, key []byte) ([]byte, error) {
+	block, err := des.NewTripleDESCipher(key)
+	if err != nil {
+		return nil, err
+	}
+	origData = PKCS5Padding(origData, block.BlockSize())
+	// origData = ZeroPadding(origData, block.BlockSize())
+	blockMode := cipher.NewCBCEncrypter(block, key[:8])
+	crypted := make([]byte, len(origData))
+	blockMode.CryptBlocks(crypted, origData)
+	return crypted, nil
+}
+
+// 3DES解密
+func TripleDesDecrypt(crypted, key []byte) ([]byte, error) {
+	block, err := des.NewTripleDESCipher(key)
+	if err != nil {
+		return nil, err
+	}
+	blockMode := cipher.NewCBCDecrypter(block, key[:8])
+	origData := make([]byte, len(crypted))
+	// origData := crypted
+	blockMode.CryptBlocks(origData, crypted)
+	origData = PKCS5UnPadding(origData)
+	// origData = ZeroUnPadding(origData)
+	return origData, nil
+}
+
+func ZeroPadding(ciphertext []byte, blockSize int) []byte {
+	padding := blockSize - len(ciphertext)%blockSize
+	padtext := bytes.Repeat([]byte{0}, padding)
+	return append(ciphertext, padtext...)
+}
+
+func ZeroUnPadding(origData []byte) []byte {
+	length := len(origData)
+	unpadding := int(origData[length-1])
+	return origData[:(length - unpadding)]
+}
+
+func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
+	padding := blockSize - len(ciphertext)%blockSize
+	padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+	return append(ciphertext, padtext...)
+}
+
+func PKCS5UnPadding(origData []byte) []byte {
+	length := len(origData)
+	// 去掉最后一个字节 unpadding 次
+	unpadding := int(origData[length-1])
+	return origData[:(length - unpadding)]
+}
+
+//DES加密
+func DesEncrypt(content string, key string) string {
+	contents := []byte(content)
+	keys := []byte(key)
+	block, err := des.NewCipher(keys)
+	if err != nil {
+		return ""
+	}
+	contents = PKCS5Padding(contents, block.BlockSize())
+	blockMode := cipher.NewCBCEncrypter(block, keys)
+	crypted := make([]byte, len(contents))
+	blockMode.CryptBlocks(crypted, contents)
+	return byteToHexString(crypted)
+}
+
+func byteToHexString(bytes []byte) string {
+	str := ""
+	for i := 0; i < len(bytes); i++ {
+		sTemp := hex.EncodeToString([]byte{bytes[i]})
+		if len(sTemp) < 2 {
+			str += string(0)
+		}
+		str += strings.ToUpper(sTemp)
+	}
+	return str
+}
+
+//DES解密
+func DesDecrypt(content string, key string) string {
+	contentBytes, err := hex.DecodeString(content)
+	if err != nil {
+		return "字符串转换16进制数组失败" + err.Error()
+	}
+	keys := []byte(key)
+	block, err := des.NewCipher(keys)
+	if err != nil {
+		return "解密失败" + err.Error()
+	}
+	blockMode := cipher.NewCBCDecrypter(block, keys)
+	origData := contentBytes
+	blockMode.CryptBlocks(origData, contentBytes)
+	origData = ZeroUnPadding(origData)
+	return string(origData)
+}
+
+// DES ECB PKCK5Padding
+func EntryptDesECB(data, key []byte) (string, error) {
+	if len(key) > 8 {
+		key = key[:8]
+	}
+	block, err := des.NewCipher(key)
+	if err != nil {
+		return "", errors.New("des.NewCipher " + err.Error())
+	}
+	bs := block.BlockSize()
+	data = PKCS5Padding(data, bs)
+	if len(data)%bs != 0 {
+		return "", errors.New("EntryptDesECB Need a multiple of the blocksize")
+	}
+	out := make([]byte, len(data))
+	dst := out
+	for len(data) > 0 {
+		block.Encrypt(dst, data[:bs])
+		data = data[bs:]
+		dst = dst[bs:]
+	}
+	return base64.StdEncoding.EncodeToString(out), nil
+}
+
+func DecryptDESECB(d string, key []byte) ([]byte, error) {
+	data, err := base64.StdEncoding.DecodeString(d)
+	if err != nil {
+		return nil, errors.New("decodebase64 " + err.Error())
+	}
+	if len(key) > 8 {
+		key = key[:8]
+	}
+	block, err := des.NewCipher(key)
+	if err != nil {
+		return nil, errors.New("des.NewCipher " + err.Error())
+	}
+	bs := block.BlockSize()
+	if len(data)%bs != 0 {
+		return nil, errors.New("DecryptDES crypto/cipher: input not full blocks")
+	}
+	out := make([]byte, len(data))
+	dst := out
+	for len(data) > 0 {
+		block.Decrypt(dst, data[:bs])
+		data = data[bs:]
+		dst = dst[bs:]
+	}
+	out = PKCS5UnPadding(out)
+	return out, nil
+}

+ 28 - 0
utils/sign.go

@@ -0,0 +1,28 @@
+package utils
+
+import (
+	"crypto/md5"
+	"fmt"
+	"sort"
+	"strings"
+)
+
+//请求参数签名校验
+func GetSign(postData map[string]string) (sign string) {
+
+	var keys []string
+	for k, _ := range postData {
+		if k != "sign" {
+			keys = append(keys, k)
+		}
+	}
+	//1,根据参数名称的ASCII码表的顺序排序
+	sort.Strings(keys)
+	//2 根据排序后的参数名称,取出对应的值,并拼接字符串
+	var signStr string
+	for _, v := range keys {
+		signStr += v + "=" + postData[v] + "&"
+	}
+	sign = strings.ToUpper(fmt.Sprintf("%x", md5.Sum([]byte(signStr+"secret="+ReportSecret))))
+	return
+}