caipin 4 年之前
父節點
當前提交
0b9c101351

+ 25 - 3
comm/functions.go

@@ -87,12 +87,14 @@ func HaveChildContract(Data []*viewmodels.FolderContract, node *viewmodels.Folde
 
 // 创建合同项目节树
 func MakeSectionContract(Data []*viewmodels.TreeSectionContract, node *viewmodels.TreeSectionContract) { //参数为父节点,添加父节点的子节点指针切片
-	childs, _ := HaveChildSectionContract(Data, node) //判断节点是否有子节点并返回
+	childs, _ := haveChildSectionContract(Data, node) //判断节点是否有子节点并返回
 	if childs != nil {
 		// 往父节点添加子节点
+		// 孩子们从小到大排序
+		sectionSelectionSort(childs)
 		node.Children = append(node.Children, childs[0:]...) //添加子节点
 		for _, v := range childs {                           //查询子节点的子节点,并添加到子节点
-			_, has := HaveChildSectionContract(Data, v)
+			_, has := haveChildSectionContract(Data, v)
 			if has {
 				// 递归添加节点
 				MakeSectionContract(Data, v)
@@ -101,8 +103,28 @@ func MakeSectionContract(Data []*viewmodels.TreeSectionContract, node *viewmodel
 	}
 }
 
+// 合同项目节孩子排序
+func sectionSelectionSort(child []*viewmodels.TreeSectionContract) {
+	for i := 0; i < len(child); i++ {
+		minIndex := i
+		// 查找最小值
+		for j := i; j < len(child); j++ {
+			if child[j].Serial < child[minIndex].Serial {
+				minIndex = j
+			}
+		}
+		swapContract(child, i, minIndex)
+	}
+}
+
+func swapContract(child []*viewmodels.TreeSectionContract, i int, minIndex int) {
+	t := child[i]
+	child[i] = child[minIndex]
+	child[minIndex] = t
+}
+
 // 是否有子树
-func HaveChildSectionContract(Data []*viewmodels.TreeSectionContract, node *viewmodels.TreeSectionContract) (child []*viewmodels.TreeSectionContract, yes bool) {
+func haveChildSectionContract(Data []*viewmodels.TreeSectionContract, node *viewmodels.TreeSectionContract) (child []*viewmodels.TreeSectionContract, yes bool) {
 	for _, v := range Data {
 		if v.ParentId == node.Id {
 			child = append(child, v)

+ 309 - 2
dao/tree_contract_dao.go

@@ -7,6 +7,11 @@
 package dao
 
 import (
+	"errors"
+	"fmt"
+	"log"
+	"strings"
+
 	"github.com/go-xorm/xorm"
 	"go.mod/models"
 )
@@ -23,12 +28,68 @@ func NewTreeContractDao(engine *xorm.Engine) *TreeContractDao {
 	}
 }
 
+// 获得本项目的合同项目节
+func (d *TreeContractDao) Get(treeId int, bidsectionId int, projectId int) *models.CmTreeContracts {
+
+	data := &models.CmTreeContracts{}
+	_, err := d.engine.
+		Where("tree_id=? and bidsection_id =? and project_id=? ", treeId, bidsectionId, projectId).
+		Get(data)
+	if err != nil {
+		data.Id = 0
+		return data
+	}
+	return data
+}
+
 // 获得项目下的项目节
-func (d *TreeContractDao) GetAll(projectId int) []models.CmTreeContracts {
+func (d *TreeContractDao) GetAll(bidsectionId int, projectId int) []models.CmTreeContracts {
 	datalist := make([]models.CmTreeContracts, 0)
 	err := d.engine.
 		Asc("id").
-		Where("project_id=?", projectId).
+		Where("bidsection_id =? and project_id=?", bidsectionId, projectId).
+		Find(&datalist)
+	if err != nil {
+		return datalist
+	} else {
+		return datalist
+	}
+}
+
+// 获得节点的孩子
+func (d *TreeContractDao) GetChildren(parentId int, bidsectionId int, projectId int) []models.CmTreeContracts {
+	datalist := make([]models.CmTreeContracts, 0)
+	err := d.engine.
+		Asc("serial").
+		Where("parent_id=?  and bidsection_id=? and project_id=?", parentId, bidsectionId, projectId).
+		Find(&datalist)
+	if err != nil {
+		return datalist
+	} else {
+		return datalist
+	}
+}
+
+//根据序号和深度获得前一个兄弟节点
+func (d *TreeContractDao) GetElderBrother(serial int, depth int, parentId int, bidsectionId int, projectId int) []models.CmTreeContracts {
+	datalist := make([]models.CmTreeContracts, 0)
+	err := d.engine.
+		Desc("serial").
+		Where("serial < ? and depth = ? and bidsection_id=?  and project_id=?", serial, depth, bidsectionId, projectId).
+		Find(&datalist)
+	if err != nil {
+		return datalist
+	} else {
+		return datalist
+	}
+}
+
+//根据序号和深度获得后一个兄弟节点
+func (d *TreeContractDao) GetYoungerBrother(serial int, depth int, parentId int, bidsectionId int, projectId int) []models.CmTreeContracts {
+	datalist := make([]models.CmTreeContracts, 0)
+	err := d.engine.
+		Asc("serial").
+		Where("serial > ? and depth = ? and bidsection_id=?  and project_id=?", serial, depth, bidsectionId, projectId).
 		Find(&datalist)
 	if err != nil {
 		return datalist
@@ -51,8 +112,254 @@ func (d *TreeContractDao) GetLast(projectId int) *models.CmTreeContracts {
 	return data
 }
 
+// 获得谋归属下的项目节
+func (d *TreeContractDao) GetAttribution(attribution string, projectId int, bidsectionId int) []models.CmTreeContracts {
+	datalist := make([]models.CmTreeContracts, 0)
+	err := d.engine.
+		Asc("serial").
+		Where("attribution like ? and project_id=? and bidsection_id=?", attribution+"%", projectId, bidsectionId).
+		Find(&datalist)
+	if err != nil {
+		return datalist
+	} else {
+		return datalist
+	}
+}
+
+// 项目节升降级
+func (d *TreeContractDao) MoveDepth(section *models.CmTreeContracts, elderBrother *models.CmTreeContracts, operation string, bidsectionId int, projectId int) error {
+
+	session := d.engine.NewSession()
+	defer session.Close()
+	err := session.Begin()
+	if err != nil {
+		return errors.New("操作失败-db")
+	}
+	// 降级
+	if operation == "downDepth" {
+		// 1.前一个兄弟节点
+		// fmt.Println(elderBrother)
+		// 2.把节点移动到兄弟节点的下级,成为兄弟的孩子
+		// 2-1 节点的父亲为兄弟的ID
+		// 2-2 节点的深度 +1
+		// 2-3 节点归属为兄弟归属+序号
+		attribution := fmt.Sprintf("%s%d-", elderBrother.Attribution, elderBrother.Serial)
+		// 2-4 序号为1
+		// 2-5 项目节编号
+		// 原编号
+		// section.Code
+		// 移动后编号
+		moveCode := attribution + "1"
+		_, err = session.Exec("UPDATE  cm_tree_contracts SET `parent_id` = ?,attribution= ? , serial = ? ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"')"+
+			",`depth` =`depth` + ? where id = ? ", elderBrother.TreeId, attribution, 1, 1, section.Id)
+		if err != nil {
+			session.Rollback()
+			return errors.New("降级失败")
+		}
+		// 3.更新节点下的归属
+		// 3-1 节点的所有孩子的归属
+		// 原节点 孩子的归属
+		attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
+		// 降级后的 孩子归属
+		moveAttributionChildren := fmt.Sprintf("%s%d-", attribution, 1)
+		// 3-2 降级 深度+1
+		_, err = session.Exec("UPDATE  cm_tree_contracts SET  "+
+			"`depth` =`depth` + ? where attribution like ? and project_id=? and bidsection_id=? ", 1, attributionChildren+"%", projectId, bidsectionId)
+		if err != nil {
+			session.Rollback()
+			return errors.New("降级失败")
+		}
+		// 3-3--替换 归属和编号
+		// "`attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"'),"
+		err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, moveCode, projectId, bidsectionId)
+		if err != nil {
+			session.Rollback()
+			return errors.New("降级失败")
+		}
+	} else if operation == "upDepth" {
+		// 升级
+		// 1.父亲节点
+		sectionFather := d.Get(section.ParentId, bidsectionId, projectId)
+		if sectionFather.Id == 0 {
+			session.Rollback()
+			return errors.New("升级-未找到上级项目节")
+		}
+		// 2.原节点的父亲ID字段升级为爷爷ID
+		// 2-1 升级 深度-1
+		// 2-2 序号 原父亲的序号+1
+		// 2-3 归属 原父亲的归属
+		// 移动后编号-需替换原编号 节点2-1-1 升级后的父节点归属 2- 加上父节点的序号+1 1+1=2 2-2
+		moveCode := fmt.Sprintf("%s%d", sectionFather.Attribution, sectionFather.Serial+1)
+		_, err = session.Exec("UPDATE  cm_tree_contracts SET `parent_id` = ?,attribution= ? , serial = ? ,`code` = replace(`code`, '"+section.Code+"', '"+moveCode+"')"+
+			",`depth` =`depth` - ? where id = ? ", sectionFather.ParentId, sectionFather.Attribution, sectionFather.Serial+1, 1, section.Id)
+		if err != nil {
+			session.Rollback()
+			return errors.New("升级失败")
+		}
+		// 3.更新节点下的归属,深度
+		// 原节点 孩子的归属
+		attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
+		// 升级后的 孩子归属
+		moveAttributionChildren := fmt.Sprintf("%s%d-", sectionFather.Attribution, sectionFather.Serial+1)
+		// 深度 -1
+		_, err = session.Exec("UPDATE  cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+
+			",`depth` =`depth` - ? where attribution like ? and project_id=? and bidsection_id=? ", 1, attributionChildren+"%", projectId, bidsectionId)
+		if err != nil {
+			session.Rollback()
+			return errors.New("升级失败")
+		}
+		// 3-1
+		err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, moveCode, projectId, bidsectionId)
+		if err != nil {
+			session.Rollback()
+			return errors.New("升级失败")
+		}
+
+	} else {
+		return errors.New("参数错误")
+	}
+
+	err = session.Commit()
+	if err != nil {
+		session.Rollback()
+		return errors.New("操作失败-db")
+	}
+	return nil
+}
+
+// 合同项目节上下移动
+func (d *TreeContractDao) MoveSerial(section *models.CmTreeContracts, brother *models.CmTreeContracts, operation string, bidsectionId int, projectId int) error {
+	session := d.engine.NewSession()
+	defer session.Close()
+	err := session.Begin()
+	if err != nil {
+		return errors.New("操作失败-db")
+	}
+
+	//1.上下移
+	// 1.项目节序号替换为兄弟序号
+	_, err = session.Exec("UPDATE  cm_tree_contracts SET  serial = ? , `code` = replace(`code`, '"+section.Code+"', '"+brother.Code+"')  where id = ? ", brother.Serial, section.Id)
+	if err != nil {
+		session.Rollback()
+		return errors.New("移动失败")
+	}
+	// 兄弟序号替换为项目节序号
+	_, err = session.Exec("UPDATE  cm_tree_contracts SET  serial = ? , `code` = replace(`code`, '"+brother.Code+"', '"+section.Code+"')  where id = ? ", section.Serial, brother.Id)
+	if err != nil {
+		session.Rollback()
+		return errors.New("移动失败")
+	}
+	//2.项目节孩子们 归属设置
+	// 原节点 孩子的归属
+	attributionChildren := fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
+	// 移动后的 孩子归属和编号
+	moveAttributionChildren := fmt.Sprintf("%s%d-", brother.Attribution, brother.Serial)
+
+	err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, section.Code, brother.Code, projectId, bidsectionId)
+	if err != nil {
+		session.Rollback()
+		return errors.New("移动失败")
+	}
+
+	// _, err = session.Exec("UPDATE  cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+
+	// 	"`code` = replace(`code`, '"+attributionChildren+"', '"+moveAttributionChildren+"') where attribution like ? and project_id=? and bidsection_id=? ", attributionChildren+"%", projectId, bidsectionId)
+	// if err != nil {
+	// 	session.Rollback()
+	// 	return errors.New("移动失败")
+	// }
+
+	// 3.兄弟节点孩子们 归属设置
+	// 兄弟节点 孩子的归属
+	attributionChildren = fmt.Sprintf("%s%d-", brother.Attribution, brother.Serial)
+	// 移动后的 孩子归属
+	moveAttributionChildren = fmt.Sprintf("%s%d-", section.Attribution, section.Serial)
+	err = d.replaceContractAttribution(session, attributionChildren, moveAttributionChildren, brother.Code, section.Code, projectId, bidsectionId)
+	if err != nil {
+		session.Rollback()
+		return errors.New("移动失败")
+	}
+	// _, err = session.Exec("UPDATE  cm_tree_contracts SET `attribution` = replace(`attribution`, '"+attributionChildren+"', '"+moveAttributionChildren+"') "+
+	// 	"`code` = replace(`code`, '"+attributionChildren+"', '"+moveAttributionChildren+"') where attribution like ? and project_id=? and bidsection_id=? ", attributionChildren+"%", projectId, bidsectionId)
+	// if err != nil {
+	// 	session.Rollback()
+	// 	return errors.New("移动失败")
+	// }
+	//
+
+	// 上移
+	// if operation == "upSerial" {
+	// 	// 1.上一个大兄弟
+	// 	// fmt.Println(brother)
+	// 	// 2.项目节 序号 兄弟的序号
+	// 	_, err = session.Exec("UPDATE  cm_tree_contracts SET  serial = ? "+
+	// 		" where id = ? ", brother.Serial, section.Id)
+	// 	if err != nil {
+	// 		session.Rollback()
+	// 		return errors.New("上移失败")
+	// 	}
+	// 	// 3.兄弟的序号为 项目节序号
+	// 	_, err = session.Exec("UPDATE  cm_tree_contracts SET  serial = ? "+
+	// 		" where id = ? ", section.Serial, brother.Id)
+	// 	if err != nil {
+	// 		session.Rollback()
+	// 		return errors.New("上移失败")
+	// 	}
+
+	// } else if operation == "downSerial" {
+	// 	// 下移
+	// 	// 1.下一个兄弟
+	// 	// fmt.Println(brother)
+	// 	// 2.项目节 序号 兄弟的序号
+
+	// } else {
+	// 	return errors.New("参数错误")
+	// }
+
+	err = session.Commit()
+	if err != nil {
+		session.Rollback()
+		return errors.New("操作失败-db")
+	}
+	return nil
+}
+
 // 插入多条数据
 func (d *TreeContractDao) CreateAll(data []*models.CmTreeContracts) error {
 	_, err := d.engine.Insert(data)
 	return err
 }
+
+//替换项目节归属
+func (d *TreeContractDao) replaceContractAttribution(session *xorm.Session, attributionChildren string, moveAttributionChildren string, code string, moveCode string, projectId int, bidsectionId int) error {
+	// 1.获得需要替换的数据
+	sectionData := d.GetAttribution(attributionChildren, projectId, bidsectionId)
+	if len(sectionData) == 0 {
+		return nil
+	}
+
+	attributionSql := " attribution = case id "
+	codeSql := " code = case id "
+	idList := make([]int, 0)
+	for _, item := range sectionData {
+		// section := &models.CmTreeContracts{}
+		// section.Id = item.Id
+		// 替换归属
+		attributionSql += fmt.Sprintf("when %d then '%s' ", item.Id, strings.Replace(item.Attribution, attributionChildren, moveAttributionChildren, 1))
+		//section.Attribution = strings.Replace(item.Attribution, attributionChildren, moveAttributionChildren, 1)
+		// 替换编号
+		codeSql += fmt.Sprintf("when %d then '%s' ", item.Id, strings.Replace(item.Code, code, moveCode, 1))
+		// section.Code = strings.Replace(item.Code, code, moveCode, 1)
+		idList = append(idList, item.Id)
+	}
+	attributionSql += " end, "
+	codeSql += " end "
+	id := strings.Replace(strings.Trim(fmt.Sprint(idList), "[]"), " ", ",", -1)
+	sql := "update cm_tree_contracts set  " + attributionSql + codeSql + " WHERE id IN (" + id + ")"
+
+	_, err := session.Exec(sql)
+	if err != nil {
+		log.Println("替换项目节归属, error=", err)
+		return err
+	}
+	return nil
+}

+ 42 - 0
dao/tree_dao.go

@@ -9,6 +9,7 @@ package dao
 import (
 	"errors"
 	"fmt"
+	"log"
 	"strconv"
 	"strings"
 
@@ -143,6 +144,20 @@ func (d *TreeDao) GetBidParentId(bidsectionId int, projectId int) *models.CmTree
 	return data
 }
 
+// 获得谋归属下的项目节
+func (d *TreeDao) GetAttribution(attribution string, projectId int, bidsectionId int) []models.CmTree {
+	datalist := make([]models.CmTree, 0)
+	err := d.engine.
+		Asc("serial").
+		Where("attribution like ? and project_id=? and bidsection_id=?", attribution+"%", projectId, bidsectionId).
+		Find(&datalist)
+	if err != nil {
+		return datalist
+	} else {
+		return datalist
+	}
+}
+
 // 删除目录以及下属目录所有数据
 func (d *TreeDao) DeleteFolderAndBid(id int, projectId int, attribution string) error {
 
@@ -330,3 +345,30 @@ func (d *TreeDao) Update(data *models.CmTree, columns []string) error {
 	_, err := d.engine.Id(data.Id).MustCols(columns...).Update(data)
 	return err
 }
+
+//替换项目节归属
+func (d *TreeDao) replaceContractAttribution(session *xorm.Session, attributionChildren string, moveAttributionChildren string, projectId int, bidsectionId int) error {
+	// 1.获得需要替换的数据
+	sectionData := d.GetAttribution(attributionChildren, projectId, bidsectionId)
+	if len(sectionData) == 0 {
+		return nil
+	}
+
+	attributionSql := " attribution = case id "
+	idList := make([]int, 0)
+	for _, item := range sectionData {
+		// 替换归属
+		attributionSql += fmt.Sprintf("when %d then '%s' ", item.Id, strings.Replace(item.Attribution, attributionChildren, moveAttributionChildren, 1))
+		idList = append(idList, item.Id)
+	}
+	attributionSql += " end "
+	id := strings.Replace(strings.Trim(fmt.Sprint(idList), "[]"), " ", ",", -1)
+	sql := "update cm_tree set  " + attributionSql + " WHERE id IN (" + id + ")"
+
+	_, err := session.Exec(sql)
+	if err != nil {
+		log.Println("替换标段归属, error=", err)
+		return err
+	}
+	return nil
+}

+ 117 - 12
services/contract_service.go

@@ -8,6 +8,7 @@ package services
 
 import (
 	"errors"
+	"fmt"
 	"log"
 	"strconv"
 	"time"
@@ -19,17 +20,21 @@ import (
 	"go.mod/datasource"
 	"go.mod/lib"
 	"go.mod/models"
+	"go.mod/web/utils"
 	"go.mod/web/viewmodels"
 )
 
 //定义项目用户Service接口
 type ContractService interface {
-	ValidRule(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
+	ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
+	ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error)
 	// Create(viewBidAccount viewmodels.BidAccount, projectId int) error
 	// Delete(viewBidAccount viewmodels.BidAccount, projectId int) error
 	GetAll()
-	GetSeciontTree(projectId int) *viewmodels.TreeSectionContract
-	SetSection(templateNumber int, projectIdInt int) error
+	GetSeciontTree(bidsectionId int, projectId int) *viewmodels.TreeSectionContract
+	SetSection(templateNumber int, bidsectionId int, projectIdInt int) error
+	MoveDepth(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int) error
+	MoveSerial(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int) error
 }
 
 //返回service操作类
@@ -54,8 +59,8 @@ func NewContractService() ContractService {
 	}
 }
 
-// 文件夹规则验证
-func (s *contractService) ValidRule(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
+// 升级降级规则验证
+func (s *contractService) ValidRuleDepth(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
 	treeSectionVaild := &viewmodels.TreeSectionContract{}
 	err := ctx.ReadJSON(treeSectionVaild)
 	if err != nil {
@@ -63,9 +68,27 @@ func (s *contractService) ValidRule(ctx iris.Context) (*viewmodels.TreeSectionCo
 		return treeSectionVaild, err
 	}
 
-	err = treeSectionVaild.Validate()
+	err = treeSectionVaild.ValidateDepth()
 	if err != nil {
-		log.Println("文件夹验证, error=", err)
+		log.Println("参数验证错误, error=", err)
+		return treeSectionVaild, err
+	}
+
+	return treeSectionVaild, nil
+}
+
+// 模板规则验证
+func (s *contractService) ValidRuleTemplate(ctx iris.Context) (*viewmodels.TreeSectionContract, error) {
+	treeSectionVaild := &viewmodels.TreeSectionContract{}
+	err := ctx.ReadJSON(treeSectionVaild)
+	if err != nil {
+		log.Println("folder-ValidRule-ReadForm转换异常, error=", err)
+		return treeSectionVaild, err
+	}
+
+	err = treeSectionVaild.ValidateTemplate()
+	if err != nil {
+		log.Println("参数验证错误, error=", err)
 		return treeSectionVaild, err
 	}
 
@@ -78,9 +101,9 @@ func (s *contractService) GetAll() {
 }
 
 // 获得合同项目节
-func (s *contractService) GetSeciontTree(projectId int) *viewmodels.TreeSectionContract {
+func (s *contractService) GetSeciontTree(bidsectionId int, projectId int) *viewmodels.TreeSectionContract {
 	sectionList := make([]*viewmodels.TreeSectionContract, 0)
-	dataList := s.treeContractDao.GetAll(projectId)
+	dataList := s.treeContractDao.GetAll(bidsectionId, projectId)
 	// 生成根
 	sectionRoot := &viewmodels.TreeSectionContract{}
 	id, _ := comm.AesEncrypt(strconv.Itoa(0), conf.SignSecret)
@@ -100,6 +123,8 @@ func (s *contractService) GetSeciontTree(projectId int) *viewmodels.TreeSectionC
 		section.ParentId = parentId
 		section.Depth = data.Depth + 1
 		section.Serial = data.Serial
+		section.Attribution = data.Attribution
+		section.Code = data.Code
 		section.ProjectId = projectId
 		section.ContractId = contractId
 
@@ -120,7 +145,7 @@ func (s *contractService) GetSeciontTree(projectId int) *viewmodels.TreeSectionC
 }
 
 // 设置合同项目节初始数据-根据模板导入
-func (s *contractService) SetSection(templateNumber int, projectIdInt int) error {
+func (s *contractService) SetSection(templateNumber int, bidsectionId int, projectId int) error {
 	// 获得模板数据
 	templateTree := make([]*lib.ItemSectionTemplateTree, 0)
 	if templateNumber == 1 {
@@ -137,12 +162,13 @@ func (s *contractService) SetSection(templateNumber int, projectIdInt int) error
 		section := &models.CmTreeContracts{}
 		section.TreeId = item.Id
 		section.ParentId = item.ParentId
-		section.ProjectId = projectIdInt
+		section.ProjectId = projectId
+		section.BidsectionId = bidsectionId
 		section.Name = item.Name
 		section.Depth = item.Depth
 		section.Serial = item.Serial
 		section.Attribution = item.Attribution
-
+		section.Code = fmt.Sprintf("%s%d", item.Attribution, item.Serial)
 		section.CreateTime = time.Now()
 
 		section.ContractPrice = "0"
@@ -159,3 +185,82 @@ func (s *contractService) SetSection(templateNumber int, projectIdInt int) error
 	}
 	return nil
 }
+
+// 项目节的层级移动
+func (s *contractService) MoveDepth(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int) error {
+	// 1.验证项目节ID
+	treeId, err := utils.GetDecryptId(sectionData.Id)
+	if err != nil {
+		return err
+	}
+	section := s.treeContractDao.Get(treeId, bidsectionId, projectId)
+	if section.Id == 0 {
+		return errors.New("未找到合同项目节")
+	}
+	// 2.层级降级-同级有前一个兄弟节点
+	elderBrother := &models.CmTreeContracts{}
+	if sectionData.Operation == "downDepth" {
+		// 获得前一个兄弟节点
+		elderBrotherList := s.treeContractDao.GetElderBrother(section.Serial, section.Depth, section.ParentId, bidsectionId, projectId)
+		if len(elderBrotherList) == 0 {
+			return errors.New("项目节不能降级")
+		}
+		elderBrother = &elderBrotherList[0]
+	} else if sectionData.Operation == "upDepth" { // 3.层级升级-只要有父亲都能升级
+
+		// 获得父亲节点
+		if section.ParentId == 0 {
+			return errors.New("项目节不能升级")
+		}
+	} else {
+		return errors.New("参数错误")
+	}
+
+	// 4.执行升降级
+	err = s.treeContractDao.MoveDepth(section, elderBrother, sectionData.Operation, bidsectionId, projectId)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// 项目节的排序移动
+func (s *contractService) MoveSerial(sectionData *viewmodels.TreeSectionContract, bidsectionId int, projectId int) error {
+	// 1.验证项目节ID
+	treeId, err := utils.GetDecryptId(sectionData.Id)
+	if err != nil {
+		return err
+	}
+	section := s.treeContractDao.Get(treeId, bidsectionId, projectId)
+	if section.Id == 0 {
+		return errors.New("未找到合同项目节")
+	}
+
+	// 2.下移
+	brother := &models.CmTreeContracts{}
+	if sectionData.Operation == "downSerial" {
+		// 获得下一个兄弟
+		youngerBrotherList := s.treeContractDao.GetYoungerBrother(section.Serial, section.Depth, section.ParentId, bidsectionId, projectId)
+		if len(youngerBrotherList) == 0 {
+			return errors.New("项目节不能下移")
+		}
+		brother = &youngerBrotherList[0]
+	} else if sectionData.Operation == "upSerial" {
+		// 获得上一个兄弟
+		elderBrotherList := s.treeContractDao.GetElderBrother(section.Serial, section.Depth, section.ParentId, bidsectionId, projectId)
+		if len(elderBrotherList) == 0 {
+			return errors.New("项目节不能上移")
+		}
+		brother = &elderBrotherList[0]
+	} else {
+		return errors.New("参数错误")
+	}
+
+	// 4.执行升降级
+	err = s.treeContractDao.MoveSerial(section, brother, sectionData.Operation, bidsectionId, projectId)
+	if err != nil {
+		return err
+	}
+	return nil
+}

+ 114 - 15
web/api/contract_api.go

@@ -58,10 +58,27 @@ func (c *ContractApi) Get() {
 // @Accept  json
 // @Produce  json
 // @Security ApiKeyAuth
+// @Param   bidsectionId     path    string     true        "标段ID"
 // @Success 200 {object} viewmodels.TreeSectionContract "{code:0成功,-1参数类错误,data:viewmodels.TreeSectionContract,msg:错误信息}"
 // @Router /api/contract/income [get]
 func (c *ContractApi) GetIncome() {
 
+	sectionData := viewmodels.TreeSectionContract{}
+	err := c.Ctx.ReadForm(&sectionData)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": "ReadJSON转换异常,请检查参数"})
+		return
+	}
+	if sectionData.BidsectionId == "" {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": "ReadJSON转换异常,请检查参数"})
+		return
+	}
+	bidsectionId, err := utils.GetDecryptId(sectionData.BidsectionId)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": "ReadJSON转换异常,请检查参数"})
+		return
+	}
+
 	// 项目ID
 	projectIdInt, err := utils.GetProjectId(c.Ctx)
 	if err != nil {
@@ -70,7 +87,7 @@ func (c *ContractApi) GetIncome() {
 	}
 
 	//获得合同项目节
-	sectionTree := c.ServiceContract.GetSeciontTree(projectIdInt)
+	sectionTree := c.ServiceContract.GetSeciontTree(bidsectionId, projectIdInt)
 
 	// 1.未设置了项目节
 	if len(sectionTree.Children) == 0 {
@@ -100,11 +117,67 @@ func (c *ContractApi) GetIncome() {
 	}
 }
 
-// 升级降级合同项目节
+// @Summary 升级降级合同项目节
+// @Tags 合同管理
+// @Description operation{upDepth,downDepth}
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Param   id     body    string     true        "项目节ID"
+// @Param   bidsectionId     body    string     true        "标段ID"
+// @Param   operation     body    string     true        "操作名称"  default(upDepth)
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/contract/section/depth [post]
 func (c *ContractApi) PostSectionDepth() {
 
-	// 验证字段
+	// 验证字段-项目节ID 操作类型
+	sectionData, err := c.ServiceContract.ValidRuleDepth(c.Ctx)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
+		return
+	}
+	// 项目ID
+	projectIdInt, err := utils.GetProjectId(c.Ctx)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
+		return
+	}
+
+	bidsectionId, err := utils.GetDecryptId(sectionData.BidsectionId)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
+		return
+	}
+
+	err = c.ServiceContract.MoveDepth(sectionData, bidsectionId, projectIdInt)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
+		return
+	}
+	c.Ctx.JSON(iris.Map{
+		"code": 0,
+		"msg":  "操作成功",
+	})
+}
 
+// @Summary 上移下移合同项目节
+// @Tags 合同管理
+// @Description operation{upSerial,downSerial}
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Param   id     body    string     true        "项目节ID"
+// @Param   bidsectionId     body    string     true        "标段ID"
+// @Param   operation     body    string     true        "操作名称"  default(upSerial)
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/contract/section/serial [post]
+func (c *ContractApi) PostSectionSerial() {
+	// 验证字段-项目节ID 操作类型
+	sectionData, err := c.ServiceContract.ValidRuleDepth(c.Ctx)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
+		return
+	}
 	// 项目ID
 	projectIdInt, err := utils.GetProjectId(c.Ctx)
 	if err != nil {
@@ -112,9 +185,23 @@ func (c *ContractApi) PostSectionDepth() {
 		return
 	}
 
+	bidsectionId, err := utils.GetDecryptId(sectionData.BidsectionId)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
+		return
+	}
+	err = c.ServiceContract.MoveSerial(sectionData, bidsectionId, projectIdInt)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
+		return
+	}
+	c.Ctx.JSON(iris.Map{
+		"code": 0,
+		"msg":  "操作成功",
+	})
 }
 
-// 修改合同好
+// 修改合同项目节号
 func (c *ContractApi) PostSectionSave() {
 
 }
@@ -126,33 +213,45 @@ func (c *ContractApi) PostSectionSave() {
 // @Produce  json
 // @Security ApiKeyAuth
 // @Param   templateNumber     body    int     true        "模板号" default(1)
-// @Success 200 {object} viewmodels.TreeSectionContract "{code:0成功,-1参数类错误,data:viewmodels.TreeSectionContract,msg:错误信息}"
+// @Param   bidsectionId     body    string     true        "标段ID"
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
 // @Router /api/contract/section/template [post]
 func (c *ContractApi) PostSectionTemplate() {
 
 	// 获得模板号
-	sectionTemplate := &viewmodels.TreeSectionContract{}
-	err := c.Ctx.ReadJSON(sectionTemplate)
+	sectionData, err := c.ServiceContract.ValidRuleTemplate(c.Ctx)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": "解析参数出错"})
 		return
 	}
-	// 检查模板号
-	if !(sectionTemplate.TemplateNumber == 1 || sectionTemplate.TemplateNumber == 2) {
-		c.Ctx.JSON(iris.Map{"code": -1, "msg": "模板号出错"})
-		return
-	}
+
 	// 项目ID
 	projectIdInt, err := utils.GetProjectId(c.Ctx)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
 		return
 	}
-
-	err = c.ServiceContract.SetSection(sectionTemplate.TemplateNumber, projectIdInt)
+	// 标段ID
+	bidsectionId, err := utils.GetDecryptId(sectionData.BidsectionId)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
 		return
 	}
-	c.Ctx.JSON(iris.Map{"code": 0, "msg": "设置成功"})
+
+	//获得合同项目节
+	sectionTree := c.ServiceContract.GetSeciontTree(bidsectionId, projectIdInt)
+
+	// 1.未设置了项目节
+	if len(sectionTree.Children) == 0 {
+		err = c.ServiceContract.SetSection(sectionData.TemplateNumber, bidsectionId, projectIdInt)
+		if err != nil {
+			c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
+			return
+		}
+		c.Ctx.JSON(iris.Map{"code": 0, "msg": "设置成功"})
+	} else {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": "项目节已经设置"})
+		return
+	}
+
 }

+ 31 - 12
web/viewmodels/tree_section_contract.go

@@ -6,16 +6,20 @@
  */
 package viewmodels
 
+import validation "github.com/go-ozzo/ozzo-validation/v3"
+
 type TreeSectionContract struct {
-	Id          string `form:"id" json:"id" `
-	ParentId    string `form:"parentId" json:"parentId"`
-	Name        string `form:"name" json:"name"`
-	Depth       int    `form:"depth" json:"depth"`
-	Serial      string `form:"serial" json:"serial"`
-	Attribution string `form:"attribution" json:"attribution"`
-	Sort        int    `form:"sort" json:"attribsortution"`
-	ProjectId   string `form:"projectId" json:"projectId"`
-	ContractId  string `form:"contractId" json:"contractId"`
+	Id           string `form:"id" json:"id" `
+	ParentId     string `form:"parentId" json:"parentId"`
+	Name         string `form:"name" json:"name"`
+	Depth        int    `form:"depth" json:"depth"`
+	Serial       int    `form:"serial" json:"serial"`
+	Attribution  string `form:"attribution" json:"attribution"`
+	Code         string `form:"code" json:"code"`
+	Sort         int    `form:"sort" json:"attribsortution"`
+	ProjectId    string `form:"projectId" json:"projectId"`
+	BidsectionId string `form:"bidsectionId" json:"bidsectionId"`
+	ContractId   string `form:"contractId" json:"contractId"`
 
 	ContractName     string `form:"contractName" json:"contractName"`
 	ContractCode     string `form:"contractCode" json:"contractCode"`
@@ -24,11 +28,26 @@ type TreeSectionContract struct {
 	ContractsPaid    string `form:"contractsPaid" json:"contractsPaid"`
 	ContractStatus   int    `form:"contractStatus" json:"contractStatus"`
 
-	CreateTime string `form:"createTime" json:"createTime"`
+	CreateTime string                 `form:"createTime" json:"createTime"`
+	Children   []*TreeSectionContract `json:"children"`
+
+	TemplateNumber int    `form:"templateNumber" json:"templateNumber"`
+	Operation      string `form:"operation" json:"operation"`
+}
 
-	Children []*TreeSectionContract `json:"children"`
+func (l TreeSectionContract) ValidateDepth() error {
+	return validation.ValidateStruct(&l,
+		validation.Field(&l.Id, validation.Required.Error("项目节ID不能为空")),
+		validation.Field(&l.BidsectionId, validation.Required.Error("标段ID不能为空")),
+		validation.Field(&l.Operation, validation.Required.Error("操作名称不能为空"), validation.In("upDepth", "downDepth", "upSerial", "downSerial").Error("未找到相关操作")),
+	)
+}
 
-	TemplateNumber int `form:"templateNumber" json:"templateNumber"`
+func (l TreeSectionContract) ValidateTemplate() error {
+	return validation.ValidateStruct(&l,
+		validation.Field(&l.TemplateNumber, validation.Required.Error("模板号不能为空"), validation.In(1, 2).Error("未找到相关模板")),
+		validation.Field(&l.BidsectionId, validation.Required.Error("标段ID不能为空")),
+	)
 }
 
 // Isfolder int `form:"isfolder" json:"isfolder"`

+ 741 - 53
工程项目管理.postman_collection.json

@@ -1,6 +1,6 @@
 {
 	"info": {
-		"_postman_id": "c565c5a4-20a3-4d88-9a3e-62981014dc4a",
+		"_postman_id": "b04f05f6-41f5-42da-9342-210e012f8b7c",
 		"name": "工程项目管理",
 		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
 	},
@@ -34,7 +34,10 @@
 									"description": "目录名称",
 									"type": "text"
 								}
-							]
+							],
+							"options": {
+								"formdata": {}
+							}
 						},
 						"url": {
 							"raw": "http://cm.com/api/tree/rename",
@@ -58,33 +61,19 @@
 						"method": "POST",
 						"header": [
 							{
-								"key": "Authorization",
-								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDA5Mjg2ODQsImlhdCI6MTYwMDY2OTQ4NCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.emddRhE_urzFWi6I90Au919Ev30NQFKXLpdw6glyRSY",
+								"key": "X-CSRF-Token",
+								"value": "gU+I94C7oeFK88H/xu6lpvYFv/vqcYVKNPEaKtiUsaPhVLEe59++80n7IwdZOLHCQgqVhRzsz+X2Y/RaaOJAVg==",
 								"type": "text"
 							}
 						],
 						"body": {
-							"mode": "formdata",
-							"formdata": [
-								{
-									"key": "id",
-									"value": "055xjkeP0g05KaKSttgv4w",
-									"description": "目录ID",
-									"type": "text"
-								},
-								{
-									"key": "depth",
-									"value": "2",
-									"description": "目录深度",
-									"type": "text"
-								},
-								{
-									"key": "name",
-									"value": "2级工程目录的子目录",
-									"description": "目录名称",
-									"type": "text"
+							"mode": "raw",
+							"raw": "{\r\n    \"id\":\"6s6ai0ZJVtQKPK_A_1qLdw\",\r\n    \"depth\":0,\r\n    \"name\":\"123-456\"\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
 								}
-							]
+							}
 						},
 						"url": {
 							"raw": "http://cm.com/api/tree/create",
@@ -104,15 +93,25 @@
 				},
 				{
 					"name": "获得树目录",
+					"protocolProfileBehavior": {
+						"disableBodyPruning": true
+					},
 					"request": {
 						"method": "GET",
 						"header": [
 							{
 								"key": "Authorization",
-								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDA5Mjg2ODQsImlhdCI6MTYwMDY2OTQ4NCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.emddRhE_urzFWi6I90Au919Ev30NQFKXLpdw6glyRSY",
+								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDE2MDgwMzEsImlhdCI6MTYwMTM0ODgzMSwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.uAGRe1XWhkGrBSOT4SvdH89ruE1kuz6otHW-hfBop_g",
 								"type": "text"
 							}
 						],
+						"body": {
+							"mode": "urlencoded",
+							"urlencoded": [],
+							"options": {
+								"urlencoded": {}
+							}
+						},
 						"url": {
 							"raw": "http://cm.com/api/tree",
 							"protocol": "http",
@@ -134,8 +133,8 @@
 						"method": "DELETE",
 						"header": [
 							{
-								"key": "Authorization",
-								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDExOTIyMjIsImlhdCI6MTYwMDkzMzAyMiwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.EED4JZVPhbMesnFp8zYgXqSIoKLzAb64WZHQtOLiFIU",
+								"key": "X-CSRF-Token",
+								"value": "gU+I94C7oeFK88H/xu6lpvYFv/vqcYVKNPEaKtiUsaPhVLEe59++80n7IwdZOLHCQgqVhRzsz+X2Y/RaaOJAVg==",
 								"type": "text"
 							}
 						],
@@ -145,13 +144,15 @@
 								{
 									"key": "id",
 									"value": "055xjkeP0g05KaKSttgv4w",
-									"description": "目录ID",
 									"type": "text"
 								}
-							]
+							],
+							"options": {
+								"formdata": {}
+							}
 						},
 						"url": {
-							"raw": "http://cm.com/api/tree?id=kC6bASCprQcl27Xsssgqzw",
+							"raw": "http://cm.com/api/tree?id=idString",
 							"protocol": "http",
 							"host": [
 								"cm",
@@ -164,12 +165,46 @@
 							"query": [
 								{
 									"key": "id",
-									"value": "kC6bASCprQcl27Xsssgqzw"
+									"value": "idString"
 								}
 							]
 						}
 					},
 					"response": []
+				},
+				{
+					"name": "移动目录",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "gU+I94C7oeFK88H/xu6lpvYFv/vqcYVKNPEaKtiUsaPhVLEe59++80n7IwdZOLHCQgqVhRzsz+X2Y/RaaOJAVg==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\n\"id\":\"6s6ai0ZJVtQKPK_A_1qLdw\",\n\"TargetFolderId\":\"xCi4xUL6uur0h7fVI--NeA\"\n}",
+							"options": {
+								"raw": {}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/tree/move",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"tree",
+								"move"
+							]
+						}
+					},
+					"response": []
 				}
 			],
 			"protocolProfileBehavior": {}
@@ -220,20 +255,36 @@
 						}
 					},
 					"response": []
