作者 yangfu

修改 机会审核(编码)

增加 草稿箱列表/删除/添加草稿
... ... @@ -459,6 +459,11 @@ func (this *ChanceController) ChanceApprove() {
msg = protocol.NewReturnResponse(nil, e)
return
}
if !(request.Type == 0 || request.Type == 1) {
msg = protocol.BadRequestParamWithMessage(2, "机会类型错误 (0,1)")
log.Error(msg)
return
}
if len([]rune(request.Reason)) > 100 {
msg = protocol.BadRequestParamWithMessage(2, "填写理由长度有误,最多输入100个字符")
log.Error(msg)
... ... @@ -788,3 +793,66 @@ func (this *ChanceController) SiftingResultsItemDetail() {
header := controllers.GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(chance.SiftingResultsItemDetail(header, request))
}
//DraftSaveChance 机会保存到草稿箱
//@router /draftSaveChance [post]
func (this *ChanceController) DraftSaveChance() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.DraftSaveChanceRequest
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.DraftSaveChance(header, request))
}
//DraftDelete 草稿删除(清空)
//@router /draftDelete [post]
func (this *ChanceController) DraftDelete() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.DraftDeleteRequest
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.DraftDelete(header, request))
}
//DraftByChance 草稿箱-机会列表
//@router /draftByChance [post]
func (this *ChanceController) DraftByChance() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.DraftByChanceRequest
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.DraftByChance(header, request))
}
... ...
package models
import (
"fmt"
"opp/internal/utils"
"time"
"github.com/astaxie/beego/orm"
)
type ChanceDraft struct {
Id int64 `orm:"column(id);pk" description:"id 主键"`
UserId int64 `orm:"column(user_id)" description:"表user_company.id id"`
DepartmentId int64 `orm:"column(department_id)" description:"表department.id 部门id (提交机会指定的部门)"`
ChanceTypeId int `orm:"column(chance_type_id)" description:"表chance_type.id 机会类型 "`
CompanyId int64 `orm:"column(company_id)" description:"表company.id 公司编号"`
AuditTemplateId int64 `orm:"column(audit_template_id)" description:"表audit_template.id 所属审批模板编号"`
AuditTemplateConfig string `orm:"column(audit_template_config);size(255);null" description:"模板配置 (存旧的配置信息,对新改动的不影响)"`
SourceContent string `orm:"column(source_content)" description:"原始表单内容 json"`
EnableStatus int8 `orm:"column(enable_status)" description:"有效状态 0:无效 1:有效 "`
UpdateAt time.Time `orm:"column(update_at);type(timestamp)" description:"更新时间"`
CreateAt time.Time `orm:"column(create_at);type(timestamp)" description:"创建时间"`
}
func (t *ChanceDraft) TableName() string {
return "chance_draft"
}
func init() {
orm.RegisterModel(new(ChanceDraft))
}
var (
DeleteAllChanceDraft = "update chance_draft set enable_status=0 where user_id=%v and enable_status=1"
DeleteChanceDraft = "update chance_draft set enable_status=0 where user_id=%v and id=%v and enable_status=1"
)
// AddChanceDraft insert a new ChanceDraft into database and returns
// last inserted Id on success.
func AddChanceDraft(m *ChanceDraft) (id int64, err error) {
o := orm.NewOrm()
id, err = o.Insert(m)
return
}
// GetChanceDraftById retrieves ChanceDraft by Id. Returns error if
// Id doesn't exist
func GetChanceDraftById(id int64) (v *ChanceDraft, err error) {
o := orm.NewOrm()
v = &ChanceDraft{Id: id}
if err = o.Read(v); err == nil {
return v, nil
}
return nil, err
}
// UpdateChanceDraft updates ChanceDraft by Id and returns error if
// the record to be updated doesn't exist
func UpdateChanceDraftById(m *ChanceDraft) (err error) {
o := orm.NewOrm()
v := ChanceDraft{Id: m.Id}
// ascertain id exists in the database
if err = o.Read(&v); err == nil {
var num int64
if num, err = o.Update(m); err == nil {
fmt.Println("Number of records updated in database:", num)
}
}
return
}
//草稿项机会列表
func GetDraftByChance(uid int64, offset int, pageSize int, v interface{}) (total int, err error) {
sql := fmt.Sprintf(`select a.*,b.images,b.speechs,b.videos
from (
select b.id chance_id,b.user_id chance_user_id,b.source_content,b.enable_status,b.audit_template_id,
b.chance_type_id,b.create_at,b.update_at,b.department_id
from chance_draft b
where b.user_id=%v and enable_status=1
)a left outer join chance_data b on a.chance_id =b.chance_id
order by a.update_at desc
limit %v,%v`, uid, offset, pageSize)
sqlCount := fmt.Sprintf(`select count(0)
from chance_draft b
where b.user_id=%v and enable_status=1
`, uid)
if err = utils.ExecuteQueryOne(&total, sqlCount); err != nil {
return
}
if v != nil {
if err = utils.ExecuteQueryAll(v, sql); err != nil {
return
}
}
return
}
... ...
package models
import (
"time"
"github.com/astaxie/beego/orm"
)
type ChanceReserveType struct {
Id int `orm:"column(id);auto"`
Name string `orm:"column(name);size(50)" description:"储备类型名称"`
CompanyId int `orm:"column(company_id)" description:"表company.id 公司编号"`
SortNum int `orm:"column(sort_num);null" description:"序号 "`
CreateAt time.Time `orm:"column(create_at);type(timestamp);null" description:"创建时间 "`
UpdateAt time.Time `orm:"column(update_at);type(timestamp);null" description:"更新时间 "`
}
func (t *ChanceReserveType) TableName() string {
return "chance_reserve_type"
}
func init() {
orm.RegisterModel(new(ChanceReserveType))
}
// GetChanceReserveTypeById retrieves ChanceReserveType by Id. Returns error if
// Id doesn't exist
func GetChanceReserveTypeById(id int) (v *ChanceReserveType, err error) {
o := orm.NewOrm()
v = &ChanceReserveType{Id: id}
if err = o.Read(v); err == nil {
return v, nil
}
return nil, err
}
... ...
... ... @@ -609,6 +609,7 @@ type ChanceItem struct {
Videos []Video `json:"videos"`
PublicStatus int `json:"-"` //publicStatus
RelatedDepartmentInfo *Dep `json:"relatedDepartment,omitempty"`
}
type ChanceData struct {
ThumbsUpTotal int `json:"thumbsupTotal"` //点赞总数
... ... @@ -687,3 +688,40 @@ type ChanceSiftResultOrm struct {
CheckTime time.Time `orm:"column(check_time)"` //通过时间时间
}
/*DraftSaveChance 机会保存到草稿箱*/
type DraftSaveChanceRequest struct {
Id int64 `json:"id"` // = 0添加 >0 编辑
AuditTemplateId int64 `json:"auditTemplateId" valid:"Required"`
FormList []*Form `json:"formList" valid:"Required"`
SelfChecks SelfChecks `json:"selfChecks"`
Speechs []Speech `json:"speechs"`
Pictures []Picture `json:"pictures"`
Videos []Video `json:"videos"`
RelatedDepartment int64 `json:"relatedDepartments" valid:"Required"`
}
type DraftSaveChanceResponse struct {
}
/*DraftDelete 草稿删除(清空)*/
type DraftDeleteRequest struct {
Id int `json:"id" valid:"Required"` //-1清空 >1:指定草稿
}
type DraftDeleteResponse struct {
}
/*DraftByChance 草稿箱-机会列表*/
type DraftByChanceRequest struct {
PageInfo
}
type DraftByChanceResponse struct{ ChancePoolResponse }
//机会池筛选项
type DraftChanceItemOrm struct {
CommChanceItemOrm
//ApproveData string `json:"approveData"` //审核数据
TemplateId int `orm:"column(audit_template_id)"`
ChanceTypeId int `orm:"column(chance_type_id)"`
DepartmentId int `orm:"column(department_id)"`
}
... ...
... ... @@ -193,6 +193,30 @@ func init() {
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "DraftByChance",
Router: `/draftByChance`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "DraftDelete",
Router: `/draftDelete`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"] = append(beego.GlobalControllerRouter["opp/controllers/v1:ChanceController"],
beego.ControllerComments{
Method: "DraftSaveChance",
Router: `/draftSaveChance`,
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"},
... ...
... ... @@ -154,6 +154,16 @@ func GetTopPosition(positions []*protocol.Position) *protocol.Position {
return top
}
func GetDepartment(dId int) *protocol.Dep {
if d, e := models.GetDepartmentById(int64(dId)); e == nil {
return &protocol.Dep{
Id: int(d.Id),
Name: d.Name,
}
}
return nil
}
//获取机会
func GetChance(chanceId int64, companyId int64) (v *protocol.ChanceDetail, err error) {
var (
... ...
package agg
import (
"fmt"
"github.com/astaxie/beego/orm"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"sync"
"sync/atomic"
"time"
)
var rwCC sync.RWMutex
var currentSN int32
func GetChanceCode(chanceId int64, chanceTypeId int, templateId int64) (rsp string, err error) {
rwCC.RLock()
defer rwCC.RUnlock()
var (
ChanceTypeCode, TemplateCode string
Num int32
loopTime int
sql = fmt.Sprintf(`select a.code chance_type_code,b.code template_code,c.num+1 num from
(select code from chance_type where id =%v) a ,
(select code from audit_template where id=%v) b,
(select count(0) num from chance where review_status=3) c`, chanceTypeId, templateId)
)
o := orm.NewOrm()
for {
if err = o.Raw(sql).QueryRow(&ChanceTypeCode, &TemplateCode, &Num); err != nil {
log.Error(err)
return
}
if currentSN != Num {
atomic.StoreInt32(&currentSN, Num)
break
}
if loopTime > 5 { //重试5次
break
}
log.Warn(fmt.Sprintf("get chance code retry(%v): cursn:%v cid:%v cc:%v tc:%v",
loopTime, currentSN, chanceId, ChanceTypeCode, TemplateCode))
time.Sleep(time.Millisecond * 500)
loopTime++
}
rsp = fmt.Sprintf("%v%v%v", ChanceTypeCode, TemplateCode, Num)
return
}
... ...
... ... @@ -304,6 +304,16 @@ func ChanceApprove(header *protocol.RequestHeader, request *protocol.ChanceAppro
err = protocol.NewErrWithMessage(5206)
return
}
if request.ReserveTypeId > 0 {
if _, err = models.GetChanceReserveTypeById(request.ReserveTypeId); err != nil {
if err == orm.ErrNoRows {
err = protocol.NewCustomMessage(1, "储备类型不存在,请重新选择")
return
}
log.Error(err)
return
}
}
if chance.ReviewStatus != protocol.ReviewStatusAuditging {
log.Error(fmt.Sprintf("机会已经被审核 chance_id:%v review_status:%v", chance.Id, chance.ReviewStatus))
err = protocol.NewErrWithMessage(5202)
... ... @@ -345,6 +355,8 @@ func ChanceApprove(header *protocol.RequestHeader, request *protocol.ChanceAppro
mapProcess["DiscoveryScore"] = request.ApproveData.Score.DiscoveryScore
mapProcess["ApproveData"] = common.AssertJson(request.ApproveData)
mapProcess["EnableStatus"] = int8(1)
mapChance["Type"] = request.Type
mapChance["ReserveTypeId"] = request.ReserveTypeId
mapChance["SelfChecks"] = common.AssertJson(request.SelfChecks)
}
}
... ... @@ -379,8 +391,9 @@ func ChanceApprove(header *protocol.RequestHeader, request *protocol.ChanceAppro
}
if approveItemResponse.IsOver == 1 {
//结束审批
{
mapChance["ReviewStatus"] = int8(request.ReviewStatus)
if request.ReviewStatus == protocol.ReviewStatusPass {
mapChance["Code"], _ = agg.GetChanceCode(chance.Id, chance.ChanceTypeId, chance.AuditTemplateId)
}
} else {
//发送下一个消息给下一流程的审核人
... ...
... ... @@ -408,7 +408,7 @@ func ChanceSubmit(header *protocol.RequestHeader, request *protocol.ChanceSubmit
AuditLevel: 1,
ReviewStatus: protocol.ReviewStatusAuditging,
DepartmentId: request.RelatedDepartment,
Code: fmt.Sprintf("%v%v", chanceType.Code, template.Code),
//Code: fmt.Sprintf("%v%v", chanceType.Code, template.Code),
Status: models.ChanceStatusOpen,
SelfChecks: common.AssertJson(request.SelfChecks),
}
... ... @@ -2253,3 +2253,131 @@ func CheckQuestions(header *protocol.RequestHeader, request *protocol.CheckQuest
}
return
}
//机会保存到草稿箱
func DraftSaveChance(header *protocol.RequestHeader, request *protocol.DraftSaveChanceRequest) (rsp *protocol.DraftSaveChanceResponse, err error) {
var (
template *models.AuditTemplate
chanceData *models.ChanceData
chance *models.ChanceDraft
)
rsp = &protocol.DraftSaveChanceResponse{}
//1.模板是否存在
if template, err = models.GetAuditTemplateById(request.AuditTemplateId); err != nil {
log.Error("模板不存在:", request.AuditTemplateId, err)
return
}
if _, err = models.GetChanceTypeById(template.ChanceTypeId); err != nil {
log.Error("一级分类不存在:", request.AuditTemplateId, err)
return
}
//2.检查模板是否有权限
if request.Id > 0 {
//更新机会
if chance, err = models.GetChanceDraftById(request.Id); err != nil {
err = protocol.NewCustomMessage(1, "该机会已不存在")
return
}
chance.SourceContent = common.AssertJson(request.FormList)
chance.UpdateAt = time.Now()
chance.DepartmentId = request.RelatedDepartment
if err = models.UpdateChanceDraftById(chance); err != nil {
err = protocol.NewCustomMessage(1, "该机会已不存在")
return
}
//更新机会数据
if chanceData, err = models.GetChanceDataByChanceId(request.Id); err != nil {
err = protocol.NewCustomMessage(1, "该机会已不存在")
return
}
chanceDataMap := map[string]interface{}{
"Speechs": common.AssertJson(request.Speechs),
"Images": common.AssertJson(request.Pictures),
"Videos": common.AssertJson(request.Videos),
"UpdateAt": time.Now(),
}
if err = utils.UpdateTableByMap(chanceData, chanceDataMap); err != nil {
log.Error(err)
return
}
return
}
//3.添加机会 添加文件
chance = &models.ChanceDraft{
Id: idgen.Next(),
UserId: header.UserId,
CompanyId: header.CompanyId,
ChanceTypeId: template.ChanceTypeId,
AuditTemplateId: template.Id,
SourceContent: common.AssertJson(request.FormList),
EnableStatus: 1,
CreateAt: time.Now(),
UpdateAt: time.Now(),
DepartmentId: request.RelatedDepartment,
}
if _, err = models.AddChanceDraft(chance); err != nil {
log.Error(err)
return
}
data := &models.ChanceData{
Id: idgen.Next(),
ChanceId: chance.Id,
Speechs: common.AssertJson(request.Speechs),
Images: common.AssertJson(request.Pictures),
Videos: common.AssertJson(request.Videos),
CreateAt: time.Now(),
UpdateAt: time.Now(),
}
if _, err = models.AddChanceData(data); err != nil {
log.Error(err)
return
}
return
}
//草稿删除(清空)
func DraftDelete(header *protocol.RequestHeader, request *protocol.DraftDeleteRequest) (rsp *protocol.DraftDeleteResponse, err error) {
var (
sql string
)
rsp = &protocol.DraftDeleteResponse{}
sql = fmt.Sprintf(models.DeleteChanceDraft, header.UserId, request.Id)
if request.Id < 0 {
sql = fmt.Sprintf(models.DeleteAllChanceDraft, header.UserId)
}
o := orm.NewOrm()
if err = utils.ExecuteSQLWithOrmer(o, sql); err != nil {
log.Error(err)
return
}
return
}
//草稿箱-机会列表
func DraftByChance(header *protocol.RequestHeader, request *protocol.DraftByChanceRequest) (rsp *protocol.DraftByChanceResponse, err error) {
var (
ormItems []protocol.DraftChanceItemOrm
)
rsp = &protocol.DraftByChanceResponse{}
rsp.List = make([]protocol.CommonListItem, 0)
if rsp.Total, err = models.GetDraftByChance(header.UserId, request.Offset(), request.PageSize, &ormItems); err != nil {
if err == orm.ErrNoRows {
err = nil
return
}
log.Error(err)
return
}
for i := 0; i < len(ormItems); i++ {
ormItem := ormItems[i]
commItem := agg.NewCommonListItem(header, ormItem.CommChanceItemOrm)
commItem.Chance.CreateTime = ormItem.UpdateTime.Unix() * 1000
commItem.Chance.RelatedDepartmentInfo = agg.GetDepartment(ormItem.DepartmentId)
commItem.Chance.ApproveTime = 0
rsp.List = append(rsp.List, commItem)
}
return
}
... ...