Explorar o código

Merge branch 'feature/gn2.4_report_history' of eta_gn_server/eta_api into master

xyxie hai 2 semanas
pai
achega
077bfd8772

+ 21 - 1
controllers/ppt_v2.go

@@ -322,7 +322,27 @@ func (this *PptV2Controller) EditPpt() {
 	//		return
 	//	}
 	//}
-
+	// 版本记录
+	historyInfo := &models.PptV2History{
+		PptId:         pptInfo.PptId,
+		TemplateType:  pptInfo.TemplateType,
+		BackgroundImg: pptInfo.BackgroundImg,
+		Title:         pptInfo.Title,
+		ReportType:    pptInfo.ReportType,
+		PptDate:       pptInfo.PptDate,
+		Content:       pptInfo.Content,
+		CoverContent:  pptInfo.CoverContent,
+		AdminId:       this.SysUser.AdminId,
+		AdminRealName: this.SysUser.RealName,
+		CreateTime:    time.Now(),
+		TitleSetting:  pptInfo.TitleSetting,
+	}
+	err = historyInfo.Add()
+	if err != nil {
+		br.Msg = "保存失败"
+		br.ErrMsg = "保存PPT版本失败, Err: " + err.Error()
+		return
+	}
 	// 日志记录
 	{
 		logInfo := &models.PptV2SaveLog{

+ 300 - 0
controllers/ppt_v2_history.go

@@ -0,0 +1,300 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/utils"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"strings"
+	"time"
+)
+
+// PptV2HistoryController PPT
+type PptV2HistoryController struct {
+	BaseAuthController
+}
+
+// List
+// @Title 获取PPT列表接口
+// @Description 获取PPT列表
+// @Param   PptId   query   int  true       "PPTID"
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Success 200 {object} models.ReportListResp
+// @router /list [get]
+func (this *PptV2HistoryController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	pptId, _ := this.GetInt("PptId")
+	isShowMe, _ := this.GetBool("IsShowMe")
+
+	if pptId <= 0 {
+		br.Msg = "请选择PPT"
+		br.ErrMsg = "请选择PPT"
+		return
+	}
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+
+	condition += ` AND ppt_id = ? `
+	pars = append(pars, pptId)
+
+	if isShowMe {
+		condition += ` AND admin_id = ? `
+		pars = append(pars, this.SysUser.AdminId)
+	}
+	var err error
+	var total int
+	var list []*models.PptV2HistoryListItem
+
+	historyObj := new(models.PptV2History)
+
+	total, err = historyObj.GetPageListCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	listTmp, err := historyObj.GetNoContentPageList(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	for _, item := range listTmp {
+		tmp := &models.PptV2HistoryListItem{
+			Id:            item.Id,
+			PptId:         item.PptId,
+			TemplateType:  item.TemplateType,
+			BackgroundImg: item.BackgroundImg,
+			Title:         item.Title,
+			ReportType:    item.ReportType,
+			PptDate:       item.PptDate,
+			AdminId:       item.AdminId,
+			AdminRealName: item.AdminRealName,
+			CreateTime:    item.CreateTime.Format(utils.FormatDateTime),
+		}
+
+		list = append(list, tmp)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(models.PptV2HistoryListResp)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Delete
+// @Title 删除版本
+// @Description 删除版本
+// @Param   Id   query   int  true       "版本ID"
+// @Success 200 {object} models.ReportListResp
+// @router /del [post]
+func (this *PptV2HistoryController) Delete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req models.DeleteReportHistoryReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.Id <= 0 {
+		br.Msg = "请选择PPT版本"
+		return
+	}
+	historyObj := new(models.PptV2History)
+
+	item, err := historyObj.GetById(req.Id)
+	if err != nil {
+		br.Msg = "该版本已删除"
+		return
+	}
+
+	err = item.Delete()
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 获取PPT历史版本详情接口
+// @Description 获取PPT详情
+// @Param	request	body models.ReportDetailReq true "type json string"
+// @Success 200 {object} models.Report
+// @router /detail [get]
+func (this *PptV2HistoryController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	id, _ := this.GetInt("Id")
+	if id <= 0 {
+		br.Msg = "请选择PPT版本"
+		return
+	}
+	historyObj := new(models.PptV2History)
+
+	history, err := historyObj.GetById(id)
+	if err != nil {
+		br.Msg = "该版本已删除"
+		return
+	}
+	pptId := history.PptId
+
+	pptInfo, err := models.GetPptV2ById(pptId)
+	if err != nil {
+		br.Msg = "信息获取失败"
+		br.ErrMsg = "信息获取失败,Err:" + err.Error()
+		return
+	}
+
+	pptInfo.TemplateType = history.TemplateType
+	pptInfo.BackgroundImg = history.BackgroundImg
+	pptInfo.Title = history.Title
+	pptInfo.ReportType = history.ReportType
+	pptInfo.PptDate = history.PptDate
+	pptInfo.Content = history.Content
+	pptInfo.CoverContent = history.CoverContent
+	pptInfo.TitleSetting = history.TitleSetting
+	pptInfo.AdminId = history.AdminId
+	pptInfo.AdminRealName = history.AdminRealName
+	pptInfo.ModifyTime = history.CreateTime
+
+	resp := new(models.PPTDetailResp)
+	resp.PptV2 = pptInfo
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Revert
+// @Title 恢复PPT内容
+// @Description 恢复PPT内容
+// @Param   Id   query   int  true       "版本ID"
+// @Success 200 {object} models.ReportListResp
+// @router /revert [post]
+func (this *PptV2HistoryController) Revert() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.DeleteReportHistoryReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.Id <= 0 {
+		br.Msg = "请选择PPT版本"
+		return
+	}
+	historyObj := new(models.PptV2History)
+
+	history, err := historyObj.GetById(req.Id)
+	if err != nil {
+		br.Msg = "该版本已删除"
+		return
+	}
+	// 获取PPT详情
+	pptInfo, err := models.GetPptV2ById(history.PptId)
+	if err != nil {
+		br.Msg = "信息获取失败"
+		br.ErrMsg = "信息获取失败,Err:" + err.Error()
+		return
+	}
+
+	// 协作人权限
+	if pptInfo.AdminId != this.SysUser.AdminId {
+		if pptInfo.CollaborateType != utils.ReportWriteTypeGroup {
+			br.Msg = "非协作人无权操作"
+			return
+		}
+		if pptInfo.CollaborateUsers == "" {
+			br.Msg = "非协作人无权操作"
+			return
+		}
+		partnerArr := strings.Split(pptInfo.CollaborateUsers, ",")
+		if !utils.InArrayByStr(partnerArr, fmt.Sprint(this.SysUser.AdminId)) {
+			br.Msg = "非协作人无权操作"
+			return
+		}
+	}
+
+	// 修改
+	pptInfo.TemplateType = history.TemplateType
+	pptInfo.BackgroundImg = history.BackgroundImg
+	pptInfo.Title = history.Title
+	pptInfo.ReportType = history.ReportType
+	pptInfo.PptDate = history.PptDate
+	pptInfo.Content = history.Content
+	pptInfo.CoverContent = history.CoverContent
+	pptInfo.ModifyTime = time.Now()
+	pptInfo.TitleSetting = history.TitleSetting
+	err = pptInfo.Update([]string{"TemplateType", "BackgroundImg", "Title", "ReportType", "PptDate", "Content", "ModifyTime", "CoverContent", "TitleSetting"})
+	if err != nil {
+		br.Msg = "编辑失败"
+		br.ErrMsg = "编辑失败,Err:" + err.Error()
+		return
+	}
+
+	// 记录修改日志
+	{
+		logInfo := &models.PptV2SaveLog{
+			PptId:         pptInfo.PptId,
+			TemplateType:  pptInfo.TemplateType,
+			BackgroundImg: pptInfo.BackgroundImg,
+			Title:         pptInfo.Title,
+			ReportType:    pptInfo.ReportType,
+			PptDate:       pptInfo.PptDate,
+			Content:       pptInfo.Content,
+			CoverContent:  pptInfo.CoverContent,
+			AdminId:       this.SysUser.AdminId,
+			AdminRealName: this.SysUser.RealName,
+			CreateTime:    time.Now(),
+		}
+		_, err = models.AddPptV2SaveLog(logInfo)
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 22 - 1
controllers/report_chapter.go

@@ -470,7 +470,28 @@ func (this *ReportController) EditDayWeekChapter() {
 			return
 		}
 	}
-
+	// 增加版本记录
+	if req.IsManualSave {
+		reportHistory := new(models.ReportHistory)
+		reportHistory.ReportId = reportChapterInfo.ReportId
+		reportHistory.ReportChapterId = reportChapterInfo.ReportChapterId
+		reportHistory.Content = reportChapterInfo.Content
+		reportHistory.Title = reportChapterInfo.Title
+		reportHistory.ContentSub = reportChapterInfo.ContentSub
+		reportHistory.ContentStruct = reportChapterInfo.ContentStruct
+		reportHistory.CanvasColor = req.CanvasColor
+		reportHistory.HeadResourceId = req.HeadResourceId
+		reportHistory.EndResourceId = req.EndResourceId
+		reportHistory.AdminId = sysUser.AdminId
+		reportHistory.AdminName = sysUser.AdminName
+		reportHistory.CreateTime = time.Now()
+		err = reportHistory.Add()
+		if err != nil {
+			br.Msg = "保存失败"
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
+		}
+	}
 	// 备份关键数据
 	chapters := make([]*models.ReportChapter, 0)
 	chapters = append(chapters, reportChapterInfo)

+ 443 - 0
controllers/report_history.go

@@ -0,0 +1,443 @@
+package controllers
+
+import (
+	"encoding/json"
+	"eta_gn/eta_api/models"
+	"eta_gn/eta_api/models/report"
+	"eta_gn/eta_api/models/smart_report"
+	"eta_gn/eta_api/services"
+	"eta_gn/eta_api/utils"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"html"
+	"time"
+)
+
+// ReportHistoryController 报告
+type ReportHistoryController struct {
+	BaseAuthController
+}
+
+// List
+// @Title 获取报告列表接口
+// @Description 获取报告列表
+// @Param   ReportId   query   int  true       "报告ID"
+// @Param   ReportChapterId   query   int  true       "报告ID"
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   IsShowMe   query   bool  true       "是否只看我的,true、false"
+// @Success 200 {object} models.ReportListResp
+// @router /list [get]
+func (this *ReportHistoryController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	reportId, _ := this.GetInt("ReportId")
+	reportChapterId, _ := this.GetInt("ReportChapterId")
+	isShowMe, _ := this.GetBool("IsShowMe")
+
+	if reportId <= 0 && reportChapterId <= 0 {
+		br.Msg = "请选择报告"
+		br.ErrMsg = "请选择报告"
+		return
+	}
+
+	var startSize int
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	startSize = utils.StartIndex(currentIndex, pageSize)
+
+	var condition string
+	var pars []interface{}
+	if reportId > 0 {
+		condition += ` AND report_id = ? `
+		pars = append(pars, reportId)
+	}
+	if reportChapterId > 0 {
+		condition += ` AND report_chapter_id = ? `
+		pars = append(pars, reportChapterId)
+	}
+	if isShowMe {
+		condition += ` AND admin_id = ? `
+		pars = append(pars, this.SysUser.AdminId)
+	}
+	var err error
+	var total int
+	var list []*models.ReportHistoryListItem
+
+	historyObj := new(models.ReportHistory)
+
+	total, err = historyObj.GetPageListCount(condition, pars)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+	listTmp, err := historyObj.GetNoContentPageList(condition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	for _, item := range listTmp {
+		tmp := new(models.ReportHistoryListItem)
+		tmp.Id = item.Id
+		tmp.ReportId = item.ReportId
+		tmp.ReportChapterId = item.ReportChapterId
+		tmp.CreateTime = item.CreateTime.Format(utils.FormatDateTime)
+		tmp.AdminId = item.AdminId
+		tmp.AdminName = item.AdminName
+		tmp.Title = item.Title
+		list = append(list, tmp)
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(models.ReportHistoryListResp)
+	resp.Paging = page
+	resp.List = list
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Delete
+// @Title 删除版本
+// @Description 删除版本
+// @Param   Id   query   int  true       "版本ID"
+// @Success 200 {object} models.ReportListResp
+// @router /del [post]
+func (this *ReportHistoryController) Delete() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req models.DeleteReportHistoryReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.Id <= 0 {
+		br.Msg = "请选择报告版本"
+		return
+	}
+	historyObj := new(models.ReportHistory)
+
+	item, err := historyObj.GetById(req.Id)
+	if err != nil {
+		br.Msg = "该版本已删除"
+		return
+	}
+
+	err = item.Delete()
+	if err != nil {
+		br.Msg = "删除失败"
+		br.ErrMsg = "删除失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// Detail
+// @Title 获取报告历史版本详情接口
+// @Description 获取报告详情
+// @Param	request	body models.ReportDetailReq true "type json string"
+// @Success 200 {object} models.Report
+// @router /detail [get]
+func (this *ReportHistoryController) Detail() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	id, _ := this.GetInt("Id")
+	if id <= 0 {
+		br.Msg = "请选择报告版本"
+		return
+	}
+	historyObj := new(models.ReportHistory)
+
+	history, err := historyObj.GetById(id)
+	if err != nil {
+		br.Msg = "该版本已删除"
+		return
+	}
+	reportId := history.ReportId
+	reportChapterId := history.ReportChapterId
+
+	reportInfo, err := models.GetReportById(reportId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			br.Msg = "报告已被删除"
+			return
+		}
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取失败,Err:" + err.Error()
+		return
+	}
+
+	chapterList := make([]*models.ReportChapter, 0)
+	if reportInfo.HasChapter == 1 && reportChapterId > 0 {
+		chapter, e := models.GetReportChapterInfoById(reportChapterId)
+		if e != nil {
+			if e.Error() == utils.ErrNoRow() {
+				br.Msg = "章节已删除"
+				return
+			}
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + e.Error()
+			return
+		}
+		chapter.Content = html.UnescapeString(history.Content)
+		chapter.ContentSub = html.UnescapeString(history.ContentSub)
+		chapter.ContentStruct = html.UnescapeString(history.ContentStruct)
+		chapter.LastModifyAdminName = history.AdminName
+		chapter.ContentModifyTime = history.CreateTime
+		chapter.LastModifyAdminId = history.AdminId
+		chapterList = append(chapterList, chapter)
+	} else {
+		reportInfo.Title = history.Title
+		reportInfo.Content = html.UnescapeString(history.Content)
+		reportInfo.ContentSub = html.UnescapeString(history.ContentSub)
+		reportInfo.ContentStruct = html.UnescapeString(history.ContentStruct)
+		reportInfo.CanvasColor = history.CanvasColor
+		reportInfo.LastModifyAdminName = history.AdminName
+		reportInfo.LastModifyAdminId = history.AdminId
+		reportInfo.ContentModifyTime = history.CreateTime.Format(utils.FormatDate)
+	}
+
+	if history.HeadResourceId > 0 {
+		headResource, err := smart_report.GetResourceItemById(history.HeadResourceId)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取资源库版头失败, Err: " + err.Error()
+			return
+		}
+		reportInfo.HeadImg = headResource.ImgUrl
+		reportInfo.HeadStyle = headResource.Style
+	} else {
+		reportInfo.HeadImg = ""
+		reportInfo.HeadStyle = ""
+	}
+
+	if history.EndResourceId > 0 {
+		endResource, err := smart_report.GetResourceItemById(history.EndResourceId)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "获取资源库版头失败, Err: " + err.Error()
+			return
+		}
+		reportInfo.EndImg = endResource.ImgUrl
+		reportInfo.EndStyle = endResource.Style
+	} else {
+		reportInfo.EndImg = ""
+		reportInfo.EndStyle = ""
+	}
+
+	resp := &models.ReportDetailView{
+		ReportDetail: reportInfo,
+		ChapterList:  chapterList,
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// Revert
+// @Title 恢复报告内容
+// @Description 恢复报告内容
+// @Param   Id   query   int  true       "版本ID"
+// @Success 200 {object} models.ReportListResp
+// @router /revert [post]
+func (this *ReportHistoryController) Revert() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	var req models.DeleteReportHistoryReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+	if req.Id <= 0 {
+		br.Msg = "请选择报告版本"
+		return
+	}
+	historyObj := new(models.ReportHistory)
+
+	history, err := historyObj.GetById(req.Id)
+	if err != nil {
+		br.Msg = "该版本已删除"
+		return
+	}
+	// 获取报告详情
+	reportInfo, err := models.GetReportByReportId(history.ReportId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			br.Msg = "报告已删除"
+			return
+		}
+		br.Msg = "获取报告失败"
+		br.ErrMsg = "获取报告失败,Err:" + err.Error()
+		return
+	}
+	if reportInfo.Id > 0 && reportInfo.State == 2 {
+		br.Msg = "该报告已发布,不允许编辑"
+		br.ErrMsg = "该报告已发布,不允许编辑"
+		br.IsSendEmail = false
+		return
+	}
+
+	// 恢复章节
+	if history.ReportChapterId > 0 {
+		// 如果不是创建人,那么就要去查看是否授权
+		reportChapterInfo, e := models.GetReportChapterInfoById(history.ReportChapterId)
+		if e != nil {
+			if utils.IsErrNoRow(e) {
+				br.Msg = "章节已删除"
+				return
+			}
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取失败,Err:" + e.Error()
+			return
+		}
+		if reportInfo.AdminId != this.SysUser.AdminId {
+			// 授权用户权限校验
+			chapterGrantObj := report.ReportChapterGrant{}
+			_, tmpErr := chapterGrantObj.GetGrantByIdAndAdmin(reportChapterInfo.ReportChapterId, this.SysUser.AdminId)
+			if tmpErr != nil {
+				if utils.IsErrNoRow(tmpErr) {
+					br.Msg = "没有权限"
+					br.ErrMsg = "没有权限"
+					br.IsSendEmail = false
+					return
+				}
+				br.Msg = "获取章节id授权用户失败"
+				br.ErrMsg = "获取章节id授权用户失败, Err: " + tmpErr.Error()
+				return
+			}
+		}
+
+		// 标记更新中
+		{
+			markStatus, err := services.UpdateReportEditMark(reportChapterInfo.ReportId, reportChapterInfo.ReportChapterId, this.SysUser.AdminId, 1, this.SysUser.RealName, this.Lang)
+			if err != nil {
+				br.Msg = err.Error()
+				return
+			}
+			if markStatus.Status == 1 {
+				br.Msg = markStatus.Msg
+				br.IsSendEmail = false
+				return
+			}
+		}
+		reportChapterInfo.Title = history.Title
+		reportChapterInfo.Content = history.Content
+		reportChapterInfo.ContentSub = history.ContentSub
+		reportChapterInfo.IsEdit = 1
+		reportChapterInfo.ModifyTime = time.Now()
+		reportChapterInfo.LastModifyAdminId = this.SysUser.AdminId
+		reportChapterInfo.LastModifyAdminName = this.SysUser.RealName
+		reportChapterInfo.ContentModifyTime = time.Now()
+		reportChapterInfo.ContentStruct = history.ContentStruct
+		updateCols := make([]string, 0)
+		updateCols = append(updateCols, "Title", "Content", "ContentSub", "IsEdit", "ModifyTime")
+		updateCols = append(updateCols, "LastModifyAdminId", "LastModifyAdminName", "ContentModifyTime", "ContentStruct")
+		err = reportChapterInfo.Update(updateCols)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + err.Error()
+			return
+		}
+	} else {
+		// 标记更新中
+		{
+			markStatus, err := services.UpdateReportEditMark(history.ReportId, 0, this.SysUser.AdminId, 1, this.SysUser.RealName, this.Lang)
+			if err != nil {
+				br.Msg = err.Error()
+				return
+			}
+			if markStatus.Status == 1 {
+				br.Msg = markStatus.Msg
+				return
+			}
+		}
+
+		if history.HeadResourceId > 0 {
+			headResource, err := smart_report.GetResourceItemById(history.HeadResourceId)
+			if err != nil {
+				br.Msg = "操作失败"
+				br.ErrMsg = "获取资源库版头失败, Err: " + err.Error()
+				return
+			}
+			reportInfo.HeadImg = headResource.ImgUrl
+		} else {
+			reportInfo.HeadImg = ""
+		}
+
+		if history.EndResourceId > 0 {
+			endResource, err := smart_report.GetResourceItemById(history.EndResourceId)
+			if err != nil {
+				br.Msg = "操作失败"
+				br.ErrMsg = "获取资源库版头失败, Err: " + err.Error()
+				return
+			}
+			reportInfo.EndImg = endResource.ImgUrl
+		} else {
+			reportInfo.EndImg = ""
+		}
+		// 恢复报告
+		// todo 标题是否需要恢复
+		reportInfo.Title = history.Title
+		reportInfo.Content = history.Content
+		reportInfo.ContentSub = history.ContentSub
+		reportInfo.ContentStruct = history.ContentStruct
+		reportInfo.CanvasColor = history.CanvasColor
+		reportInfo.HeadResourceId = history.HeadResourceId
+		reportInfo.EndResourceId = history.EndResourceId
+		reportInfo.ModifyTime = time.Now()
+		reportInfo.ContentModifyTime = time.Now()
+		updateCols := []string{"Title", "Content", "ContentSub", "ContentStruct", "HeadImg", "EndImg", "CanvasColor", "HeadResourceId", "EndResourceId", "ModifyTime", "ContentModifyTime"}
+		err = reportInfo.UpdateReport(updateCols)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	// 报告的最后编辑人
+	reportInfo.LastModifyAdminId = this.SysUser.AdminId
+	reportInfo.LastModifyAdminName = this.SysUser.RealName
+	reportInfo.ModifyTime = time.Now()
+	err = reportInfo.UpdateReport([]string{"LastModifyAdminId", "LastModifyAdminName", "ModifyTime"})
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "操作失败,Err:" + err.Error()
+		return
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}

+ 34 - 3
controllers/report_v2.go

@@ -758,8 +758,18 @@ func (this *ReportController) SaveReportContent() {
 	}
 
 	// 获取报告详情
-	reportInfo, _ := models.GetReportByReportId(req.ReportId)
-	if reportInfo != nil && reportInfo.State == 2 {
+	reportInfo, err := models.GetReportByReportId(req.ReportId)
+	if err != nil {
+		if utils.IsErrNoRow(err) {
+			br.Msg = "该报告不存在"
+			br.ErrMsg = "该报告不存在, Err: " + err.Error()
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取报告详情失败, Err: " + err.Error()
+		return
+	}
+	if reportInfo.Id > 0 && reportInfo.State == 2 {
 		br.Msg = "该报告已发布,不允许编辑"
 		br.ErrMsg = "该报告已发布,不允许编辑"
 		br.IsSendEmail = false
@@ -780,7 +790,7 @@ func (this *ReportController) SaveReportContent() {
 	}
 
 	// 内容有过修改的话,那么逻辑处理
-	if noChangeFlag != 1 {
+	if noChangeFlag != 1 || req.IsManualSave {
 		content := req.Content
 		if content == "" {
 			content = this.GetString("Content")
@@ -822,6 +832,27 @@ func (this *ReportController) SaveReportContent() {
 				br.ErrMsg = "保存失败,Err:" + err.Error()
 				return
 			}
+			// 增加版本记录
+			if req.IsManualSave {
+				reportHistory := new(models.ReportHistory)
+				reportHistory.ReportId = req.ReportId
+				reportHistory.Title = reportInfo.Title
+				reportHistory.Content = reportInfo.Content
+				reportHistory.ContentSub = reportInfo.ContentSub
+				reportHistory.ContentStruct = reportInfo.ContentStruct
+				reportHistory.CanvasColor = reportInfo.CanvasColor
+				reportHistory.HeadResourceId = reportInfo.HeadResourceId
+				reportHistory.EndResourceId = reportInfo.EndResourceId
+				reportHistory.AdminId = sysUser.AdminId
+				reportHistory.AdminName = sysUser.AdminName
+				reportHistory.CreateTime = time.Now()
+				e = reportHistory.Add()
+				if e != nil {
+					br.Msg = "保存失败"
+					br.ErrMsg = "保存失败,Err:" + e.Error()
+					return
+				}
+			}
 			go models.AddReportSaveLog(reportId, this.SysUser.AdminId, reportInfo.Content, reportInfo.ContentSub, reportInfo.ContentStruct, reportInfo.CanvasColor, this.SysUser.AdminName, reportInfo.HeadResourceId, reportInfo.EndResourceId)
 		}
 	}

+ 89 - 0
models/ppt_v2_history.go

@@ -0,0 +1,89 @@
+package models
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+type PptV2History struct {
+	Id            int       `gorm:"primaryKey"`
+	PptId         int       `description:"ppt ID"`
+	TemplateType  int       `description:"模板类型"`
+	BackgroundImg string    `description:"背景图"`
+	Title         string    `description:"标题"`
+	ReportType    string    `description:"报告类型"`
+	PptDate       string    `description:"选择日期"`
+	Content       string    `description:"内容"`
+	AdminId       int       `description:"操作人ID"`
+	AdminRealName string    `description:"操作人真实姓名"`
+	CreateTime    time.Time `description:"创建时间"`
+	CoverContent  string    `description:"封面内容"`
+	TitleSetting  string    `description:"标题设置"`
+}
+
+// 获取表名
+func (p *PptV2History) TableName() string {
+	return "ppt_v2_history"
+}
+
+func (p *PptV2History) Add() (err error) {
+	err = global.DmSQL["rddp"].Create(p).Error
+	return
+}
+
+func (p *PptV2History) GetNoContentPageList(condition string, pars []interface{}, startSize, pageSize int) (list []*PptV2History, err error) {
+	sql := fmt.Sprintf(`SELECT id, ppt_id, template_type, background_img, title, report_type, ppt_date, create_time, admin_id, admin_real_name  FROM %s WHERE 1=1 `, p.TableName())
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY create_time DESC, id DESC LIMIT ?, ?`
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+func (p *PptV2History) GetPageListCount(condition string, pars []interface{}) (count int, err error) {
+	sql := fmt.Sprintf(`SELECT COUNT(1) AS count  FROM %s WHERE 1=1 `, p.TableName())
+	if condition != "" {
+		sql += condition
+	}
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// 删除接口
+func (p *PptV2History) Delete() (err error) {
+	err = global.DmSQL["rddp"].Delete(p).Error
+	return
+}
+
+// 查询单条记录
+func (p *PptV2History) GetById(id int) (item *PptV2History, err error) {
+	err = global.DmSQL["rddp"].Where("id = ?", id).First(&item).Error
+	return
+}
+
+// PptV2HistoryListItem 定义PPT历史记录列表项的结构体
+type PptV2HistoryListItem struct {
+	Id            int    `description:"PPT历史记录id"`
+	PptId         int    `description:"ppt ID"`
+	TemplateType  int    `description:"模板类型"`
+	BackgroundImg string `description:"背景图"`
+	Title         string `description:"标题"`
+	ReportType    string `description:"报告类型"`
+	PptDate       string `description:"选择日期"`
+	AdminId       int    `description:"操作人ID"`
+	AdminRealName string `description:"操作人真实姓名"`
+	CreateTime    string `description:"创建时间"`
+}
+
+type PptV2HistoryListResp struct {
+	List   []*PptV2HistoryListItem
+	Paging *paging.PagingItem `description:"分页数据"`
+}
+
+type DeletePptV2HistoryReq struct {
+	Id int `description:"PPT历史记录id"`
+}

+ 2 - 0
models/report.go

@@ -802,6 +802,8 @@ type SaveReportContent struct {
 	NeedSplice     int    `description:"是否拼接版头版位的标记,主要是为了兼容历史报告。0-不需要 1-需要"`
 	HeadResourceId int    `description:"版头资源ID"`
 	EndResourceId  int    `description:"版尾资源ID"`
+
+	IsManualSave bool `description:"是否手动保存:true:手动 false:自动"`
 }
 
 func AddReportSaveLog(reportId, adminId int, content, contentSub, contentStruct, canvasColor, adminName string, headResourceId, endResourceId int) (err error) {

+ 1 - 0
models/report_chapter.go

@@ -172,6 +172,7 @@ type EditReportChapterReq struct {
 	CanvasColor    string `description:"画布颜色"`
 	HeadResourceId int    `description:"版头资源ID"`
 	EndResourceId  int    `description:"版尾资源ID"`
+	IsManualSave   bool   `description:"是否手动保存:true:手动 false:自动"`
 }
 
 type EditTickList struct {

+ 86 - 0
models/report_history.go

@@ -0,0 +1,86 @@
+package models
+
+import (
+	"eta_gn/eta_api/global"
+	"fmt"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+// ReportHistory 定义报告历史记录的结构体
+type ReportHistory struct {
+	Id              int       `gorm:"primaryKey"`
+	ReportId        int       `description:"报告id"`
+	ReportChapterId int       `description:"报告章节id"`
+	Title           string    `description:"标题"`
+	Content         string    `description:"内容"`
+	CreateTime      time.Time `description:"创建时间"`
+	ContentSub      string    `description:"部分内容"`
+	AdminId         int       `description:"创建人id"`
+	AdminName       string    `description:"创建人姓名"`
+	ContentStruct   string    `description:"内容组件"`
+	CanvasColor     string    `description:"画布颜色"`
+	HeadResourceId  int       `description:"版头资源ID"`
+	EndResourceId   int       `description:"版尾资源ID"`
+}
+
+func (r *ReportHistory) TableName() string {
+	return "report_history"
+}
+
+func (r *ReportHistory) Add() (err error) {
+	err = global.DmSQL["rddp"].Create(r).Error
+	return
+}
+
+func (r *ReportHistory) GetNoContentPageList(condition string, pars []interface{}, startSize, pageSize int) (list []*ReportHistory, err error) {
+	sql := fmt.Sprintf(`SELECT id, report_id, report_chapter_id, title, create_time, admin_id, admin_name  FROM %s WHERE 1=1 `, r.TableName())
+	if condition != "" {
+		sql += condition
+	}
+	sql += ` ORDER BY create_time DESC, id DESC LIMIT ?, ?`
+	pars = append(pars, startSize, pageSize)
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+func (r *ReportHistory) GetPageListCount(condition string, pars []interface{}) (count int, err error) {
+	sql := fmt.Sprintf(`SELECT COUNT(1) AS count  FROM %s WHERE 1=1 `, r.TableName())
+	if condition != "" {
+		sql += condition
+	}
+	err = global.DmSQL["rddp"].Raw(sql, pars...).Scan(&count).Error
+	return
+}
+
+// 删除接口
+func (r *ReportHistory) Delete() (err error) {
+	err = global.DmSQL["rddp"].Delete(r).Error
+	return
+}
+
+// 查询单条记录
+func (r *ReportHistory) GetById(id int) (item *ReportHistory, err error) {
+	err = global.DmSQL["rddp"].Where("id = ?", id).First(&item).Error
+	return
+}
+
+// ReportHistoryListItem 定义报告历史记录列表项的结构体
+type ReportHistoryListItem struct {
+	Id              int    `description:"报告历史记录id"`
+	ReportId        int    `description:"报告id"`
+	ReportChapterId int    `description:"报告章节id"`
+	Title           string `description:"标题"`
+	CreateTime      string `description:"创建时间"`
+	AdminId         int    `description:"创建人id"`
+	AdminName       string `description:"创建人姓名"`
+}
+
+type ReportHistoryListResp struct {
+	List   []*ReportHistoryListItem
+	Paging *paging.PagingItem `description:"分页数据"`
+}
+
+type DeleteReportHistoryReq struct {
+	Id int `description:"报告历史记录id"`
+}

+ 72 - 0
routers/commentsRouter.go

@@ -6883,6 +6883,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"],
+        beego.ControllerComments{
+            Method: "Delete",
+            Router: `/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:PptV2HistoryController"],
+        beego.ControllerComments{
+            Method: "Revert",
+            Router: `/revert`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportAuthorController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportAuthorController"],
         beego.ControllerComments{
             Method: "Author",
@@ -7432,6 +7468,42 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"],
+        beego.ControllerComments{
+            Method: "Delete",
+            Router: `/del`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"],
+        beego.ControllerComments{
+            Method: "Detail",
+            Router: `/detail`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportHistoryController"],
+        beego.ControllerComments{
+            Method: "Revert",
+            Router: `/revert`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportUploadCommonController"] = append(beego.GlobalControllerRouter["eta_gn/eta_api/controllers:ReportUploadCommonController"],
         beego.ControllerComments{
             Method: "UploadImg",

+ 10 - 0
routers/router.go

@@ -344,6 +344,16 @@ func init() {
 				&controllers.BIDaShboardController{},
 			),
 		),
+		web.NSNamespace("/report_history",
+			web.NSInclude(
+				&controllers.ReportHistoryController{},
+			),
+		),
+		web.NSNamespace("/ppt_history",
+			web.NSInclude(
+				&controllers.PptV2HistoryController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }