Răsfoiți Sursa

Merge branch '2.0'

xiziwen 3 luni în urmă
părinte
comite
d24a98f767

+ 338 - 0
controllers/data_manage/excel/balance_table.go

@@ -1,6 +1,7 @@
 package excel
 
 import (
+	"archive/zip"
 	"encoding/json"
 	"errors"
 	"eta/eta_mobile/models"
@@ -11,8 +12,12 @@ import (
 	"eta/eta_mobile/services/data"
 	"eta/eta_mobile/services/data/data_manage_permission"
 	excelService "eta/eta_mobile/services/data/excel"
+	excel2 "eta/eta_mobile/services/excel"
 	"eta/eta_mobile/utils"
 	"fmt"
+	"github.com/tealeg/xlsx"
+	"io/ioutil"
+	"os"
 	"time"
 )
 
@@ -239,3 +244,336 @@ func refreshBalanceTable(excelDetail response.ExcelInfoDetail, lang string) (err
 	}
 	return
 }
+
+// GetChildTable
+// @Title 获取子表
+// @Description 获取子表
+// @Param	request	body request.MixedTableCellDataReq true "type json string"
+// @router /excel_info/child_table [get]
+func (c *ExcelInfoController) GetChildTable() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	parentId, _ := c.GetInt("ParentId")
+	if parentId <= 0 {
+		br.Msg = "请选择父表"
+		return
+	}
+	list := make([]*excel.ExcelInfo, 0)
+	// 查询所有子表
+	childList, err := excel.GetChildExcelInfoByParentId(parentId)
+	if err != nil {
+		br.Msg = "查询子表失败"
+		return
+	}
+	if len(childList) > 0 {
+		list = childList
+	}
+
+	resp := &response.BalanceChildTableResp{List: list}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "查询成功"
+	br.Data = resp
+}
+
+// BalanceVersionList
+// @Title 查询平衡表版本号列表
+// @Description 查询平衡表版本号列表
+// @Param	request	body request.EditExcelInfoReq true "type json string"
+// @Success 200 {object} response.AddExcelInfoResp
+// @router /excel_info/balance/version [get]
+func (c *ExcelInfoController) BalanceVersionList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	excelInfoId, _ := c.GetInt("ExcelInfoId")
+	if excelInfoId <= 0 {
+		br.Msg = "请选择表格"
+		br.ErrMsg = "ExcelInfoId未传"
+		br.IsSendEmail = false
+		return
+	}
+	excelInfo, err := excel.GetExcelInfoById(excelInfoId)
+	if err != nil {
+		br.Msg = "获取ETA表格失败"
+		br.ErrMsg = "获取ETA表格失败,Err:" + err.Error()
+		return
+	}
+	if excelInfo.Source != utils.BALANCE_TABLE {
+		br.Msg = "请选择平衡表"
+		return
+	}
+	if excelInfo.BalanceType != 0 && excelInfo.ParentId != 0 {
+		br.Msg = "请选择动态平衡表"
+		return
+	}
+	list := make([]*response.BalanceTableVersionListItem, 0)
+	list = append(list, &response.BalanceTableVersionListItem{
+		ExcelInfoId:    excelInfo.ExcelInfoId,
+		UniqueCode:     excelInfo.UniqueCode,
+		BalanceType:    excelInfo.BalanceType,
+		RelExcelInfoId: excelInfo.RelExcelInfoId,
+		VersionName:    "动态表", //todo 有个默认的版本名称
+	})
+	//查询动态表所有的子表,并复制为静态表
+	condition := " AND rel_excel_info_id=? AND parent_id = 0 AND balance_type = 1 "
+	var pars []interface{}
+	pars = append(pars, excelInfoId)
+
+	staticList, err := excel.GetNoContentExcelInfoListByConditionNoPage(condition, pars)
+	if err != nil {
+		br.Msg = "获取子表失败"
+		br.ErrMsg = fmt.Sprintf("获取子表失败 %s", err.Error())
+		return
+	}
+
+	for _, staticInfo := range staticList {
+		tmp := &response.BalanceTableVersionListItem{
+			ExcelInfoId:    staticInfo.ExcelInfoId,
+			UniqueCode:     staticInfo.UniqueCode,
+			BalanceType:    staticInfo.BalanceType,
+			RelExcelInfoId: staticInfo.RelExcelInfoId,
+			VersionName:    staticInfo.VersionName,
+		}
+		list = append(list, tmp)
+	}
+	ret := &response.BalanceTableVersionListResp{List: list}
+	br.Data = ret
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+}
+
+// GetBalanceChartList
+// @Title 获取平衡表表关联的图表
+// @Description 获取平衡表表关联的图表
+// @Param	request	body request.MixedTableCellDataReq true "type json string"
+// @router /excel_info/balance/chart_list [get]
+func (c *ExcelInfoController) GetBalanceChartList() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		c.Data["json"] = br
+		c.ServeJSON()
+	}()
+
+	sysUser := c.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+
+	excelInfoId, _ := c.GetInt("ExcelInfoId")
+	if excelInfoId <= 0 {
+		br.Msg = "请选择平衡表"
+		return
+	}
+	// 查询所有子表
+	excelInfo, err := excel.GetExcelInfoById(excelInfoId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "表格不存在"
+			return
+		}
+		br.Msg = "查询子表失败"
+		br.ErrMsg = "查询子表失败,Err:" + err.Error()
+		return
+	}
+	list := make([]*data_manage.BalanceChartInfoDetailResp, 0)
+	chartInfoList, mappingListMap, dataListMap, err, errMsg := excelService.GetBalanceExcelChartList(excelInfo, "")
+	if err != nil {
+		if errMsg != "" {
+			br.Msg = errMsg
+			br.ErrMsg = err.Error()
+			return
+		} else {
+			br.Msg = "查询图表失败"
+			br.ErrMsg = "查询图表失败,Err:" + err.Error()
+		}
+		return
+	}
+	for _, chartInfo := range chartInfoList {
+		mappingList, ok := mappingListMap[chartInfo.ChartInfoId]
+		if !ok {
+			br.Msg = "未找到图表关联的指标信息"
+			return
+		}
+		var chartInfoResp *data_manage.ChartInfoDetailResp
+		chartInfoResp, err, errMsg = data.GetBalanceExcelChartDetail(chartInfo, mappingList, sysUser, dataListMap)
+		if err != nil {
+			br.Msg = "查询图表详情失败"
+			br.ErrMsg = "查询图表详情失败,Err:" + err.Error()
+			return
+		}
+		chartEdbList := make([]*data_manage.ExcelChartEdbView, 0)
+		for _, v := range mappingList {
+			tmp := &data_manage.ExcelChartEdbView{
+				ExcelChartEdbId: v.ExcelChartEdbId,
+				DateSequenceStr: v.DateSequence,
+				DataSequenceStr: v.DataSequence,
+				FromTag:         v.FromTag,
+			}
+			chartEdbList = append(chartEdbList, tmp)
+		}
+
+		balanceChartInfoResp := &data_manage.BalanceChartInfoDetailResp{
+			ChartInfoDetailResp: chartInfoResp,
+			ExcelEdbList:        chartEdbList,
+		}
+		list = append(list, balanceChartInfoResp)
+	}
+
+	ret := &data_manage.BalanceTableChartListResp{List: list}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "查询成功"
+	br.Data = ret
+}
+
+func downloadBalanceTable(excelInfo *excel.ExcelInfo, lang string) (savePath, zipName string, uploadDir string, err error, errMsg string) {
+	dateDir := time.Now().Format("20060102")
+	randStr := time.Now().Format(utils.FormatDateTimeUnSpace)
+	uploadDir = "static/xls/" + dateDir + "/" + randStr
+	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
+	if err != nil {
+		return
+	}
+	fileList := make([]string, 0)
+	if excelInfo.ParentId != 0 && excelInfo.BalanceType != 0 {
+		errMsg = "平衡表类型错误"
+		err = fmt.Errorf("平衡表类型错误 ")
+		return
+	}
+	//复制静态表
+	staticCondition := " AND parent_id = 0 AND balance_type = 1 AND rel_excel_info_id=? "
+	var staticPars []interface{}
+	staticPars = append(staticPars, excelInfo.ExcelInfoId)
+	excelList, err := excel.GetExcelInfoListByCondition(staticCondition, staticPars)
+	if err != nil {
+		errMsg = "获取表格失败"
+		err = fmt.Errorf("获取表格失败 %s", err.Error())
+		return
+	}
+	excelList = append(excelList, excelInfo)
+	for _, staticExcelInfo := range excelList {
+		cCondition := " AND parent_id = ?"
+		var cPars []interface{}
+		cPars = append(cPars, staticExcelInfo.ExcelInfoId)
+		childList, e := excel.GetExcelInfoListByCondition(cCondition, cPars)
+		if e != nil {
+			errMsg = "获取子表失败"
+			err = fmt.Errorf("获取子表失败 %s", err.Error())
+			return
+		}
+		xlsxFile := xlsx.NewFile()
+		fileName := staticExcelInfo.ExcelName + ".xlsx"
+		fpath := uploadDir + "/" + fileName
+		for _, childExcelInfo := range childList {
+			var result request.MixedTableReq
+			err = json.Unmarshal([]byte(childExcelInfo.Content), &result)
+			if err != nil {
+				errMsg = "获取失败"
+				err = fmt.Errorf("表格json转结构体失败,Err:" + err.Error())
+				return
+			}
+			newResult, er, msg := excelService.GetMixedTableCellData(result, lang)
+			if er != nil {
+				err = er
+				errMsg = msg
+				return
+			}
+			tableData, er := excel2.GetTableDataByMixedTableData(newResult, false)
+			if er != nil {
+				errMsg = "获取失败"
+				err = fmt.Errorf("转换成table失败,Err:" + err.Error())
+				return
+			}
+			tableData, err = excel2.HandleRuleToTableCell(childExcelInfo.ExcelInfoId, tableData)
+			if err != nil {
+				errMsg = "获取失败"
+				err = fmt.Errorf("处理条件格式管理规则失败,Err:%w", err)
+				return
+			}
+			// 将单个sheet的数据写入到excel
+			err = tableData.WriteExcelSheetData(xlsxFile, childExcelInfo.ExcelName)
+			if err != nil {
+				return
+			}
+		}
+		//处理excel文件
+		//return
+		err = xlsxFile.Save(fpath)
+		if err != nil {
+			return
+		}
+		fileList = append(fileList, fileName)
+	}
+	// 创建zip
+	zipName = excelInfo.ExcelName + ".zip"
+
+	savePath = uploadDir + "/" + zipName
+	fmt.Println(savePath)
+	zipFile, err := os.Create(savePath)
+	if err != nil {
+		return
+	}
+	zipWriter := zip.NewWriter(zipFile)
+	// 生成zip过程中报错关闭
+	defer func() {
+		if err != nil {
+			zipWriter.Close()
+			zipFile.Close()
+		}
+		//os.Remove(savePath)
+	}()
+	//写入zip
+	for i := 0; i < len(fileList); i++ {
+		ioWriter, e := zipWriter.Create(fileList[i])
+		if e != nil {
+			err = fmt.Errorf("创建zip失败,Err:" + e.Error())
+			if os.IsPermission(e) {
+				fmt.Println("权限不足: ", e)
+				return
+			}
+			return
+		}
+		fullPath := uploadDir + "/" + fileList[i]
+		content, e := ioutil.ReadFile(fullPath)
+		if e != nil {
+			err = fmt.Errorf("读取文件失败,Err:" + e.Error())
+			return
+		}
+		ioWriter.Write(content)
+	}
+	// 生成zip后关闭,否则下载文件会损坏
+	zipWriter.Close()
+	zipFile.Close()
+	//this.Ctx.Output.Download(downLoadnFilePath, downloadFileName)
+	return
+}

