def.go 6.4 KB
Newer Older
aaronchen2k2k's avatar
aaronchen2k2k 已提交
1 2 3
package serverService

import (
aaronchen2k2k's avatar
aaronchen2k2k 已提交
4
	"github.com/easysoft/zendata/src/gen"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
5 6
	"github.com/easysoft/zendata/src/model"
	"github.com/easysoft/zendata/src/server/repo"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
7
	serverUtils "github.com/easysoft/zendata/src/server/utils"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
8
	"github.com/easysoft/zendata/src/service"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
9 10
	constant "github.com/easysoft/zendata/src/utils/const"
	fileUtils "github.com/easysoft/zendata/src/utils/file"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
11
	stringUtils "github.com/easysoft/zendata/src/utils/string"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
12
	"github.com/easysoft/zendata/src/utils/vari"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
13 14
	"github.com/jinzhu/gorm"
	"gopkg.in/yaml.v3"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
15
	"io/ioutil"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
16
	"path"
17
	"strings"
aaronchen2k2k's avatar
aaronchen2k2k 已提交
18 19 20 21 22 23
)

type DefService struct {
	defRepo *serverRepo.DefRepo
	fieldRepo *serverRepo.FieldRepo
	referRepo *serverRepo.ReferRepo
aaronchen2k2k's avatar
aaronchen2k2k 已提交
24
	resService *ResService
aaronchen2k2k's avatar
aaronchen2k2k 已提交
25 26
}

