作者 yangfu

修改 草稿箱列表(自查内容,表单)

增加 命令程序(迁移媒体数据)
@@ -4,6 +4,7 @@ import ( @@ -4,6 +4,7 @@ import (
4 "encoding/json" 4 "encoding/json"
5 "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log" 5 "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
6 "opp/protocol" 6 "opp/protocol"
  7 + "opp/services"
7 "opp/services/chance" 8 "opp/services/chance"
8 "opp/services/message" 9 "opp/services/message"
9 ) 10 )
@@ -74,3 +75,24 @@ func (this *H5Controller) ChanceExample() { @@ -74,3 +75,24 @@ func (this *H5Controller) ChanceExample() {
74 header := GetRequestHeader(this.Ctx) 75 header := GetRequestHeader(this.Ctx)
75 msg = protocol.NewReturnResponse(chance.ChanceExample(header, request)) 76 msg = protocol.NewReturnResponse(chance.ChanceExample(header, request))
76 } 77 }
  78 +
  79 +//SysCommand
  80 +//@router /sysCommand [post]
  81 +func (this *H5Controller) SysCommand() {
  82 + var msg *protocol.ResponseMessage
  83 + defer func() {
  84 + this.Resp(msg)
  85 + }()
  86 + var request *protocol.SysCommandRequest
  87 + if err := json.Unmarshal(this.ByteBody, &request); err != nil {
  88 + log.Error(err)
  89 + msg = protocol.BadRequestParam(1)
  90 + return
  91 + }
  92 + if b, m := this.Valid(request); !b {
  93 + msg = m
  94 + return
  95 + }
  96 + header := GetRequestHeader(this.Ctx)
  97 + msg = protocol.NewReturnResponse(services.SysCommand(header, request))
  98 +}
@@ -105,3 +105,20 @@ type VideoMeta struct { @@ -105,3 +105,20 @@ type VideoMeta struct {
105 Title string `json:"title" xml:"Title"` 105 Title string `json:"title" xml:"Title"`
106 VideoId string `json:"videoId" xml:"VideoId"` 106 VideoId string `json:"videoId" xml:"VideoId"`
107 } 107 }
  108 +
  109 +type UserData struct {
  110 + MessageCallback string `json:"MessageCallback"`
  111 + Extend string `json:"Extend"` //用户自定义的扩展字段,用于回调时透传返回,最大长度512字节。
  112 +}
  113 +
  114 +type CallBack struct {
  115 + CallbackType string `json:"CallbackType"` //回调类型 http
  116 + CallbackURL string `json:"CallbackURL"` //回调地址 http://callback-host/addr
  117 +}
  118 +
  119 +func NewCallBackHttp(callbackUrl string) *CallBack {
  120 + return &CallBack{
  121 + CallbackType: "http",
  122 + CallbackURL: callbackUrl,
  123 + }
  124 +}
1 package aliyun 1 package aliyun
2 2
3 import ( 3 import (
  4 + "encoding/json"
4 "fmt" 5 "fmt"
5 "github.com/aliyun/alibaba-cloud-sdk-go/sdk" 6 "github.com/aliyun/alibaba-cloud-sdk-go/sdk"
6 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" 7 "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
@@ -9,9 +10,11 @@ import ( @@ -9,9 +10,11 @@ import (
9 "github.com/prometheus/common/log" 10 "github.com/prometheus/common/log"
10 "gitlab.fjmaimaimai.com/mmm-go/gocomm/common" 11 "gitlab.fjmaimaimai.com/mmm-go/gocomm/common"
11 comm_time "gitlab.fjmaimaimai.com/mmm-go/gocomm/time" 12 comm_time "gitlab.fjmaimaimai.com/mmm-go/gocomm/time"
  13 + "net/url"
12 "opp/internal/utils" 14 "opp/internal/utils"
13 "path" 15 "path"
14 "path/filepath" 16 "path/filepath"
  17 + "strings"
15 "time" 18 "time"
16 ) 19 )
17 20
@@ -135,3 +138,60 @@ func getFileName(fileType string, filename string) string { @@ -135,3 +138,60 @@ func getFileName(fileType string, filename string) string {
135 sourcePath := fmt.Sprintf("%v/%v/%v/%v/%v", beego.BConfig.AppName, beego.BConfig.RunMode, fileType, date, filename) 138 sourcePath := fmt.Sprintf("%v/%v/%v/%v/%v", beego.BConfig.AppName, beego.BConfig.RunMode, fileType, date, filename)
136 return sourcePath 139 return sourcePath
137 } 140 }
  141 +
  142 +//上传媒体数据按路径
  143 +//@urls 需要上传得媒体地址列表
  144 +//@callBack 回调设置
  145 +//@extend 回调用返回数据
  146 +func UploadMediaByURL(urls []string, callBack *CallBack, extend interface{}) (response *vod.UploadMediaByURLResponse, err error) {
  147 + client, e := DefaultVodClient()
  148 + if e != nil {
  149 + err = e
  150 + return
  151 + }
  152 + request := vod.CreateUploadMediaByURLRequest()
  153 +
  154 + // 对URL进行编码
  155 + uploadUrls := []string{}
  156 + metaData := []map[string]interface{}{}
  157 + for _, surl := range urls {
  158 + encodeUrl := url.QueryEscape(surl)
  159 + uploadUrls = append(uploadUrls, encodeUrl)
  160 + metadata := map[string]interface{}{"SourceURL": encodeUrl} //, "Title":"UploadMediaByURL Sample Title"
  161 + metaData = append(metaData, metadata)
  162 + }
  163 +
  164 + // 设置上传的URL列表,用逗号分隔
  165 + request.UploadURLs = strings.Join(uploadUrls, ",")
  166 +
  167 + // 可选项,设置URL对应的Meta信息
  168 + jsonMetas, err := json.Marshal(metaData)
  169 + if err != nil {
  170 + fmt.Println("json.Marshal failed:", err)
  171 + return
  172 + }
  173 + request.UploadMetadatas = string(jsonMetas)
  174 +
  175 + // 可选项,设置转码模板组
  176 + //request.TemplateGroupId = "<TemplateGroupId>"
  177 +
  178 + //设置回调
  179 + if callBack != nil {
  180 + ud := UserData{
  181 + MessageCallback: assertMarsh(callBack),
  182 + Extend: assertMarsh(extend),
  183 + }
  184 + request.UserData = assertMarsh(ud)
  185 + }
  186 +
  187 + request.AcceptFormat = "JSON"
  188 + return client.UploadMediaByURL(request)
  189 +}
  190 +
  191 +func assertMarsh(v interface{}) string {
  192 + data, e := json.Marshal(v)
  193 + if e != nil {
  194 + return ""
  195 + }
  196 + return string(data)
  197 +}
@@ -90,6 +90,14 @@ func JsonUnmarshal(jsonData string, v interface{}) { @@ -90,6 +90,14 @@ func JsonUnmarshal(jsonData string, v interface{}) {
90 } 90 }
91 } 91 }
92 92
  93 +func JsonMarsh(v interface{}) string {
  94 + data, e := json.Marshal(v)
  95 + if e != nil {
  96 + return ""
  97 + }
  98 + return string(data)
  99 +}
  100 +