+ 24 - 0
controllers/data_manage/excel/excel_info.go

@@ -347,6 +347,9 @@ func (c *ExcelInfoController) List() {
 	} else {
 		condition += " AND source = ? "
 		pars = append(pars, source)
+		if source == utils.BALANCE_TABLE { //平衡表的列表只显示动态表的一级表(不显示子表和静态表)
+			condition += " AND parent_id = 0 AND balance_type=0 "
+		}
 	}
 
 	// 筛选分类
@@ -2195,6 +2198,27 @@ func (c *ExcelInfoController) Download() {
 			br.ErrMsg = "转换成table失败,Err:" + err.Error()
 			return
 		}
+	case utils.BALANCE_TABLE: // 混合表格
+		savePath, fileName, uploadDir, err, errMsg := downloadBalanceTable(excelInfo, c.Lang)
+		if err != nil {
+			br.Msg = "下载失败"
+			if errMsg != `` {
+				br.Msg = errMsg
+			}
+			br.ErrMsg = "获取最新的数据失败,Err:" + err.Error()
+			return
+		}
+		defer func() {
+			_ = os.RemoveAll(uploadDir)
+		}()
+		// todo 删除文件
+		c.Ctx.Output.Download(savePath, fileName)
+		br.Ret = 200
+		br.Success = true
+		br.Msg = "获取成功"
+		br.Data = excelInfo
+		return
+
 	}
 
 	downloadFilePath, err := tableData.ToExcel()

