caipin 4 년 전
부모
커밋
688fad05f0

+ 16 - 13
bootstrap/bootstrap.go

@@ -107,20 +107,23 @@ func (b *Bootstrapper) SetupCsrfHandlers(csrfKey string) {
 //处理异常--设置错误信息展示
 func (b *Bootstrapper) SetupErrorHandlers() {
 	b.OnAnyErrorCode(func(ctx iris.Context) {
-		err := iris.Map{
-			"app":     b.AppName,
-			"status":  ctx.GetStatusCode(),
-			"message": ctx.Values().GetString("message"),
-		}
+		// err := iris.Map{
+		// 	"app":     b.AppName,
+		// 	"status":  ctx.GetStatusCode(),
+		// 	"message": ctx.Values().GetString("message"),
+		// }
 		//如果是json格式,使用json方式输出
-		if jsonOutput := ctx.URLParamExists("json"); jsonOutput {
-			ctx.JSON(err)
-			return
-		}
-
-		ctx.ViewData("Err", err)
-		ctx.ViewData("Title", "Error")
-		ctx.View("shared/error.html")
+		// if jsonOutput := ctx.URLParamExists("json"); jsonOutput {
+		// 	ctx.JSON(err)
+		// 	return
+		// }
+
+		// ctx.ViewData("Err", err)
+		// ctx.ViewData("Title", "Error")
+		// ctx.View("shared/error.html")
+
+		ctx.JSON(iris.Map{"code": -1, "msg": "请求错误,请检查"})
+
 	})
 }
 

+ 5 - 2
comm/functions.go

@@ -167,7 +167,10 @@ func AesEncrypt(orig string, key string) (string, error) {
 func AesDecrypt(cryted string, key string) (string, error) {
 	//使用RawURLEncoding 不要使用StdEncoding
 	//不要使用StdEncoding  放在url参数中回导致错误
-	crytedByte, _ := base64.RawURLEncoding.DecodeString(cryted)
+	crytedByte, err := base64.RawURLEncoding.DecodeString(cryted)
+	if err != nil {
+		return "", err
+	}
 	k := []byte(key)
 
 	// 分组秘钥
@@ -181,7 +184,7 @@ func AesDecrypt(cryted string, key string) (string, error) {
 	blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
 	// 创建数组
 	orig := make([]byte, len(crytedByte))
-	// 解密
+	// 解密--传入不正确的字符时会报错-TODO 需捕获
 	blockMode.CryptBlocks(orig, crytedByte)
 	// 去补全码
 	orig = PKCS7UnPadding(orig)

+ 154 - 0
dao/bid_account_dao.go

@@ -7,7 +7,11 @@
 package dao
 
 import (
+	"encoding/json"
+	"errors"
+
 	"github.com/go-xorm/xorm"
+	"go.mod/lib"
 	"go.mod/models"
 )
 
@@ -37,3 +41,153 @@ func (d *BidAccountDao) GetBidAccount(bidsectionId int, projectId int) []models.
 		return datalist
 	}
 }
+
+// 创建标段成员关系
+func (d *BidAccountDao) Create(bidsectionId int, accountData *models.CmProjectAccount, treeId int, projectId int) error {
+
+	session := d.engine.NewSession()
+	defer session.Close()
+	err := session.Begin()
+	if err != nil {
+		return errors.New("新增标段成员出错-dbsession")
+	}
+
+	// -更新树成员量
+	// 1.获得标段成员量
+	bidAccountData := d.GetBidAccount(bidsectionId, projectId)
+	accounts := len(bidAccountData) + 1
+	_, err = session.Exec("UPDATE cm_tree SET `accounts` = ? where id = ?", accounts, treeId)
+	if err != nil {
+		session.Rollback()
+		return errors.New("更新标段成员量出错")
+	}
+
+	// -更新账号表的标段ID
+	// 1.获得账号中已绑定的标段
+	bidsectionIdsString := accountData.BidsectionIds
+	bidsectionIds := make([]lib.BidsectionIds, 0)
+	bidsectionIdsByte := []byte("")
+	// 2.未有标段
+	if bidsectionIdsString == "" {
+		bidsectionIds[0].Id = bidsectionId
+		bidsectionIdsByte, err = json.Marshal(bidsectionIds)
+		if err != nil {
+			return err
+		}
+	} else {
+		// 2.获得已有的标段ID
+		err := json.Unmarshal([]byte(bidsectionIdsString), &bidsectionIds)
+		if err != nil {
+			return err
+		}
+		bidId := lib.BidsectionIds{}
+		bidId.Id = bidsectionId
+		// 加入ID
+		bidsectionIds = append(bidsectionIds, bidId)
+		// 转换JSON字符byte
+		bidsectionIdsByte, err = json.Marshal(bidsectionIds)
+		if err != nil {
+			return err
+		}
+	}
+	bidsectionIdsString = string(bidsectionIdsByte[:])
+	// 3.更新账号标段ID组
+	_, err = session.Exec("UPDATE cm_project_account SET `bidsection_ids` = ? where id = ?", bidsectionIdsString, accountData.Id)
+	if err != nil {
+		session.Rollback()
+		return errors.New("更新账号下标段出错")
+	}
+
+	// -写入标段用户关系
+	bidAccount := models.CmBidAccount{}
+	bidAccount.AccountId = accountData.Id
+	bidAccount.BidsectionId = bidsectionId
+	bidAccount.ProjectId = projectId
+	_, err = session.Insert(bidAccount)
+	if err != nil {
+		session.Rollback()
+		return errors.New("账号关联标段出错")
+	}
+
+	err = session.Commit()
+	if err != nil {
+		session.Rollback()
+		return errors.New("新增标段成员出错-dbsession")
+	}
+	return nil
+}
+
+// 移除标段中的成员
+func (d *BidAccountDao) Delete(bidsectionId int, accountData *models.CmProjectAccount, treeId int, projectId int) error {
+	session := d.engine.NewSession()
+	defer session.Close()
+	err := session.Begin()
+	if err != nil {
+		return errors.New("移除标段成员出错-dbsession")
+	}
+
+	// 1.移除标段账号关系中的账号
+	_, err = session.Exec("DELETE FROM `cm_bid_account` WHERE account_id = ? and bidsection_id = ? and project_id= ? limit 1",
+		accountData.Id, bidsectionId, projectId)
+	if err != nil {
+		session.Rollback()
+		return errors.New("移除标段成员出错")
+	}
+
+	// -更新树成员量
+	// 2.获得标段成员量
+	bidAccountData := d.GetBidAccount(bidsectionId, projectId)
+	accounts := len(bidAccountData)
+	_, err = session.Exec("UPDATE cm_tree SET `accounts` = ? where id = ?", accounts, treeId)
+	if err != nil {
+		session.Rollback()
+		return errors.New("更新标段成员量出错")
+	}
+
+	// 3.移除账号表中的标段ID
+	bidsectionIdsString := accountData.BidsectionIds
+	bidsectionIds := make([]lib.BidsectionIds, 0)
+	bidsectionIdsByte := []byte("")
+	// 2.未有标段
+	if bidsectionIdsString == "" {
+		return errors.New("移除标段成员出错")
+	}
+	// 2.获得已有的标段ID
+	err = json.Unmarshal([]byte(bidsectionIdsString), &bidsectionIds)
+	if err != nil {
+		return err
+	}
+	// 获得需要删除标段ID的下标
+	bidsectionIdsIndex := -1
+	for index, data := range bidsectionIds {
+		if data.Id == bidsectionId {
+			bidsectionIdsIndex = index
+			break
+		}
+	}
+	if bidsectionIdsIndex == -1 {
+		return errors.New("移除标段成员出错")
+	}
+	// 删除标段ID
+	bidsectionIds = append(bidsectionIds[:bidsectionIdsIndex], bidsectionIds[bidsectionIdsIndex+1:]...)
+
+	// 转换JSON字符byte
+	bidsectionIdsByte, err = json.Marshal(bidsectionIds)
+	if err != nil {
+		return err
+	}
+	bidsectionIdsString = string(bidsectionIdsByte[:])
+	// 3.更新账号标段ID组
+	_, err = session.Exec("UPDATE cm_project_account SET `bidsection_ids` = ? where id = ?", bidsectionIdsString, accountData.Id)
+	if err != nil {
+		session.Rollback()
+		return errors.New("移除账号下标段出错")
+	}
+
+	err = session.Commit()
+	if err != nil {
+		session.Rollback()
+		return errors.New("移除标段成员出错-dbsession")
+	}
+	return nil
+}

+ 69 - 20
dao/tree_dao.go

@@ -30,15 +30,30 @@ func NewTreeDao(engine *xorm.Engine) *TreeDao {
 
 //id获得数据
 func (d *TreeDao) Get(id int, projectId int) *models.CmTree {
-	data := &models.CmTree{Id: id, ProjectId: projectId, Isdelete: 0}
-	//Get取到值后,会自动赋值到data中
-	ok, err := d.engine.Get(data)
-	if ok && err == nil {
-		return data
-	} else {
+	// data := &models.CmTree{Id: id, ProjectId: projectId, Isdelete: 0}
+	// // Get取到值后,会自动赋值到data中
+	// ok, err := d.engine.Get(data)
+
+	// if ok && err == nil {
+	// 	return data
+	// } else {
+	// 	data.Id = 0
+	// 	return data
+	// }
+
+	// fmt.Println("sqlid=")
+	// fmt.Println(id)
+	data := &models.CmTree{}
+	_, err := d.engine.
+		Where("id=? and project_id=? and isdelete=0", id, projectId).
+		Get(data)
+	// fmt.Println(data)
+	if err != nil {
 		data.Id = 0
 		return data
 	}
+	return data
+
 }
 
 // 获得该目录下的标段
@@ -115,6 +130,19 @@ func (d *TreeDao) GetFolderAndBid(projectId int, attribution string) []models.Cm
 	}
 }
 
+// 获得标段的目录
+func (d *TreeDao) GetBidParentId(bidsectionId int, projectId int) *models.CmTree {
+	data := &models.CmTree{}
+	_, err := d.engine.
+		Where("bidsection_id=? and project_id=? and isdelete=0", bidsectionId, projectId).
+		Get(data)
+	if err != nil {
+		data.Id = 0
+		return data
+	}
+	return data
+}
+
 // 删除目录以及下属目录所有数据
 func (d *TreeDao) DeleteFolderAndBid(id int, projectId int, attribution string) error {
 
@@ -147,7 +175,7 @@ func (d *TreeDao) DeleteFolderAndBid(id int, projectId int, attribution string)
 			idList = append(idList, strconv.Itoa(bidData.Id))
 		}
 		inId := strings.Join(idList, ",")
-		_, err = session.Exec("UPDATE cm_tender SET `isdelete` = 1 where id in (?)", inId)
+		_, err = session.Exec("UPDATE cm_bidsection SET `isdelete` = 1 where id in (?)", inId)
 		if err != nil {
 			session.Rollback()
 			return errors.New("删除标段出错")
@@ -172,21 +200,29 @@ func (d *TreeDao) Move(treeNode *models.CmTree, moveFolder *models.CmTree) error
 		return errors.New("移动出错-db")
 	}
 
-	// 被移动跟目录-父亲节点转换
-	data := &models.CmTree{ParentId: moveFolder.Id}
-	_, err = session.
-		Where("id=? and isdelete=0", treeNode.Id).
-		Update(data)
+	// 原目录父节点替换目标目录的ID
+	_, err = session.Exec("UPDATE  cm_tree SET `parent_id` = ? where id = ? and isdelete=0", moveFolder.Id, treeNode.Id)
 	if err != nil {
-		session.Rollback()
-		return errors.New("移动目录出错")
+		return err //errors.New("移动目录出错---")
 	}
+	// data := &models.CmTree{ParentId: moveFolder.Id}
+	// _, err = session.
+	// 	Where("id=? and isdelete=0", treeNode.Id).
+	// 	Update(data)
+	// if err != nil {
+	// 	session.Rollback()
+	// 	return err //errors.New("移动目录出错---")
+	// }
 
 	// 移动目录的归属和标段的归属关系--TODO 效率问题在修改
 	// 1-原来目录的归属
 	attribution := fmt.Sprintf("%s%d-", treeNode.Attribution, treeNode.Serial)
-	// 2-移动后目录的归属
-	movrAttribution := fmt.Sprintf("%s%d-", moveFolder.Attribution, moveFolder.Serial)
+	// 2-移动后目录的归属--跟目录的话,所属为空
+	movrAttribution := ""
+	if moveFolder.Id != 0 {
+		movrAttribution = fmt.Sprintf("%s%d-", moveFolder.Attribution, moveFolder.Serial)
+	}
+
 	// 3-获得移动后最大序列号
 	depth := moveFolder.Depth + 1
 
@@ -196,22 +232,35 @@ func (d *TreeDao) Move(treeNode *models.CmTree, moveFolder *models.CmTree) error
 	if maxIndex != 0 {
 		serial = datalist[maxIndex-1].Serial + 1
 	}
-	// 4-移动原目录货标段-最大序号
-	_, err = session.Exec("UPDATE  cm_tree SET `attribution` = ?,`serial` = ? where id = ? and isdelete=0", movrAttribution, serial, treeNode.Id)
+	// 3-1 深度差=原目录depth-目标目录depth
+	difference := (treeNode.Depth - 1) - moveFolder.Depth
+
+	// 移动后目录depth=原目录depth-差
+	// 4-移动原目录或标段-最大序号
+	_, err = session.Exec("UPDATE  cm_tree SET `attribution` = ?,`serial` = ?,`depth` =`depth` - ? where id = ? and isdelete=0",
+		movrAttribution, serial, difference, treeNode.Id)
 	if err != nil {
 		session.Rollback()
 		return errors.New("移动目录或标段出错")
 	}
 
-	// 5-移动原目录下所有子目录和标段
+	//
+
+	// 5-移动原目录下所有子目录和标段-项目下
 	movrAttribution = fmt.Sprintf("%s%d-", movrAttribution, serial)
-	_, err = session.Exec("UPDATE  cm_tree SET `attribution` = replace(`attribution`, '"+attribution+"', '"+movrAttribution+"') where attribution like ? and isdelete=0", attribution+"%")
+	_, err = session.Exec("UPDATE  cm_tree SET `attribution` = replace(`attribution`, '"+attribution+"', '"+movrAttribution+"') "+
+		",`depth` =`depth` - ? where attribution like ? and project_id=? and isdelete=0", difference, attribution+"%", treeNode.ProjectId)
 	//_, err = session.Exec("UPDATE from cm_tree SET `attribution` = replace(`attribution`, ?, ?) where attribution like ?", attribution,movrAttribution,attribution+"%")
 	if err != nil {
 		session.Rollback()
 		return errors.New("移动目录或标段出错")
 	}
 
+	// 6-更新depth
+	// 6-1原目录深度差
+	//difference := treeNode.Depth - moveFolder.Depth
+	// 原目录depth-差,移动后的depth
+
 	err = session.Commit()
 	if err != nil {
 		session.Rollback()

+ 19 - 14
models/cm_tree.go

@@ -5,18 +5,23 @@ import (
 )
 
 type CmTree struct {
-	Id           int       `xorm:"not null pk autoincr comment('自增ID') INT(11)"`
-	Name         string    `xorm:"not null comment('名称') VARCHAR(64)"`
-	ProjectId    int       `xorm:"not null default 0 comment('项目ID') INT(11)"`
-	Depth        int       `xorm:"not null default 0 comment('深度') TINYINT(4)"`
-	Serial       int       `xorm:"not null default 0 comment('序号') TINYINT(4)"`
-	Attribution  string    `xorm:"comment('归属') VARCHAR(32)"`
-	Sort         int       `xorm:"not null default 0 comment('排序') TINYINT(4)"`
-	Isfolder     int       `xorm:"not null default 1 comment('是否文件夹 1文件夹 0其他') TINYINT(1)"`
-	BidsectionId int       `xorm:"comment('标段ID') INT(11)"`
-	ParentId     int       `xorm:"not null default 0 comment('父级ID') INT(11)"`
-	Ancounts     int       `xorm:"not null default 0 comment('账号数') TINYINT(4)"`
-	Isdelete     int       `xorm:"not null default 0 comment('1删除') TINYINT(1)"`
-	CreateTime   time.Time `xorm:"comment('创建时间') DATETIME"`
-	UpdateTime   time.Time `xorm:"not null default 'CURRENT_TIMESTAMP' comment('更新时间') TIMESTAMP"`
+	Id                int       `xorm:"not null pk autoincr comment('自增ID') INT(11)"`
+	Name              string    `xorm:"not null comment('名称') VARCHAR(64)"`
+	ProjectId         int       `xorm:"not null default 0 comment('项目ID') INT(11)"`
+	Depth             int       `xorm:"not null default 0 comment('深度') TINYINT(4)"`
+	Serial            int       `xorm:"not null default 0 comment('序号') TINYINT(4)"`
+	Attribution       string    `xorm:"comment('归属') VARCHAR(32)"`
+	Sort              int       `xorm:"not null default 0 comment('排序') TINYINT(4)"`
+	Isfolder          int       `xorm:"not null default 1 comment('是否文件夹 1文件夹 0其他') TINYINT(1)"`
+	BidsectionId      int       `xorm:"comment('标段ID') INT(11)"`
+	ParentId          int       `xorm:"not null default 0 comment('父级ID') INT(11)"`
+	Ancounts          int       `xorm:"not null default 0 comment('账号数') TINYINT(4)"`
+	Contracts         int       `xorm:"not null default 0 comment('合同数') TINYINT(4)"`
+	ContractsIncome   string    `xorm:"not null default 0.00 comment('合同收入总金额') DECIMAL(12,2)"`
+	ContractsReturned string    `xorm:"not null default 0.00 comment('合同已收总金额') DECIMAL(12,2)"`
+	ContractsPay      string    `xorm:"not null default 0.00 comment('合同支付总金额') DECIMAL(12,2)"`
+	ContractsPaid     string    `xorm:"not null default 0.00 comment('合同已支付金额') DECIMAL(12,2)"`
+	Isdelete          int       `xorm:"not null default 0 comment('1删除') TINYINT(1)"`
+	CreateTime        time.Time `xorm:"comment('创建时间') DATETIME"`
+	UpdateTime        time.Time `xorm:"not null default 'CURRENT_TIMESTAMP' comment('更新时间') TIMESTAMP"`
 }

+ 55 - 3
services/bid_account_service.go

@@ -21,6 +21,7 @@ import (
 type BidAccountService interface {
 	ValidRule(ctx iris.Context) (viewmodels.BidAccount, error)
 	Create(viewBidAccount viewmodels.BidAccount, projectId int) error
+	Delete(viewBidAccount viewmodels.BidAccount, projectId int) error
 }
 
 //返回service操作类
@@ -29,6 +30,7 @@ type bidAccountService struct {
 	projectDao        *dao.ProjectDao
 	bidsectionDao     *dao.BidsectionDao
 	treeDao           *dao.TreeDao
+	bidAccountDao     *dao.BidAccountDao
 }
 
 //创建项目用户service
@@ -38,6 +40,7 @@ func NewBidAccountService() BidAccountService {
 		projectDao:        dao.NewProjectDao(datasource.InstanceDbMaster()),
 		bidsectionDao:     dao.NewBidsectionDao(datasource.InstanceDbMaster()),
 		treeDao:           dao.NewTreeDao(datasource.InstanceDbMaster()),
+		bidAccountDao:     dao.NewBidAccountDao(datasource.InstanceDbMaster()),
 	}
 }
 
@@ -60,7 +63,7 @@ func (s *bidAccountService) ValidRule(ctx iris.Context) (viewmodels.BidAccount,
 
 // 新增标段于账号的关系
 func (s *bidAccountService) Create(viewBidAccount viewmodels.BidAccount, projectId int) error {
-	// 写入关系表-标段的成员数量-账号表中标段ID TODO
+	// 写入关系表-标段的成员数量-账号表中标段ID
 	// 1.检查账号合法性
 	accountId, err := utils.GetDecryptId(viewBidAccount.AccountId)
 	if err != nil {
@@ -80,14 +83,63 @@ func (s *bidAccountService) Create(viewBidAccount viewmodels.BidAccount, project
 		return errors.New("标段不合法")
 	}
 	// 3.检查目录的合法性
-	treeId, err := utils.GetDecryptId(viewBidAccount.FolderId)
+	// 3-1标段ID,,项目ID
+	treeData := s.treeDao.GetBidParentId(bidsectionId, projectId)
+	// 3-2获得目录ID
+	if treeData.Id == 0 {
+		return errors.New("目录不合法")
+	}
+	treeId := treeData.Id
+	// treeId, err := utils.GetDecryptId(viewBidAccount.FolderId)
+	// if err != nil {
+	// 	return err
+	// }
+	// treeData := s.treeDao.Get(treeId, projectId)
+	// if treeData.Id == 0 {
+	// 	return errors.New("目录不合法")
+	// }
+
+	// 新增成员到标段
+	err = s.bidAccountDao.Create(bidsectionId, accountData, treeId, projectId)
 	if err != nil {
 		return err
 	}
-	treeData := s.treeDao.Get(treeId, projectId)
+	return nil
+}
+
+//移除标段成员
+func (s *bidAccountService) Delete(viewBidAccount viewmodels.BidAccount, projectId int) error {
+	// 1.检查账号合法性
+	accountId, err := utils.GetDecryptId(viewBidAccount.AccountId)
+	if err != nil {
+		return err
+	}
+	accountData := s.projectAccountDao.Get(accountId, projectId)
+	if accountData.Id == 0 {
+		return errors.New("添加的账号不合法")
+	}
+	// 2.检查标段合法性
+	bidsectionId, err := utils.GetDecryptId(viewBidAccount.BidsectionId)
+	if err != nil {
+		return err
+	}
+	bidsection := s.bidsectionDao.Get(bidsectionId, projectId)
+	if bidsection.Id == 0 {
+		return errors.New("标段不合法")
+	}
+	// 3.检查目录的合法性
+	// 3-1标段ID,,项目ID
+	treeData := s.treeDao.GetBidParentId(bidsectionId, projectId)
+	// 3-2获得目录ID
 	if treeData.Id == 0 {
 		return errors.New("目录不合法")
 	}
+	treeId := treeData.Id
 
+	// 删除成员到标段
+	err = s.bidAccountDao.Delete(bidsectionId, accountData, treeId, projectId)
+	if err != nil {
+		return err
+	}
 	return nil
 }

+ 40 - 0
services/contract_service.go

@@ -0,0 +1,40 @@
+/*
+ * @description: 合同数据相关操作
+ * @Author: CP
+ * @Date: 2020-10-27 11:28:24
+ * @FilePath: \construction_management\services\contract_service.go
+ */
+package services
+
+//定义项目用户Service接口
+type ContractService interface {
+	// ValidRule(ctx iris.Context) (viewmodels.BidAccount, error)
+	// Create(viewBidAccount viewmodels.BidAccount, projectId int) error
+	// Delete(viewBidAccount viewmodels.BidAccount, projectId int) error
+	GetAll()
+}
+
+//返回service操作类
+type contractService struct {
+	// dao *dao.ProjectAccountDao
+	// projectDao        *dao.ProjectDao
+	// bidsectionDao     *dao.BidsectionDao
+	// treeDao           *dao.TreeDao
+	// bidAccountDao     *dao.BidAccountDao
+}
+
+//创建项目用户service
+func NewContractService() ContractService {
+	return &contractService{
+		// projectAccountDao: dao.NewProjectAccountDao(datasource.InstanceDbMaster()),
+		// projectDao:        dao.NewProjectDao(datasource.InstanceDbMaster()),
+		// bidsectionDao:     dao.NewBidsectionDao(datasource.InstanceDbMaster()),
+		// treeDao:           dao.NewTreeDao(datasource.InstanceDbMaster()),
+		// bidAccountDao:     dao.NewBidAccountDao(datasource.InstanceDbMaster()),
+	}
+}
+
+// 获得合同标段内容
+func (s *contractService) GetAll() {
+
+}

+ 100 - 7
services/tree_service.go

@@ -28,7 +28,8 @@ type TreeService interface {
 	//ValidManager(code string, account string, password string) error
 	ValidRule(ctx iris.Context) (viewmodels.Tree, error)
 	Create(data viewmodels.Tree) error
-	GetAllProject(int) *viewmodels.Tree
+	GetAllProject(projectId int) *viewmodels.Tree
+	GetAllContract(projectId int) *viewmodels.Tree
 	Rename(treevm viewmodels.Tree, projectId int) error
 	GetFolderAndBid(id int, projectId int) ([]models.CmTree, error)
 	DeleteFolderAndBid(id int, projectId int) error
@@ -67,7 +68,6 @@ func (s *treeService) ValidRule(ctx iris.Context) (viewmodels.Tree, error) {
 
 // 获得项目下 相关文件夹-整个树结构
 func (s *treeService) GetAllProject(projectId int) *viewmodels.Tree {
-
 	datalist := s.dao.GetAllTree(projectId)
 	folderlist := make([]viewmodels.Tree, 0)
 	// 生成根
@@ -118,6 +118,59 @@ func (s *treeService) GetAllProject(projectId int) *viewmodels.Tree {
 	return node
 }
 
+// 获得合同管理的目录
+func (s *treeService) GetAllContract(projectId int) *viewmodels.Tree {
+	datalist := s.dao.GetAllTree(projectId)
+	folderlist := make([]viewmodels.Tree, 0)
+	// 生成根
+	folder := viewmodels.Tree{}
+	id, _ := comm.AesEncrypt(strconv.Itoa(0), conf.SignSecret)
+	parentId, _ := comm.AesEncrypt(strconv.Itoa(-1), conf.SignSecret)
+	folder.Id = id
+	folder.Name = "root"
+	folder.ParentId = parentId
+	folderlist = append(folderlist, folder)
+	// 加入数据
+	for _, data := range datalist {
+		folder := viewmodels.Tree{}
+		id, _ := comm.AesEncrypt(strconv.Itoa(data.Id), conf.SignSecret)
+		parentId, _ := comm.AesEncrypt(strconv.Itoa(data.ParentId), conf.SignSecret)
+		projectId, _ := comm.AesEncrypt(strconv.Itoa(data.ProjectId), conf.SignSecret)
+		serial, _ := comm.AesEncrypt(strconv.Itoa(data.Serial), conf.SignSecret)
+		folder.Id = id
+		folder.Name = data.Name
+		folder.ParentId = parentId
+		folder.ProjectId = projectId
+		folder.Depth = data.Depth + 1
+		folder.Serial = serial
+		folder.Ancounts = data.Ancounts
+		// 合同数据
+
+		folder.Isfolder = data.Isfolder
+		folder.IsEnd = false
+
+		folder.HasFolder = false
+		folder.IsBid = false
+		folder.CreateTime = data.CreateTime.Format(conf.SysTimeform)
+		folderlist = append(folderlist, folder)
+	}
+
+	//fmt.Println(folderlist)
+
+	var data []*viewmodels.Tree
+	data = make([]*viewmodels.Tree, 0)
+	for i, _ := range folderlist {
+		var a *viewmodels.Tree
+		a = &folderlist[i]
+		data = append(data, a)
+	}
+
+	node := &folderlist[0] //父节点
+	maketree(data, node)   //调用生成tree
+	//transformjson(node)    //转化为json
+	return node
+}
+
 // 新增一个文件夹
 func (s *treeService) Create(data viewmodels.Tree) error {
 	// 类型校验
@@ -275,15 +328,55 @@ func (s *treeService) DeleteFolderAndBid(id int, projectId int) error {
 func (s *treeService) Move(id int, moveId int, projectId int) error {
 	// 获得项目目录
 	treeNode := s.dao.Get(id, projectId)
+
 	if treeNode.Id == 0 {
 		return errors.New("目录或标段解析错误")
 	}
-	moveFolder := s.dao.Get(moveId, projectId)
-	if moveFolder.Id == 0 {
-		return errors.New("目录解析错误")
+
+	targetFolder := &models.CmTree{}
+	// id为0是跟目录
+	if moveId == 0 {
+		// id
+		targetFolder.Id = 0
+		// 1.获得最大序号
+		// seriallist := s.dao.GetALLDepthByAttribution(0, projectId, "")
+		// maxIndex := len(seriallist)
+		// serial := 0
+		// if maxIndex != 0 {
+		// 	serial = seriallist[maxIndex-1].Serial + 1
+		// }
+		// targetFolder.Serial = serial
+		targetFolder.Serial = 0
+		// 2.归属
+		targetFolder.Attribution = ""
+		// 3.深度depth-根目录为-1
+		targetFolder.Depth = -1
+		// 4.为目录
+		targetFolder.Isfolder = 1
+		// 5.项目ID
+		targetFolder.ProjectId = projectId
+
+		// fmt.Println(targetFolder)
+		// if targetFolder.Id == 0 {
+		// 	return errors.New("目录解析错误-测试")
+		// }
+	} else {
+		targetFolder = s.dao.Get(moveId, projectId)
+		if targetFolder.Id == 0 {
+			return errors.New("目录解析错误")
+		}
+	}
+
+	// 目录必须是目录
+	if targetFolder.Isfolder == 0 {
+		return errors.New("目标不是文件夹")
+	}
+
+	// 目录的目标不能是自己
+	if id == moveId {
+		return errors.New("目标目录是原目录-不能移动")
 	}
 
-	// TODO
 	// 移动的是目录
 	if treeNode.Isfolder == 1 {
 		// 1.目录下不能有标段
@@ -301,7 +394,7 @@ func (s *treeService) Move(id int, moveId int, projectId int) error {
 		}
 	}
 
-	err := s.dao.Move(treeNode, moveFolder)
+	err := s.dao.Move(treeNode, targetFolder)
 	if err != nil {
 		return err
 	}

+ 43 - 0
web/api/contract_api.go

@@ -0,0 +1,43 @@
+/*
+ * @description: 合同管理相关API
+ * @Author: CP
+ * @Date: 2020-10-26 15:27:04
+ * @FilePath: \construction_management\web\api\contract_api.go
+ */
+package api
+
+import (
+	"github.com/kataras/iris/v12"
+	"go.mod/services"
+	"go.mod/web/utils"
+)
+
+type ContractApi struct {
+	//框架-web应用上下文环境
+	Ctx iris.Context
+	// // 需要用的service
+	ServiceTree services.TreeService
+	// ServiceLogin          services.LoginService
+	// ServiceProject        services.ProjectService
+}
+
+func (c *ContractApi) Get() {
+	// 获得项目ID
+	projectIdInt, err := utils.GetProjectId(c.Ctx)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{
+			"code": -1,
+			"msg":  err,
+		})
+		return
+	}
+
+	// 获得层级文件夹
+	FolderData := c.ServiceTree.GetAllContract(projectIdInt)
+
+	c.Ctx.JSON(iris.Map{
+		"code": 0,
+		"msg":  "",
+		"data": FolderData,
+	})
+}

+ 23 - 7
web/api/project_api.go

@@ -31,13 +31,6 @@ type ProjectApi struct {
 // @Success 200 {object} viewmodels.Project "{code:0成功,-1参数类错误,data:viewmodels.ProjectAccount,msg:错误信息}"
 // @Router /api/project [get]
 func (c *ProjectApi) Get() {
-	// 验证内容
-	// ProjectData := viewmodels.Project{}
-	// err := c.Ctx.ReadForm(&ProjectData)
-	// if err != nil {
-	// 	c.Ctx.JSON(iris.Map{"code": -1, "msg": "ReadForm转换异常"})
-	// 	return
-	// } else {
 	// 获得项目ID
 	projectIdInt, err := utils.GetProjectId(c.Ctx)
 	if err != nil {
@@ -54,6 +47,29 @@ func (c *ProjectApi) Get() {
 	// }
 }
 
+// 保存项目管理员信息
+func (c *ProjectApi) PostSave() {
+	// ErrMsg := ""
+	// // 验证内容
+	// AccountData, err := c.ServiceProjectAccount.ValidRule(c.Ctx)
+	// if err != nil {
+	// 	ErrMsg = utils.FormValidError(err)
+	// 	comm.Redirect(c.Ctx.ResponseWriter(), "/account?errMsg="+ErrMsg)
+	// } else {
+	// 	// 获得更新用户ID
+	// 	id, err := c.Ctx.Values().GetInt("accountId")
+	// 	if err != nil {
+	// 		comm.Redirect(c.Ctx.ResponseWriter(), "/account?errMsg="+ErrMsg)
+	// 	}
+	// 	// 保存信息
+	// 	err = c.ServiceProjectAccount.Save(AccountData, id, 0)
+	// 	if err != nil {
+	// 		comm.Redirect(c.Ctx.ResponseWriter(), "/account?errMsg="+ErrMsg)
+	// 	}
+	// 	comm.Redirect(c.Ctx.ResponseWriter(), "/account?success=修改成功")
+	// }
+}
+
 // 获得多个项目信息--暂无使用
 func (c *ProjectApi) GetList() {
 	// 验证内容

+ 48 - 7
web/api/project_setting_auth_api.go

@@ -66,20 +66,20 @@ func (c *ProjectSettingApi) GetBidAccount() {
 	})
 }
 
-// 标段中添加成员-账号
-// @Summary 获得标段账号
+// @Summary 标段中添加成员-账号
 // @Tags 项目设置-标段成员权限-管理员
-// @Description 获得标段账号
+// @Description 标段中添加成员-账号
 // @Accept  json
 // @Produce  json
 // @Security ApiKeyAuth
-// @Param   bidsectionId     path    string     false        "标段ID"
-// @Success 200 {object} viewmodels.ProjectAccount "{code:0成功,-1参数类错误,data:viewmodels.ProjectAccount,msg:错误信息}"
-// @Router /api/projectSetting/bid/account [get]
+// @Param   bidsectionId     body    string     false        "标段ID"
+// @Param   accountId     body    string     false        "账号ID"
+// @Success 200 {string} string "{code:0成功,-1参数类错误,data:viewmodels.ProjectAccount,msg:错误信息}"
+// @Router /api/projectSetting/bid/account/create [post]
 func (c *ProjectSettingApi) PostBidAccountCreate() {
+
 	// 账号ID,标段ID,目录ID
 	BidAccountData, err := c.ServiceBidAccount.ValidRule(c.Ctx)
-
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": utils.FormValidError(err)})
 		return
@@ -102,3 +102,44 @@ func (c *ProjectSettingApi) PostBidAccountCreate() {
 		"msg":  "新增成功",
 	})
 }
+
+// 设置权限
+func (c *ProjectSettingApi) PostBidAccountAuth() {
+
+}
+
+// @Summary 移除标段成员-账号
+// @Tags 项目设置-标段成员权限-管理员
+// @Description 移除标段成员-账号
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Param   bidsectionId     body    string     false        "标段ID"
+// @Param   accountId     body    string     false        "账号ID"
+// @Success 200 {string} string "{code:0成功,-1参数类错误,data:viewmodels.ProjectAccount,msg:错误信息}"
+// @Router /api/projectSetting/bid/account [delete]
+func (c *ProjectSettingApi) DeleteBidAccount() {
+	// 账号ID,标段ID
+	BidAccountData, err := c.ServiceBidAccount.ValidRule(c.Ctx)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": utils.FormValidError(err)})
+		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.ServiceBidAccount.Delete(BidAccountData, projectIdInt)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": ""})
+		return
+	}
+	c.Ctx.JSON(iris.Map{
+		"code": 0,
+		"msg":  "移除成功",
+	})
+}

+ 9 - 3
web/api/tree_api.go

@@ -167,7 +167,13 @@ func (c *TreeApi) Delete() {
 	// fmt.Println(treeData)
 	// 添加锁
 
-	id, err := utils.GetDecryptId(c.Ctx.URLParam("id"))
+	idString := c.Ctx.URLParam("id")
+	if idString == "" {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": "目录不存在"})
+		return
+	}
+
+	id, err := utils.GetDecryptId(idString)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
 		return
@@ -204,7 +210,7 @@ func (c *TreeApi) Delete() {
 // @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
 // @Router /api/tree/move [post]
 func (c *TreeApi) PostMove() {
-	// 获得目录ID和移动目录ID
+	// 获得目录ID和移动目录ID--TODO 判断
 	Tree := viewmodels.Tree{}
 	err := c.Ctx.ReadJSON(&Tree)
 	if err != nil {
@@ -216,7 +222,7 @@ func (c *TreeApi) PostMove() {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
 		return
 	}
-	moveId, err := utils.GetDecryptId(Tree.MoveId)
+	moveId, err := utils.GetDecryptId(Tree.TargetFolderId)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
 		return

+ 14 - 6
web/routes/routes.go

@@ -41,10 +41,10 @@ func Configure(b *bootstrap.Bootstrapper) {
 	todo.Router.Use(middleware.SessionsAuth)
 	todo.Handle(new(controllers.TodoController))
 
-	// 合同管理
-	contract := mvc.New(b.Party("/contract"))
-	contract.Router.Use(middleware.SessionsAuth)
-	contract.Handle(new(controllers.ContractController))
+	// // 合同管理
+	// contract := mvc.New(b.Party("/contract"))
+	// contract.Router.Use(middleware.SessionsAuth)
+	// contract.Handle(new(controllers.ContractController))
 	// 安全巡检
 
 	//用户相关
@@ -99,8 +99,8 @@ func Configure(b *bootstrap.Bootstrapper) {
 	// 项目设置接口
 	apiSetting := mvc.New(b.Party("/api/projectSetting"))
 	apiSetting.Register(ProjectAccountService)
-	apiProject.Register(ProjectService)
-	apiProject.Register(BidAccountService)
+	apiSetting.Register(ProjectService)
+	apiSetting.Register(BidAccountService)
 	apiSetting.Router.Use(middleware.SessionsAuth)
 	apiSetting.Router.Use(middleware.AccessAuth)
 	apiSetting.Handle(new(api.ProjectSettingApi))
@@ -111,4 +111,12 @@ func Configure(b *bootstrap.Bootstrapper) {
 	apiTree.Router.Use(middleware.SessionsAuth)
 	apiTree.Router.Use(middleware.AccessAuth)
 	apiTree.Handle(new(api.TreeApi))
+
+	// 合同管理
+	apiContract := mvc.New(b.Party("/api/contract"))
+	apiContract.Register(TreeService)
+	// 中间件
+	apiContract.Router.Use(middleware.SessionsAuth)
+	apiContract.Router.Use(middleware.AccessAuth)
+	apiContract.Handle(new(api.ContractApi))
 }

+ 2 - 1
web/viewmodels/bid_account.go

@@ -20,8 +20,9 @@ type BidAccount struct {
 func (l BidAccount) Validate() error {
 	return validation.ValidateStruct(&l,
 		// Code cannot be empty, and the length must between 5 and 50
-		validation.Field(&l.BidsectionId, validation.Required.Error("标段不能为空")),
+		validation.Field(&l.BidsectionId, validation.Required.Error("标段ID不能为空")),
 		validation.Field(&l.AccountId, validation.Required.Error("账号ID不能为空")),
+		// validation.Field(&l.FolderId, validation.Required.Error("目录ID不能为空")),
 		//validation.Field(&l.Password, validation.Required.Error("密码不能为空"), validation.Length(6, 50).Error("密码最少要输入 6 个字符")),
 	)
 }

+ 13 - 0
web/viewmodels/bid_auth.go

@@ -0,0 +1,13 @@
+/*
+ * @description:标段权限相关
+ * @Author: CP
+ * @Date: 2020-10-23 16:08:30
+ * @FilePath: \construction_management\web\viewmodels\bid_auth.go
+ */
+package viewmodels
+
+type BidAuth struct {
+	ContractPermission []string `form:"contractPermission"`
+	QualityPermission  []string `form:"qualityPermission"`
+	SafePermission     []string `form:"safePermission"`
+}

+ 14 - 13
web/viewmodels/tree.go

@@ -13,19 +13,19 @@ import (
 // Leaf 叶子节点为true 可以显示创建标段
 // IsBid为true 目录下已包含标段
 type Tree struct {
-	Id           string `form:"id" json:"id" `
-	Name         string `form:"name" json:"name"`
-	ProjectId    string `form:"projectId" json:"projectId"`
-	BidsectionId string `form:"bidsectionId" json:"bidsectionId"`
-	ParentId     string `form:"parentId" json:"parentId"`
-	Depth        int    `form:"depth" json:"depth"`
-	Serial       string `form:"serial" json:"serial"`
-	Attribution  string `form:"attribution" json:"attribution"`
-	Isfolder     int    `form:"isfolder" json:"isfolder"`
-	CreateTime   string `form:"createTime" json:"createTime"`
-	UpdateTime   string `form:"updateTime" json:"updateTime"`
-	MoveId       string `form:"moveId" json:"moveId"`
-	Ancounts     int    `form:"ancounts" json:"ancounts"`
+	Id             string `form:"id" json:"id" `
+	Name           string `form:"name" json:"name"`
+	ProjectId      string `form:"projectId" json:"projectId"`
+	BidsectionId   string `form:"bidsectionId" json:"bidsectionId"`
+	ParentId       string `form:"parentId" json:"parentId"`
+	Depth          int    `form:"depth" json:"depth"`
+	Serial         string `form:"serial" json:"serial"`
+	Attribution    string `form:"attribution" json:"attribution"`
+	Isfolder       int    `form:"isfolder" json:"isfolder"`
+	CreateTime     string `form:"createTime" json:"createTime"`
+	UpdateTime     string `form:"updateTime" json:"updateTime"`
+	TargetFolderId string `form:"targetFolderId" json:"targetFolderId"`
+	Ancounts       int    `form:"ancounts" json:"ancounts"`
 
 	Csrf string `form:"csrf" json:"csrf"`
 	// Leaf        bool    `json:"leaf" `
@@ -38,6 +38,7 @@ type Tree struct {
 
 func (l Tree) Validate() error {
 	return validation.ValidateStruct(&l,
+		validation.Field(&l.Id, validation.Required.Error("文件夹ID不能为空")),
 		validation.Field(&l.Name, validation.Required.Error("文件夹名称不能为空"), validation.Length(1, 60).Error("最多 15 个字符")),
 	)
 }

+ 40 - 0
web/viewmodels/tree_contract.go

@@ -0,0 +1,40 @@
+/*
+ * @description:合同目录视图模型
+ * @Author: CP
+ * @Date: 2020-10-27 17:07:50
+ * @FilePath: \construction_management\web\viewmodels\tree_contract.go
+ */
+package viewmodels
+
+import validation "github.com/go-ozzo/ozzo-validation/v3"
+
+type TreeContract struct {
+	Id             string `form:"id" json:"id" `
+	Name           string `form:"name" json:"name"`
+	ProjectId      string `form:"projectId" json:"projectId"`
+	BidsectionId   string `form:"bidsectionId" json:"bidsectionId"`
+	ParentId       string `form:"parentId" json:"parentId"`
+	Depth          int    `form:"depth" json:"depth"`
+	Serial         string `form:"serial" json:"serial"`
+	Attribution    string `form:"attribution" json:"attribution"`
+	Isfolder       int    `form:"isfolder" json:"isfolder"`
+	CreateTime     string `form:"createTime" json:"createTime"`
+	UpdateTime     string `form:"updateTime" json:"updateTime"`
+	TargetFolderId string `form:"targetFolderId" json:"targetFolderId"`
+	Ancounts       int    `form:"ancounts" json:"ancounts"`
+
+	Csrf string `form:"csrf" json:"csrf"`
+	// Leaf        bool    `json:"leaf" `
+	HasFolder   bool            `json:"hasFolder" `
+	IsBid       bool            `json:"isBid" `
+	IsEnd       bool            `json:"isEnd"`
+	ChildsTotal int             `json:"childsTotal"`
+	Children    []*TreeContract `json:"children"`
+}
+
+func (l TreeContract) Validate() error {
+	return validation.ValidateStruct(&l,
+		validation.Field(&l.Id, validation.Required.Error("文件夹ID不能为空")),
+		validation.Field(&l.Name, validation.Required.Error("文件夹名称不能为空"), validation.Length(1, 60).Error("最多 15 个字符")),
+	)
+}