作者 yangfu

Merge remote-tracking branch 'origin/dev' into test

... ... @@ -27,13 +27,13 @@
### 阶段二接口完成进度
|功能|完成状态|时间|接口路径
|---|---|----|----|
|我的机会-我提交的| | | |
|机会详情| | | |
|我的机会-我提交的| | |/v1/chance/mySubmitChance|
|机会详情| | |v1/chance/detail|
|机会更新| | | |
|机会删除| | | |
|机会删除| | |/v1/chance/delete|
|我的机会-我的审核| | | |
|机会审核(评分/修改公开状态)| | | |
|用户评分配置| | | |
|计算发现分| | | |
|用户机会权限| | | |
|机会池| | | |
|消息-点赞| | |v1/message/msgInteractive|
... ... @@ -49,7 +49,7 @@
|机会审核消息| | |v1/message/msgInteractive|
|我提交的机会| | | v1/chance/chances|
|我审核的机会| | | v1/chance/chances|
|机会详情| | | v1/chance/detail|
|机会详情| | | |
|待抓住机会列表| | |v1/chance/chances|
|配置-评分| | |v1/config/score|
|机会审核| | |v1/chance/audit|
... ...
appname = opportunity
httpport = 8080
runmode = "${RUN_MODE||local}"
runmode = "${RUN_MODE||dev}"
#没设置的话 this.Ctx.Input.RequestBody 没有值
copyrequestbody = true
... ... @@ -10,7 +10,7 @@ copyrequestbody = true
#开启应用内文档开关
EnableDocs = true
include "local.conf"
include "dev.conf"
include "dev-online.conf"
include "test.conf"
include "prod.conf"
... ...
... ... @@ -23,7 +23,7 @@ yunpian_app_key ="0bf6fb10a11a68a95dee80901eb545b5"
#存储 http://ability.fjmaimaimai.com:8080/
source_host ="http://mmm-opp-dev.fjmaimaimai.com/"
source_virtual_path=file/opp
source_path ="${aliyun_file_access||/var/www/opp/file}
source_path =/var/www/opp/file
#网易云信 IM
net_im_base_url ="https://api.netease.im/nimserver"
... ... @@ -37,7 +37,7 @@ user_center_app_key ="39aefef9e22744a3b2d2d3791824ae7b"
user_center_app_secret ="cykbjnfqgctn"
#Html5
h5_host = "https://web-open.fjmaimaimai.com"
h5_host = "https://web-open-test.fjmaimaimai.com"
#审核中心
suplus_host ="http://suplus-approve-dev.fjmaimaimai.com"
\ No newline at end of file
... ...
[local]
[dev]
#数据库相关
mysql_user = "${MYSQL_USER||root}"
mysql_password = "${MYSQL_PASSWORD||sutianxia2015}"
... ... @@ -38,7 +38,7 @@ user_center_app_secret ="cykbjnfqgctn"
#Html5
h5_host = "https://web-open.fjmaimaimai.com"
h5_host = "https://web-open-test.fjmaimaimai.com"
#审核中心
suplus_approve_host ="http://suplus-approve-dev.fjmaimaimai.com"
... ...
... ... @@ -37,7 +37,7 @@ user_center_app_key ="39aefef9e22744a3b2d2d3791824ae7b"
user_center_app_secret ="cykbjnfqgctn"
#Html5
h5_host = "https://web-open.fjmaimaimai.com"
h5_host = "https://web-open-test.fjmaimaimai.com"
#审核中心
suplus_host ="http://suplus-approve-test.fjmaimaimai.com"
\ No newline at end of file
... ...
... ... @@ -74,7 +74,6 @@ func (this *BaseController) Valid(obj interface{}) (result bool, msg *protocol.R
}
func (this *BaseController) Resp(msg *protocol.ResponseMessage) {
this.Data["json"] = msg
this.ServeJSON()
}
... ...
... ... @@ -4,6 +4,7 @@ import (
"encoding/json"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"opp/protocol"
"opp/services/chance"
"opp/services/message"
)
... ... @@ -52,3 +53,24 @@ func (this *H5Controller) AnnouncementSubmit() {
header := GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(message.H5AnnouncementSubmit(header, request))
}
//ChanceExample 示例
//@router /chanceExample [post]
func (this *H5Controller) ChanceExample() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.ChanceExampleRequest
if err := json.Unmarshal(this.ByteBody, &request); err != nil {
log.Error(err)
msg = protocol.BadRequestParam(1)
return
}
if b, m := this.Valid(request); !b {
msg = m
return
}
header := GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(chance.ChanceExample(header, request))
}
... ...
... ... @@ -294,8 +294,28 @@ func (this *ChanceController) ChanceDetail() {
msg = protocol.NewReturnResponse(chance.ChanceDetail(header, request))
}
//ChanceApproveProcess 机会审核流程信息
//func(this *ChanceController)ChanceApproveProcess(){
// var msg *protocol.ResponseMessage
// defer func() {
// this.Resp(msg)
// }()
// var request *protocol.ChanceApproveProcessRequest
// if err:=json.Unmarshal(this.ByteBody,&request);err!=nil{
// log.Error(err)
// msg = protocol.BadRequestParam(1)
// return
// }
// if b,m :=this.Valid(request);!b{
// msg = m
// return
// }
// header := controllers.GetRequestHeader(this.Ctx)
// msg = protocol.NewReturnResponse(chance.ChanceApproveProcess(header,request))
//}
//ChanceDelete 机会删除
//@router /chanceDelete [post]
//@router /delete [post]
func (this *ChanceController) ChanceDelete() {
var msg *protocol.ResponseMessage
defer func() {
... ... @@ -316,36 +336,22 @@ func (this *ChanceController) ChanceDelete() {
}
//ChanceApprove 机会审核
//func(this *ChanceController)ChanceApprove(){
// var msg *protocol.ResponseMessage
// defer func() {
// this.Resp(msg)
// }()
// var request *protocol.ChanceApproveRequest
// if err:=json.Unmarshal(this.ByteBody,&request);err!=nil{
// log.Error(err)
// msg = protocol.BadRequestParam(1)
// return
// }
// if b,m :=this.Valid(request);!b{
// msg = m
// return
// }
// header := controllers.GetRequestHeader(this.Ctx)
// msg = protocol.NewReturnResponse(chance.ChanceApprove(header,request))
//}
//
///*ChanceApprove */
//type ChanceApproveRequest struct {
// Xxx string`json:"xxx" valid:"Required"`
//}
//type ChanceApproveResponse struct {
//}
//
//func ChanceApprove(header *protocol.RequestHeader,request *protocol.ChanceApproveRequest)(rsp *protocol.ChanceApproveResponse,err error){
// var (
//
// )
// rsp =&protocol.ChanceApproveResponse{}
// return
//}
//@router /approve [post]
func (this *ChanceController) ChanceApprove() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.ChanceApproveRequest
if err := json.Unmarshal(this.ByteBody, &request); err != nil {
log.Error(err)
msg = protocol.BadRequestParam(1)
return
}
if b, m := this.Valid(request); !b {
msg = m
return
}
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(chance.ChanceApprove(header, request))
}
... ...
... ... @@ -4,6 +4,7 @@ go 1.12
require (
github.com/astaxie/beego v1.10.0
github.com/disintegration/imaging v1.6.2
github.com/go-sql-driver/mysql v1.4.1
github.com/gomodule/redigo v1.7.0
github.com/gorilla/websocket v1.4.1
... ... @@ -13,7 +14,6 @@ require (
github.com/satori/go.uuid v1.2.0
github.com/sony/sonyflake v1.0.0
gitlab.fjmaimaimai.com/mmm-go/gocomm v0.0.1
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect
google.golang.org/appengine v1.6.2 // indirect
)
... ...
... ... @@ -180,6 +180,6 @@ func ExecuteSQLWithOrmer(o orm.Ormer, sqlstr string, param ...interface{}) error
return err
}
num, _ := r.RowsAffected()
log.Debug("RowsAffected:%d", num)
log.Debug(fmt.Sprintf("RowsAffected:%d", num))
return nil
}
... ...
... ... @@ -58,3 +58,19 @@ func JoinInt8s(ids []int8, spilt string) string {
}
return strings.Join(idStrings, spilt)
}
func JoinInt64s(ids []int64, spilt string) string {
var idStrings []string = make([]string, len(ids))
for i := 0; i < len(ids); i++ {
idStrings[i] = fmt.Sprintf("%v", ids[i])
}
return strings.Join(idStrings, spilt)
}
//判断是否为空
func IsNil(i interface{}) bool {
vi := reflect.ValueOf(i)
if vi.Kind() == reflect.Ptr {
return vi.IsNil()
}
return false
}
... ...
... ... @@ -35,7 +35,7 @@ func init() {
log.Fatal("connect to redis error address:", beego.AppConfig.String("redis_add_port"), beego.AppConfig.String("redis_auth"), err)
//panic(err)
}
dataSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?loc=Asia%%2FShanghai",
dataSource := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?loc=Asia%%2FShanghai&charset=utf8mb4",
beego.AppConfig.String("mysql_user"),
beego.AppConfig.String("mysql_password"),
beego.AppConfig.String("mysql_host"),
... ...
... ... @@ -2,6 +2,7 @@ package models
import (
"fmt"
"opp/internal/utils"
"time"
"github.com/astaxie/beego/orm"
... ... @@ -24,6 +25,9 @@ type AuditFlowProcess struct {
CreateAt time.Time `orm:"column(create_at);type(timestamp)" description:"创建时间"`
UpdateAt time.Time `orm:"column(update_at);type(timestamp)" description:"更新时间"`
EnableStatus int8 `orm:"column(enable_status)" description:"有效状态 0:无效 1:有效 (被驳回以后,未完成的审核置为无效)"`
UserName string `orm:"column(user_name);size(50)" description:"用户名-冗余"`
RoleName string `orm:"column(role_name);size(50)" description:"角色名-冗余"`
RoleId int `orm:"column(role_id);size(50)" description:"角色id-冗余"`
}
func (t *AuditFlowProcess) TableName() string {
... ... @@ -82,3 +86,54 @@ func DeleteAuditFlowProcess(id int64) (err error) {
}
return
}
//审核流程编号 按用户编号
//获取审核流节点
func GetAuditFlowProcessBy(processId, uid int64) (v *AuditFlowProcess, err error) {
o := orm.NewOrm()
sql := "select * from audit_flow_process where id=? and uid=? and enable_status=1"
if err = o.Raw(sql, processId, uid).QueryRow(&v); err == nil {
return v, nil
}
return nil, err
}
//当前审批批次已经结束 唤醒下一批次审批人
func UpdatetAuditFlowProcessToNext(chanceId int64, level int, uids []int64) (err error) {
o := orm.NewOrm()
sql := "update audit_flow_process set enable_status =1,is_active=1,update_at=now() where chance_id=? and level=? and uid in (?)"
if err = utils.ExecuteSQLWithOrmer(o, sql, chanceId, level, utils.JoinInt64s(uids, ",")); err != nil {
return
}
return
}
//或签 有一人已经通过 同批次在审核状态置为无效
func UpdatetAuditFlowProcessNoApprove(chanceId int64, level int, reviewStatus int) (err error) {
o := orm.NewOrm()
sql := "update audit_flow_process set enable_status =0,is_active=0,update_at=now() where chance_id=? and level=? and review_status=?"
if err = utils.ExecuteSQLWithOrmer(o, sql, chanceId, level, reviewStatus); err != nil {
return
}
return
}
//获取机会审核流信息
func GetAuditFlowProcessList(chanceId int64) (v []*AuditFlowProcess, err error) {
o := orm.NewOrm()
sql := "select * from audit_flow_process where chance_id=? and enable_status=1 order by id,review_status"
if _, err = o.Raw(sql, chanceId).QueryRows(&v); err == nil {
return v, nil
}
return nil, err
}
//删除机会时关闭所有审核信息
func CloseAuditFlowProcess(chanceId int64) (err error) {
o := orm.NewOrm()
sql := "update audit_flow_process set enable_status =0,is_active=0,update_at=now() where chance_id=?"
if err = utils.ExecuteSQLWithOrmer(o, sql, chanceId); err != nil {
return
}
return
}
... ...
... ... @@ -90,3 +90,13 @@ func GetAuditTemplates(companyId int64, chanceTypeId int) (v []*AuditTemplate, e
}
return
}
//获取模板示例
func GetAuditTemplateExample(id int64) (v string, err error) {
o := orm.NewOrm()
sql := "select example from audit_template where id=?"
if err = o.Raw(sql, id).QueryRow(&v); err == nil {
return
}
return
}
... ...
... ... @@ -30,6 +30,7 @@ type Chance struct {
ValueSorce float64 `orm:"column(value_sorce);null;digits(4);decimals(1)" description:"价值评分"`
DiscoverySorce float64 `orm:"column(discovery_sorce);null;digits(4);decimals(1)" description:"发现得分(发现得分=基础评分*系数 + 附加评分*系数 + 价值评分*系数)"`
PublishStatus int `orm:"column(publish_status)" description:"公开状态 0未公开、1部门公开、2公司公开"`
PublishData string `orm:"column(publish_data)" description:"公开数据 冗余"`
AuditLevel int `orm:"column(audit_level)" description:"当前审批步骤"`
}
... ...
... ... @@ -38,6 +38,7 @@ const (
ReviewStatusAuditging = 1 //待审核
ReviewStatusReturn = 2 //退回
ReviewStatusPass = 3 //通过
ReviewStatusSubmit = 4 //提交
)
//公开状态
... ... @@ -92,14 +93,14 @@ type SympathyActionRequest struct {
type SympathyActionResponse struct {
}
/*ChanceType */
/*ChanceType 机会一级分类请求*/
type ChanceTypeRequest struct {
}
type ChanceTypeResponse struct {
List []*models.ChanceType `json:"list"`
}
/*Templates */
/*Templates 模板列表请求*/
type TemplatesRequest struct {
ChanceTypeId int `json:"chanceTypeId" valid:"Required"`
}
... ... @@ -107,14 +108,17 @@ type TemplatesResponse struct {
Templates []*Template `json:"list"`
}
//模板
type Template struct {
Id int64 `json:"id"`
Name string `json:"name"`
Doc string `json:"doc"`
Icon string `json:"icon"`
FormList []*Form `json:"formList"`
Link string `json:"link"` //示例
}
//表单
type Form struct {
Id int `json:"id"`
Label string `json:"label"`
... ... @@ -124,6 +128,14 @@ type Form struct {
Required int8 `json:"required"`
}
/*ChanceExample*/
type ChanceExampleRequest struct {
TemplateId int `json:"templateId" valid:"Required"`
}
type ChanceExampleResponse struct {
Content string `json:"content"`
}
type ChanceSubmitRequest struct {
Id int64 `json:"id"` // = 0添加 >0 编辑
AuditTemplateId int64 `json:"auditTemplateId" valid:"Required"`
... ... @@ -208,7 +220,9 @@ type ChanceDetailRequest struct {
}
type ChanceDetailResponse struct {
ChanceDetail ChanceItem `json:"chanceDetail"`
ApproveProcess interface{} `json:"approveProcess"`
PublicData *PublicData `json:"publicData"`
ApproveProcess []*ProcessItem `json:"approveProcess"`
ApproveAccess *ApproveAccess `json:"approveAccess"` //
}
/*ChanceDelete 机会删除*/
... ...
package protocol
const (
ApproveTypePass = 2 //审核通过
ApproveTypeReject = 3 //审核驳回
//ApproveReturn =4 //审核撤回
)
type ApproveProcess struct {
//RelativeId int64 `json:"relativeId"`
Uid int64 `json:"uid"`
... ... @@ -9,3 +15,86 @@ type ApproveProcess struct {
Active int `json:"active"`
ApproveTime int64 `json:"approveTime"` //审核时间
}
/*ChanceApprove 机会审核*/
type ChanceApproveRequest struct {
Uid int64 `json:"uid"` //TODO:测试使用 注入审核人
ChanceId int64 `json:"chanceId"` //机会编号
ProcessId int64 `json:"processId"` //审批流程编号
ReviewStatus int `json:"reviewStatus"` //protocol.ReviewStatus
//Suggestion string `json:"suggestion"` //原因/建议
}
type ChanceApproveResponse struct {
}
/*ChanceApproveProcess 机会审核流程信息*/
type ChanceApproveProcessRequest struct {
ChanceId int64 `json:"chanceId"`
}
type ChanceApproveProcessResponse struct {
ApproveProcess []*ProcessItem `json:"approveProcess"`
ApproveAccess *ApproveAccess `json:"approveOperate"`
}
//进程项
type ProcessItem struct {
Id int64 `json:"id"`
ReviewStatus int `json:"reviewStatus"` //当前步骤审批状态 0-待处理 1- 待审核 2- 退回 3-通过 4-提交 6-撤销
ApproveWay int `json:"approveWay"` //审批方式 1 会签 2 或签
ApproveType int `json:"approveType"` //审批类型 1 业务区域负责人 2 指定成员 3 角色
ApproveTime int64 `json:"approveTime"` //审核时间
//Role Role `json:"role"` //角色
Uid int64 `json:"uid"`
Name string `json:"name"`
RoleName string `json:"roleName"`
Role int `json:"-"`
ApproveData ApproveData `json:"ApproveData"` //审核数据
//ApproveUser UserItem `json:"approveUser"` //审核人 //状态不是审核中
ApproveUsers []UserItem `json:"approveUsers"` //审核人员 //1 会签 2 或签 //审核中 1.部门长 2.角色
}
//用户项
type UserItem struct {
Uid int64 `json:"uid"`
Name string `json:"name"`
}
//角色项
type Role struct {
Id int `json:"id"`
Name string `json:"name"`
}
//审核数据 审核通过
type ApproveData struct {
PublicData *PublicData `json:"publicData"` // 公开数据
Score *Score `json:"score"`
}
//公开数据
type PublicData struct {
PublishStatus int `json:"publishStatus"`
VisibleObjects []*VisibleObject `json:"visibleObject"`
}
//可见对象
type VisibleObject struct {
Id string `json:"id"`
Name string `json:"name,omitempty"`
Type int `json:"type"` //1:部门 2:指定人员
}
//评分
type Score struct {
BasicScore int `json:"basicScore"` //基础评分
ExtraScore int `json:"extraScore"` //额外分
ValueScore int `json:"valueScore"` //价值分
DiscoveryScore int `json:"-"` //发现分
}
//审核操作权限
type ApproveAccess struct {
ProcessId int64 `json:"processId"`
AllowApprove int `json:"allowApprove"`
AllowReject int `json:"allowReject"`
}
... ...
... ... @@ -37,8 +37,20 @@ var errmessge ErrorMap = map[int]string{
//机会审批相关
5201: "该机会模板未配置审批人,请选择其他模板",
5202: "该机会已被审批",
5203: "审批服务器操作失败",
//模板相关
5301: "机会模板不存在",
}
const (
MsgTypeBulletin = 1 //公告
MsgTypeCommend = 2 //表彰
MsgTypeInteraction = 4 //互动消息
MsgTypeAudit = 8 //机会审核
)
/*MessageCenter */
type MessageCenterRequest struct {
MsgType int `json:"msgType" valid:"Required"`
... ...
... ... @@ -23,4 +23,12 @@ func init() {
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers:H5Controller"] = append(beego.GlobalControllerRouter["opp/controllers:H5Controller"],
beego.ControllerComments{
Method: "ChanceExample",
Router: `/chanceExample`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
}
... ...
... ... @@ -57,6 +57,22 @@ func init() {
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "ChanceApprove",
Router: `/approve`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "ChanceDetail",
Router: `/chanceDetail`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "ChanceType",
Router: `/chanceType`,
AllowHTTPMethods: []string{"post"},
... ... @@ -89,6 +105,14 @@ func init() {
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "ChanceDelete",
Router: `/delete`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "Favorite",
Router: `/favorite`,
AllowHTTPMethods: []string{"post"},
... ...
... ... @@ -26,7 +26,7 @@ func GetUserBaseInfoAggregation(id int64, companyId int64) (v *protocol.UserBase
return
}
if len(v.UserCompany.NickName) > 0 {
v.User.NickName = v.UserCompany.NickName //公司里面的用户名称
v.User.NickName = v.User.NickName
}
wg.Add(3)
go func() {
... ...
package agg
import (
"fmt"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/identity/idgen"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"opp/models"
"opp/protocol"
"time"
)
var (
MessageApproving = "提交了一条%v机会消息,需要您审核"
MessageApproveSuccess = "审核通过你提交的%v机会"
MessageApproveReject = "退回您了提交的%v机会"
)
//发送审批消息
func SendApproveMsg(receiverId int64, name string, companyId int64, chanceId int64, chanceTypeId int, reviewStatus int) (err error) {
var (
userMsg *models.UserMsg
chanceType *models.ChanceType
format string
)
switch reviewStatus {
case protocol.ReviewStatusAuditging:
format = MessageApproving
break
case protocol.ReviewStatusReturn:
format = MessageApproveReject
break
case protocol.ReviewStatusPass:
format = MessageApproveSuccess
break
default:
format = MessageApproving
break
}
if chanceType, err = models.GetChanceTypeById(chanceTypeId); err != nil {
return
}
userMsg = &models.UserMsg{
Id: idgen.Next(),
CompanyId: companyId,
ReceiveUserId: receiverId,
MsgType: protocol.MsgTypeAudit,
Message: fmt.Sprintf(format, chanceType.Name),
SourceId: chanceId,
SourceType: protocol.SourceTypeChance,
IsPublic: 0,
CreateAt: time.Now(),
}
if _, err = models.AddUserMsg(userMsg); err != nil {
return
}
logMsg(userMsg, name)
return
}
//发送审批消息
func SendApproveMsgByFormat(receiverId int64, name string, companyId int64, chanceId int64, chanceTypeId int, format string) (err error) {
var (
userMsg *models.UserMsg
chanceType *models.ChanceType
)
if chanceType, err = models.GetChanceTypeById(chanceTypeId); err != nil {
return
}
userMsg = &models.UserMsg{
Id: idgen.Next(),
CompanyId: companyId,
ReceiveUserId: receiverId,
MsgType: protocol.MsgTypeAudit,
Message: fmt.Sprintf(format, chanceType.Name),
SourceId: chanceId,
SourceType: protocol.SourceTypeChance,
IsPublic: 0,
CreateAt: time.Now(),
}
if _, err = models.AddUserMsg(userMsg); err != nil {
return
}
logMsg(userMsg, name)
return
}
//打印消息日志
func logMsg(msg *models.UserMsg, name string) {
log.Info(fmt.Sprintf("发送消息 消息类型:%v Receiver:%v(%v) Message:%v SourceId:%v SourceType:%v",
msg.MsgType, msg.ReceiveUserId, name, msg.Message, msg.SourceId, msg.SourceType))
}
... ...
... ... @@ -4,12 +4,16 @@ import (
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/httplib"
"github.com/astaxie/beego/orm"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/common"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"io/ioutil"
"net/http"
"opp/internal/utils"
"opp/models"
"opp/protocol"
"opp/services/agg"
"time"
"encoding/json"
)
... ... @@ -26,14 +30,15 @@ const (
ApproveIntegrate = "/approve-processes/integrate"
)
//素加审批系统
type SuplusApprove struct {
}
//新增审批实例
func (s SuplusApprove) NewApproveInstance(header *protocol.RequestHeader, process []*models.AuditFlowProcess) (err error) {
func (s SuplusApprove) NewApproveInstance(header *protocol.RequestHeader, process []*models.AuditFlowProcess) (response NewApproveInstanceResponse, err error) {
var (
request NewApproveInstanceRequest
response NewApproveInstanceResponse
//response NewApproveInstanceResponse
mapApproves map[int]*Approve = make(map[int]*Approve)
relativeId int64
userCompany *models.UserCompany
... ... @@ -54,14 +59,14 @@ func (s SuplusApprove) NewApproveInstance(header *protocol.RequestHeader, proces
approve *Approve
approveType int //审批类型
approveWay int //审批方式
approver *models.User
//approver *models.User
)
item := process[i]
if relativeId == 0 {
relativeId = item.ChanceId
}
if _, ok := mapApproves[i]; ok {
approve = mapApproves[i]
if _, ok := mapApproves[item.Level]; ok {
approve = mapApproves[item.Level]
} else {
approveType = item.AuditFlowType
if approveType == protocol.AuditBySpecailUser {
... ... @@ -76,21 +81,19 @@ func (s SuplusApprove) NewApproveInstance(header *protocol.RequestHeader, proces
ApproveType: item.AuditFlowType,
ApproveWay: approveWay,
}
mapApproves[i] = approve
}
if approver, err = models.GetUserByUcid(item.Uid); err != nil {
log.Error(err)
return
mapApproves[item.Level] = approve
}
//if approver, err = models.GetUserByUcid(item.Uid); err != nil {
// log.Error(err)
// return
//}
approve.ApproveUsers = append(approve.ApproveUsers, ApproveUsers{
Uid: item.Uid,
Name: approver.NickName,
//RoleId:5,
RoleId: 0,
Name: item.UserName,
})
}
request.RelativeId = relativeId
for i := 0; i < len(mapApproves); i++ {
for i := 1; i <= len(mapApproves); i++ {
if v, ok := mapApproves[i]; ok {
request.Approves = append(request.Approves, v)
}
... ... @@ -102,19 +105,20 @@ func (s SuplusApprove) NewApproveInstance(header *protocol.RequestHeader, proces
}
//审批操作
func (s SuplusApprove) ApproveItem(header *protocol.RequestHeader, approveType int, chanceId int64) (response ApproveItemResponse, err error) {
func (s SuplusApprove) ApproveItem(header *protocol.RequestHeader, approveType int, chanceId int64, processId int64) (response ApproveItemResponse, err error) {
var (
request ApproveItemRequest = ApproveItemRequest{
RelativeId: chanceId,
Type: approveType,
Suggestion: "",
Sign: ApproveSign,
ApproveType: 2,
ApproveType: 2, //编辑
Uid: header.UserId,
ExtendRelativeId: processId,
}
)
if s.DoRequest(ApproveItem, http.MethodPost, request, &response); err != nil {
log.Error(err)
if err = s.DoRequest(ApproveItem, http.MethodPost, request, &response); err != nil {
return
}
log.Info(fmt.Sprintf("success request suplus-approve:%v request:%v response:%v", ApproveItem, common.AssertJson(request), common.AssertJson(response)))
return
... ... @@ -178,7 +182,7 @@ func (s SuplusApprove) DoRequest(method string, methodType string, request inter
log.Error(e)
return
}
log.Debug(fmt.Sprintf("request-%v request:%v rsp:%v", url, common.AssertJson(request), common.AssertJson(response)))
log.Debug(fmt.Sprintf("request-%v request:%v rsp:%v", url, common.AssertJson(request), string(responseData)))
return
}
... ... @@ -193,12 +197,17 @@ type NewApproveInstanceRequest struct {
RelativeId int64 `json:"relativeId"` //关联id
}
type NewApproveInstanceResponse interface{}
type NewApproveInstanceResponse struct {
MessageData []MessageDataItem `json:"messageData"`
}
//审批节点
type Approve struct {
ApproveWay int `json:"approveWay"` //审批方式 1 会签 2 或签 3 发起人从角色成员中自选
ApproveType int `json:"approveType"` //审批类型 1 业务区域负责人 2 指定成员 3 角色
IsDefault int `json:"isDefault"` //1 是默认 0 不是
RoleName string `json:"roleName"` //角色名/负责人
RoleId int `json:"roleId"` //角色id
ApproveUsers []ApproveUsers `json:"approveUsers"` //审批人
}
... ... @@ -206,12 +215,25 @@ type Approve struct {
type ApproveUsers struct {
Uid int64 `json:"uid"` //用户id
Name string `json:"name"` //用户名
IsDefault int `json:"isDefault"` //1 是默认 0 不是
RoleName string `json:"roleName"` //角色名/负责人
RoleId int `json:"roleId"` //角色id
ParentIds []int `json:"parentIds"`
}
//审批 消息列表
type MessageDataItem struct {
MessageContent contentItem `json:"messageContent"`
ReceiverInfo receiverInfo `json:"receiverInfo"`
}
type contentItem struct {
ApproveInstanceId int `json:"approveInstanceId"` //审批实例-id
ApproveProcessId int `json:"approveProcessId"` //审批进程节点-id
RelativeId int `json:"relativeId"` //机会编号
MsgApproveStatus int `json:"msgApproveStatus"` //审核状态
}
type receiverInfo struct {
ReceiverUid int64 `json:"receiverUid"` //用户id
ReceiverName string `json:"receiverName"` //接收人
}
/*ApproveItem 审批操作*/
type ApproveItemRequest struct {
RelativeId int64 `json:"relativeId"` //关联id
... ... @@ -220,11 +242,15 @@ type ApproveItemRequest struct {
Sign string `json:"sign"` //CHANCE
ApproveType int `json:"approveType"` //1-新增(订单用新增) 2-编辑
Uid int64 `json:"uid"` //用户id
ExtendRelativeId int64 `json:"extendRelativeId"` //业务管理id
}
type ApproveItemResponse struct {
Status int `json:"status"` //状态1-待确认2-已确认3-已驳回4-已撤回
ApproveStatus int `json:"approveStatus"` //审批状态0 待审批 1 审批中 2 同意 3 驳回 4 提交订单 5 已被其他人处理 (0这个状态不存在审批后)
IsApprove int `json:"isApprove"` //是否需要审批 1是 0 否
MessageData ApproveMessageItem `json:"messageData"`
IsOver int `json:"isOver"` //是否结束1
}
type ApproveMessageItem struct {
ApproveMessage []MessageDataItem `json:"approveMessage"`
ApplyUserMessage []MessageDataItem `json:"applyUserMessage"`
}
/*ApproveIntegrate 审核列表*/
... ... @@ -237,3 +263,218 @@ type AppproveProcess struct {
ExtendRelativeId int64 `json:"extendRelativeId"`
Status int `json:"status"`
}
//机会审核
func ChanceApprove(header *protocol.RequestHeader, request *protocol.ChanceApproveRequest) (rsp *protocol.ChanceApproveResponse, err error) {
var (
process *models.AuditFlowProcess
chance *models.Chance
suplusApprove SuplusApprove
approveType int
approveItemResponse ApproveItemResponse
)
//TODO:测试注入
if request.Uid != 0 {
header.UserId = request.Uid
}
approveType = ConverReviewStatus(request.ReviewStatus)
if approveType == 0 {
log.Error("request.reviewStatus error :", request.ReviewStatus)
err = protocol.NewErrWithMessage(2)
return
}
if chance, err = models.GetChanceById(request.ChanceId); err != nil {
log.Error(err)
err = protocol.NewErrWithMessage(5101)
return
}
if process, err = models.GetAuditFlowProcessBy(request.ProcessId, header.UserId); err != nil {
log.Error(request.ProcessId, header.UserId, err)
err = protocol.NewErrWithMessage(5202)
return
}
if chance.ReviewStatus != protocol.ReviewStatusAuditging {
log.Error(fmt.Sprintf("机会已经被审核 chance_id:%v review_status:%v", chance.Id, chance.ReviewStatus))
err = protocol.NewErrWithMessage(5202)
return
}
log.Info(fmt.Sprintf("用户:%v 提交审核 机会编号:%v 审批流编号:%v 审批状态:%v", header.UserId, chance.Id, process.Id, request.ReviewStatus))
if approveItemResponse, err = suplusApprove.ApproveItem(header, approveType, chance.Id, process.Id); err != nil {
log.Error(err)
err = protocol.NewErrWithMessage(5203)
return
}
if err = utils.UpdateTableByMap(process, map[string]interface{}{
"ReviewStatus": int8(request.ReviewStatus), "ApproveTime": time.Now()}); err != nil {
log.Error("更新机会审核状态失败 process_id:", process.Id, err)
return
}
log.Info(fmt.Sprintf("用户%v 更新机会审核状态 process_id:%v 状态:%v", header.UserId, process.Id, request.ReviewStatus))
{
//更新下一批次的审核人
var nextApprovers []int64
if approveItemResponse.IsOver == 1 {
//结束审批
if err = utils.UpdateTableByMap(chance, map[string]interface{}{
"ReviewStatus": int8(request.ReviewStatus), "AuditLevel": chance.AuditLevel}); err != nil {
log.Error("更新机会审核状态失败 chance_id:", chance.Id, err)
return
}
//发送审核结果消息给提交人
for i := range approveItemResponse.MessageData.ApplyUserMessage {
message := approveItemResponse.MessageData.ApplyUserMessage[i]
nextApprovers = append(nextApprovers, message.ReceiverInfo.ReceiverUid)
if err = agg.SendApproveMsg(message.ReceiverInfo.ReceiverUid, message.ReceiverInfo.ReceiverName,
header.CompanyId, chance.Id, chance.ChanceTypeId, request.ReviewStatus); err != nil {
log.Error(err)
return
}
}
//更新同批次的为审核的状态置为无效
if err = models.UpdatetAuditFlowProcessNoApprove(chance.Id, chance.AuditLevel, protocol.ReviewStatusAuditging); err != nil {
log.Error(err)
return
}
} else {
//发送下一个消息给下一流程的审核人
for i := range approveItemResponse.MessageData.ApproveMessage {
message := approveItemResponse.MessageData.ApproveMessage[i]
nextApprovers = append(nextApprovers, message.ReceiverInfo.ReceiverUid)
if err = agg.SendApproveMsg(message.ReceiverInfo.ReceiverUid, message.ReceiverInfo.ReceiverName,
header.CompanyId, chance.Id, chance.ChanceTypeId, protocol.ReviewStatusAuditging); err != nil {
log.Error(err)
return
}
}
//更新下一批次的审核人 同批次的为审核的状态置为无效
if len(nextApprovers) != 0 {
if err = models.UpdatetAuditFlowProcessToNext(chance.Id, chance.AuditLevel+1, nextApprovers); err != nil {
log.Error(err)
log.Info(fmt.Sprintf("更新机会失败 chance_id:%v 下一批次审批人员:%v", chance.Id, nextApprovers))
return
}
log.Info(fmt.Sprintf("更新机会 chance_id:%v 下一批次审批人员:%v", chance.Id, nextApprovers))
if err = models.UpdatetAuditFlowProcessNoApprove(chance.Id, chance.AuditLevel, protocol.ReviewStatusAuditging); err != nil {
log.Error(err)
return
}
}
}
}
rsp = &protocol.ChanceApproveResponse{}
return
}
/*ProcessIntegrate */
type ProcessIntegrateRequest struct {
}
type ProcessIntegrateResponse struct {
}
func ProcessIntegrate(header *protocol.RequestHeader, request *ProcessIntegrateRequest) (rsp *ProcessIntegrateResponse, err error) {
var ()
rsp = &ProcessIntegrateResponse{}
return
}
//系统审核状态转为审核类型 reviewStatus - > approveType
func ConverReviewStatus(reviewStatus int) (approveType int) {
if reviewStatus == protocol.ReviewStatusPass {
approveType = protocol.ApproveTypePass
} else if reviewStatus == protocol.ReviewStatusReturn {
approveType = protocol.ApproveTypeReject
}
return
}
func ConverTypeToReviewStaus(approveType int) (reviewStatus int) {
if approveType == protocol.ApproveTypePass {
reviewStatus = protocol.ReviewStatusPass
} else if approveType == protocol.ApproveTypeReject {
reviewStatus = protocol.ReviewStatusReturn
}
return
}
// 机会审核流程信息
func ChanceApproveProcess(header *protocol.RequestHeader, chance *models.Chance) (rsp *protocol.ChanceApproveProcessResponse, err error) {
var (
processList []*models.AuditFlowProcess
)
if processList, err = models.GetAuditFlowProcessList(chance.Id); err != nil {
log.Error(fmt.Sprintf("chance_id :%v 未查询到审核流信息", chance.Id), err)
if err == orm.ErrNoRows {
err = nil
return
}
return
}
rsp = &protocol.ChanceApproveProcessResponse{}
newProcessItem := func(process *models.AuditFlowProcess) *protocol.ProcessItem {
item := &protocol.ProcessItem{
Id: process.Id,
ReviewStatus: int(process.ReviewStatus),
ApproveWay: int(process.AuditFlowType),
Uid: process.Uid,
Name: process.UserName,
}
if item.ApproveWay == protocol.AuditBySpecailUser {
item.ApproveWay = protocol.AuditByUser
}
if item.ReviewStatus != protocol.ReviewStatusAuditging {
item.ApproveTime = process.ApproveTime.Unix() * 1000
}
switch item.ApproveWay {
case protocol.AuditByDepartmentor:
break
case protocol.AuditByUser:
//item.Uid=process.Uid
//item.Name=process.UserName
break
case protocol.AuditByRole:
item.Role = process.RoleId
item.RoleName = process.RoleName
break
}
return item
}
//检查审核权限
checkApprovePermission := func(process *models.AuditFlowProcess) {
if chance.ReviewStatus == protocol.ReviewStatusPass {
return
}
if process.ReviewStatus == protocol.ReviewStatusAuditging && process.Uid == header.UserId {
rsp.ApproveAccess = &protocol.ApproveAccess{
AllowApprove: 1,
AllowReject: 1,
ProcessId: process.Id,
}
}
}
for i := range processList {
p := processList[i]
item := newProcessItem(p)
checkApprovePermission(p)
//机会已经审核通过的直接添加到审核人列表
if chance.ReviewStatus == protocol.ReviewStatusPass {
rsp.ApproveProcess = append(rsp.ApproveProcess, item)
continue
}
//当前再审核的列表
if p.Level == chance.AuditLevel && item.ReviewStatus == protocol.ReviewStatusAuditging {
item = newProcessItem(p)
for j := i; j < len(processList); j++ {
p = processList[j]
checkApprovePermission(p)
item.ApproveUsers = append(item.ApproveUsers, protocol.UserItem{
Uid: p.Uid,
Name: p.UserName,
})
}
rsp.ApproveProcess = append(rsp.ApproveProcess, item)
break
}
rsp.ApproveProcess = append(rsp.ApproveProcess, item)
}
return
}
... ...
... ... @@ -3,6 +3,7 @@ package chance
import (
"encoding/json"
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/common"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/identity/idgen"
... ... @@ -190,6 +191,7 @@ func Templates(header *protocol.RequestHeader, request *protocol.TemplatesReques
Icon: item.Icon,
Doc: item.Doc,
FormList: make([]*protocol.Form, len(forms)),
Link: fmt.Sprintf("%v/#/ability/opportunity?id=%v", beego.AppConfig.String("h5_host"), item.Id),
}
for j := range forms {
form := forms[j]
... ... @@ -212,6 +214,20 @@ func checkTemplateIsVisible(header *protocol.RequestHeader, template *models.Aud
return
}
//模板示例
func ChanceExample(header *protocol.RequestHeader, request *protocol.ChanceExampleRequest) (rsp *protocol.ChanceExampleResponse, err error) {
var (
example string
)
if example, err = models.GetAuditTemplateExample(int64(request.TemplateId)); err != nil {
log.Error(request.TemplateId, err)
err = protocol.NewErrWithMessage(5301) //模板不存在
return
}
rsp = &protocol.ChanceExampleResponse{example}
return
}
//提交机会
func ChanceSubmit(header *protocol.RequestHeader, request *protocol.ChanceSubmitRequest) (rsp *protocol.ChanceSubmitResponse, err error) {
var (
... ... @@ -248,33 +264,52 @@ func ChanceSubmit(header *protocol.RequestHeader, request *protocol.ChanceSubmit
ReviewStatus: protocol.ReviewStatusAuditging,
DepartmentId: request.RelatedDepartment,
}
if _, err = orm.Insert(chance); err != nil {
logAndRollBack := func(err error) {
log.Error(err)
orm.Rollback()
return
}
if _, err = orm.Insert(chance); err != nil {
logAndRollBack(err)
return
}
//生成提交记录
if _, err = orm.Insert(GenAuditFlowProcess_Submit(header, chance.Id, template.Id)); err != nil {
logAndRollBack(err)
return
}
//4.查询审核配置
//5.生成审核流
if auditFlows, err = GenAuditFlowProcess(header, chance.Id, template.Id, auditConfig); err != nil {
log.Error(err)
orm.Rollback()
logAndRollBack(err)
return
}
for i := 0; i < len(auditFlows); i++ {
if _, err = orm.Insert(auditFlows[i]); err != nil {
log.Error(err)
orm.Rollback()
logAndRollBack(err)
return
}
}
if len(auditFlows) > 0 {
if err = suplusApprove.NewApproveInstance(header, auditFlows); err != nil {
log.Error(fmt.Sprintf("uid:%v", header.UserId), "request suplus-approve.NewApproveInstance err", err)
//7.发送审批实例给审批服务器
if m, e := suplusApprove.NewApproveInstance(header, auditFlows); e != nil {
log.Error(fmt.Sprintf("uid:%v", header.UserId), "request suplus-approve.NewApproveInstance err", e)
orm.Rollback()
err = e
return
} else {
//7.发送消息通知给审核人(审核消息)
for i := range m.MessageData {
message := m.MessageData[i]
if err = agg.SendApproveMsg(message.ReceiverInfo.ReceiverUid, message.ReceiverInfo.ReceiverName,
header.CompanyId, chance.Id, chance.ChanceTypeId, protocol.ReviewStatusAuditging); err != nil {
logAndRollBack(err)
return
}
}
}
}
//6.文件
{
... ... @@ -288,15 +323,12 @@ func ChanceSubmit(header *protocol.RequestHeader, request *protocol.ChanceSubmit
UpdateAt: time.Now(),
}
if _, err = orm.Insert(data); err != nil {
log.Error(err)
orm.Rollback()
logAndRollBack(err)
return
}
}
orm.Commit()
//6.激活审核流
//TODO:7.发送消息通知给审核人(审核消息)
rsp = &protocol.ChanceSubmitResponse{}
return
}
... ... @@ -342,21 +374,6 @@ func ChanceUpdate(header *protocol.RequestHeader, request *protocol.ChanceSubmit
}
}
//4.查询审核配置
//5.生成审核流 删除旧的 生成新的
//if auditFlows, err = GenAuditFlowProcess(header, chance.Id, template.Id, auditConfig); err != nil {
// log.Error(err)
// orm.Rollback()
// return
//}
//for i := 0; i < len(auditFlows); i++ {
// if _, err = orm.Insert(auditFlows[i]); err != nil {
// log.Error(err)
// orm.Rollback()
// return
// }
//}
//6.更新文件
{
if chanceData, err = models.GetChanceDataByChanceId(chance.Id); err == nil {
... ... @@ -395,6 +412,27 @@ func ChanceUpdate(header *protocol.RequestHeader, request *protocol.ChanceSubmit
return
}
//生成审批流-提交记录
func GenAuditFlowProcess_Submit(header *protocol.RequestHeader, chanceId int64, templateId int64) (v *models.AuditFlowProcess) {
v = &models.AuditFlowProcess{
Id: idgen.Next(),
ChanceId: chanceId,
Uid: header.UserId,
CreateAt: time.Now(),
UpdateAt: time.Now(),
ApproveTime: time.Now(),
EnableStatus: 1,
ReviewStatus: protocol.ReviewStatusSubmit,
}
if approver, err := models.GetUsersById(header.Uid); err != nil {
log.Error(err)
return
} else {
v.UserName = approver.NickName
}
return
}
//生成审批流
func GenAuditFlowProcess(header *protocol.RequestHeader, chanceId int64, templateId int64, auditConfig *protocol.AuditConfig) (v []*models.AuditFlowProcess, err error) {
var (
... ... @@ -403,6 +441,8 @@ func GenAuditFlowProcess(header *protocol.RequestHeader, chanceId int64, templat
ids []int64
groupId int64
company *models.Company
roleName string
approver *models.User
)
if configs, err = models.GetAuditFlowConfigsLevel(templateId, 1); err != nil {
if err == orm.ErrNoRows {
... ... @@ -464,7 +504,6 @@ func GenAuditFlowProcess(header *protocol.RequestHeader, chanceId int64, templat
err = fmt.Errorf("GenAuditFlowProcess:company.admin is not set")
return
}
//3.生成审核列表
for i := range configs {
config := configs[i]
... ... @@ -481,7 +520,8 @@ func GenAuditFlowProcess(header *protocol.RequestHeader, chanceId int64, templat
return
}
case protocol.AuditByRole:
//roleName="" //TODO:角色
return
}
if len(userIds) == 0 { //当前步骤没有用户 默认一个空审核人
userIds = append(userIds, 0)
... ... @@ -495,6 +535,10 @@ func GenAuditFlowProcess(header *protocol.RequestHeader, chanceId int64, templat
log.Info(fmt.Sprintf("生成机会审批流-转给管理员:chance_id:%v audit_level:%v audit_user:%v -> admin:%v", chanceId, config.Level, uid, company.AdminId))
uid = company.AdminId
}
if approver, err = models.GetUserByUcid(uid); err != nil {
log.Error(err)
return
}
item := &models.AuditFlowProcess{
Id: idgen.Next(),
ChanceId: chanceId,
... ... @@ -505,14 +549,13 @@ func GenAuditFlowProcess(header *protocol.RequestHeader, chanceId int64, templat
AuditFlowType: config.AuditFlowType,
FlowType: config.FlowType,
ActionType: int(config.ActionType),
EnableStatus: 1,
RoleName: roleName,
UserName: approver.NickName,
ReviewStatus: protocol.ReviewStatusAuditging,
}
//if uid==0 && auditConfig.NoApprover==1{//审批人为空 自动通过
// item.
//}
if config.Level == 1 {
item.IsActive = 1
//通知 user_msg
item.EnableStatus = 1
}
log.Info(fmt.Sprintf("生成机会审批流:chance_id:%v audit_id:%v audit_level:%v audit_user:%v action_type:%v", chanceId, item.Id, config.Level, uid, resolveActionType(config.ActionType)))
v = append(v, item)
... ... @@ -655,20 +698,27 @@ func ChanceDetail(header *protocol.RequestHeader, request *protocol.ChanceDetail
chance *models.Chance
chanceData *models.ChanceData
provider *protocol.BaseUserInfo
approveProcess *protocol.ChanceApproveProcessResponse
)
//检查是否可见
if provider, err = agg.GetUserBaseInfo(chance.UserId, header.CompanyId); err != nil {
rsp = &protocol.ChanceDetailResponse{}
if chance, err = models.GetChanceById(request.Id); err != nil {
if err == orm.ErrNoRows {
err = protocol.NewErrWithMessage(5101)
return
}
log.Error(err)
return
}
if chance, err = models.GetChanceById(request.Id); err != nil {
if err == orm.ErrNoRows {
if chance.EnableStatus == 0 {
err = protocol.NewErrWithMessage(5101)
return
}
//用户信息
if provider, err = agg.GetUserBaseInfo(chance.UserId, header.CompanyId); err != nil {
log.Error(err)
return
}
item := protocol.ChanceItem{
Id: chance.Id,
Provider: provider,
... ... @@ -680,7 +730,15 @@ func ChanceDetail(header *protocol.RequestHeader, request *protocol.ChanceDetail
jsonUnmarshal(chanceData.Speechs, &item.Speechs)
jsonUnmarshal(chanceData.Videos, &item.Videos)
}
rsp = &protocol.ChanceDetailResponse{}
jsonUnmarshal(chance.PublishData, &rsp.PublicData)
rsp.ChanceDetail = item
if approveProcess, err = ChanceApproveProcess(header, chance); err != nil {
log.Error(err)
return
} else {
rsp.ApproveProcess = approveProcess.ApproveProcess
rsp.ApproveAccess = approveProcess.ApproveAccess
}
return
}
... ... @@ -689,6 +747,7 @@ func ChanceDelete(header *protocol.RequestHeader, request *protocol.ChanceDelete
var (
chance *models.Chance
)
rsp = &protocol.ChanceDeleteResponse{}
if chance, err = models.GetChanceById(request.Id); err != nil {
if err == orm.ErrNoRows {
err = protocol.NewErrWithMessage(5101)
... ... @@ -697,8 +756,24 @@ func ChanceDelete(header *protocol.RequestHeader, request *protocol.ChanceDelete
log.Error(err)
return
}
if chance != nil {
if chance.ReviewStatus == protocol.ReviewStatusPass {
err = protocol.NewErrWithMessage(5202)
return
}
//被人审核过 公开状态数据不为空
if chance.ReviewStatus == protocol.ReviewStatusAuditging && len(chance.PublishData) != 0 {
err = protocol.NewErrWithMessage(5202)
return
}
if err = utils.UpdateTableByMap(chance, map[string]interface{}{
"EnableStatus": int8(0),
}); err != nil {
log.Error(err)
return
}
if err = models.CloseAuditFlowProcess(chance.Id); err != nil {
log.Error(err)
return
}
rsp = &protocol.ChanceDeleteResponse{}
return
}
... ...
... ... @@ -105,7 +105,7 @@ func Announcements(header *protocol.RequestHeader, request *protocol.Announcemen
Title: bulletin.Title,
Control: int(bulletin.AllowClose),
//link:'https://web-open.fjmaimaimai.com/#/ability/announcement?id='+announcementCfgData[i].id+'&uid='+param.uid
Link: fmt.Sprintf("%v#/ability/announcement?id=%v&uid=%v", beego.AppConfig.String("h5_host"), bulletin.Id, msg.ReceiveUserId),
Link: fmt.Sprintf("%v#/ability/announcement?id=%v&uid=%v&oppo", beego.AppConfig.String("h5_host"), bulletin.Id, msg.ReceiveUserId),
}
item.Cover = protocol.Cover{
Path: bulletin.Cover,
... ...
... ... @@ -2,6 +2,7 @@ package upload
import (
"fmt"
"github.com/disintegration/imaging"
"io"
"mime/multipart"
"os"
... ... @@ -69,8 +70,9 @@ func UploadFile(request *protocol.FileRequest) (rsp *protocol.FileResponse, err
virtualPath = beego.AppConfig.String("source_host") + filepath.Join(virtualPath, request.FileType, date)
for i := range request.Files {
f := request.Files[i]
prefix := fmt.Sprintf("%v_%v", time.Now().Unix(), common.RandomString(32))
subfix := path.Ext(f.Filename)
filename = fmt.Sprintf("%v_%v%v", time.Now().Unix(), common.RandomString(32), subfix)
filename = fmt.Sprintf("%v%v", prefix, subfix)
src, err = f.Open()
if err != nil {
log.Error(err)
... ... @@ -88,6 +90,35 @@ func UploadFile(request *protocol.FileRequest) (rsp *protocol.FileResponse, err
return
}
rsp.Paths = append(rsp.Paths, filepath.Join(virtualPath, filename))
ResizeImage(request.FileType, sourcePath, prefix, subfix, f)
}
return
}
func ResizeImage(fileType, sourcePath, prefix, subfix string, file *multipart.FileHeader) (err error) {
var (
src multipart.File
thumbName = "_thumb"
)
if fileType != protocol.FileImage {
return
}
filename := fmt.Sprintf("%v%v%v", prefix, thumbName, subfix)
filename = filepath.Join(sourcePath, filename)
if src, err = file.Open(); err != nil {
log.Error(err)
return
}
image, err := imaging.Decode(src)
if err != nil {
fmt.Println(err)
return
}
image = imaging.Resize(image, 0, 200, imaging.Lanczos)
err = imaging.Save(image, filename)
if err != nil {
log.Error(err)
}
log.Debug(fmt.Sprintf("resize iamge:%v", filename))
return
}
... ...