93 //深度拷贝 101 //深度拷贝
94 func DeepCopy(dst, src interface{}) error { 102 func DeepCopy(dst, src interface{}) error {
95 var buf bytes.Buffer 103 var buf bytes.Buffer
@@ -20,6 +20,7 @@ type ChanceDraft struct { @@ -20,6 +20,7 @@ type ChanceDraft struct {
20 EnableStatus int8 `orm:"column(enable_status)" description:"有效状态 0:无效 1:有效 "` 20 EnableStatus int8 `orm:"column(enable_status)" description:"有效状态 0:无效 1:有效 "`
21 UpdateAt time.Time `orm:"column(update_at);type(timestamp)" description:"更新时间"` 21 UpdateAt time.Time `orm:"column(update_at);type(timestamp)" description:"更新时间"`
22 CreateAt time.Time `orm:"column(create_at);type(timestamp)" description:"创建时间"` 22 CreateAt time.Time `orm:"column(create_at);type(timestamp)" description:"创建时间"`
  23 + SelfChecks string `orm:"column(self_checks);size(1000);null" description:"自查内容"`
23 } 24 }
24 25
25 func (t *ChanceDraft) TableName() string { 26 func (t *ChanceDraft) TableName() string {
@@ -74,7 +75,7 @@ func GetDraftByChance(uid int64, offset int, pageSize int, v interface{}) (total @@ -74,7 +75,7 @@ func GetDraftByChance(uid int64, offset int, pageSize int, v interface{}) (total
74 sql := fmt.Sprintf(`select a.*,b.images,b.speechs,b.videos 75 sql := fmt.Sprintf(`select a.*,b.images,b.speechs,b.videos
75 from ( 76 from (
76 select b.id chance_id,b.user_id chance_user_id,b.source_content,b.enable_status,b.audit_template_id, 77 select b.id chance_id,b.user_id chance_user_id,b.source_content,b.enable_status,b.audit_template_id,
77 -b.chance_type_id,b.create_at,b.update_at,b.department_id 78 +b.chance_type_id,b.create_at,b.update_at,b.department_id,b.self_checks
78 from chance_draft b 79 from chance_draft b
79 where b.user_id=%v and enable_status=1 80 where b.user_id=%v and enable_status=1
80 )a left outer join chance_data b on a.chance_id =b.chance_id 81 )a left outer join chance_data b on a.chance_id =b.chance_id
@@ -408,6 +408,7 @@ type CommChanceItemOrm struct { @@ -408,6 +408,7 @@ type CommChanceItemOrm struct {
408 CommentTotal int `orm:"column(comment_total)"` 408 CommentTotal int `orm:"column(comment_total)"`
409 ZanTotal int `orm:"column(zan_total)"` 409 ZanTotal int `orm:"column(zan_total)"`
410 ViewTotal int `orm:"column(view_total)"` 410 ViewTotal int `orm:"column(view_total)"`
  411 + SelfChecks string `json:"self_checks"`
411 412
412 TemplateId int `orm:"column(audit_template_id)"` 413 TemplateId int `orm:"column(audit_template_id)"`
413 ChanceTypeId int `orm:"column(chance_type_id)"` 414 ChanceTypeId int `orm:"column(chance_type_id)"`
@@ -530,7 +531,8 @@ func ClearEmptyForm(inputFormList []*Form) (FormList []*Form) { @@ -530,7 +531,8 @@ func ClearEmptyForm(inputFormList []*Form) (FormList []*Form) {
530 type Speech struct { 531 type Speech struct {
531 Path string `json:"path"` 532 Path string `json:"path"`
532 Duration int `json:"duration"` 533 Duration int `json:"duration"`
533 - VideoId string `json:"-"` //videoId 534 + VideoId string `json:"videoId"` //videoId
  535 + PathBak string `json:"path_bak"` //备份路径
534 } 536 }
535 537
536 //图片 538 //图片
@@ -538,7 +540,9 @@ type Picture struct { @@ -538,7 +540,9 @@ type Picture struct {
538 Path string `json:"path"` 540 Path string `json:"path"`
539 W int `json:"w"` 541 W int `json:"w"`
540 H int `json:"h"` 542 H int `json:"h"`
541 - ImageId string `json:"-"` //imageId 543 + ImageId string `json:"imageId"` //imageId
  544 + PathBak string `json:"path_bak"`
  545 + JobId string `json:"job_id"`
542 } 546 }
543 547
544 //视频 548 //视频
@@ -546,7 +550,8 @@ type Video struct { @@ -546,7 +550,8 @@ type Video struct {
546 Path string `json:"path"` 550 Path string `json:"path"`
547 Cover Cover `json:"cover"` //封面 551 Cover Cover `json:"cover"` //封面
548 Duration int `json:"duration"` 552 Duration int `json:"duration"`
549 - VideoId string `json:"-"` //videoId 553 + VideoId string `json:"videoId"` //videoId
  554 + PathBak string `json:"path_bak"`
550 } 555 }
551 556
552 //审批配置 557 //审批配置
  1 +package protocol
  2 +
  3 +/*SysCommand */
  4 +type SysCommandRequest struct {
  5 + CmdCode string `json:"cmdCode" valid:"Required"`
  6 + Phone string `json:"phone" valid:"Required"`
  7 +}
  8 +type SysCommandResponse struct {
  9 +}
@@ -31,4 +31,12 @@ func init() { @@ -31,4 +31,12 @@ func init() {
31 MethodParams: param.Make(), 31 MethodParams: param.Make(),
32 Params: nil}) 32 Params: nil})
33 33
  34 + beego.GlobalControllerRouter["opp/controllers:H5Controller"] = append(beego.GlobalControllerRouter["opp/controllers:H5Controller"],
  35 + beego.ControllerComments{
  36 + Method: "SysCommand",
  37 + Router: `/sysCommand`,
  38 + AllowHTTPMethods: []string{"post"},
  39 + MethodParams: param.Make(),
  40 + Params: nil})
  41 +
34 } 42 }
@@ -2311,6 +2311,7 @@ func DraftSaveChance(header *protocol.RequestHeader, request *protocol.DraftSave @@ -2311,6 +2311,7 @@ func DraftSaveChance(header *protocol.RequestHeader, request *protocol.DraftSave
2311 chance.SourceContent = common.AssertJson(request.FormList) 2311 chance.SourceContent = common.AssertJson(request.FormList)
2312 chance.UpdateAt = time.Now() 2312 chance.UpdateAt = time.Now()
2313 chance.DepartmentId = request.RelatedDepartment 2313 chance.DepartmentId = request.RelatedDepartment
  2314 + chance.SelfChecks = common.AssertJson(request.SelfChecks)
2314 if err = models.UpdateChanceDraftById(chance); err != nil { 2315 if err = models.UpdateChanceDraftById(chance); err != nil {
2315 err = protocol.NewCustomMessage(1, "该机会已不存在") 2316 err = protocol.NewCustomMessage(1, "该机会已不存在")
2316 return 2317 return
@@ -2345,6 +2346,7 @@ func DraftSaveChance(header *protocol.RequestHeader, request *protocol.DraftSave @@ -2345,6 +2346,7 @@ func DraftSaveChance(header *protocol.RequestHeader, request *protocol.DraftSave
2345 CreateAt: time.Now(), 2346 CreateAt: time.Now(),
2346 UpdateAt: time.Now(), 2347 UpdateAt: time.Now(),
2347 DepartmentId: request.RelatedDepartment, 2348 DepartmentId: request.RelatedDepartment,
  2349 + SelfChecks: common.AssertJson(request.SelfChecks),
2348 } 2350 }
2349 if _, err = models.AddChanceDraft(chance); err != nil { 2351 if _, err = models.AddChanceDraft(chance); err != nil {
2350 log.Error(err) 2352 log.Error(err)
@@ -2406,7 +2408,79 @@ func DraftByChance(header *protocol.RequestHeader, request *protocol.DraftByChan @@ -2406,7 +2408,79 @@ func DraftByChance(header *protocol.RequestHeader, request *protocol.DraftByChan
2406 commItem.Chance.RelatedDepartmentInfo = agg.GetDepartment(ormItem.DepartmentId) 2408 commItem.Chance.RelatedDepartmentInfo = agg.GetDepartment(ormItem.DepartmentId)
2407 commItem.Chance.ApproveTime = 0 2409 commItem.Chance.ApproveTime = 0
2408 2410
  2411 + commItem.Chance.FormList = GetNewestFormList(header, ormItem.ChanceTypeId, ormItem.TemplateId, commItem.Chance.FormList)
  2412 + if len(ormItem.SelfChecks) > 0 {
  2413 + utils.JsonUnmarshal(ormItem.SelfChecks, &commItem.Chance.SelfChecks)
  2414 + }
  2415 + commItem.Chance.SelfChecks = GetNewestSelfChecks(int64(ormItem.TemplateId), commItem.Chance.SelfChecks)
2409 rsp.List = append(rsp.List, commItem) 2416 rsp.List = append(rsp.List, commItem)
2410 } 2417 }
2411 return 2418 return
2412 } 2419 }
  2420 +
  2421 +//获取最新的表单列表
  2422 +func GetNewestFormList(header *protocol.RequestHeader, chanceType, tpId int, old []*protocol.Form) []*protocol.Form {
  2423 + var (
  2424 + new []*protocol.Form
  2425 + )
  2426 + if forms, err := Template(header, &protocol.TemplateRequest{ChanceTypeId: int(chanceType), TemplateId: int(tpId)}); err != nil {
  2427 + return old
  2428 + } else {
  2429 + new = forms.Template.FormList
  2430 + }
  2431 + return getNewestFormList(new, old)
  2432 +}
  2433 +func getNewestFormList(new []*protocol.Form, old []*protocol.Form) []*protocol.Form {
  2434 + for i := 0; i < len(new); i++ {
  2435 + itemNew := new[i]
  2436 + for j := 0; j < len(old); j++ {
  2437 + itemOld := old[j]
  2438 + if itemNew.Id == itemOld.Id && itemNew.Label == itemOld.Label {
  2439 + new[i].Value = itemOld.Value
  2440 + break
  2441 + }
  2442 + }
  2443 + }
  2444 + return new
  2445 +}
  2446 +
  2447 +//获取最新的自查列表
  2448 +func GetNewestSelfChecks(tpId int64, old []protocol.SelfCheck) protocol.SelfChecks {
  2449 + var new []protocol.SelfCheck = make([]protocol.SelfCheck, 0)
  2450 + if questions, err := agg.GetCheckQuestionsByTemplateId(tpId); err != nil {
  2451 + log.Error(err)
  2452 + return old
  2453 + } else {
  2454 + for i := range questions {
  2455 + q := questions[i]
  2456 + new = append(new, protocol.SelfCheck{
  2457 + Id: q.Id,
  2458 + ParentId: q.ParentId,
  2459 + CheckItem: q.CheckItem,
  2460 + GroupId: q.GroupId,
  2461 + Answer: q.Answer,
  2462 + Reason: q.Reason,
  2463 + })
  2464 + }
  2465 + }
  2466 + new = getNewestSelfChecks(new, old)
  2467 + protocol.SelfChecks(new).SetSelfChecksLevel1ByRule()
  2468 + return new
  2469 +}
  2470 +func getNewestSelfChecks(new []protocol.SelfCheck, old []protocol.SelfCheck) []protocol.SelfCheck {
  2471 + if len(new) == 0 {
  2472 + return old
  2473 + }
  2474 + for i := 0; i < len(new); i++ {
  2475 + itemNew := new[i]
  2476 + for j := 0; j < len(old); j++ {
  2477 + itemOld := old[j]
  2478 + if itemNew.GroupId == itemOld.GroupId && itemNew.CheckItem == itemOld.CheckItem {
  2479 + new[i].Answer = itemOld.Answer
  2480 + new[i].Reason = itemOld.Reason
  2481 + break
  2482 + }
  2483 + }
  2484 + }
  2485 + return new
  2486 +}
  1 +package contrab
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/astaxie/beego/orm"
  6 + "gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
  7 + "opp/internal/aliyun"
  8 + "opp/internal/utils"
  9 + "opp/models"
  10 + "opp/protocol"
  11 +)
  12 +
  13 +const LoopSize = 1
  14 +
  15 +const (
  16 + Uploaded = "已上传,跳过"
  17 + UploadSuccess = "上传成功"
  18 + UploadFail = "上传失败"
  19 +)
  20 +
  21 +var (
  22 + CallBackMethod = "/h5/aliCallback"
  23 +)
  24 +
  25 +/*
  26 +上传-》aliyun-》job》回调》更新对应机会数据
  27 +*/
  28 +func MigrateChanceDataToAliYun() {
  29 + log.Info("【迁移机会媒体数据】开始迁移")
  30 + defer log.Info("【迁移机会媒体数据】结束迁移")
  31 + var (
  32 + datas []*models.ChanceData
  33 + query = `select * from chance_data order by id limit ?,?`
  34 + pageInfo = protocol.PageInfo{PageSize: LoopSize}
  35 + )
  36 + o := orm.NewOrm()
  37 + for {
  38 + if _, e := o.Raw(query, pageInfo.Offset(), pageInfo.PageSize).QueryRows(&datas); e != nil {
  39 + if e == orm.ErrNoRows {
  40 + break
  41 + }
  42 + log.Error(e)
  43 + break
  44 + }
  45 +
  46 + for i := range datas {
  47 + data := datas[i]
  48 +
  49 + //上传图片
  50 + data.Images = utils.JsonMarsh(uploadImages(data, data.Images))
  51 + //上传视频
  52 + //上传音频
  53 +
  54 + //更新数据
  55 + o.Update(data)
  56 + }
  57 + pageInfo.PageIndex += 1
  58 + break
  59 + }
  60 +}
  61 +
  62 +func uploadImages(d *models.ChanceData, img string) (rsp []protocol.Picture) {
  63 + utils.JsonUnmarshal(img, &rsp)
  64 + if len(rsp) == 0 {
  65 + rsp = make([]protocol.Picture, 0)
  66 + return
  67 + }
  68 + for i := range rsp {
  69 + p := rsp[i]
  70 + if len(p.ImageId) > 0 {
  71 + printInfo(d, p.Path, Uploaded)
  72 + continue
  73 + }
  74 + //上传图片
  75 + callBack := aliyun.NewCallBackHttp(getCallBackUrl())
  76 + extend := NewChanceDataExtend(d, aliyun.FileImage, p.Path)
  77 + response, err := aliyun.UploadMediaByURL([]string{p.Path}, callBack, extend)
  78 + if err != nil || response == nil || len(response.UploadJobs) == 0 {
  79 + printInfo(d, p.Path, UploadFail)
  80 + continue
  81 + }
  82 + //备份路径
  83 + rsp[i].PathBak = p.Path
  84 + rsp[i].JobId = response.UploadJobs[0].JobId
  85 + printInfo(d, p.Path, UploadSuccess)
  86 + }
  87 + return
  88 +}
  89 +
  90 +type ChanceDataExtend struct {
  91 + Id int64 `json:"id"`
  92 + ChanceId int64 `json:"chance_id"`
  93 + FileType string `json:"fileType"` //image video voice
  94 + Path string `json:"path"`
  95 +}
  96 +
  97 +func NewChanceDataExtend(d *models.ChanceData, ft string, path string) ChanceDataExtend {
  98 + return ChanceDataExtend{
  99 + Id: d.Id,
  100 + ChanceId: d.ChanceId,
  101 + FileType: ft,
  102 + Path: path,
  103 + }
  104 +}
  105 +
  106 +func getCallBackUrl() string {
  107 + //return fmt.Sprintf("%v%v",beego.AppConfig.String("source_host"),CallBackMethod)
  108 + return fmt.Sprintf("%v%v", "http://mmm-opp-dev.fjmaimaimai.com/", CallBackMethod)
  109 +}
  110 +
  111 +//打印日志
  112 +//@path 文件路径
  113 +//@info 提示
  114 +func printInfo(d *models.ChanceData, path, info string) {
  115 + log.Debug(fmt.Sprintf("【迁移机会媒体数据】 Id:%v Chance_id:%v Path:%v info:%v", d.Id, d.ChanceId, path, info))
  116 +}
  1 +package services
  2 +
  3 +import (
  4 + "opp/protocol"
  5 + "opp/services/contrab"
  6 +)
  7 +
  8 +func SysCommand(header *protocol.RequestHeader, request *protocol.SysCommandRequest) (rsp *protocol.SysCommandResponse, err error) {
  9 + var ()
  10 + rsp = &protocol.SysCommandResponse{}
  11 + if request.Phone != "18860183050" {
  12 + err = protocol.NewCustomMessage(1, "无效用户")
  13 + return
  14 + }
  15 + switch request.CmdCode {
  16 + case "MigrateChanceDataToAliYun":
  17 + contrab.MigrateChanceDataToAliYun()
  18 + break
  19 + default:
  20 + break
  21 + }
  22 + return
  23 +}