浏览代码

add:复制任务,批量修改模版数据

zoie 4 周之前
父节点
当前提交
d25c14c789
共有 5 个文件被更改,包括 518 次插入46 次删除
  1. 39 25
      controllers/Task.go
  2. 379 16
      controllers/VerifyTemplate.go
  3. 37 4
      models/Task/Task.go
  4. 61 1
      models/VerifyTemplate/VerifyTemplateMapData.go
  5. 2 0
      routers/VerifyTemplate.go

+ 39 - 25
controllers/Task.go

@@ -3645,6 +3645,7 @@ func GetWatermarkPdf_command(task Task.Task, pdfURL string, flag string) (pdf st
 
 	return
 }
+
 func GetSignaturePdf_command(task Task.Task, pdfURL string, flag string) (pdf string) {
 	if len(pdfURL) == 0 {
 		return
@@ -4062,31 +4063,40 @@ func (c *TaskController) Copy() {
 				infoCollectionName = newCompany.T_name
 			}
 
-			// 创建新的信息采集
-			newInfoCollection := InfoCollection.InfoCollection{
-				T_uuid:               new_T_uuid,
-				T_name:               infoCollectionName,
-				T_InfoTemplate_class: infoCollection.T_InfoTemplate_class,
-				T_InfoTemplate_id:    infoCollection.T_InfoTemplate_id,
-				T_status:             1,
-				T_State:              1,
-				T_start_time:         infoCollection.T_start_time,
-				T_end_time:           infoCollection.T_end_time,
-				T_time_interval:      infoCollection.T_time_interval,
-			}
-			newInfoCollectionId, err := InfoCollection.Add_InfoCollection(newInfoCollection)
-			if err != nil {
-				c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加信息采集失败: " + err.Error()}
-				c.ServeJSON()
-				return
-			}
-			target_InfoCollection_id = newInfoCollectionId
-			// 重新读取新创建的信息采集以获取完整信息
-			infoCollection, is = InfoCollection.Read_InfoCollection(target_InfoCollection_id)
-			if !is {
-				c.Data["json"] = lib.JSONS{Code: 202, Msg: "获取新创建的信息采集失败!"}
-				c.ServeJSON()
-				return
+			// 先查询信息采集标题是否存在
+			existingInfoCollection, found := InfoCollection.Read_InfoCollection_By_T_uuid_Name(new_T_uuid, infoCollectionName)
+			if found {
+				// 如果存在则直接用
+				target_InfoCollection_id = existingInfoCollection.T_InfoCollection_id
+				infoCollection = existingInfoCollection
+			} else {
+				// 不存在才添加
+				// 创建新的信息采集
+				newInfoCollection := InfoCollection.InfoCollection{
+					T_uuid:               new_T_uuid,
+					T_name:               infoCollectionName,
+					T_InfoTemplate_class: infoCollection.T_InfoTemplate_class,
+					T_InfoTemplate_id:    infoCollection.T_InfoTemplate_id,
+					T_status:             1,
+					T_State:              1,
+					T_start_time:         infoCollection.T_start_time,
+					T_end_time:           infoCollection.T_end_time,
+					T_time_interval:      infoCollection.T_time_interval,
+				}
+				newInfoCollectionId, err := InfoCollection.Add_InfoCollection(newInfoCollection)
+				if err != nil {
+					c.Data["json"] = lib.JSONS{Code: 202, Msg: "添加信息采集失败: " + err.Error()}
+					c.ServeJSON()
+					return
+				}
+				target_InfoCollection_id = newInfoCollectionId
+				// 重新读取新创建的信息采集以获取完整信息
+				infoCollection, is = InfoCollection.Read_InfoCollection(target_InfoCollection_id)
+				if !is {
+					c.Data["json"] = lib.JSONS{Code: 202, Msg: "获取新创建的信息采集失败!"}
+					c.ServeJSON()
+					return
+				}
 			}
 		}
 	}
@@ -4151,6 +4161,9 @@ func (c *TaskController) Copy() {
 		logs.Error("自动填写布点失败", err)
 	}
 
+	// 检查必填项是否都有值
+	VerifyTemplate.Check_RequiredFields_HaveValue(T_paste_task_id)
+
 	NatsServer.Create_Local_Table(T_paste_task_id)
 	Task.Redis_Task_T_report_number_DelK(var_.T_report_number) // 删除redis内的任务编号
 
@@ -4383,6 +4396,7 @@ func (c *TaskController) SyncVerifyTemplateMapData() {
 	c.ServeJSON()
 	return
 }
+
 func (c *TaskController) TaskData_Stat() {
 	StartTime := c.GetString("StartTime")
 	if len(StartTime) > 0 {

+ 379 - 16
controllers/VerifyTemplate.go

@@ -14,6 +14,7 @@ import (
 	"fmt"
 	"math"
 	"os"
+	"sort"
 	"strconv"
 	"strings"
 	"time"
@@ -31,7 +32,8 @@ func (c *VerifyTemplateController) Prepare() {
 	GetCookie := c.Ctx.GetCookie("User_tokey")
 	GetString := c.GetString("User_tokey")
 	fmt.Println(c.Ctx.Request.URL.Path)
-	if strings.Contains(c.Ctx.Request.URL.Path, "/VerifyTemplateMapData/Pu") {
+	if strings.Contains(c.Ctx.Request.URL.Path, "/VerifyTemplateMapData/Pu") ||
+		strings.Contains(c.Ctx.Request.URL.Path, "/VerifyTemplateMapData/Batch_Update") {
 		return
 	}
 
@@ -438,6 +440,153 @@ func (c *VerifyTemplateController) Map_List() {
 	return
 }
 
+// 多任务获取标签列表 -
+func (c *VerifyTemplateController) Map_List_By_TaskIds() {
+	// 验证登录
+	_, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
+	if !User_is {
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	type requestBody struct {
+		TaskIds []string `json:"task_ids"`
+	}
+
+	var body requestBody
+
+	taskIdsParam := c.GetString("task_ids")
+	if len(taskIdsParam) > 0 {
+		body.TaskIds = lib.SplitStringSeparator(taskIdsParam, ",")
+	}
+	T_source, _ := c.GetInt("T_source")
+
+	if len(body.TaskIds) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "任务id不能为空!"}
+		c.ServeJSON()
+		return
+	}
+
+	if T_source == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "T_source Err!"}
+		c.ServeJSON()
+		return
+	}
+
+	cleanTaskIds := make([]string, 0, len(body.TaskIds))
+	seenTaskIds := make(map[string]struct{}, len(body.TaskIds))
+	for _, id := range body.TaskIds {
+		id = strings.TrimSpace(id)
+		if len(id) == 0 {
+			continue
+		}
+		if _, ok := seenTaskIds[id]; ok {
+			continue
+		}
+		seenTaskIds[id] = struct{}{}
+		cleanTaskIds = append(cleanTaskIds, id)
+	}
+
+	if len(cleanTaskIds) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "有效任务id不能为空!"}
+		c.ServeJSON()
+		return
+	}
+
+	tasks, err := Task.Read_Task_List_By_TaskIds(cleanTaskIds)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询任务失败!"}
+		c.ServeJSON()
+		return
+	}
+
+	if len(tasks) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "未查询到任务!"}
+		c.ServeJSON()
+		return
+	}
+
+	foundTaskIds := make(map[string]struct{}, len(tasks))
+	templateIdList := make([]string, 0)
+	templateIdSet := make(map[string]struct{})
+	for _, task := range tasks {
+		foundTaskIds[task.T_task_id] = struct{}{}
+		if len(task.T_VerifyTemplate_id) == 0 {
+			continue
+		}
+		if _, ok := templateIdSet[task.T_VerifyTemplate_id]; ok {
+			continue
+		}
+		templateIdSet[task.T_VerifyTemplate_id] = struct{}{}
+		templateIdList = append(templateIdList, task.T_VerifyTemplate_id)
+	}
+
+	missingTaskIds := make([]string, 0)
+	for _, id := range cleanTaskIds {
+		if _, ok := foundTaskIds[id]; !ok {
+			missingTaskIds = append(missingTaskIds, id)
+		}
+	}
+	if len(missingTaskIds) > 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("任务不存在: %s", strings.Join(missingTaskIds, ","))}
+		c.ServeJSON()
+		return
+	}
+
+	if len(templateIdList) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: []interface{}{}}
+		c.ServeJSON()
+		return
+	}
+
+	type templateTag struct {
+		VerifyTemplate.VerifyTemplateMap_R
+		T_value             string `json:"T_value"`
+		T_VerifyTemplate_id string `json:"T_VerifyTemplate_id"`
+	}
+
+	tagMap := make(map[string]templateTag)
+	for _, templateId := range templateIdList {
+		tagList := VerifyTemplate.Read_VerifyTemplateMap_List_For_Data(templateId, T_source, 0)
+		for _, tag := range tagList {
+			if tag.T_label == 3 || tag.T_label == 4 {
+				continue
+			}
+			if len(tag.T_id) == 0 {
+				continue
+			}
+			if _, ok := tagMap[tag.T_id]; ok {
+				continue
+			}
+			tagMap[tag.T_id] = templateTag{
+				VerifyTemplateMap_R: VerifyTemplate.VerifyTemplateMapToVerifyTemplateMap_R(tag),
+				T_VerifyTemplate_id: templateId,
+			}
+		}
+	}
+
+	if len(tagMap) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: []interface{}{}}
+		c.ServeJSON()
+		return
+	}
+
+	tagIds := make([]string, 0, len(tagMap))
+	for id := range tagMap {
+		tagIds = append(tagIds, id)
+	}
+	sort.Strings(tagIds)
+
+	result := make([]templateTag, 0, len(tagIds))
+	for _, id := range tagIds {
+		result = append(result, tagMap[id])
+	}
+
+	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: result}
+	c.ServeJSON()
+}
+
 // 标签添加-
 func (c *VerifyTemplateController) Map_Add() {
 	// 验证登录 User_is, User_r
@@ -638,22 +787,7 @@ func (c *VerifyTemplateController) Map_Data_List() {
 
 // 添加标签数据
 func (c *VerifyTemplateController) Map_Data_Pu() {
-	//验证登录 User_is, User_r
 	var err error
-	//token := c.Ctx.Request.Header.Get("user_tokey")
-	//User_r, User_is := Account.Verification_Admin(token, "")
-	//if !User_is {
-	//	c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
-	//	c.ServeJSON()
-	//	return
-	//}
-	//err = albb.DescribeInstances()
-	////err := RunInstances(tea.StringSlice(os.Args[1:]))
-	//if err != nil {
-	//	c.Data["json"] = lib.JSONS{Code: 202, Msg: "服务启动失败!"}
-	//	c.ServeJSON()
-	//	return
-	//}
 
 	type RequestBody struct {
 		User_tokey            string
@@ -703,6 +837,7 @@ func (c *VerifyTemplateController) Map_Data_Pu() {
 		task.T_collection_state = Task.TaskCollectionStateSubmitted
 		task.T_collection_submit_time = time.Now().Format("2006-01-02 15:04:05")
 	}
+
 	if !Task.Update_Task(task, "T_step", "T_reporting_state", "T_collection_state", "T_collection_submit_time") {
 		c.Data["json"] = lib.JSONS{Code: 202, Msg: "修改任务步骤失败!"}
 		c.ServeJSON()
@@ -801,6 +936,8 @@ func (c *VerifyTemplateController) Map_Data_Pu() {
 
 	}
 
+	VerifyTemplate.Check_RequiredFields_HaveValue(body.T_task_id)
+
 	System.Add_UserLogs_T(User_r.T_uuid, "验证模版标签数据", "保存", body)
 
 	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: ids}
@@ -808,6 +945,227 @@ func (c *VerifyTemplateController) Map_Data_Pu() {
 	return
 }
 
+// 批量修改多个任务的标签数据
+func (c *VerifyTemplateController) Map_Data_Batch_Update() {
+	var err error
+
+	type VerifyTemplateMapData_R struct {
+		T_id                   string
+		T_VerifyTemplateMap_id string // 标签id
+		T_source               int
+		T_label                int    //
+		T_name                 string // 标题
+		T_value                string //
+		T_Required             int    //
+		T_Construction         int    //
+		// 验证流程
+		T_flow_sort int // 验证流程排序
+		T_max_time  int // 验证流程最大时间
+		T_min_time  int // 验证流程最小时间
+	}
+
+	type RequestBody struct {
+		User_tokey            string
+		T_source              int
+		T_task_ids            []string // 多个任务ID
+		VerifyTemplateMapData []VerifyTemplateMapData_R
+	}
+
+	var body RequestBody
+	data := c.Ctx.Input.RequestBody
+	err = json.Unmarshal(data, &body)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "json返序列化失败:" + err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	logs.Println(fmt.Sprintf("%+v", body))
+
+	User_r, User_is := Account.Verification_Admin(body.User_tokey, "")
+	if !User_is {
+		System.Add_UserLogs_T(User_r.T_uuid, "验证模版标签数据", "未登录-批量修改", body)
+
+		c.Data["json"] = lib.JSONS{Code: 201, Msg: "请重新登录!"}
+		c.ServeJSON()
+		return
+	}
+
+	// 验证任务ID列表
+	if len(body.T_task_ids) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "任务ID列表不能为空!"}
+		c.ServeJSON()
+		return
+	}
+
+	// 验证标签数据
+	if len(body.VerifyTemplateMapData) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "标签数据不能为空!"}
+		c.ServeJSON()
+		return
+	}
+
+	// 验证所有任务是否存在
+	tasks, err := Task.Read_Task_List_By_TaskIds(body.T_task_ids)
+	if err != nil {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "查询任务失败:" + err.Error()}
+		c.ServeJSON()
+		return
+	}
+
+	if len(tasks) == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: "未找到任何任务!"}
+		c.ServeJSON()
+		return
+	}
+
+	// 检查是否有任务不存在
+	foundTaskIds := make(map[string]bool)
+	for _, task := range tasks {
+		foundTaskIds[task.T_task_id] = true
+	}
+
+	missingTaskIds := make([]string, 0)
+	for _, taskId := range body.T_task_ids {
+		if !foundTaskIds[taskId] {
+			missingTaskIds = append(missingTaskIds, taskId)
+		}
+	}
+
+	if len(missingTaskIds) > 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: fmt.Sprintf("以下任务不存在: %s", strings.Join(missingTaskIds, ","))}
+		c.ServeJSON()
+		return
+	}
+
+	// 为每个任务批量更新标签数据
+	successCount := 0
+	failedTasks := make([]string, 0)
+	skippedTasks := make([]string, 0) // 标签名称不匹配的任务
+
+	for _, task := range tasks {
+		// 根据任务的模版ID查询该模版下的所有标签
+		templateMaps, _ := VerifyTemplate.Read_VerifyTemplateMap_List(task.T_VerifyTemplate_id, 0, 0)
+		if len(templateMaps) == 0 {
+			failedTasks = append(failedTasks, task.T_task_id)
+			logs.Error(fmt.Sprintf("任务 %s 的模版ID %s 下没有标签", task.T_task_id, task.T_VerifyTemplate_id))
+			continue
+		}
+
+		// 创建标签名称到标签ID的映射
+		nameToMapId := make(map[string]string)
+		for _, tm := range templateMaps {
+			nameToMapId[tm.T_name] = tm.T_id
+		}
+
+		// 构建该任务的标签数据列表
+		MapDataList := make([]VerifyTemplate.VerifyTemplateMapData, 0)
+		matchedCount := 0
+		unmatchedLabels := make([]string, 0)
+
+		for _, v := range body.VerifyTemplateMapData {
+			// 通过标签名称查找对应的标签ID
+			mapId, exists := nameToMapId[v.T_name]
+			if !exists {
+				unmatchedLabels = append(unmatchedLabels, v.T_name)
+				logs.Info(fmt.Sprintf("任务 %s 的模版中不存在标签名称: %s", task.T_task_id, v.T_name))
+				continue
+			}
+
+			// 查找对应的标签信息以获取标签类型(用于特殊逻辑处理)
+			var templateMap VerifyTemplate.VerifyTemplateMap_R
+			for _, tm := range templateMaps {
+				if tm.T_id == mapId {
+					templateMap = tm
+					break
+				}
+			}
+
+			val := VerifyTemplate.VerifyTemplateMapData{
+				T_source:               v.T_source,
+				T_task_id:              task.T_task_id,
+				T_VerifyTemplate_id:    task.T_VerifyTemplate_id, // 使用任务自己的模版ID
+				T_VerifyTemplateMap_id: mapId,                    // 使用通过名称匹配到的标签ID
+				T_Required:             v.T_Required,             // 使用传入的值
+				T_Construction:         v.T_Construction,         // 使用传入的值
+				T_flow_sort:            v.T_flow_sort,            // 使用传入的值
+				T_max_time:             v.T_max_time,             // 使用传入的值
+				T_min_time:             v.T_min_time,             // 使用传入的值
+				T_value:                v.T_value,                // 使用传入的值
+			}
+			MapDataList = append(MapDataList, val)
+			matchedCount++
+
+			// 处理标签类型16的特殊逻辑
+			if templateMap.T_label == 16 && len(v.T_value) > 0 {
+				verifyTemplateMap, exist := VerifyTemplate.Read_VerifyTemplateMap(mapId)
+				if exist {
+					options := lib.SplitStringSeparator(verifyTemplateMap.T_text, "|")
+					found := false
+					for _, opt := range options {
+						if opt == v.T_value {
+							found = true
+							break
+						}
+					}
+					if !found {
+						verifyTemplateMap.T_text = verifyTemplateMap.T_text + "|" + v.T_value
+						VerifyTemplate.Update_VerifyTemplateMap(verifyTemplateMap, "T_text")
+					}
+				}
+			}
+		}
+
+		// 如果没有任何标签匹配,跳过该任务
+		if matchedCount == 0 {
+			skippedTasks = append(skippedTasks, task.T_task_id)
+			logs.Info(fmt.Sprintf("任务 %s 没有匹配的标签,跳过。未匹配的标签: %s", task.T_task_id, strings.Join(unmatchedLabels, ",")))
+			continue
+		}
+
+		// 批量更新该任务的标签数据(不保存历史,不覆盖)
+		_, is := VerifyTemplate.AddOrUpdate_VerifyTemplateMapData_ADD_History(MapDataList, body.T_source, User_r.T_uuid, 2, 1, 0)
+		if !is {
+			failedTasks = append(failedTasks, task.T_task_id)
+			logs.Error(fmt.Sprintf("任务 %s 标签数据更新失败", task.T_task_id))
+			continue
+		}
+
+		// 检查必填项
+		VerifyTemplate.Check_RequiredFields_HaveValue(task.T_task_id)
+		successCount++
+	}
+
+	// 记录操作日志
+	System.Add_UserLogs_T(User_r.T_uuid, "验证模版标签数据", "批量修改", fmt.Sprintf("任务数量:%d, 成功:%d, 失败:%d, 跳过:%d", len(body.T_task_ids), successCount, len(failedTasks), len(skippedTasks)))
+
+	// 返回结果
+	result := map[string]interface{}{
+		"total":        len(body.T_task_ids),
+		"success":      successCount,
+		"failed":       len(failedTasks),
+		"skipped":      len(skippedTasks),
+		"failedTasks":  failedTasks,
+		"skippedTasks": skippedTasks,
+	}
+
+	msg := fmt.Sprintf("成功:%d, 失败:%d, 跳过:%d", successCount, len(failedTasks), len(skippedTasks))
+	if len(failedTasks) > 0 {
+		msg += fmt.Sprintf(" (失败任务: %s)", strings.Join(failedTasks, ","))
+	}
+	if len(skippedTasks) > 0 {
+		msg += fmt.Sprintf(" (跳过任务: %s)", strings.Join(skippedTasks, ","))
+	}
+
+	if len(failedTasks) > 0 || successCount == 0 {
+		c.Data["json"] = lib.JSONS{Code: 202, Msg: msg, Data: result}
+	} else {
+		c.Data["json"] = lib.JSONS{Code: 200, Msg: msg, Data: result}
+	}
+	c.ServeJSON()
+	return
+}
+
 // 相同模版id复制标签数据
 func (c *VerifyTemplateController) Map_Data_Copy2() {
 	// 验证登录 User_is, User_r
@@ -925,6 +1283,8 @@ func (c *VerifyTemplateController) Map_Data_Copy() {
 		return
 	}
 
+	VerifyTemplate.Check_RequiredFields_HaveValue(T_paste_task_id)
+
 	System.Add_UserLogs_T(User_r.T_uuid, "验证模版标签数据", "通过标签名称复制", fmt.Sprintf("copy_task_id:%s | paste_task_id:%s", T_copy_task_id, T_paste_task_id))
 
 	c.Data["json"] = lib.JSONS{Code: 200, Msg: "ok!", Data: ids}
@@ -1226,6 +1586,7 @@ func (c *VerifyTemplateController) Class_List() {
 	c.ServeJSON()
 	return
 }
+
 func (c *VerifyTemplateController) Class_Add() {
 	// 验证登录 User_is, User_r
 	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
@@ -1257,6 +1618,7 @@ func (c *VerifyTemplateController) Class_Add() {
 	c.ServeJSON()
 	return
 }
+
 func (c *VerifyTemplateController) Class_Up() {
 	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
 	if !User_is {
@@ -1291,6 +1653,7 @@ func (c *VerifyTemplateController) Class_Up() {
 	c.ServeJSON()
 	return
 }
+
 func (c *VerifyTemplateController) Class_Del() {
 	User_r, User_is := Account.Verification_Admin(c.Ctx.GetCookie("User_tokey"), c.GetString("User_tokey"))
 	if !User_is {

+ 37 - 4
models/Task/Task.go

@@ -193,13 +193,13 @@ type Task struct {
 	T_collection             string `orm:"size(256);null"`     // 数据采集 负责人UUID
 	T_reporting              string `orm:"size(256);null"`     // 报告编写 负责人UUID
 	T_delivery               string `orm:"size(256);null"`     // 交付审核 负责人UUID
-	T_scheme_state           int    `orm:"size(2);default(0)"` // 实施方案 状态 0 未完成 1 已完成(客户通过) 2已退回(客户) 3已通过(负责人) 4已退回(负责人) 5已提交
+	T_scheme_state           int    `orm:"size(2);default(0)"` // 实施方案 状态 0 未完成 1 已完成(客户通过) 2已退回(客户) 3已通过(负责人) 4已退回(负责人) 5已提交 10 必填项已填写
 	T_collection_state       int    `orm:"size(2);default(0)"` // 数据采集 状态 0 未完成 1 数据来源已完成 2 处理中 3 已采集-无数据 4 APP已提交 5已通过(负责人) 6已退回(负责人)
-	T_reporting_state        int    `orm:"size(2);default(0)"` // 报告编写 状态 0 未完成 1 已完成(客户通过) 2已退回(客户) 3已通过(负责人) 4已退回(负责人) 5已提交 6已点报告生成
+	T_reporting_state        int    `orm:"size(2);default(0)"` // 报告编写 状态 0 未完成 1 已完成(客户通过) 2已退回(客户) 3已通过(负责人) 4已退回(负责人) 5已提交 6已点报告生成 10 必填项已填写
 	T_delivery_state         int    `orm:"size(2);default(0)"` // 交付审核 状态 0 未完成 1 已完成 2 处理中
 	T_marking_state          int    `orm:"size(2);default(0)"` // 验证标识 状态 0 未完成 1 已完成
-	T_examining_report_state int    `orm:"size(2);default(0)"` // 检测报告 状态 0 未完成 1 已完成(客户通过) 2已退回(客户) 3已通过(负责人) 4已退回(负责人) 5已提交
-	T_original_record_state  int    `orm:"size(2);default(0)"` // 原始记录 状态 0 未完成 3 已通过(负责人) 4已退回(负责人) 5已提交
+	T_examining_report_state int    `orm:"size(2);default(0)"` // 检测报告 状态 0 未完成 1 已完成(客户通过) 2已退回(客户) 3已通过(负责人) 4已退回(负责人) 5已提交 10 必填项已填写
+	T_original_record_state  int    `orm:"size(2);default(0)"` // 原始记录 状态 0 未完成 3 已通过(负责人) 4已退回(负责人) 5已提交 10 必填项已填写
 	T_record                 string `orm:"type(text);null"`    // 领导备注
 
 	T_collection_submit_time string `orm:"size(256);null"` // 数据采集 提交时间
@@ -586,6 +586,8 @@ func TaskToTask_(T Task, userMap, adminMap map[string]string) (T_ Task_) {
 	T_.T_reporting_state = T.T_reporting_state
 	T_.T_delivery_state = T.T_delivery_state
 	T_.T_marking_state = T.T_marking_state
+	T_.T_examining_report_state = T.T_examining_report_state
+	T_.T_original_record_state = T.T_original_record_state
 	T_.T_scheme_state_str = TaskSchemeStateMap[T.T_scheme_state]
 	T_.T_collection_state_str = TaskCollectionStateMap[T.T_collection_state]
 	T_.T_reporting_state_str = TaskReportingStateMap[T.T_reporting_state]
@@ -870,6 +872,37 @@ func Read_Task(T_task_id string) (r Task, is bool) {
 	return r, true
 }
 
+// 批量获取任务
+func Read_Task_List_By_TaskIds(taskIds []string) ([]Task, error) {
+	cleanIds := make([]string, 0, len(taskIds))
+	seen := make(map[string]struct{}, len(taskIds))
+	for _, id := range taskIds {
+		id = strings.TrimSpace(id)
+		if len(id) == 0 {
+			continue
+		}
+		if _, ok := seen[id]; ok {
+			continue
+		}
+		seen[id] = struct{}{}
+		cleanIds = append(cleanIds, id)
+	}
+
+	if len(cleanIds) == 0 {
+		return []Task{}, nil
+	}
+
+	o := orm.NewOrm()
+	var tasks []Task
+	_, err := o.QueryTable(new(Task)).Filter("T_task_id__in", cleanIds).Filter("T_State", 1).All(&tasks)
+	if err != nil {
+		logs.Error(lib.FuncName(), err)
+		return nil, err
+	}
+
+	return tasks, nil
+}
+
 // 获取 By T_uid
 func Read_Task_ByUid(T_uid string) (r Task, is bool) {
 	o := orm.NewOrm()

+ 61 - 1
models/VerifyTemplate/VerifyTemplateMapData.go

@@ -425,6 +425,8 @@ func Clear_VerifyTemplateMapData_T_value(T_task_id, T_VerifyTemplate_id, T_Verif
 // 检查T_source=1和T_source=2的必填项是否都有值
 // 如果T_source=1(方案)必填项全部有数据,则修改Task的T_scheme_state为10
 // 如果T_source=2(报告)必填项全部有数据,则修改Task的T_reporting_state为10
+// 如果T_source=4(检测报告)必填项全部有数据,则修改Task的T_examining_report_state为10
+// 如果T_source=5(原始记录)必填项全部有数据,则修改Task的T_original_record_state为10
 func Check_RequiredFields_HaveValue(T_task_id string) bool {
 	o := orm.NewOrm()
 
@@ -452,6 +454,22 @@ func Check_RequiredFields_HaveValue(T_task_id string) bool {
 	cond2 = cond2.And("T_VerifyTemplate_id", T_VerifyTemplate_id).And("T_Required", 1).And("T_source__in", []int{0, 2, 3, 7})
 	qs_map2.SetCond((*orm2.Condition)(cond2)).All(&requiredMaps_source2)
 
+	// 查询T_source=4的所有必填项(T_Required=1)
+	// T_source=4对应检测报告,包含source: 0,5,8
+	var requiredMaps_source4 []VerifyTemplateMap
+	qs_map4 := o.QueryTable(new(VerifyTemplateMap))
+	cond4 := orm.NewCondition()
+	cond4 = cond4.And("T_VerifyTemplate_id", T_VerifyTemplate_id).And("T_Required", 1).And("T_source__in", []int{0, 5, 8})
+	qs_map4.SetCond((*orm2.Condition)(cond4)).All(&requiredMaps_source4)
+
+	// 查询T_source=5的所有必填项(T_Required=1)
+	// T_source=5对应原始记录,包含source: 0,6,8
+	var requiredMaps_source5 []VerifyTemplateMap
+	qs_map5 := o.QueryTable(new(VerifyTemplateMap))
+	cond5 := orm.NewCondition()
+	cond5 = cond5.And("T_VerifyTemplate_id", T_VerifyTemplate_id).And("T_Required", 1).And("T_source__in", []int{0, 6, 8})
+	qs_map5.SetCond((*orm2.Condition)(cond5)).All(&requiredMaps_source5)
+
 	// 查询所有数据
 	var allData []VerifyTemplateMapData
 	qs_data := o.QueryTable(new(VerifyTemplateMapData))
@@ -493,6 +511,34 @@ func Check_RequiredFields_HaveValue(T_task_id string) bool {
 		}
 	}
 
+	// 检查T_source=4的必填项是否都有值
+	source4Complete := true
+	for _, mapItem := range requiredMaps_source4 {
+		data, exists := dataMap[mapItem.T_id]
+		if !exists {
+			source4Complete = false
+			break
+		}
+		if len(strings.TrimSpace(data.T_value)) == 0 {
+			source4Complete = false
+			break
+		}
+	}
+
+	// 检查T_source=5的必填项是否都有值
+	source5Complete := true
+	for _, mapItem := range requiredMaps_source5 {
+		data, exists := dataMap[mapItem.T_id]
+		if !exists {
+			source5Complete = false
+			break
+		}
+		if len(strings.TrimSpace(data.T_value)) == 0 {
+			source5Complete = false
+			break
+		}
+	}
+
 	// 更新状态
 	updateCols := make([]string, 0)
 	needUpdate := false
@@ -511,6 +557,20 @@ func Check_RequiredFields_HaveValue(T_task_id string) bool {
 		needUpdate = true
 	}
 
+	// 如果T_source=4(检测报告)必填项全部有数据,则修改T_examining_report_state为10
+	if source4Complete && task.T_examining_report_state != 10 {
+		task.T_examining_report_state = 10
+		updateCols = append(updateCols, "T_examining_report_state")
+		needUpdate = true
+	}
+
+	// 如果T_source=5(原始记录)必填项全部有数据,则修改T_original_record_state为10
+	if source5Complete && task.T_original_record_state != 10 {
+		task.T_original_record_state = 10
+		updateCols = append(updateCols, "T_original_record_state")
+		needUpdate = true
+	}
+
 	// 执行更新
 	if needUpdate {
 		if !Task.Update_Task(task, updateCols...) {
@@ -519,5 +579,5 @@ func Check_RequiredFields_HaveValue(T_task_id string) bool {
 		}
 	}
 
-	return source1Complete && source2Complete
+	return source1Complete && source2Complete && source4Complete && source5Complete
 }

+ 2 - 0
routers/VerifyTemplate.go

@@ -29,6 +29,7 @@ func init() {
 	beego.Router("/VerifyTemplate/Get", &controllers.VerifyTemplateController{}, "*:Get")   // 模版修改
 	beego.Router("/VerifyTemplate/Copy", &controllers.VerifyTemplateController{}, "*:Copy") // 模版复制
 
+	beego.Router("/VerifyTemplate/Map_List_By_TaskIds", &controllers.VerifyTemplateController{}, "*:Map_List_By_TaskIds")     // 多任务标签列表
 	beego.Router("/VerifyTemplate/Map_List", &controllers.VerifyTemplateController{}, "*:Map_List")                           // 标签列表
 	beego.Router("/VerifyTemplate/Map_Add", &controllers.VerifyTemplateController{}, "*:Map_Add")                             // 标签添加
 	beego.Router("/VerifyTemplate/Map_Up", &controllers.VerifyTemplateController{}, "*:Map_Up")                               // 标签修改
@@ -38,6 +39,7 @@ func init() {
 
 	beego.Router("/VerifyTemplateMapData/List", &controllers.VerifyTemplateController{}, "*:Map_Data_List")                           // 标签数据列表
 	beego.Router("/VerifyTemplateMapData/Pu", &controllers.VerifyTemplateController{}, "*:Map_Data_Pu")                               // 添加标签数据
+	beego.Router("/VerifyTemplateMapData/Batch_Update", &controllers.VerifyTemplateController{}, "*:Map_Data_Batch_Update")           // 批量修改多个任务的标签数据
 	beego.Router("/VerifyTemplateMapData/Copy", &controllers.VerifyTemplateController{}, "*:Map_Data_Copy")                           // 复制标签数据
 	beego.Router("/VerifyTemplateMapData/Clear_Value", &controllers.VerifyTemplateController{}, "*:Map_Data_Clear_Value")             // 复制标签数据
 	beego.Router("/VerifyTemplateMapData/History_List", &controllers.VerifyTemplateController{}, "*:Map_Data_History_List")           // 历史提交列表