27 28
func (s *DefService) List(keywords string, page int) (list []*model.ZdDef, total int) {
	list, total, _ = s.defRepo.List(strings.TrimSpace(keywords), page)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
29 30 31
	return
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
32
func (s *DefService) Get(id int) (def model.ZdDef, dirs []model.Dir) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
33
	def, _ = s.defRepo.Get(uint(id))
aaronchen2k2k's avatar
aaronchen2k2k 已提交
34

aaronchen2k2k's avatar
aaronchen2k2k 已提交
35
	serverUtils.GetDirs(constant.ResDirUsers, &dirs)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
36 37 38 39

	return
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
40 41
func (s *DefService) Save(def *model.ZdDef) (err error) {
	def.Folder = serverUtils.DealWithPathSepRight(def.Folder)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
42
	def.Path = vari.WorkDir + def.Folder + serverUtils.AddExt(def.FileName, ".yaml")
aaronchen2k2k's avatar
aaronchen2k2k 已提交
43 44 45 46 47 48

	if def.ID == 0 {
		err = s.Create(def)
	} else {
		err = s.Update(def)
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
49 50
	s.updateYaml(def.ID)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
51 52
	return
}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
53

aaronchen2k2k's avatar
aaronchen2k2k 已提交
54
func (s *DefService) Create(def *model.ZdDef) (err error) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
55 56
	err = s.defRepo.Create(def)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
57
	// add root field node
aaronchen2k2k's avatar
aaronchen2k2k 已提交
58
	rootField, err := s.fieldRepo.CreateTreeNode(def.ID, 0, "字段", "root")
aaronchen2k2k's avatar
aaronchen2k2k 已提交
59
	s.referRepo.CreateDefault(rootField.ID, constant.ResTypeDef)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
60
	err = s.defRepo.Update(def)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
61

aaronchen2k2k's avatar
aaronchen2k2k 已提交
62 63 64
	return
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
65
func (s *DefService) Update(def *model.ZdDef) (err error) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
66 67
	var old model.ZdDef
	old, err = s.defRepo.Get(def.ID)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
68 69 70
	if err == gorm.ErrRecordNotFound {
		return
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
71 72
	if def.Path != old.Path {
		fileUtils.RemoveExist(old.Path)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
73 74 75 76 77 78 79 80
	}

	err = s.defRepo.Update(def)

	return
}

func (s *DefService) Remove(id int) (err error) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
81 82
	var old model.ZdDef
	old, err = s.defRepo.Get(uint(id))
aaronchen2k2k's avatar
aaronchen2k2k 已提交
83 84 85
	if err == gorm.ErrRecordNotFound {
		return
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
86
	fileUtils.RemoveExist(old.Path)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
87 88 89 90 91

	err = s.defRepo.Remove(uint(id))
	return
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
92 93 94
func (s *DefService) updateYaml(id uint) (err error) {
	var po model.ZdDef
	po, _ = s.defRepo.Get(id)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
95

aaronchen2k2k's avatar
aaronchen2k2k 已提交
96 97 98
	s.genYaml(&po)
	err = s.defRepo.UpdateYaml(po)
	fileUtils.WriteFile(po.Path, po.Yaml)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
99 100 101 102

	return
}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
103
func (s *DefService) genYaml(def *model.ZdDef) (str string) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
104 105 106 107 108
	root, err := s.fieldRepo.GetDefFieldTree(def.ID)
	if err != nil {
		return
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
109 110
	yamlObj := model.DefData{}
	s.defRepo.GenDef(*def, &yamlObj)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
111

aaronchen2k2k's avatar
aaronchen2k2k 已提交
112
	for _, child := range root.Fields { // ignore the root
aaronchen2k2k's avatar
aaronchen2k2k 已提交
113
		defField := model.DefField{}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
114
		zdFieldToFieldForExport(*child, &defField)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
115

aaronchen2k2k's avatar
aaronchen2k2k 已提交
116
		yamlObj.Fields = append(yamlObj.Fields, defField)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
117 118
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
119
	bytes, err := yaml.Marshal(yamlObj)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
120
	def.Yaml = stringUtils.ConvertYamlStringToMapFormat(bytes)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
121 122 123 124

	return
}

125
func (s *DefService) Sync(files []model.ResFile) (err error) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
126
	list := s.defRepo.ListAll()
127

aaronchen2k2k's avatar
aaronchen2k2k 已提交
128 129 130
	mp := map[string]*model.ZdDef{}
	for _, item := range list {
		mp[item.Path] = item
aaronchen2k2k's avatar
aaronchen2k2k 已提交
131 132
	}

133
	for _, fi := range files {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
134 135 136 137 138
		// for yaml "res", "data" type should be default value text
		if fi.ResType == "" || fi.ResType == constant.ResTypeYaml {
			fi.ResType = constant.ResTypeText
		}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
139
		_, found := mp[fi.Path]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
140 141
		if !found { // no record
			s.SyncToDB(fi)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
142 143
		} else if fi.UpdatedAt.Unix() > mp[fi.Path].UpdatedAt.Unix() { // db is old
			s.defRepo.Remove(mp[fi.Path].ID)
144
			s.SyncToDB(fi)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
145 146 147 148 149
		}
	}

	return
}
150 151 152
func (s *DefService) SyncToDB(fi model.ResFile) (err error) {
	content, _ := ioutil.ReadFile(fi.Path)
	yamlContent := stringUtils.ReplaceSpecialChars(content)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
153 154 155 156 157 158 159
	po := model.ZdDef{}
	err = yaml.Unmarshal(yamlContent, &po)
	po.Title = fi.Title
	po.Type = fi.ResType
	po.Desc = fi.Desc
	po.Path = fi.Path
	po.Folder = serverUtils.GetRelativePath(po.Path)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
160 161 162 163

	po.ReferName = service.PathToName(po.Path, constant.ResDirUsers)
	po.FileName = fileUtils.GetFileName(po.Path)

aaronchen2k2k's avatar
aaronchen2k2k 已提交
164 165 166 167 168
	po.Yaml = string(content)

	s.defRepo.Create(&po)

	rootField, _ := s.fieldRepo.CreateTreeNode(po.ID, 0, "字段", "root")
169
	s.referRepo.CreateDefault(rootField.ID, constant.ResTypeDef)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
170
	for i, field := range po.Fields {
171
		field.Ord = i + 1
aaronchen2k2k's avatar
aaronchen2k2k 已提交
172
		s.saveFieldToDB(&field, fi.Path, rootField.ID, po.ID)
173 174 175 176
	}

	return
}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
177 178 179 180 181 182 183 184 185 186 187 188
func (s *DefService) saveFieldToDB(item *model.ZdField, currPath string, parentID, defID uint) {
	refer := model.ZdRefer{OwnerType: "def", OwnerID: item.ID}

	if item.Config != "" { // refer to config
		refer.Type = constant.ResTypeConfig

		item.Config = strings.TrimSpace(item.Config)
		rangeSections := gen.ParseRangeProperty(item.Config)
		if len(rangeSections) == 1 {
			rangeSection := rangeSections[0]
			desc, _, count := gen.ParseRangeSection(rangeSection)
			refer.Count = count
189 190 191

			path := FileToPath(desc, currPath)
			refer.File = strings.Replace(path, vari.WorkDir, "", 1)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
192 193 194 195 196 197 198 199 200
		}

	} else if item.Select != "" { // refer to excel
		refer.Type = constant.ResTypeExcel

		refer.ColName = item.Select
		refer.Condition = item.Where
		refer.Rand = item.Rand

aaronchen2k2k's avatar
aaronchen2k2k 已提交
201 202
		_, sheet := fileUtils.ConvertResExcelPath(item.From)
		refer.File = item.From
aaronchen2k2k's avatar
aaronchen2k2k 已提交
203 204 205
		refer.Sheet = sheet

	} else if item.Use != "" { // refer to ranges or instances
aaronchen2k2k's avatar
aaronchen2k2k 已提交
206
		refer.File = item.From
aaronchen2k2k's avatar
aaronchen2k2k 已提交
207
		refer.ColName, _, refer.Count = gen.ParseRangeSection(item.Use)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
208 209 210

		path := FileToPath(item.From, currPath)
		_, _, refer.Type = service.ReadYamlInfo(path)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
211 212 213 214 215 216 217 218 219 220

	} else if item.Range != "" { // deal with yaml and text refer using range prop
		item.Range = strings.TrimSpace(item.Range)
		rangeSections := gen.ParseRangeProperty(item.Range)
		if len(rangeSections) == 1 {
			rangeSection := rangeSections[0]
			desc, _, count := gen.ParseRangeSection(rangeSection)

			if path.Ext(desc) == ".txt" {
				refer.Type = constant.ResTypeText
aaronchen2k2k's avatar
aaronchen2k2k 已提交
221
			} else if path.Ext(desc) == ".yaml" {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
222 223
				refer.Type = constant.ResTypeYaml
			}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
224
			if path.Ext(desc) == ".txt" || path.Ext(desc) == ".yaml" {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
225
				refer.Count = count
226 227 228

				path := FileToPath(desc, currPath)
				refer.File = strings.Replace(path, vari.WorkDir, "", 1)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
229 230 231 232
			}
		}
	}

aaronchen2k2k's avatar
aaronchen2k2k 已提交
233 234
	item.DefID = defID
	item.ParentID = parentID
aaronchen2k2k's avatar
aaronchen2k2k 已提交
235 236 237 238 239 240
	if item.Type == "" {
		item.Type = constant.FieldTypeList
	}
	if item.Mode == "" {
		item.Mode = constant.ModeParallel
	}
aaronchen2k2k's avatar
aaronchen2k2k 已提交
241
	s.fieldRepo.Save(item)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
242 243
	refer.OwnerID = item.ID
	s.referRepo.Save(&refer)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
244 245

	for _, child := range item.Fields {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
246
		s.saveFieldToDB(child, currPath, item.ID, defID)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
247 248
	}
}
249

aaronchen2k2k's avatar
aaronchen2k2k 已提交
250 251
func NewDefService(defRepo *serverRepo.DefRepo, fieldRepo *serverRepo.FieldRepo,
	referRepo *serverRepo.ReferRepo) *DefService {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
252 253
	return &DefService{defRepo: defRepo, fieldRepo: fieldRepo, referRepo: referRepo}
}