+ 106 - 0
controllers/resource.go

@@ -2,6 +2,7 @@ package controllers
 
 import (
 	"bufio"
+	"encoding/base64"
 	"encoding/json"
 	"eta/eta_mobile/models"
 	"eta/eta_mobile/services"
@@ -10,6 +11,7 @@ import (
 	"fmt"
 	"github.com/kgiannakakis/mp3duration/src/mp3duration"
 	"io"
+	"net/http"
 	"os"
 	"path"
 	"regexp"
@@ -23,6 +25,11 @@ type ResourceController struct {
 	BaseCommonController
 }
 
+// ResourceAuthController 文件资源
+type ResourceAuthController struct {
+	BaseAuthController
+}
+
 // @Title 图片上传
 // @Description 图片上传接口
 // @Param   file   query   file  true       "文件"
@@ -919,3 +926,102 @@ func (this *ResourceController) WechatWarning() {
 	br.Ret = 200
 	br.Success = true
 }
+
+
+// FileDownload
+// @Title 文件下载
+// @Description 文件下载
+// @Param   FileUrl  query  string  true  "文件路径"
+// @Success 200 Ret=200 操作成功
+// @router /file/download [get]
+func (this *ResourceAuthController) FileDownload() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	//fileName := this.GetString("FileName")
+	//fileName = strings.TrimSpace(fileName)
+	//if fileName == "" {
+	//	br.Msg = "参数有误"
+	//	return
+	//}
+	fileEncode := this.GetString("FileUrl")
+	fileEncode = strings.TrimSpace(fileEncode)
+	if fileEncode == "" {
+		br.Msg = "参数有误"
+		return
+	}
+	fileByte, e := base64.StdEncoding.DecodeString(fileEncode)
+	if e != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "文件地址解析失败, Err: " + e.Error()
+		return
+	}
+	fileUrl := string(fileByte)
+	fileArr := strings.Split(fileUrl, "/")
+	if len(fileArr) == 0 {
+		br.Msg = "文件地址有误"
+		return
+	}
+	fileName := fileArr[len(fileArr)-1]
+	//fmt.Println(fileName)
+
+	// 获取文件
+	down, e := http.Get(fileUrl)
+	if e != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "文件下载失败, http get: " + e.Error()
+		return
+	}
+	defer down.Body.Close()
+	if down.StatusCode != http.StatusOK {
+		br.Msg = "下载失败"
+		br.ErrMsg = fmt.Sprintf("文件下载失败, http status: %d", down.StatusCode)
+		return
+	}
+
+	// 生成本地文件
+	localFilePath := fmt.Sprintf("%s%s", utils.GetRandStringNoSpecialChar(6), fileName)
+	localFile, e := os.Create(localFilePath)
+	if e != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "生成本地文件失败, Err: " + e.Error()
+		return
+	}
+	defer func() {
+		if e = localFile.Close(); e != nil {
+			fmt.Println("local file close err: ", e.Error())
+		}
+		if e = os.Remove(localFilePath); e != nil {
+			fmt.Println("local file remove err: ", e.Error())
+		}
+	}()
+
+	// 写入响应流
+	//_, e = io.Copy(this.Ctx.ResponseWriter, down.Body)
+	_, e = io.Copy(localFile, down.Body)
+	if e != nil {
+		br.Msg = "下载失败"
+		br.ErrMsg = "复制文件资源失败, Err: " + e.Error()
+		return
+	}
+	// 设置响应头
+	//this.Ctx.ResponseWriter.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", fileName))
+	//this.Ctx.ResponseWriter.Header().Set("Content-Type", "application/octet-stream")
+
+	br.Ret = 200
+	br.Msg = "下载成功"
+	br.Success = true
+	this.Ctx.Output.Download(localFilePath, fileName)
+}

+ 16 - 0
models/data_manage/chart_info.go

@@ -2737,3 +2737,19 @@ func getThsHfEdbDataListMinAndMaxByMongo(source, subSource, edbInfoId int, start
 	maxData = result.MaxValue
 	return
 }
+
+type BalanceTableChartListResp struct {
+	List []*BalanceChartInfoDetailResp
+}
+
+type BalanceChartInfoDetailResp struct {
+	*ChartInfoDetailResp
+	ExcelEdbList []*ExcelChartEdbView
+}
+
+type ExcelChartEdbView struct {
+	ExcelChartEdbId int
+	DateSequenceStr string `description:"日期序列选区"`
+	DataSequenceStr string `description:"数据序列选区"`
+	FromTag         string `description:"标签"`
+}

+ 49 - 0
models/data_manage/excel/excel_info.go

@@ -653,3 +653,52 @@ type ExcelInfoDetailButton struct {
 	RefreshEdbButton bool `description:"是否可刷新指标"`
 	OpWorkerButton   bool `description:"是否修改协作人"`
 }
+
+// GetChildExcelInfoByParentId 根据id 获取eta表格详情
+func GetChildExcelInfoByParentId(parentId int) (items []*ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT excel_info_id,source,excel_type,excel_name,unique_code,excel_classify_id,sys_user_id,sys_user_real_name,excel_image,file_url,sort,create_time,modify_time,is_join_permission, parent_id, balance_type, update_user_id,update_user_real_name FROM excel_info WHERE parent_id=? AND is_delete=0 order by sort asc, excel_info_id asc`
+	_, err = o.Raw(sql, parentId).QueryRows(&items)
+	return
+}
+
+func GetNoContentExcelInfoListByConditionNoPage(condition string, pars []interface{}) (items []*ExcelInfo, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT excel_info_id,excel_classify_id,excel_name,
+             unique_code,sys_user_id,sys_user_real_name,sort,is_join_permission, parent_id, balance_type, update_user_id,update_user_real_name,rel_excel_info_id,version_name FROM excel_info WHERE is_delete=0 `
+	if condition != "" {
+		sql += condition
+	}
+
+	sql += ` ORDER BY excel_info_id DESC `
+	_, err = o.Raw(sql, pars).QueryRows(&items)
+	return
+}
+
+type ExcelInfoRuleMappingView struct {
+	ExcelInfoRuleMappingId int    `orm:"pk" description:"主键"`
+	ExcelInfoId            int    `description:"Excel信息ID"`
+	RuleType               int    `description:"规则类型"`
+	LeftValue              string `description:"左值"`
+	LeftValueBack          string `description:"左值后端存储" json:"-"`
+	LeftValueType          int    `description:"左值类型"`
+	RightValue             string `description:"右值"`
+	RightValueBack         string `description:"右值后端存储" json:"-"`
+	RightValueType         int    `description:"右值类型"`
+	FontColor              string `description:"字体颜色"`
+	BackgroundColor        string `description:"背景颜色"`
+	Remark                 string `description:"预设颜色说明"`
+	RemarkEn               string `description:"预设颜色英文说明"`
+	Scope                  string `description:"作用范围"`
+	ScopeCoord             string `description:"作用范围坐标"`
+	ScopeShow              string `description:"作用范围坐标前端显示"`
+	CreateTime             string `description:"创建时间"`
+}
+
+// GetExcelRuleMappingByExcelInfoId 根据excelInfoId获取规则映射信息
+func GetExcelRuleMappingByExcelInfoId(id int) (items []*ExcelInfoRuleMappingView, err error) {
+	o := orm.NewOrmUsingDB("data")
+	sql := `SELECT * FROM excel_info_rule_mapping WHERE excel_info_id = ? ORDER BY create_time ASC`
+	_, err = o.Raw(sql, id).QueryRows(&items)
+	return
+}

+ 17 - 0
models/data_manage/excel/response/excel_info.go

@@ -102,3 +102,20 @@ type ExcelInfoDetailButton struct {
 	OpEdbButton      bool `description:"是否可生成指标"`
 	RefreshEdbButton bool `description:"是否可刷新指标"`
 }
+
+type BalanceChildTableResp struct {
+	List []*excel2.ExcelInfo
+}
+
+
+type BalanceTableVersionListItem struct {
+	ExcelInfoId    int    `description:"表格id"`
+	UniqueCode     string `description:"表格唯一编码"`
+	BalanceType    int    `description:"平衡表类型:0 动态表,1静态表"`
+	RelExcelInfoId int    `description:"平衡表里静态表关联的动态表excel id"`
+	VersionName    string `description:"静态表版本名称"`
+}
+
+type BalanceTableVersionListResp struct {
+	List []*BalanceTableVersionListItem
+}

+ 11 - 0
models/data_manage/my_chart.go

@@ -975,3 +975,14 @@ func GetChartItems(cond string, pars []interface{}, orderRule string) (item []*C
 	_, err = o.Raw(sql, pars).QueryRows(&item)
 	return
 }
+
+func GetChartInfoViewByIdList(chartInfoIdList []int) (items []*ChartInfoView, err error) {
+	num := len(chartInfoIdList)
+	if num <= 0 {
+		return
+	}
+	o := orm.NewOrmUsingDB("data")
+	sql := ` SELECT * FROM chart_info WHERE chart_info_id in (` + utils.GetOrmInReplace(num) + `) `
+	_, err = o.Raw(sql, chartInfoIdList).QueryRows(&items)
+	return
+}

+ 36 - 0
routers/commentsRouter.go

