Skip to content

Commit 08ae441

Browse files
author
piexlMax(奇淼
committed
feat: 增加字典的json导出和导入
1 parent a1f18e1 commit 08ae441

File tree

4 files changed

+259
-128
lines changed

4 files changed

+259
-128
lines changed

server/api/v1/system/sys_dictionary.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,17 @@ func (s *DictionaryApi) ExportSysDictionary(c *gin.Context) {
171171
// @Security ApiKeyAuth
172172
// @accept application/json
173173
// @Produce application/json
174-
// @Param data body map[string]interface{} true "字典JSON数据"
174+
// @Param data body request.ImportSysDictionaryRequest true "字典JSON数据"
175175
// @Success 200 {object} response.Response{msg=string} "导入字典"
176176
// @Router /sysDictionary/importSysDictionary [post]
177177
func (s *DictionaryApi) ImportSysDictionary(c *gin.Context) {
178-
var importData map[string]interface{}
179-
err := c.ShouldBindJSON(&importData)
178+
var req request.ImportSysDictionaryRequest
179+
err := c.ShouldBindJSON(&req)
180180
if err != nil {
181181
response.FailWithMessage(err.Error(), c)
182182
return
183183
}
184-
err = dictionaryService.ImportSysDictionary(importData)
184+
err = dictionaryService.ImportSysDictionary(req.Json)
185185
if err != nil {
186186
global.GVA_LOG.Error("导入失败!", zap.Error(err))
187187
response.FailWithMessage("导入失败: "+err.Error(), c)

server/model/system/request/sys_dictionary.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ package request
33
type SysDictionarySearch struct {
44
Name string `json:"name" form:"name" gorm:"column:name;comment:字典名(中)"` // 字典名(中)
55
}
6+
7+
type ImportSysDictionaryRequest struct {
8+
Json string `json:"json" binding:"required"` // JSON字符串
9+
}

server/service/system/sys_dictionary.go

Lines changed: 65 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package system
22

33
import (
4+
"encoding/json"
45
"errors"
56

67
"github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
@@ -153,7 +154,7 @@ func (dictionaryService *DictionaryService) checkCircularReference(currentID uin
153154
return nil
154155
}
155156

156-
//@author: [yourname]
157+
//@author: [pixelMax]
157158
//@function: ExportSysDictionary
158159
//@description: 导出字典JSON(包含字典详情)
159160
//@param: id uint
@@ -169,55 +170,65 @@ func (dictionaryService *DictionaryService) ExportSysDictionary(id uint) (export
169170
return nil, err
170171
}
171172

173+
// 清空字典详情中的ID、创建时间、更新时间等字段
174+
var cleanDetails []map[string]interface{}
175+
for _, detail := range dictionary.SysDictionaryDetails {
176+
cleanDetail := map[string]interface{}{
177+
"label": detail.Label,
178+
"value": detail.Value,
179+
"extend": detail.Extend,
180+
"status": detail.Status,
181+
"sort": detail.Sort,
182+
"level": detail.Level,
183+
"path": detail.Path,
184+
}
185+
cleanDetails = append(cleanDetails, cleanDetail)
186+
}
187+
172188
// 构造导出数据
173189
exportData = map[string]interface{}{
174-
"name": dictionary.Name,
175-
"type": dictionary.Type,
176-
"status": dictionary.Status,
177-
"desc": dictionary.Desc,
178-
"details": dictionary.SysDictionaryDetails,
190+
"name": dictionary.Name,
191+
"type": dictionary.Type,
192+
"status": dictionary.Status,
193+
"desc": dictionary.Desc,
194+
"sysDictionaryDetails": cleanDetails,
179195
}
180196

181197
return exportData, nil
182198
}
183199

184-
//@author: [yourname]
200+
//@author: [pixelMax]
185201
//@function: ImportSysDictionary
186202
//@description: 导入字典JSON(包含字典详情)
187-
//@param: importData map[string]interface{}
203+
//@param: jsonStr string
188204
//@return: err error
189205

190-
func (dictionaryService *DictionaryService) ImportSysDictionary(importData map[string]interface{}) error {
191-
// 解析基本字典信息
192-
name, ok := importData["name"].(string)
193-
if !ok || name == "" {
194-
return errors.New("字典名称不能为空")
206+
func (dictionaryService *DictionaryService) ImportSysDictionary(jsonStr string) error {
207+
// 直接解析到 SysDictionary 结构体
208+
var importData system.SysDictionary
209+
if err := json.Unmarshal([]byte(jsonStr), &importData); err != nil {
210+
return errors.New("JSON 格式错误: " + err.Error())
195211
}
196212

197-
dictType, ok := importData["type"].(string)
198-
if !ok || dictType == "" {
213+
// 验证必填字段
214+
if importData.Name == "" {
215+
return errors.New("字典名称不能为空")
216+
}
217+
if importData.Type == "" {
199218
return errors.New("字典类型不能为空")
200219
}
201220

202221
// 检查字典类型是否已存在
203-
if !errors.Is(global.GVA_DB.First(&system.SysDictionary{}, "type = ?", dictType).Error, gorm.ErrRecordNotFound) {
222+
if !errors.Is(global.GVA_DB.First(&system.SysDictionary{}, "type = ?", importData.Type).Error, gorm.ErrRecordNotFound) {
204223
return errors.New("存在相同的type,不允许导入")
205224
}
206225

207-
// 创建字典
226+
// 创建字典(清空导入数据的ID和时间戳)
208227
dictionary := system.SysDictionary{
209-
Name: name,
210-
Type: dictType,
211-
}
212-
213-
// 处理status字段
214-
if status, ok := importData["status"].(bool); ok {
215-
dictionary.Status = &status
216-
}
217-
218-
// 处理desc字段
219-
if desc, ok := importData["desc"].(string); ok {
220-
dictionary.Desc = desc
228+
Name: importData.Name,
229+
Type: importData.Type,
230+
Status: importData.Status,
231+
Desc: importData.Desc,
221232
}
222233

223234
// 开启事务
@@ -228,84 +239,53 @@ func (dictionaryService *DictionaryService) ImportSysDictionary(importData map[s
228239
}
229240

230241
// 处理字典详情
231-
if details, ok := importData["details"].([]interface{}); ok && len(details) > 0 {
242+
if len(importData.SysDictionaryDetails) > 0 {
232243
// 创建一个映射来跟踪旧ID到新ID的对应关系
233244
idMap := make(map[uint]uint)
234245

235-
// 第一遍:创建所有详情记录(不设置parent_id)
236-
for _, detail := range details {
237-
detailMap, ok := detail.(map[string]interface{})
238-
if !ok {
246+
// 第一遍:创建所有详情记录
247+
for _, detail := range importData.SysDictionaryDetails {
248+
// 验证必填字段
249+
if detail.Label == "" || detail.Value == "" {
239250
continue
240251
}
241252

242-
label, _ := detailMap["label"].(string)
243-
value, _ := detailMap["value"].(string)
244-
245-
if label == "" || value == "" {
246-
continue
247-
}
253+
// 记录旧ID
254+
oldID := detail.ID
248255

256+
// 创建新的详情记录(ID会被GORM自动设置)
249257
detailRecord := system.SysDictionaryDetail{
250-
Label: label,
251-
Value: value,
258+
Label: detail.Label,
259+
Value: detail.Value,
260+
Extend: detail.Extend,
261+
Status: detail.Status,
262+
Sort: detail.Sort,
263+
Level: detail.Level,
264+
Path: detail.Path,
252265
SysDictionaryID: int(dictionary.ID),
253266
}
254267

255-
// 处理extend字段
256-
if extend, ok := detailMap["extend"].(string); ok {
257-
detailRecord.Extend = extend
258-
}
259-
260-
// 处理status字段
261-
if status, ok := detailMap["status"].(bool); ok {
262-
detailRecord.Status = &status
263-
}
264-
265-
// 处理sort字段
266-
if sort, ok := detailMap["sort"].(float64); ok {
267-
detailRecord.Sort = int(sort)
268-
}
269-
270268
// 创建详情记录
271269
if err := tx.Create(&detailRecord).Error; err != nil {
272270
return err
273271
}
274272

275-
// 记录ID映射(如果有原始ID)
276-
if oldID, ok := detailMap["ID"].(float64); ok {
277-
idMap[uint(oldID)] = detailRecord.ID
273+
// 记录旧ID到新ID的映射
274+
if oldID > 0 {
275+
idMap[oldID] = detailRecord.ID
278276
}
279277
}
280278

281279
// 第二遍:更新parent_id关系
282-
for i, detail := range details {
283-
detailMap, ok := detail.(map[string]interface{})
284-
if !ok {
285-
continue
286-
}
287-
288-
// 如果有parentID,更新它
289-
if oldParentID, ok := detailMap["parentID"].(float64); ok && oldParentID > 0 {
290-
if newParentID, exists := idMap[uint(oldParentID)]; exists {
291-
// 获取新创建的记录ID(按顺序)
292-
if oldID, ok := detailMap["ID"].(float64); ok {
293-
if newID, exists := idMap[uint(oldID)]; exists {
294-
if err := tx.Model(&system.SysDictionaryDetail{}).Where("id = ?", newID).Update("parent_id", newParentID).Error; err != nil {
295-
return err
296-
}
297-
}
298-
} else {
299-
// 如果没有ID,使用索引来查找
300-
var allDetails []system.SysDictionaryDetail
301-
if err := tx.Where("sys_dictionary_id = ?", dictionary.ID).Order("id").Find(&allDetails).Error; err != nil {
280+
for _, detail := range importData.SysDictionaryDetails {
281+
if detail.ParentID != nil && *detail.ParentID > 0 && detail.ID > 0 {
282+
if newID, exists := idMap[detail.ID]; exists {
283+
if newParentID, parentExists := idMap[*detail.ParentID]; parentExists {
284+
if err := tx.Model(&system.SysDictionaryDetail{}).
285+
Where("id = ?", newID).
286+
Update("parent_id", newParentID).Error; err != nil {
302287
return err
303288
}
304-
if i < len(allDetails) {
305-
if err := tx.Model(&system.SysDictionaryDetail{}).Where("id = ?", allDetails[i].ID).Update("parent_id", newParentID).Error; err != nil {
306-
return err
307-
}
308-
}
309289
}
310290
}
311291
}

0 commit comments

Comments
 (0)