作者 yangfu

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

增加 命令程序(迁移媒体数据)
... ... @@ -4,6 +4,7 @@ import (
"encoding/json"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"opp/protocol"
"opp/services"
"opp/services/chance"
"opp/services/message"
)
... ... @@ -74,3 +75,24 @@ func (this *H5Controller) ChanceExample() {
header := GetRequestHeader(this.Ctx)
msg = protocol.NewReturnResponse(chance.ChanceExample(header, request))
}
//SysCommand
//@router /sysCommand [post]
func (this *H5Controller) SysCommand() {
var msg *protocol.ResponseMessage
defer func() {
this.Resp(msg)
}()
var request *protocol.SysCommandRequest
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(services.SysCommand(header, request))
}
... ...
... ... @@ -105,3 +105,20 @@ type VideoMeta struct {
Title string `json:"title" xml:"Title"`
VideoId string `json:"videoId" xml:"VideoId"`
}
type UserData struct {
MessageCallback string `json:"MessageCallback"`
Extend string `json:"Extend"` //用户自定义的扩展字段,用于回调时透传返回,最大长度512字节。
}
type CallBack struct {
CallbackType string `json:"CallbackType"` //回调类型 http
CallbackURL string `json:"CallbackURL"` //回调地址 http://callback-host/addr
}
func NewCallBackHttp(callbackUrl string) *CallBack {
return &CallBack{
CallbackType: "http",
CallbackURL: callbackUrl,
}
}
... ...
package aliyun
import (
"encoding/json"
"fmt"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk"
"github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
... ... @@ -9,9 +10,11 @@ import (
"github.com/prometheus/common/log"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/common"
comm_time "gitlab.fjmaimaimai.com/mmm-go/gocomm/time"
"net/url"
"opp/internal/utils"
"path"
"path/filepath"
"strings"
"time"
)
... ... @@ -135,3 +138,60 @@ func getFileName(fileType string, filename string) string {
sourcePath := fmt.Sprintf("%v/%v/%v/%v/%v", beego.BConfig.AppName, beego.BConfig.RunMode, fileType, date, filename)
return sourcePath
}
//上传媒体数据按路径
//@urls 需要上传得媒体地址列表
//@callBack 回调设置
//@extend 回调用返回数据
func UploadMediaByURL(urls []string, callBack *CallBack, extend interface{}) (response *vod.UploadMediaByURLResponse, err error) {
client, e := DefaultVodClient()
if e != nil {
err = e
return
}
request := vod.CreateUploadMediaByURLRequest()
// 对URL进行编码
uploadUrls := []string{}
metaData := []map[string]interface{}{}
for _, surl := range urls {
encodeUrl := url.QueryEscape(surl)
uploadUrls = append(uploadUrls, encodeUrl)
metadata := map[string]interface{}{"SourceURL": encodeUrl} //, "Title":"UploadMediaByURL Sample Title"
metaData = append(metaData, metadata)
}
// 设置上传的URL列表,用逗号分隔
request.UploadURLs = strings.Join(uploadUrls, ",")
// 可选项,设置URL对应的Meta信息
jsonMetas, err := json.Marshal(metaData)
if err != nil {
fmt.Println("json.Marshal failed:", err)
return
}
request.UploadMetadatas = string(jsonMetas)
// 可选项,设置转码模板组
//request.TemplateGroupId = "<TemplateGroupId>"
//设置回调
if callBack != nil {
ud := UserData{
MessageCallback: assertMarsh(callBack),
Extend: assertMarsh(extend),
}
request.UserData = assertMarsh(ud)
}
request.AcceptFormat = "JSON"
return client.UploadMediaByURL(request)
}
func assertMarsh(v interface{}) string {
data, e := json.Marshal(v)
if e != nil {
return ""
}
return string(data)
}
... ...
... ... @@ -90,6 +90,14 @@ func JsonUnmarshal(jsonData string, v interface{}) {
}
}
func JsonMarsh(v interface{}) string {
data, e := json.Marshal(v)
if e != nil {
return ""
}
return string(data)
}
//深度拷贝
func DeepCopy(dst, src interface{}) error {
var buf bytes.Buffer
... ...
... ... @@ -20,6 +20,7 @@ type ChanceDraft struct {
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:"创建时间"`
SelfChecks string `orm:"column(self_checks);size(1000);null" description:"自查内容"`
}
func (t *ChanceDraft) TableName() string {
... ... @@ -74,7 +75,7 @@ func GetDraftByChance(uid int64, offset int, pageSize int, v interface{}) (total
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
b.chance_type_id,b.create_at,b.update_at,b.department_id,b.self_checks
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
... ...
... ... @@ -408,6 +408,7 @@ type CommChanceItemOrm struct {
CommentTotal int `orm:"column(comment_total)"`
ZanTotal int `orm:"column(zan_total)"`
ViewTotal int `orm:"column(view_total)"`
SelfChecks string `json:"self_checks"`
TemplateId int `orm:"column(audit_template_id)"`
ChanceTypeId int `orm:"column(chance_type_id)"`
... ... @@ -530,7 +531,8 @@ func ClearEmptyForm(inputFormList []*Form) (FormList []*Form) {
type Speech struct {
Path string `json:"path"`
Duration int `json:"duration"`
VideoId string `json:"-"` //videoId
VideoId string `json:"videoId"` //videoId
PathBak string `json:"path_bak"` //备份路径
}
//图片
... ... @@ -538,7 +540,9 @@ type Picture struct {
Path string `json:"path"`
W int `json:"w"`
H int `json:"h"`
ImageId string `json:"-"` //imageId
ImageId string `json:"imageId"` //imageId
PathBak string `json:"path_bak"`
JobId string `json:"job_id"`
}
//视频
... ... @@ -546,7 +550,8 @@ type Video struct {
Path string `json:"path"`
Cover Cover `json:"cover"` //封面
Duration int `json:"duration"`
VideoId string `json:"-"` //videoId
VideoId string `json:"videoId"` //videoId
PathBak string `json:"path_bak"`
}
//审批配置
... ...
package protocol
/*SysCommand */
type SysCommandRequest struct {
CmdCode string `json:"cmdCode" valid:"Required"`
Phone string `json:"phone" valid:"Required"`
}
type SysCommandResponse struct {
}
... ...
... ... @@ -31,4 +31,12 @@ func init() {
MethodParams: param.Make(),
Params: nil})
beego.GlobalControllerRouter["opp/controllers:H5Controller"] = append(beego.GlobalControllerRouter["opp/controllers:H5Controller"],
beego.ControllerComments{
Method: "SysCommand",
Router: `/sysCommand`,
AllowHTTPMethods: []string{"post"},
MethodParams: param.Make(),
Params: nil})
}
... ...
... ... @@ -2311,6 +2311,7 @@ func DraftSaveChance(header *protocol.RequestHeader, request *protocol.DraftSave
chance.SourceContent = common.AssertJson(request.FormList)
chance.UpdateAt = time.Now()
chance.DepartmentId = request.RelatedDepartment
chance.SelfChecks = common.AssertJson(request.SelfChecks)
if err = models.UpdateChanceDraftById(chance); err != nil {
err = protocol.NewCustomMessage(1, "该机会已不存在")
return
... ... @@ -2345,6 +2346,7 @@ func DraftSaveChance(header *protocol.RequestHeader, request *protocol.DraftSave
CreateAt: time.Now(),
UpdateAt: time.Now(),
DepartmentId: request.RelatedDepartment,
SelfChecks: common.AssertJson(request.SelfChecks),
}
if _, err = models.AddChanceDraft(chance); err != nil {
log.Error(err)
... ... @@ -2406,7 +2408,79 @@ func DraftByChance(header *protocol.RequestHeader, request *protocol.DraftByChan
commItem.Chance.RelatedDepartmentInfo = agg.GetDepartment(ormItem.DepartmentId)
commItem.Chance.ApproveTime = 0
commItem.Chance.FormList = GetNewestFormList(header, ormItem.ChanceTypeId, ormItem.TemplateId, commItem.Chance.FormList)
if len(ormItem.SelfChecks) > 0 {
utils.JsonUnmarshal(ormItem.SelfChecks, &commItem.Chance.SelfChecks)
}
commItem.Chance.SelfChecks = GetNewestSelfChecks(int64(ormItem.TemplateId), commItem.Chance.SelfChecks)
rsp.List = append(rsp.List, commItem)
}
return
}
//获取最新的表单列表
func GetNewestFormList(header *protocol.RequestHeader, chanceType, tpId int, old []*protocol.Form) []*protocol.Form {
var (
new []*protocol.Form
)
if forms, err := Template(header, &protocol.TemplateRequest{ChanceTypeId: int(chanceType), TemplateId: int(tpId)}); err != nil {
return old
} else {
new = forms.Template.FormList
}
return getNewestFormList(new, old)
}
func getNewestFormList(new []*protocol.Form, old []*protocol.Form) []*protocol.Form {
for i := 0; i < len(new); i++ {
itemNew := new[i]
for j := 0; j < len(old); j++ {
itemOld := old[j]
if itemNew.Id == itemOld.Id && itemNew.Label == itemOld.Label {
new[i].Value = itemOld.Value
break
}
}
}
return new
}
//获取最新的自查列表
func GetNewestSelfChecks(tpId int64, old []protocol.SelfCheck) protocol.SelfChecks {
var new []protocol.SelfCheck = make([]protocol.SelfCheck, 0)
if questions, err := agg.GetCheckQuestionsByTemplateId(tpId); err != nil {
log.Error(err)
return old
} else {
for i := range questions {
q := questions[i]
new = append(new, protocol.SelfCheck{
Id: q.Id,
ParentId: q.ParentId,
CheckItem: q.CheckItem,
GroupId: q.GroupId,
Answer: q.Answer,
Reason: q.Reason,
})
}
}
new = getNewestSelfChecks(new, old)
protocol.SelfChecks(new).SetSelfChecksLevel1ByRule()
return new
}
func getNewestSelfChecks(new []protocol.SelfCheck, old []protocol.SelfCheck) []protocol.SelfCheck {
if len(new) == 0 {
return old
}
for i := 0; i < len(new); i++ {
itemNew := new[i]
for j := 0; j < len(old); j++ {
itemOld := old[j]
if itemNew.GroupId == itemOld.GroupId && itemNew.CheckItem == itemOld.CheckItem {
new[i].Answer = itemOld.Answer
new[i].Reason = itemOld.Reason
break
}
}
}
return new
}
... ...
package contrab
import (
"fmt"
"github.com/astaxie/beego/orm"
"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
"opp/internal/aliyun"
"opp/internal/utils"
"opp/models"
"opp/protocol"
)
const LoopSize = 1
const (
Uploaded = "已上传,跳过"
UploadSuccess = "上传成功"
UploadFail = "上传失败"
)
var (
CallBackMethod = "/h5/aliCallback"
)
/*
上传-》aliyun-》job》回调》更新对应机会数据
*/
func MigrateChanceDataToAliYun() {
log.Info("【迁移机会媒体数据】开始迁移")
defer log.Info("【迁移机会媒体数据】结束迁移")
var (
datas []*models.ChanceData
query = `select * from chance_data order by id limit ?,?`
pageInfo = protocol.PageInfo{PageSize: LoopSize}
)
o := orm.NewOrm()
for {
if _, e := o.Raw(query, pageInfo.Offset(), pageInfo.PageSize).QueryRows(&datas); e != nil {
if e == orm.ErrNoRows {
break
}
log.Error(e)
break
}
for i := range datas {
data := datas[i]
//上传图片
data.Images = utils.JsonMarsh(uploadImages(data, data.Images))
//上传视频
//上传音频
//更新数据
o.Update(data)
}
pageInfo.PageIndex += 1
break
}
}
func uploadImages(d *models.ChanceData, img string) (rsp []protocol.Picture) {
utils.JsonUnmarshal(img, &rsp)
if len(rsp) == 0 {
rsp = make([]protocol.Picture, 0)
return
}
for i := range rsp {
p := rsp[i]
if len(p.ImageId) > 0 {
printInfo(d, p.Path, Uploaded)
continue
}
//上传图片
callBack := aliyun.NewCallBackHttp(getCallBackUrl())
extend := NewChanceDataExtend(d, aliyun.FileImage, p.Path)
response, err := aliyun.UploadMediaByURL([]string{p.Path}, callBack, extend)
if err != nil || response == nil || len(response.UploadJobs) == 0 {
printInfo(d, p.Path, UploadFail)
continue
}
//备份路径
rsp[i].PathBak = p.Path
rsp[i].JobId = response.UploadJobs[0].JobId
printInfo(d, p.Path, UploadSuccess)
}
return
}
type ChanceDataExtend struct {
Id int64 `json:"id"`
ChanceId int64 `json:"chance_id"`
FileType string `json:"fileType"` //image video voice
Path string `json:"path"`
}
func NewChanceDataExtend(d *models.ChanceData, ft string, path string) ChanceDataExtend {
return ChanceDataExtend{
Id: d.Id,
ChanceId: d.ChanceId,
FileType: ft,
Path: path,
}
}
func getCallBackUrl() string {
//return fmt.Sprintf("%v%v",beego.AppConfig.String("source_host"),CallBackMethod)
return fmt.Sprintf("%v%v", "http://mmm-opp-dev.fjmaimaimai.com/", CallBackMethod)
}
//打印日志
//@path 文件路径
//@info 提示
func printInfo(d *models.ChanceData, path, info string) {
log.Debug(fmt.Sprintf("【迁移机会媒体数据】 Id:%v Chance_id:%v Path:%v info:%v", d.Id, d.ChanceId, path, info))
}
... ...
package services
import (
"opp/protocol"
"opp/services/contrab"
)
func SysCommand(header *protocol.RequestHeader, request *protocol.SysCommandRequest) (rsp *protocol.SysCommandResponse, err error) {
var ()
rsp = &protocol.SysCommandResponse{}
if request.Phone != "18860183050" {
err = protocol.NewCustomMessage(1, "无效用户")
return
}
switch request.CmdCode {
case "MigrateChanceDataToAliYun":
contrab.MigrateChanceDataToAliYun()
break
default:
break
}
return
}
... ...