@@ -763,6 +763,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "GetBalanceChartList",
+            Router: `/excel_info/balance/chart_list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "BalanceVersionList",
+            Router: `/excel_info/balance/version`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"],
         beego.ControllerComments{
             Method: "GetBaseEdbInfo",
@@ -772,6 +790,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"],
+        beego.ControllerComments{
+            Method: "GetChildTable",
+            Router: `/excel_info/child_table`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"] = append(beego.GlobalControllerRouter["eta/eta_mobile/controllers/data_manage/excel:ExcelInfoController"],
         beego.ControllerComments{
             Method: "Copy",
@@ -5731,6 +5758,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_mobile/controllers:ResourceAuthController"] = append(beego.GlobalControllerRouter["eta/eta_mobile/controllers:ResourceAuthController"],
+        beego.ControllerComments{
+            Method: "FileDownload",
+            Router: `/file/download`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_mobile/controllers:ResourceController"] = append(beego.GlobalControllerRouter["eta/eta_mobile/controllers:ResourceController"],
         beego.ControllerComments{
             Method: "Upload",

+ 1 - 0
routers/router.go

@@ -144,6 +144,7 @@ func init() {
 		web.NSNamespace("/resource",
 			web.NSInclude(
 				&controllers.ResourceController{},
+				&controllers.ResourceAuthController{},
 			),
 		),
 		web.NSNamespace("/datamanage",

+ 66 - 0
services/data/excel/balance_table.go

@@ -406,3 +406,69 @@ func GetBalanceExcelInfoOpButton(sysUserId, parentSysUserId int, haveOperaAuth b
 	}
 	return
 }
+
+func GetBalanceExcelChartList(excelInfo *excelModel.ExcelInfo, lang string) (list []*data_manage.ChartInfoView, mappingListMap map[int][]*excelModel.ExcelChartEdb, dataListMap map[int][]*data_manage.EdbDataList, err error, errMsg string) {
+	dataListMap = make(map[int][]*data_manage.EdbDataList)
+	// 相关联指标
+	mappingListTmp, err := excelModel.GetExcelChartEdbMappingByExcelInfoId(excelInfo.ExcelInfoId)
+	if err != nil {
+		errMsg = "获取失败"
+		err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", err.Error())
+		return
+	}
+	charInfoIds := make([]int, 0)
+	mappingListMap = make(map[int][]*excelModel.ExcelChartEdb, 0)
+	if excelInfo.BalanceType == 1 {
+		for _, mapping := range mappingListTmp {
+			mappingListMap[mapping.ChartInfoId] = append(mappingListMap[mapping.ChartInfoId], mapping)
+		}
+		//查询库里是否有值
+		chartDataList, e := excelModel.GetExcelChartDataByExcelInfoId(excelInfo.ExcelInfoId)
+		if e != nil {
+			err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error())
+			return
+		}
+		if len(chartDataList) > 0 {
+			for _, v := range chartDataList {
+				tmp := &data_manage.EdbDataList{
+					EdbDataId:     v.ExcelChartDataId,
+					EdbInfoId:     v.ExcelChartEdbId,
+					DataTime:      v.DataTime,
+					DataTimestamp: v.DataTimestamp,
+					Value:         v.Value,
+				}
+				dataListMap[v.ExcelChartEdbId] = append(dataListMap[v.ExcelChartEdbId], tmp)
+			}
+		}
+	} else {
+		newExcelDataMap, excelAllRows, excelAllCols, e, msg := GetBalanceExcelData(excelInfo, lang)
+		if e != nil {
+			err = e
+			errMsg = msg
+			return
+		}
+		for _, mapping := range mappingListTmp {
+			mappingListMap[mapping.ChartInfoId] = append(mappingListMap[mapping.ChartInfoId], mapping)
+			er, ms := GetBalanceExcelEdbData(mapping, newExcelDataMap, dataListMap, excelAllRows, excelAllCols)
+			if er != nil {
+				utils.FileLog.Info(fmt.Sprintf(" 获取图表,指标信息失败 Err:%s, %s", er.Error(), ms))
+				continue
+			}
+		}
+	}
+
+	for k, _ := range mappingListMap {
+		charInfoIds = append(charInfoIds, k)
+	}
+	list = make([]*data_manage.ChartInfoView, 0)
+	if len(charInfoIds) > 0 {
+		chartInfoList, e := data_manage.GetChartInfoViewByIdList(charInfoIds)
+		if e != nil {
+			errMsg = "获取失败"
+			err = fmt.Errorf(" 获取图表,指标信息失败 Err:%s", e.Error())
+			return
+		}
+		list = chartInfoList
+	}
+	return
+}

+ 220 - 0
services/excel/lucky_sheet.go

@@ -3,6 +3,7 @@ package excel
 import (
 	"encoding/json"
 	"errors"
+	"eta/eta_mobile/models/data_manage/excel"
 	"eta/eta_mobile/models/data_manage/excel/request"
 	"eta/eta_mobile/utils"
 	"fmt"
@@ -1724,3 +1725,222 @@ func GetTableDataByMixedTableData(config [][]request.MixedTableCellDataReq, hide
 
 	return
 }
+
+// HandleRuleToTableCell 根据管理规则渲染单元格数据
+func HandleRuleToTableCell(excelInfoId int, oldTableData TableData) (newTableData TableData, err error) {
+	newTableData = oldTableData
+	excelRuleMappingList, err := excel.GetExcelRuleMappingByExcelInfoId(excelInfoId)
+	if err != nil {
+		return
+	}
+	if len(excelRuleMappingList) == 0 {
+		return
+	}
+	tableDataList := oldTableData.TableDataList
+	excelRuleMap := make(map[int]*excel.ExcelInfoRuleMappingView)
+	for _, v := range excelRuleMappingList {
+		excelRuleMap[v.ExcelInfoRuleMappingId] = v
+	}
+	ruleScopeMap := generateRuleScopeIndexMap(excelRuleMappingList)
+	for row, scopeValues := range ruleScopeMap {
+		for col, ruleId := range scopeValues {
+			if v, ok := excelRuleMap[ruleId]; ok {
+				if len(tableDataList) > row && len(tableDataList[row]) > col {
+					// 符合管理规则要求,则进行字体和背景颜色的渲染
+					if checkCellRule(v, tableDataList[row][col].Monitor, tableDataList) {
+						tableDataList[row][col].Background = v.BackgroundColor
+						tableDataList[row][col].FontColor = v.FontColor
+					}
+				} else {
+					continue
+				}
+			} else {
+				continue
+			}
+		}
+	}
+	return
+}
+
+func getCellValueByType(value string, valueType int, tableDataList [][]LuckySheetDataValue) (float64, bool) {
+	if valueType == 2 {
+		coords := strings.Split(value, ",")
+		var coordIntArr []int
+		for _, v := range coords {
+			t, _ := strconv.Atoi(v)
+			coordIntArr = append(coordIntArr, t)
+		}
+		if len(coordIntArr) == 2 {
+			x, y := coordIntArr[0]-1, coordIntArr[1]-1
+			conditionValue, err := strconv.ParseFloat(tableDataList[y][x].Monitor, 64)
+			if err != nil {
+				return 0, false
+			}
+			return conditionValue, true
+		}
+	} else {
+		conditionValue, err := strconv.ParseFloat(value, 64)
+		if err != nil {
+			return 0, false
+		}
+		return conditionValue, true
+	}
+	return 0, false
+}
+
+func checkCellRule(ruleInfo *excel.ExcelInfoRuleMappingView, value string, tableDataList [][]LuckySheetDataValue) bool {
+	var tableValue float64
+	var tableTime time.Time
+	var err error
+
+	if ruleInfo.RuleType == 5 {
+		tableTime, err = time.ParseInLocation(utils.FormatDate, value, time.Local)
+		if err != nil {
+			return false
+		}
+	} else {
+		tableValue, err = strconv.ParseFloat(value, 64)
+		if err != nil {
+			return false
+		}
+	}
+	switch ruleInfo.RuleType {
+	// 大于
+	case 1:
+		conditionValue, ok := getCellValueByType(ruleInfo.LeftValueBack, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if tableValue > conditionValue {
+			return true
+		}
+	// 小于
+	case 2:
+		conditionValue, ok := getCellValueByType(ruleInfo.LeftValueBack, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if tableValue < conditionValue {
+			return true
+		}
+	// 介于
+	case 3:
+		leftcondValue, ok := getCellValueByType(ruleInfo.LeftValueBack, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		rightcondValue, ok := getCellValueByType(ruleInfo.RightValueBack, ruleInfo.RightValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if leftcondValue <= tableValue && tableValue <= rightcondValue {
+			return true
+		}
+	// 等于
+	case 4:
+		conditionValue, ok := getCellValueByType(ruleInfo.LeftValueBack, ruleInfo.LeftValueType, tableDataList)
+		if !ok {
+			return false
+		}
+		if tableValue == conditionValue {
+			return true
+		}
+	// 发生日期
+	case 5:
+		// 发生日期
+		var dateStart, dataEnd time.Time
+		switch ruleInfo.LeftValueBack {
+		// 今天
+		case "today":
+			// 获得今天的零点零分零秒
+			dateStart = utils.Today()
+			if tableTime == dateStart {
+				return true
+			}
+		// 明天
+		case "tomorrow":
+			dateStart = utils.Tomorrow()
+			if tableTime == dateStart {
+				return true
+			}
+		// 最近7天
+		case "last7days":
+			dateStart, dataEnd = utils.Last7Days()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 上周
+		case "lastweek":
+			dateStart, dataEnd = utils.LastWeek()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 本周
+		case "thisweek":
+			dateStart, dataEnd = utils.ThisWeek()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 下周
+		case "nextweek":
+			dateStart, dataEnd = utils.NextWeek()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 上月
+		case "lastmonth":
+			dateStart, dataEnd = utils.LastMonth()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 本月
+		case "thismonth":
+			dateStart, dataEnd = utils.ThisMonth()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		// 下月
+		case "nextmonth":
+			dateStart, dataEnd = utils.NextMonth()
+			if tableTime.After(dateStart) && tableTime.Before(dataEnd) {
+				return true
+			}
+		default:
+			return false
+		}
+
+	}
+	return false
+}
+
+func generateRuleScopeIndexMap(items []*excel.ExcelInfoRuleMappingView) (ruleScopeMap map[int]map[int]int) {
+	ruleScopeMap = make(map[int]map[int]int)
+	for _, item := range items {
+		coords := strings.Split(item.ScopeCoord, ",")
+		var coordIntArr []int
+		for _, v := range coords {
+			t, _ := strconv.Atoi(v)
+			coordIntArr = append(coordIntArr, t)
+		}
+
+		if len(coords) == 4 {
+			xmin, ymin, xmax, ymax := coordIntArr[0]-1, coordIntArr[1]-1, coordIntArr[2]-1, coordIntArr[3]-1
+			for i := ymin; i <= ymax; i++ {
+				for j := xmin; j <= xmax; j++ {
+					if _, ok := ruleScopeMap[i]; !ok {
+						ruleScopeMap[i] = make(map[int]int)
+					}
+					ruleScopeMap[i][j] = item.ExcelInfoRuleMappingId
+				}
+			}
+		}
+		if len(coords) == 2 {
+			x, y := coordIntArr[0]-1, coordIntArr[1]-1
+			if _, ok := ruleScopeMap[y]; !ok {
+				ruleScopeMap[y] = make(map[int]int)
+			}
+			ruleScopeMap[y][x] = item.ExcelInfoRuleMappingId
+		}
+	}
+	return
+}

+ 74 - 0
utils/time.go

@@ -0,0 +1,74 @@
+package utils
+
+import "time"
+
+// 获取今天的日期(零点零分零秒)
+func Today() time.Time {
+	now := time.Now()
+	return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
+}
+
+// 获取明天的日期(零点零分零秒)
+func Tomorrow() time.Time {
+	return Today().AddDate(0, 0, 1)
+}
+
+// 获取最近7天的日期范围
+func Last7Days() (time.Time, time.Time) {
+	today := Today()
+	return today.AddDate(0, 0, -6), today.Add(time.Hour * 23).Add(time.Minute * 59).Add(time.Second * 59)
+}
+
+// 获取上周的日期范围
+func LastWeek() (time.Time, time.Time) {
+	start := Today().AddDate(0, 0, -7)
+	end := start.AddDate(0, 0, 6).Add(time.Hour * 23).Add(time.Minute * 59).Add(time.Second * 59)
+	return start, end
+}
+
+// 获取本周的日期范围
+func ThisWeek() (time.Time, time.Time) {
+	start := Today().Round(0).Local().AddDate(0, 0, 0-int(time.Now().Weekday())+1) // 0是本周的第一天,+1是因为AddDate是相对于当前时间的
+	end := start.AddDate(0, 0, 6).Add(time.Hour * 23).Add(time.Minute * 59).Add(time.Second * 59)
+	return start, end
+}
+
+// 获取下周的日期范围
+func NextWeek() (time.Time, time.Time) {
+	_, thisEnd := ThisWeek()
+	start := thisEnd.AddDate(0, 0, 1)
+	end := start.AddDate(0, 0, 6).Add(time.Hour * 23).Add(time.Minute * 59).Add(time.Second * 59)
+	return start, end
+}
+
+// 获取上月的日期范围
+func LastMonth() (time.Time, time.Time) {
+	today := time.Now()
+	year, month, _ := today.Date()
+	start := time.Date(year, month-1, 1, 0, 0, 0, 0, today.Location())
+	end := time.Date(year, month, 0, 23, 59, 59, 999999999, today.Location())
+	return start, end
+}
+
+// 获取本月的日期范围
+func ThisMonth() (time.Time, time.Time) {
+	today := time.Now()
+	year, month, _ := today.Date()
+	start := time.Date(year, month, 1, 0, 0, 0, 0, today.Location())
+	end := time.Date(year, month+1, 0, 23, 59, 59, 999999999, today.Location())
+	return start, end
+}
+
+// 获取下月的日期范围
+func NextMonth() (time.Time, time.Time) {
+	now := time.Now()
+	year, month, _ := now.Date()
+	nextMonth := month + 1
+	if nextMonth > 12 {
+		nextMonth = 1
+		year++
+	}
+	startOfNextMonth := time.Date(year, nextMonth, 1, 0, 0, 0, 0, now.Location())
+	endOfNextMonth := startOfNextMonth.AddDate(0, 1, -1).Add(time.Hour*23 + time.Minute*59 + time.Second*59)
+	return startOfNextMonth, endOfNextMonth
+}