-				},
+				}
+			],
+			"protocolProfileBehavior": {}
+		},
+		{
+			"name": "账号相关",
+			"item": [
 				{
-					"name": "获得一组项目信息",
+					"name": "获得登陆账号",
+					"protocolProfileBehavior": {
+						"disableBodyPruning": true
+					},
 					"request": {
 						"method": "GET",
 						"header": [
 							{
 								"key": "Authorization",
-								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDA5Mjg2ODQsImlhdCI6MTYwMDY2OTQ4NCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.emddRhE_urzFWi6I90Au919Ev30NQFKXLpdw6glyRSY",
-								"type": "text"
+								"type": "text",
+								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDEyNzcxMDAsImlhdCI6MTYwMTAxNzkwMCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.s8rmnOghfJoEZHhahR9SMGoX10bgaLZfMe5zd55pfh0"
 							}
 						],
+						"body": {
+							"mode": "raw",
+							"raw": "",
+							"options": {
+								"raw": {}
+							}
+						},
 						"url": {
-							"raw": "http://cm.com/api/project/list?code=2",
+							"raw": "http://cm.com/api/projectAccount",
 							"protocol": "http",
 							"host": [
 								"cm",
@@ -241,14 +292,28 @@
 							],
 							"path": [
 								"api",
-								"project",
-								"list"
+								"projectAccount"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "获得项目账号列表",
+					"request": {
+						"method": "GET",
+						"header": [],
+						"url": {
+							"raw": "http://cm.com/api/projectAccount/list",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
 							],
-							"query": [
-								{
-									"key": "code",
-									"value": "2"
-								}
+							"path": [
+								"api",
+								"projectAccount",
+								"list"
 							]
 						}
 					},
@@ -258,21 +323,28 @@
 			"protocolProfileBehavior": {}
 		},
 		{
-			"name": "账号相关",
+			"name": "标段相关",
 			"item": [
 				{
-					"name": "获得一个账号信息",
+					"name": "创建标段",
 					"request": {
-						"method": "GET",
+						"method": "POST",
 						"header": [
 							{
 								"key": "Authorization",
-								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDEyNzcxMDAsImlhdCI6MTYwMTAxNzkwMCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.s8rmnOghfJoEZHhahR9SMGoX10bgaLZfMe5zd55pfh0",
+								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDE2MDgwMzEsImlhdCI6MTYwMTM0ODgzMSwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.uAGRe1XWhkGrBSOT4SvdH89ruE1kuz6otHW-hfBop_g",
 								"type": "text"
 							}
 						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\n\"folderId\":\"kC6bASCprQcl27Xsssgqzw\",\n\"name\":\"工程目录下的叶子节点\"\n}",
+							"options": {
+								"raw": {}
+							}
+						},
 						"url": {
-							"raw": "http://cm.com/api/projectAccount",
+							"raw": "http://cm.com/api/bidsection/create",
 							"protocol": "http",
 							"host": [
 								"cm",
@@ -280,7 +352,8 @@
 							],
 							"path": [
 								"api",
-								"projectAccount"
+								"bidsection",
+								"create"
 							]
 						}
 					},
@@ -290,10 +363,625 @@
 			"protocolProfileBehavior": {}
 		},
 		{
-			"name": "项目用户登陆",
-			"request": {
-				"method": "POST",
-				"header": [],
+			"name": "项目设置",
+			"item": [
+				{
+					"name": "获得项目账号相关",
+					"protocolProfileBehavior": {
+						"disableBodyPruning": true
+					},
+					"request": {
+						"method": "GET",
+						"header": [
+							{
+								"key": "Authorization",
+								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDI0NzMyODQsImlhdCI6MTYwMjIxNDA4NCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.vyTJQ8FJ70VSmXUY9JJ1BVrAYA8LDrO9wP6dtBuBi7M",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"id\":\"PcqqGsn1O0jBSmLqkuOTwQ\"\r\n}",
+							"options": {
+								"raw": {}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/account",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"account"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "账号检索",
+					"protocolProfileBehavior": {
+						"disableBodyPruning": true
+					},
+					"request": {
+						"method": "GET",
+						"header": [
+							{
+								"key": "Authorization",
+								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDI0NzMyODQsImlhdCI6MTYwMjIxNDA4NCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.vyTJQ8FJ70VSmXUY9JJ1BVrAYA8LDrO9wP6dtBuBi7M",
+								"type": "text",
+								"disabled": true
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"name\":\"蔡\"\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/account/search",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"account",
+								"search"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "添加账号",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "Authorization",
+								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDI0NzMyODQsImlhdCI6MTYwMjIxNDA4NCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.vyTJQ8FJ70VSmXUY9JJ1BVrAYA8LDrO9wP6dtBuBi7M",
+								"type": "text",
+								"disabled": true
+							},
+							{
+								"key": "X-CSRF-Token",
+								"value": "B8HzuSJc/lKy1uKz01dpnClZy9ie7XkkTN2QGgUp0r5Nd/XCCL/PClSDSTCibsBd7IAXlM19B/0f7VkimzVVqg==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"account\":\"test123456\",\r\n    \"password\":\"test123456\",\r\n    \"name\":\"test123456\",\r\n    \"company\":\"test123456\",\r\n    \"position\":\"test123456\",\r\n    \"mobile\":\"13411417327\",\r\n    \"telephone\":\"7762855\",\r\n    \"accountGroup\":1\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/account/add",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"account",
+								"add"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "编辑账号",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "Jw/zkIxktih/M+oXtyVl4l8a6bWLNi2RnSJ96+NBR0xtufXrpoeHcJlmQZTGHMwjmsM1+dimU0jOErTTfV3AWA==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"id\":\"PcqqGsn1O0jBSmLqkuOTwQ\",\r\n    \"name\":\"text123445\",\r\n    \"company\":\"textiik\",\r\n    \"position\":\"经理\",\r\n    \"telephone\":\"0758-8854888\",\r\n    \"accountGroup\":3\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/account/save",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"account",
+								"save"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "账号启用/禁用",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "Jw/zkIxktih/M+oXtyVl4l8a6bWLNi2RnSJ96+NBR0xtufXrpoeHcJlmQZTGHMwjmsM1+dimU0jOErTTfV3AWA==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"id\":\"PcqqGsn1O0jBSmLqkuOTwQ\",\r\n    \"enable\":1\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/account/enable",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"account",
+								"enable"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "账号删除",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "Jw/zkIxktih/M+oXtyVl4l8a6bWLNi2RnSJ96+NBR0xtufXrpoeHcJlmQZTGHMwjmsM1+dimU0jOErTTfV3AWA==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"id\":\"oy4r31Li6DXHaZQ6zx8DzA\"\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/account/delete",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"account",
+								"delete"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "修改账号密码",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "Jw/zkIxktih/M+oXtyVl4l8a6bWLNi2RnSJ96+NBR0xtufXrpoeHcJlmQZTGHMwjmsM1+dimU0jOErTTfV3AWA==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"id\":\"PcqqGsn1O0jBSmLqkuOTwQ\",\r\n    \"account\":\"textoopd\",\r\n    \"password\":\"ww123456\"\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/account/change",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"account",
+								"change"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "保存项目信息",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "Jw/zkIxktih/M+oXtyVl4l8a6bWLNi2RnSJ96+NBR0xtufXrpoeHcJlmQZTGHMwjmsM1+dimU0jOErTTfV3AWA==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"name\":\"红旗大桥\"\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/project/save",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"project",
+								"save"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "获得标段账号",
+					"protocolProfileBehavior": {
+						"disableBodyPruning": true
+					},
+					"request": {
+						"method": "GET",
+						"header": [],
+						"body": {
+							"mode": "formdata",
+							"formdata": [
+								{
+									"key": "bidsectionId",
+									"value": "055xjkeP0g05KaKSttgv4w",
+									"description": "标段ID",
+									"type": "text"
+								}
+							],
+							"options": {
+								"formdata": {}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectaccount/list",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectaccount",
+								"list"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "为标段创建成员",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "gU+I94C7oeFK88H/xu6lpvYFv/vqcYVKNPEaKtiUsaPhVLEe59++80n7IwdZOLHCQgqVhRzsz+X2Y/RaaOJAVg==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{}",
+							"options": {
+								"raw": {
+									"language": "javascript"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/bid/account/create",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"bid",
+								"account",
+								"create"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "移除标段成员",
+					"request": {
+						"method": "DELETE",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "gU+I94C7oeFK88H/xu6lpvYFv/vqcYVKNPEaKtiUsaPhVLEe59++80n7IwdZOLHCQgqVhRzsz+X2Y/RaaOJAVg==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/projectSetting/bid/account",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"projectSetting",
+								"bid",
+								"account"
+							]
+						}
+					},
+					"response": []
+				}
+			],
+			"protocolProfileBehavior": {}
+		},
+		{
+			"name": "登陆相关",
+			"item": [
+				{
+					"name": "获得项目列表-名称",
+					"protocolProfileBehavior": {
+						"disableBodyPruning": true
+					},
+					"request": {
+						"method": "GET",
+						"header": [
+							{
+								"key": "Authorization",
+								"value": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MDA5Mjg2ODQsImlhdCI6MTYwMDY2OTQ4NCwiaWRlbnRpdHkiOiI1R0lWLVdIZm15aDNnUXhEU0VCVk5BIiwiaXNzIjoiY20iLCJwcm9qZWN0IjoiZG5sUE5sWjN6SFFVSHBQOVBUTXNldyJ9.emddRhE_urzFWi6I90Au919Ev30NQFKXLpdw6glyRSY",
+								"type": "text",
+								"disabled": true
+							}
+						],
+						"body": {
+							"mode": "formdata",
+							"formdata": [
+								{
+									"key": "code",
+									"value": "2",
+									"type": "text"
+								}
+							],
+							"options": {
+								"formdata": {}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/login/project/name",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"login",
+								"project",
+								"name"
+							]
+						}
+					},
+					"response": []
+				}
+			],
+			"protocolProfileBehavior": {}
+		},
+		{
+			"name": "合同管理",
+			"item": [
+				{
+					"name": "获得合同目录和标段",
+					"request": {
+						"method": "GET",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "gU+I94C7oeFK88H/xu6lpvYFv/vqcYVKNPEaKtiUsaPhVLEe59++80n7IwdZOLHCQgqVhRzsz+X2Y/RaaOJAVg==",
+								"type": "text"
+							}
+						],
+						"url": {
+							"raw": "http://cm.com/api/contract",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"contract"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "获得收入合同信息接口",
+					"request": {
+						"method": "GET",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "gU+I94C7oeFK88H/xu6lpvYFv/vqcYVKNPEaKtiUsaPhVLEe59++80n7IwdZOLHCQgqVhRzsz+X2Y/RaaOJAVg==",
+								"type": "text"
+							}
+						],
+						"url": {
+							"raw": "http://cm.com/api/contract/income",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"contract",
+								"income"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "设置项目节模板",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"type": "text",
+								"value": "loGRfxf11p5+94lKvMzvUAbzX7CnyG+VhtSNJyvnBNbXr42H5HZLJINgcWeo/ThAQh3dEXxnxf3SocVYr0sCwg=="
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"templateNumber\":1,\r\n    \"bidsectionId\":\"Ta0Pnq8nIrAzKOrUpU6gKw\"\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/contract/section/template",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"contract",
+								"section",
+								"template"
+							]
+						}
+					},
+					"response": []
+				},
+				{
+					"name": "合同项目节升降级",
+					"request": {
+						"method": "POST",
+						"header": [
+							{
+								"key": "X-CSRF-Token",
+								"value": "QqX3ii86u/uQ6HapY5x+laHLIM+r3WbvsdgzPMSSAoHLe2FcrnuenAZtGew6LSU8mMV9nBzs+Chs6jfsQMHIsg==",
+								"type": "text"
+							}
+						],
+						"body": {
+							"mode": "raw",
+							"raw": "{\r\n    \"id\":\"kC6bASCprQcl27Xsssgqzw\",\r\n    \"bidsectionId\":\"Ta0Pnq8nIrAzKOrUpU6gKw\",\r\n    \"operation\":\"upDepth\"\r\n}",
+							"options": {
+								"raw": {
+									"language": "json"
+								}
+							}
+						},
+						"url": {
+							"raw": "http://cm.com/api/contract/section/depth",
+							"protocol": "http",
+							"host": [
+								"cm",
+								"com"
+							],
+							"path": [
+								"api",
+								"contract",
+								"section",
+								"depth"
+							]
+						}
+					},
+					"response": []
+				}
+			],
+			"protocolProfileBehavior": {}
+		},
+		{
+			"name": "项目用户登陆",
+			"request": {
+				"method": "POST",
+				"header": [
+					{
+						"key": "X-CSRF-Token",
+						"value": "GkKHnhdNaEihcWjc7XbSntzo9+PskU604R8msigo5iZ3ddMaSWAzEHWyHOaA6vVR+Ac7BmCcOebCOOboZ3iYLw==",
+						"type": "text"
+					}
+				],
 				"body": {
 					"mode": "raw",
 					"raw": "{\n\"code\":\"234\",\n\"account\":\"caipin\",\n\"password\":\"123456\"\n}",