Browse Source

账号设置

caipin 4 years atrás
parent
commit
507a2e1a31

+ 36 - 36
bootstrap/bootstrap.go

@@ -9,6 +9,7 @@ package bootstrap
 import (
 	"time"
 
+	"github.com/iris-contrib/middleware/csrf"
 	"github.com/kataras/iris/v12"
 	"github.com/kataras/iris/v12/middleware/logger"
 	"github.com/kataras/iris/v12/middleware/recover"
@@ -64,41 +65,41 @@ func (b *Bootstrapper) SetupViews(viewsDir string) {
 }
 
 // 配置csrf
-// func (b *Bootstrapper) SetupCsrfHandlers(csrfKey string) {
-// 	protect := csrf.Protect([]byte(csrfKey), csrf.FieldName("csrf"), csrf.Secure(false))
-// 	//csrf.Domain("")
+func (b *Bootstrapper) SetupCsrfHandlers(csrfKey string) {
+	protect := csrf.Protect([]byte(csrfKey), csrf.FieldName("csrf"), csrf.Secure(false))
+	//csrf.Domain("")
 
-// 	b.Party("/", protect)
-// }
+	b.Party("/", protect)
+}
 
 // 配置jwt
-func (b *Bootstrapper) SetupJwtHandlers(jwtKey string) {
-
-	// j2 := jwt.New(jwt.Config{
-	// 	// 注意,新增了一个错误处理函数
-	// 	ErrorHandler: func(ctx iris.Context, err error) {
-	// 		if err == nil {
-	// 			return
-	// 		}
-
-	// 		ctx.StopExecution()
-	// 		ctx.StatusCode(iris.StatusUnauthorized)
-	// 		ctx.JSON(ResModel{
-	// 			Code: "501",
-	// 			Msg:  err.Error(),
-	// 		})
-	// 	},
-	// 	// 设置一个函数返回秘钥,关键在于return []byte("这里设置秘钥")
-	// 	ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
-	// 		return []byte(jwtKey), nil
-	// 	},
-
-	// 	// 设置一个加密方法
-	// 	SigningMethod: jwt.SigningMethodHS256,
-	// })
-
-	//b.Party("/", j2.Serve)
-}
+// func (b *Bootstrapper) SetupJwtHandlers(jwtKey string) {
+
+// 	// j2 := jwt.New(jwt.Config{
+// 	// 	// 注意,新增了一个错误处理函数
+// 	// 	ErrorHandler: func(ctx iris.Context, err error) {
+// 	// 		if err == nil {
+// 	// 			return
+// 	// 		}
+
+// 	// 		ctx.StopExecution()
+// 	// 		ctx.StatusCode(iris.StatusUnauthorized)
+// 	// 		ctx.JSON(ResModel{
+// 	// 			Code: "501",
+// 	// 			Msg:  err.Error(),
+// 	// 		})
+// 	// 	},
+// 	// 	// 设置一个函数返回秘钥,关键在于return []byte("这里设置秘钥")
+// 	// 	ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
+// 	// 		return []byte(jwtKey), nil
+// 	// 	},
+
+// 	// 	// 设置一个加密方法
+// 	// 	SigningMethod: jwt.SigningMethodHS256,
+// 	// })
+
+// 	//b.Party("/", j2.Serve)
+// }
 
 //处理异常--设置错误信息展示
 func (b *Bootstrapper) SetupErrorHandlers() {
@@ -151,18 +152,17 @@ func (b *Bootstrapper) Bootstrap() *Bootstrapper {
 	// 	[]byte("lot-secret-of-characters-big-too"),
 	// )
 	// 设置csrf
-	//b.SetupCsrfHandlers(CsrfKey)
+	b.SetupCsrfHandlers(CsrfKey)
 	// 设置jwt
-	b.SetupJwtHandlers(JwtKey)
+	//b.SetupJwtHandlers(JwtKey)
 	//设置异常信息
 	b.SetupErrorHandlers()
 
 	// static files
 	b.Favicon(StaticAssets + Favicon)
 	//b.StaticWeb(StaticAssets[1:], StaticAssets)
-
 	b.HandleDir(StaticAssets[1:], iris.Dir(StaticAssets))
-
+	b.HandleDir("/docs", iris.Dir("./docs"))
 	// indexHtml, err := ioutil.ReadFile(StaticAssets + "/index.html")
 	// if err == nil {
 	// 	b.StaticContent(StaticAssets[1:]+"/", "text/html",

+ 48 - 0
comm/account_group.go

@@ -0,0 +1,48 @@
+package comm
+
+import "errors"
+
+type AccountGroup struct {
+	JSDW int
+	JLDW int
+	SGDW int
+	SJDW int
+	DJDW int
+	GZSJ int
+	QT   int
+}
+
+func NewAccountGroup() *AccountGroup {
+	return &AccountGroup{
+		JSDW: 1,
+		JLDW: 2,
+		SGDW: 3,
+		SJDW: 4,
+		DJDW: 5,
+		GZSJ: 6,
+		QT:   7,
+	}
+}
+
+// 验证输入
+func (a *AccountGroup) ValidRule(index int) error {
+	if a.JSDW == index || a.JLDW == index || a.SGDW == index || a.SJDW == index || a.DJDW == index || a.GZSJ == index || a.QT == index {
+		return nil
+	} else {
+		return errors.New("账号组不正确")
+	}
+}
+
+// const AccountGroup:=map[string]int{
+// 	"JSDW": 1,
+//     "JLDW": 2,
+//     "SGDW": 3,
+//     "SJDW": 4,
+//     "DJDW": 5,
+//     "GZSJ": 6,
+//     "QT": 7,
+// }
+
+// const Group:=[...]string{
+// 	AccountGroup.
+// }

+ 19 - 0
comm/client.go

@@ -0,0 +1,19 @@
+/*
+ * @description:第三方请求相关
+ * @Author: CP
+ * @Date: 2020-09-03 16:19:26
+ * @FilePath: \construction_management\comm\client.go
+ */
+package comm
+
+import "github.com/kirinlabs/HttpRequest"
+
+func sendRequest(url string, data map[string]string, method string, dataType string) map[string]string {
+	req := HttpRequest.NewRequest()
+	//req := HttpRequest.NewRequest().Debug(debug).SetTimeout(5)
+	if dataType == "JSON" {
+		req.SetHeaders(map[string]string{"Content-Type": "application/json"})
+	}
+
+	return nil
+}

+ 27 - 0
comm/functions.go

@@ -23,8 +23,27 @@ import (
 	"strings"
 
 	"go.mod/conf"
+	"go.mod/models"
+	"go.mod/web/viewmodels"
 )
 
+// 构造视图层models
+func MakeProjectAccountVM(modelsAccount *models.CmProjectAccount) viewmodels.ProjectAccount {
+	viewAccountData := viewmodels.ProjectAccount{}
+	aesId, _ := AesEncrypt(strconv.Itoa(modelsAccount.Id), conf.SignSecret)
+	aesProjectId, _ := AesEncrypt(strconv.Itoa(modelsAccount.ProjectId), conf.SignSecret)
+	viewAccountData.Id = aesId
+	viewAccountData.ProjectId = aesProjectId
+	viewAccountData.Account = modelsAccount.Account
+	viewAccountData.Name = modelsAccount.Name
+	viewAccountData.Company = modelsAccount.Company
+	viewAccountData.Role = modelsAccount.Role
+	viewAccountData.Mobile = modelsAccount.Mobile
+	viewAccountData.Telephone = modelsAccount.Telephone
+	viewAccountData.IsAdmin = modelsAccount.IsAdmin
+	return viewAccountData
+}
+
 // 当前时间的时间戳
 func NowUnix() int {
 	return int(time.Now().In(conf.SysTimeLocation).Unix())
@@ -63,6 +82,14 @@ func Random(max int) int {
 	}
 }
 
+// 加密密码
+func CreatePasswordSign(password string, account string) string {
+	str := string(conf.SignSecret) + password + account
+	str1 := fmt.Sprintf("%x", md5.Sum([]byte(str)))
+	sign := fmt.Sprintf("%x", md5.Sum([]byte(str1)))
+	return sign
+}
+
 // 对字符串进行签名
 func CreateSign(str string) string {
 	str = string(conf.SignSecret) + str

+ 1 - 1
conf/project.go

@@ -21,7 +21,7 @@ var SignSecret = "cpcm005687gokaif"
 // cookie中的加密验证密钥
 var CookieSecret = "cm_login_account"
 
-const UserPrizeMax = 3000 // 用户每天最多抽奖次数
+const UserPrizeMax = 3000 //
 
 // 定义24小时的奖品分配权重
 var PrizeDataRandomDayTime = [100]int{

+ 0 - 2
dao/manager_dao.go

@@ -42,8 +42,6 @@ func (d *ManagerDao) Get(id int) *models.CmManager {
 //获得全部管理员数据
 func (d *ManagerDao) GetAll() []models.CmManager {
 
-	fmt.Println(d.engine)
-
 	datalist := make([]models.CmManager, 0)
 	err := d.engine.Asc("created_time").Find(&datalist)
 	//Asc("displayorder").

+ 37 - 3
dao/project_account_dao.go

@@ -37,9 +37,8 @@ func (d *ProjectAccountDao) GetOne(data *models.CmProjectAccount) *models.CmProj
 }
 
 //id获得数据
-func (d *ProjectAccountDao) Get(id int) *models.CmProjectAccount {
-	data := &models.CmProjectAccount{Id: id}
-	//Get取到值后,会自动赋值到data中
+func (d *ProjectAccountDao) Get(id int, projectId int) *models.CmProjectAccount {
+	data := &models.CmProjectAccount{Id: id, ProjectId: projectId}
 	ok, err := d.engine.Get(data)
 	if ok && err == nil {
 		return data
@@ -49,6 +48,41 @@ func (d *ProjectAccountDao) Get(id int) *models.CmProjectAccount {
 	}
 }
 
+// 获得项目下的账号信息
+func (d *ProjectAccountDao) GetAll(projectId int) []models.CmProjectAccount {
+	datalist := make([]models.CmProjectAccount, 0)
+	err := d.engine.
+		Where("project_id = ?", projectId).
+		Desc("id").
+		Find(&datalist)
+	if err != nil {
+		return datalist
+	} else {
+		return datalist
+	}
+}
+
+// 检索 账号姓名单位手机
+func (d *ProjectAccountDao) Search(name string, projectId int) []models.CmProjectAccount {
+	datalist := make([]models.CmProjectAccount, 0)
+	err := d.engine.
+		Where("project_id = ? ", projectId).
+		And("account like ? or name like ? or company like ? or mobile like ?", name+"%", name+"%", name+"%", name+"%").
+		Desc("id").
+		Find(&datalist)
+	if err != nil {
+		return datalist
+	} else {
+		return datalist
+	}
+}
+
+// 新增
+func (d *ProjectAccountDao) Add(data *models.CmProjectAccount) error {
+	_, err := d.engine.Insert(data)
+	return err
+}
+
 //更新
 func (d *ProjectAccountDao) Update(data *models.CmProjectAccount, columns []string) error {
 	_, err := d.engine.Id(data.Id).MustCols(columns...).Update(data)

+ 0 - 3
dao/project_dao.go

@@ -7,8 +7,6 @@
 package dao
 
 import (
-	"fmt"
-
 	"github.com/go-xorm/xorm"
 	"go.mod/models"
 )
@@ -45,7 +43,6 @@ func (d *ProjectDao) GetListByCode(code string) []models.CmProject {
 		Where("code like ?", code+"%").
 		Desc("id").
 		Find(&datalist)
-	fmt.Println(datalist)
 	if err != nil {
 		return datalist
 	} else {

+ 35 - 0
dao/tree_dao.go

@@ -235,6 +235,41 @@ func (d *TreeDao) GetAllTree(projectId int) []models.CmTree {
 	}
 }
 
+// treeNode重命名
+func (d *TreeDao) Rename(data *models.CmTree, columns []string) error {
+
+	session := d.engine.NewSession()
+	defer session.Close()
+	err := session.Begin()
+	if err != nil {
+		return errors.New("重命名失败-db")
+	}
+
+	// 重命名treeNode
+	_, err = d.engine.Id(data.Id).MustCols(columns...).Update(data)
+	if err != nil {
+		session.Rollback()
+		return errors.New("标段重命名失败")
+	}
+	// 重命名标段
+	bidsection := models.CmBidsection{}
+	bidsection.Id = data.BidsectionId
+	bidsection.Name = data.Name
+	_, err = d.engine.Id(bidsection.Id).MustCols(columns...).Update(bidsection)
+	if err != nil {
+		session.Rollback()
+		return errors.New("标段重命名失败-bid")
+	}
+
+	err = session.Commit()
+	if err != nil {
+		session.Rollback()
+		return errors.New("重命名失败-db")
+	}
+
+	return nil
+}
+
 //创建
 func (d *TreeDao) Create(data *models.CmTree) error {
 	_, err := d.engine.Insert(data)

+ 2 - 2
models/cm_bidsection.go

@@ -24,8 +24,8 @@ type CmBidsection struct {
 	SImType      string    `xorm:"comment('期,中间计量,模式') VARCHAR(11)"`
 	Cooperation  string    `xorm:"comment('协作人员和功能列表') TEXT"`
 	Valuation    int       `xorm:"comment('计价规范') TINYINT(4)"`
-	TotalPrice   string    `xorm:"comment('0号台账 -- 金额') DECIMAL(12,2)"`
-	DealTp       string    `xorm:"comment('签约 -- 金额') DECIMAL(12,2)"`
+	TotalPrice   string    `xorm:"not null default 0.00 comment('0号台账 -- 金额') DECIMAL(12,2)"`
+	DealTp       string    `xorm:"not null default 0.00 comment('签约 -- 金额') DECIMAL(12,2)"`
 	Uuid         string    `xorm:"comment('更新时间') VARCHAR(64)"`
 	Isdelete     int       `xorm:"default 0 comment('1删除') TINYINT(1)"`
 }

+ 3 - 2
models/cm_project_account.go

@@ -14,11 +14,12 @@ type CmProjectAccount struct {
 	AccountGroup     int       `xorm:"comment('所属账号组') TINYINT(4)"`
 	Name             string    `xorm:"comment('姓名') VARCHAR(32)"`
 	Company          string    `xorm:"comment('公司名称') VARCHAR(64)"`
-	LastLogin        int       `xorm:"comment('最后登录时间') INT(11)"`
+	Position         string    `xorm:"comment('职位') VARCHAR(32)"`
+	LastLogin        time.Time `xorm:"comment('最后登录时间') DATETIME"`
 	Role             string    `xorm:"comment('角色') VARCHAR(32)"`
 	Mobile           string    `xorm:"comment('手机') VARCHAR(15)"`
 	Telephone        string    `xorm:"comment('座机') VARCHAR(15)"`
-	CreateTime       int       `xorm:"comment('创建时间') INT(11)"`
+	CreateTime       time.Time `xorm:"comment('创建时间') DATETIME"`
 	IsAdmin          int       `xorm:"comment('是否为管理员 1为管理员') TINYINT(1)"`
 	Enable           int       `xorm:"comment('是否启用 1为启用') TINYINT(1)"`
 	AuthMobile       string    `xorm:"comment('认证手机') VARCHAR(32)"`

+ 1 - 0
models/cm_tree.go

@@ -11,6 +11,7 @@ type CmTree struct {
 	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)"`

+ 120 - 54
services/login_service.go

@@ -8,13 +8,11 @@ package services
 
 import (
 	"errors"
-	"fmt"
 	"log"
 	"net/http"
+	"net/url"
 	"strconv"
-	"time"
 
-	"github.com/iris-contrib/middleware/jwt"
 	"github.com/kataras/iris/v12"
 	"go.mod/comm"
 	"go.mod/conf"
@@ -28,7 +26,8 @@ import (
 //定义项目用户Service接口
 type LoginService interface {
 	ValidRule(ctx iris.Context) (viewmodels.Login, error)
-	ValidProjectAccount(viewmodels.Login, http.ResponseWriter) error
+	ValidProjectAccount(viewmodels.Login, http.ResponseWriter) (*viewmodels.ProjectAccount, error)
+	Out(ctx iris.Context) error
 }
 
 //返回service操作类
@@ -63,85 +62,132 @@ func (s *loginService) ValidRule(ctx iris.Context) (viewmodels.Login, error) {
 }
 
 // 验证项目用户登陆相关
-func (s *loginService) ValidProjectAccount(loginData viewmodels.Login, writer http.ResponseWriter) error {
+func (s *loginService) ValidProjectAccount(loginData viewmodels.Login, writer http.ResponseWriter) (*viewmodels.ProjectAccount, error) {
 	projectInfo := models.CmProject{}
 	// 工程项目是否存在
 	projectInfo.Code = loginData.Code
-	fmt.Println(projectInfo.Code)
 	s.projectDao.Get(&projectInfo)
 	if projectInfo.Id == 0 {
-		return errors.New("工程建设管理员还未创建拉取项目,禁止登录")
+		return nil, errors.New("工程建设管理员还未创建项目,禁止登录")
 	}
 	// 获得项目用户
-	projectAccountInfo := s.projectAccountDao.Get(projectInfo.UserId)
+
+	projectAccountInfo := s.projectAccountDao.Get(projectInfo.UserId, projectInfo.Id)
 	if projectAccountInfo.Id == 0 {
-		return errors.New("工程建设管理员不存在,禁止登录")
+		return nil, errors.New("工程建设管理员不存在,禁止登录")
 	}
-	// 验证密码
+	// 验证密码-TODO
 	Jlzf := lib.NewJlzf()
 	err := Jlzf.LoginValid(loginData)
 	if err != nil {
-		return err
+		return nil, err
 	}
 
 	// 加密用户标识
 	identity, err := comm.AesEncrypt(strconv.Itoa(projectAccountInfo.Id), conf.CookieSecret)
 	if err != nil {
-		return err
+		return nil, err
 	}
 	// 加密项目标识
 	projectId, err := comm.AesEncrypt(strconv.Itoa(projectAccountInfo.ProjectId), conf.CookieSecret)
 	if err != nil {
-		return err
+		return nil, err
 	}
-	// jwt token
-	token := jwt.NewTokenWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
-		// 根据需求,可以存一些必要的数据
-		"identity": identity,
-		"project":  projectId,
-		// 签发人
-		"iss": "cm",
-		// 签发时间
-		"iat": time.Now().Unix(),
-		// 设定过期时间,便于测试,设置7天过期
-		"exp": time.Now().Add(72 * time.Hour * time.Duration(1)).Unix(),
-	})
-
-	// 使用设置的秘钥,签名生成jwt字符串
-	tokenString, _ := token.SignedString([]byte(conf.SignSecret))
-	fmt.Println(tokenString)
+
+	digitalToken := comm.CreateSign(conf.CookieSecret + strconv.Itoa(projectAccountInfo.Id))
+
+	// 设置cookie
 	maxAge := 60 * 60 * 24 * 7
-	// params := url.Values{}
-	// params.Add("token", tokenString)
+	params := url.Values{}
+	params.Add("identity", identity)
+	params.Add("attachedIdentity", projectId)
+	params.Add("digitalToken", digitalToken)
 	c := &http.Cookie{
-		Name:   "cm",
-		Value:  tokenString, //params.Encode(),
-		Path:   "/",
-		MaxAge: maxAge,
+		Name:     "cm",
+		Value:    params.Encode(),
+		Path:     "/",
+		MaxAge:   maxAge,
+		HttpOnly: true,
 	}
 	http.SetCookie(writer, c)
 
-	// // 加密用户标识 生成数字证书
-	// identity, err := comm.AesEncrypt(strconv.Itoa(projectAccountInfo.Id), conf.CookieSecret)
-	// if err != nil {
-	// 	return err
-	// }
-	// digitalToken := comm.CreateSign(conf.CookieSecret + strconv.Itoa(projectAccountInfo.Id))
-
-	// // 设置cookie
-	// maxAge := 60 * 60 * 24 * 7
-	// params := url.Values{}
-	// params.Add("identity", identity)
-	// params.Add("digitalToken", digitalToken)
-	// c := &http.Cookie{
-	// 	Name:   "cm",
-	// 	Value:  params.Encode(),
-	// 	Path:   "/",
-	// 	MaxAge: maxAge,
-	// }
-	// http.SetCookie(writer, c)
 	// TODO--分布式会话--后续需要在加入
 
+	viewAccountData := comm.MakeProjectAccountVM(projectAccountInfo)
+	return &viewAccountData, nil
+}
+
+// TODO -替换jwt
+// 验证项目用户登陆相关
+// func (s *loginService) ValidProjectAccount(loginData viewmodels.Login, writer http.ResponseWriter) error {
+// 	projectInfo := models.CmProject{}
+// 	// 工程项目是否存在
+// 	projectInfo.Code = loginData.Code
+// 	s.projectDao.Get(&projectInfo)
+// 	if projectInfo.Id == 0 {
+// 		return errors.New("工程建设管理员还未创建项目,禁止登录")
+// 	}
+// 	// 获得项目用户
+// 	projectAccountInfo := s.projectAccountDao.Get(projectInfo.UserId, projectInfo.Id)
+// 	if projectAccountInfo.Id == 0 {
+// 		return errors.New("工程建设管理员不存在,禁止登录")
+// 	}
+// 	// 验证密码-TODO
+// 	Jlzf := lib.NewJlzf()
+// 	err := Jlzf.LoginValid(loginData)
+// 	if err != nil {
+// 		return err
+// 	}
+
+// 	// 加密用户标识
+// 	identity, err := comm.AesEncrypt(strconv.Itoa(projectAccountInfo.Id), conf.CookieSecret)
+// 	if err != nil {
+// 		return err
+// 	}
+// 	// 加密项目标识
+// 	projectId, err := comm.AesEncrypt(strconv.Itoa(projectAccountInfo.ProjectId), conf.CookieSecret)
+// 	if err != nil {
+// 		return err
+// 	}
+// 	// jwt token
+// 	token := jwt.NewTokenWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
+// 		// 根据需求,可以存一些必要的数据
+// 		"identity": identity,
+// 		"project":  projectId,
+// 		// 签发人
+// 		"iss": "cm",
+// 		// 签发时间
+// 		"iat": time.Now().Unix(),
+// 		// 设定过期时间,便于测试,设置7天过期
+// 		"exp": time.Now().Add(72 * time.Hour * time.Duration(1)).Unix(),
+// 	})
+
+// 	// 使用设置的秘钥,签名生成jwt字符串
+// 	tokenString, _ := token.SignedString([]byte(conf.SignSecret))
+// 	fmt.Println(tokenString)
+// 	maxAge := 60 * 60 * 24 * 7
+// 	// params := url.Values{}
+// 	// params.Add("token", tokenString)
+// 	c := &http.Cookie{
+// 		Name:   "cm",
+// 		Value:  tokenString, //params.Encode(),
+// 		Path:   "/",
+// 		MaxAge: maxAge,
+// 		//HttpOnly: true,
+// 	}
+// 	http.SetCookie(writer, c)
+
+// 	// TODO--分布式会话--后续需要在加入
+
+// 	return nil
+// }
+
+// 登出
+func (s *loginService) Out(ctx iris.Context) error {
+	// 作废jwt token
+
+	// 移除cookie
+	ctx.RemoveCookie("cm")
 	return nil
 }
 
@@ -165,3 +211,23 @@ func (s *loginService) ValidProjectAccount(loginData viewmodels.Login, writer ht
 // 	Account:  ctx.FormValue("account"),
 // 	Password: ctx.FormValue("password"),
 // }
+
+// // 加密用户标识 生成数字证书
+// identity, err := comm.AesEncrypt(strconv.Itoa(projectAccountInfo.Id), conf.CookieSecret)
+// if err != nil {
+// 	return err
+// }
+// digitalToken := comm.CreateSign(conf.CookieSecret + strconv.Itoa(projectAccountInfo.Id))
+
+// // 设置cookie
+// maxAge := 60 * 60 * 24 * 7
+// params := url.Values{}
+// params.Add("identity", identity)
+// params.Add("digitalToken", digitalToken)
+// c := &http.Cookie{
+// 	Name:   "cm",
+// 	Value:  params.Encode(),
+// 	Path:   "/",
+// 	MaxAge: maxAge,
+// }
+// http.SetCookie(writer, c)

+ 74 - 37
services/project_account_service.go

@@ -7,12 +7,13 @@
 package services
 
 import (
+	"errors"
+	"html"
 	"log"
-	"strconv"
+	"time"
 
 	"github.com/kataras/iris/v12"
 	"go.mod/comm"
-	"go.mod/conf"
 	"go.mod/models"
 	"go.mod/web/viewmodels"
 
@@ -24,7 +25,10 @@ import (
 type ProjectAccountService interface {
 	ValidRule(ctx iris.Context) (viewmodels.ProjectAccount, error)
 	Save(viewAccount viewmodels.ProjectAccount, id int) error
-	Get(id int) *viewmodels.ProjectAccount
+	Get(accountId int, projectId int) *viewmodels.ProjectAccount
+	GetAll(projectId int) []viewmodels.ProjectAccount
+	Search(name string, projectId int) []viewmodels.ProjectAccount
+	Add(viewAccount viewmodels.ProjectAccount) error
 }
 
 //返回service操作类
@@ -42,7 +46,7 @@ func NewProjectAccountService() ProjectAccountService {
 // 用户规则验证
 func (s *projectAccountService) ValidRule(ctx iris.Context) (viewmodels.ProjectAccount, error) {
 	accountVaild := viewmodels.ProjectAccount{}
-	err := ctx.ReadForm(&accountVaild)
+	err := ctx.ReadJSON(&accountVaild)
 	if err != nil {
 		log.Println("account-ValidRule-ReadForm转换异常, error=", err)
 		return accountVaild, err
@@ -54,33 +58,83 @@ func (s *projectAccountService) ValidRule(ctx iris.Context) (viewmodels.ProjectA
 		return accountVaild, err
 	}
 
+	// 验证账号组
+	accountGroup := comm.NewAccountGroup()
+	err = accountGroup.ValidRule(accountVaild.AccountGroup)
+	if err != nil {
+		log.Println("用户验证, error=", err)
+		return accountVaild, err
+	}
+
+	// xss
+	accountVaild.Account = html.EscapeString(accountVaild.Account)
+	accountVaild.Password = html.EscapeString(accountVaild.Password)
+	accountVaild.Name = html.EscapeString(accountVaild.Name)
+	accountVaild.Company = html.EscapeString(accountVaild.Company)
+	accountVaild.Position = html.EscapeString(accountVaild.Position)
+	accountVaild.Mobile = html.EscapeString(accountVaild.Mobile)
+	accountVaild.Telephone = html.EscapeString(accountVaild.Telephone)
+
 	return accountVaild, nil
 }
 
 // 获得一个项目用户
-func (s *projectAccountService) Get(id int) *viewmodels.ProjectAccount {
-	modelsAccount := s.dao.Get(id)
+func (s *projectAccountService) Get(id int, projectId int) *viewmodels.ProjectAccount {
+	modelsAccount := s.dao.Get(id, projectId)
 	viewAccountData := viewmodels.ProjectAccount{}
 	if modelsAccount.Id == 0 {
 		viewAccountData.Id = "0"
 		return &viewAccountData
 	}
 
-	viewAccountData = makeProjectAccountVM(modelsAccount)
+	viewAccountData = comm.MakeProjectAccountVM(modelsAccount)
 	return &viewAccountData
-	// viewAccountData = makeProjectAccountVM(modelsAccount)
-
-	// aesId, _ := comm.AesEncrypt(strconv.Itoa(modelsAccount.Id), conf.SignSecret)
-	// aesProjectId, _ := comm.AesEncrypt(strconv.Itoa(modelsAccount.ProjectId), conf.SignSecret)
-	// viewAccountData.Id = aesId
-	// viewAccountData.ProjectId = aesProjectId
-	// viewAccountData.Account = modelsAccount.Account
-	// viewAccountData.Name = modelsAccount.Name
-	// viewAccountData.Company = modelsAccount.Company
-	// viewAccountData.Role = modelsAccount.Role
-	// viewAccountData.Mobile = modelsAccount.Mobile
-	// viewAccountData.Telephone = modelsAccount.Telephone
-	// return &viewAccountData
+}
+
+// 获得项目下所有账号信息
+func (s *projectAccountService) GetAll(projectId int) []viewmodels.ProjectAccount {
+	accountList := s.dao.GetAll(projectId)
+	accountListVM := make([]viewmodels.ProjectAccount, 0)
+	for _, data := range accountList {
+		account := comm.MakeProjectAccountVM(&data)
+		accountListVM = append(accountListVM, account)
+	}
+	return accountListVM
+}
+
+// 检索 账号姓名单位手机
+func (s *projectAccountService) Search(name string, projectId int) []viewmodels.ProjectAccount {
+	accountList := s.dao.Search(name, projectId)
+	accountListVM := make([]viewmodels.ProjectAccount, 0)
+	for _, data := range accountList {
+		account := comm.MakeProjectAccountVM(&data)
+		accountListVM = append(accountListVM, account)
+	}
+	return accountListVM
+}
+
+// 新增账号
+func (s *projectAccountService) Add(viewAccount viewmodels.ProjectAccount) error {
+
+	// 验证该项目下是否有同名账号--TODO
+	accountValid := &models.CmProjectAccount{}
+	s.dao.GetOne(accountValid)
+	if accountValid.Id != 0 {
+		return errors.New("已存在相同的账号")
+	}
+
+	account := models.CmProjectAccount{}
+	account.Account = viewAccount.Account
+	account.Password = comm.CreatePasswordSign(viewAccount.Password, viewAccount.Account)
+	account.Name = viewAccount.Name
+	account.Company = viewAccount.Company
+	account.Position = viewAccount.Position
+	account.Mobile = viewAccount.Mobile
+	account.Telephone = viewAccount.Telephone
+	account.AccountGroup = viewAccount.AccountGroup
+	account.CreateTime = time.Now()
+	err := s.dao.Add(&account)
+	return err
 }
 
 // 保存用户信息
@@ -97,20 +151,3 @@ func (s *projectAccountService) Save(viewAccount viewmodels.ProjectAccount, id i
 
 	return err
 }
-
-// 构造视图层models
-func makeProjectAccountVM(modelsAccount *models.CmProjectAccount) viewmodels.ProjectAccount {
-	viewAccountData := viewmodels.ProjectAccount{}
-	aesId, _ := comm.AesEncrypt(strconv.Itoa(modelsAccount.Id), conf.SignSecret)
-	aesProjectId, _ := comm.AesEncrypt(strconv.Itoa(modelsAccount.ProjectId), conf.SignSecret)
-	viewAccountData.Id = aesId
-	viewAccountData.ProjectId = aesProjectId
-	viewAccountData.Account = modelsAccount.Account
-	viewAccountData.Name = modelsAccount.Name
-	viewAccountData.Company = modelsAccount.Company
-	viewAccountData.Role = modelsAccount.Role
-	viewAccountData.Mobile = modelsAccount.Mobile
-	viewAccountData.Telephone = modelsAccount.Telephone
-	viewAccountData.IsAdmin = modelsAccount.IsAdmin
-	return viewAccountData
-}

+ 22 - 0
services/project_service.go

@@ -25,6 +25,7 @@ type ProjectService interface {
 	ValidRule(iris.Context) (viewmodels.Project, error)
 	Get(*viewmodels.Project)
 	GetList(viewmodels.Project) []viewmodels.Project
+	GetName(code string) []viewmodels.Project
 }
 
 //返回service操作类
@@ -116,6 +117,20 @@ func (s *projectService) GetList(projectVM viewmodels.Project) []viewmodels.Proj
 	return datalist
 }
 
+// 获得项目名称
+func (s *projectService) GetName(code string) []viewmodels.Project {
+	datalist := make([]viewmodels.Project, 0)
+	if code != "" {
+		projectData := s.dao.GetListByCode(code)
+		for _, data := range projectData {
+			projectVM := makeProjectNameVM(&data)
+			datalist = append(datalist, projectVM)
+		}
+		return datalist
+	}
+	return datalist
+}
+
 // 构造视图层models
 func makeProjectVM(projectCM *models.CmProject) viewmodels.Project {
 	projectVM := viewmodels.Project{}
@@ -125,3 +140,10 @@ func makeProjectVM(projectCM *models.CmProject) viewmodels.Project {
 	projectVM.Name = projectCM.Name
 	return projectVM
 }
+
+func makeProjectNameVM(projectCM *models.CmProject) viewmodels.Project {
+	projectVM := viewmodels.Project{}
+	projectVM.Code = projectCM.Code
+	projectVM.Name = projectCM.Name
+	return projectVM
+}

+ 16 - 6
services/tree_service.go

@@ -188,13 +188,23 @@ func (s *treeService) Rename(data viewmodels.Tree) error {
 	if err1 != nil {
 		return err1
 	}
-	// 装配需要更新的数据
-	folder := models.CmTree{}
-	folder.Id = IdInt
-	folder.Name = data.Name
-	err = s.dao.Update(&folder, []string{"Name"})
+
+	// 获得树信息
+	treeData := s.dao.Get(IdInt)
+	treeNode := models.CmTree{}
+	treeNode.Id = IdInt
+	treeNode.Name = data.Name
+	if treeData.Isfolder == 1 {
+		// 目录
+		err = s.dao.Update(&treeNode, []string{"Name"})
+	} else {
+		// 标段
+		treeNode.BidsectionId = treeData.BidsectionId
+		err = s.dao.Rename(&treeNode, []string{"Name"})
+	}
+
 	if err != nil {
-		return errors.New("目录重命名出错")
+		return err
 	}
 	return nil
 }

+ 78 - 44
web/api/login_api.go

@@ -7,11 +7,10 @@
 package api
 
 import (
-	"fmt"
-
 	"github.com/kataras/iris/v12"
 	"go.mod/services"
 	"go.mod/web/utils"
+	"go.mod/web/viewmodels"
 )
 
 type LoginApi struct {
@@ -20,6 +19,83 @@ type LoginApi struct {
 	// 需要用的service
 	ServiceProjectAccount services.ProjectAccountService
 	ServiceLogin          services.LoginService
+	ServiceProject        services.ProjectService
+}
+
+// @Summary 登录
+// @Description 登录接口
+// @Tags 登录/登出
+// @Accept  json
+// @Produce  json
+// @Param   code     	body    string     true        "项目编号" 	default(234)
+// @Param   account     body    string     true        "项目账号" 	default(caipin)
+// @Param   password     body    string    true        "密码"		default(123456)
+// @Param   X-CSRF-Token      header    string     true        "csrf"
+// @Success 200 {object} viewmodels.ProjectAccount
+// @Failure 400 {string} string	"{code:0,msg:string}"
+// @Router /api/login [post]
+func (c *LoginApi) Post() {
+
+	//验证规则
+	LoginData, err := c.ServiceLogin.ValidRule(c.Ctx)
+	if err != nil {
+		ErrMsg := utils.FormValidError(err)
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": ErrMsg})
+		return
+	}
+	//验证登陆用户
+	Data, err := c.ServiceLogin.ValidProjectAccount(LoginData, c.Ctx.ResponseWriter())
+	if err != nil {
+
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
+		return
+	}
+	c.Ctx.JSON(iris.Map{
+		"code": 0,
+		"msg":  "",
+		"data": Data,
+	})
+}
+
+// @Summary 登出
+// @Tags 登录/登出
+// @Accept  json
+// @Produce  json
+// @Success 200 {string} string	"{code:0,msg:string}"
+// @Failure 400 {string} string "{code:-1,msg:string}"
+// @Router /api/login/out [post]
+func (c *LoginApi) PostOut() {
+	c.ServiceLogin.Out(c.Ctx)
+	c.Ctx.JSON(iris.Map{"code": 0, "msg": ""})
+}
+
+// @Summary 获得项目名称
+// @Tags 登录/登出
+// @Accept  json
+// @Produce  json
+// @Param   code     	query    string     true        "项目编号" 	default({code:2})
+// @Success 200 {object} viewmodels.Project
+// @Failure 400 {string} string "{code:-1,msg:string}"
+// @Router /api/login/project/name [get]
+func (c *LoginApi) GetProjectName() {
+	// 验证内容
+	ProjectData := viewmodels.Project{}
+	err := c.Ctx.ReadForm(&ProjectData)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{
+			"code": -1,
+			"msg":  "ReadJSON转换异常,请检查code",
+		})
+		return
+	} else {
+		// 获得项目信息
+		dataList := c.ServiceProject.GetName(ProjectData.Code)
+		c.Ctx.JSON(iris.Map{
+			"code": 0,
+			"msg":  "",
+			"data": dataList,
+		})
+	}
 }
 
 // func (c *LoginApi) Get() {
@@ -43,45 +119,3 @@ type LoginApi struct {
 // 	// 返回
 // 	c.Ctx.JSON(tokenString)
 // }
-
-//登陆
-func (c *LoginApi) Post() {
-	ErrMsg := ""
-	Code := -1
-	//验证规则
-	LoginData, err := c.ServiceLogin.ValidRule(c.Ctx)
-	if err != nil {
-		ErrMsg = utils.FormValidError(err)
-	} else {
-		//验证登陆用户
-		err = c.ServiceLogin.ValidProjectAccount(LoginData, c.Ctx.ResponseWriter())
-		if err != nil {
-			ErrMsg = fmt.Sprintf("%s", err)
-		} else {
-			//验证通关
-			Code = 0
-			// c.Ctx.JSON(iris.Map{
-			// 	"code": 200,
-			// 	"msg":  ErrMsg,
-			// })
-
-		}
-	}
-
-	c.Ctx.JSON(iris.Map{
-		"code": Code,
-		"msg":  ErrMsg,
-	})
-
-	// return mvc.View{
-	// 	Name: "login/login.html",
-	// 	Data: iris.Map{
-	// 		"Title":     "用户登录",
-	// 		"Channel":   "login",
-	// 		"Action":    "login",
-	// 		"LoginData": LoginData,
-	// 		"ErrMsg":    ErrMsg,
-	// 	},
-	// 	Layout: "login/layout.html",
-	// }
-}

+ 19 - 8
web/api/project_account_api.go

@@ -7,6 +7,8 @@
 package api
 
 import (
+	"fmt"
+
 	"github.com/kataras/iris/v12"
 	"go.mod/services"
 	"go.mod/web/utils"
@@ -19,21 +21,30 @@ type ProjectAccountApi struct {
 	ServiceProjectAccount services.ProjectAccountService
 }
 
-// 获得项目账号相关信息
+// @Summary 获得登陆账号信息相关
+// @Tags 项目账号相关
+// @Description 获得登陆账号相关信息
+// @Security ApiKeyAuth
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/projectAccount [get]
 func (c *ProjectAccountApi) Get() {
 
-	// 获得项目ID
+	// 获得项目账号ID
 	projectAccountIdInt, err := utils.GetProjectAccountId(c.Ctx)
 	if err != nil {
-		c.Ctx.JSON(iris.Map{
-			"code": -1,
-			"msg":  err,
-		})
+		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": fmt.Sprintf("%s", err)})
 		return
 	}
 
-	// 获得层级文件夹
-	AccountData := c.ServiceProjectAccount.Get(projectAccountIdInt)
+	// 获得登陆用户
+	AccountData := c.ServiceProjectAccount.Get(projectAccountIdInt, projectIdInt)
 
 	c.Ctx.JSON(iris.Map{
 		"code": 0,

+ 141 - 0
web/api/project_setting.go

@@ -0,0 +1,141 @@
+/*
+ * @description: 项目设置相关--管理员可访问
+ * @Author: CP
+ * @Date: 2020-10-09 10:35:38
+ * @FilePath: \construction_management\web\api\project_setting.go
+ */
+package api
+
+import (
+	"fmt"
+
+	"github.com/iris-contrib/middleware/csrf"
+	"github.com/kataras/iris/v12"
+	"go.mod/services"
+	"go.mod/web/utils"
+	"go.mod/web/viewmodels"
+)
+
+type ProjectSettingApi struct {
+	//框架-web应用上下文环境
+	Ctx iris.Context
+	// 需要用的service
+	ServiceProjectAccount services.ProjectAccountService
+}
+
+// @Summary 获得项目账号列表
+// @Tags 项目设置-管理员
+// @Description id获得单条信息<br/>name模糊检索
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Param   id     body    string     false        "账号ID"
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/projectSetting/account [get]
+func (c *ProjectSettingApi) GetAccount() {
+	// 获得项目ID
+	projectIdInt, err := utils.GetProjectId(c.Ctx)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
+		return
+	}
+
+	// 获得账号ID
+	AccountData := viewmodels.ProjectAccount{}
+	err = c.Ctx.ReadJSON(&AccountData)
+	if err != nil {
+		// 获得所有项目下的账号
+		dataList := c.ServiceProjectAccount.GetAll(projectIdInt)
+		c.Ctx.JSON(iris.Map{
+			"code": 0,
+			"msg":  "",
+			"data": dataList,
+		})
+	} else {
+		// 获得单个账号ID
+		id, err := utils.GetDecryptId(AccountData.Id)
+		if err != nil {
+			c.Ctx.JSON(iris.Map{"code": -1, "msg": err})
+			return
+		}
+
+		accountData := c.ServiceProjectAccount.Get(id, projectIdInt)
+		c.Ctx.JSON(iris.Map{
+			"code": 0,
+			"msg":  "",
+			"data": accountData,
+		})
+	}
+}
+
+// @Summary 检索账号信息
+// @Tags 项目设置-管理员
+// @Description 检索字段:账号 姓名 单位 手机 前匹配
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Param   name     body    string     true        "检索内容"
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/projectSetting/account/search [get]
+func (c *ProjectSettingApi) GetAccountSearch() {
+	// 获得项目ID
+	projectIdInt, err := utils.GetProjectId(c.Ctx)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
+		return
+	}
+	c.Ctx.Header("X-CSRF-Token", csrf.Token(c.Ctx))
+	fmt.Println(c.Ctx.GetHeader("X-CSRF-Token"))
+
+	fmt.Println(csrf.Token(c.Ctx))
+	// 获得检索关键字
+	AccountData := viewmodels.ProjectAccount{}
+	err = c.Ctx.ReadJSON(&AccountData)
+	if err != nil {
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("JSON转换异常, error=%s", err)})
+		return
+	}
+
+	// 检索
+	dataList := c.ServiceProjectAccount.Search(AccountData.Name, projectIdInt)
+	c.Ctx.JSON(iris.Map{
+		"code": 0, "msg": "",
+		"data": dataList,
+	})
+}
+
+// @Summary 新增账号
+// @Tags 项目设置-管理员
+// @Description 新增账号
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Param   account     body    string     true        "账号"
+// @Param   password     body    string     true        "密码"
+// @Param   name     body    string     true        "姓名"
+// @Param   company     body    string     true        "公司"
+// @Param   position     body    string     true        "职位"
+// @Param   mobile     body    string     true        "手机"
+// @Param   telephone     body    string     true        "座机"
+// @Param   accountGroup     body    string     true        "账号组"
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/projectSetting/account/add [post]
+func (c *ProjectSettingApi) PostAccountAdd() {
+	ErrMsg := ""
+	// 验证内容
+	AccountData, err := c.ServiceProjectAccount.ValidRule(c.Ctx)
+
+	if err != nil {
+		ErrMsg = utils.FormValidError(err)
+		c.Ctx.JSON(iris.Map{"code": -1, "msg": ErrMsg})
+		return
+	} else {
+		// 新增账号信息
+		err := c.ServiceProjectAccount.Add(AccountData)
+		if err != nil {
+			c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
+			return
+		}
+		c.Ctx.JSON(iris.Map{"code": 0, "msg": "新增成功"})
+	}
+}

+ 23 - 7
web/api/tree_api.go

@@ -1,5 +1,5 @@
 /*
- * @description:
+ * @description:文件夹相关-管理员可访问
  * @Author: CP
  * @Date: 2020-09-17 17:50:50
  * @FilePath: \construction_management\web\api\tree_api.go
@@ -23,7 +23,14 @@ type TreeApi struct {
 	ServiceTree services.TreeService
 }
 
-// 获得项目目录结构
+// @Summary 获得目录和数据
+// @Tags 目录相关-管理员
+// @Description 获得目录和数据
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/tree [get]
 func (c *TreeApi) Get() {
 
 	// 获得项目ID
@@ -87,7 +94,16 @@ func (c *TreeApi) PostCreate() {
 	}
 }
 
-// 文件夹重命名
+// @Summary 重命名
+// @Tags 目录相关-管理员
+// @Description 重命名-文件夹或者标段
+// @Accept  json
+// @Produce  json
+// @Security ApiKeyAuth
+// @Param   id     body    string     true        "treeId"
+// @Param   name     body    string     true        "重命名的名称"
+// @Success 200 {string} string	"{code:0成功,-1参数类错误,-2服务端内部错误,msg:错误信息}"
+// @Router /api/tree/rename [post]
 func (c *TreeApi) PostRename() {
 	ErrMsg := ""
 	// 验证内容
@@ -152,18 +168,18 @@ func (c *TreeApi) Delete() {
 // 移动文件夹
 func (c *TreeApi) PostMove() {
 	// 获得目录ID和移动目录ID
-	ProjectAccountVM := viewmodels.ProjectAccount{}
-	err := c.Ctx.ReadJSON(&ProjectAccountVM)
+	Tree := viewmodels.Tree{}
+	err := c.Ctx.ReadJSON(&Tree)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
 		return
 	}
-	id, err := utils.GetDecryptId(ProjectAccountVM.Id)
+	id, err := utils.GetDecryptId(Tree.Id)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
 		return
 	}
-	moveId, err := utils.GetDecryptId(ProjectAccountVM.MoveId)
+	moveId, err := utils.GetDecryptId(Tree.MoveId)
 	if err != nil {
 		c.Ctx.JSON(iris.Map{"code": -1, "msg": fmt.Sprintf("%s", err)})
 		return

+ 1 - 1
web/controllers/login.go

@@ -58,7 +58,7 @@ func (c *LoginController) PostLogin() mvc.Result {
 		ErrMsg = utils.FormValidError(err)
 	} else {
 		//验证登陆用户
-		err = c.ServiceLogin.ValidProjectAccount(LoginData, c.Ctx.ResponseWriter())
+		_, err = c.ServiceLogin.ValidProjectAccount(LoginData, c.Ctx.ResponseWriter())
 		if err != nil {
 			ErrMsg = fmt.Sprintf("%s", err)
 		} else {

+ 22 - 0
web/main.go

@@ -12,6 +12,11 @@ import (
 	"go.mod/bootstrap"
 	"go.mod/web/middleware/identity"
 	"go.mod/web/routes"
+
+	_ "go.mod/web/docs"
+
+	"github.com/iris-contrib/swagger/v12"              // swagger middleware for Iris
+	"github.com/iris-contrib/swagger/v12/swaggerFiles" // swagger embed files
 )
 
 var port = 6060
@@ -26,6 +31,16 @@ func newApp() *bootstrap.Bootstrapper {
 	return app
 }
 
+// @title 工程项目管理系统 API
+// @version 1.0
+// @description 工程项目管理系统-接口
+
+// @contact.name CP Support
+
+// @securityDefinitions.apikey ApiKeyAuth
+// @in header
+// @name Authorization
+
 func main() {
 	// 服务器集群的时候才需要区分这项设置
 	// 比如:根据服务器的IP、名称、端口号等,或者运行的参数
@@ -34,5 +49,12 @@ func main() {
 	// }
 
 	app := newApp()
+
+	// api接口文档配置
+	config := &swagger.Config{
+		URL: "http://cm.com/docs/swagger.json", //The url pointing to API definition
+	}
+	app.Get("/swagger/{any:path}", swagger.CustomWrapHandler(config, swaggerFiles.Handler))
+
 	app.Listen(fmt.Sprintf(":%d", port))
 }

+ 13 - 0
web/middleware/accessAuth.go

@@ -0,0 +1,13 @@
+/*
+ * @description: 访问权限认证
+ * @Author: CP
+ * @Date: 2020-10-09 10:43:39
+ * @FilePath: \construction_management\web\middleware\accessAuth.go
+ */
+package middleware
+
+import "github.com/kataras/iris/v12"
+
+func accessAuth(ctx iris.Context) {
+
+}

+ 1 - 11
web/middleware/csrf.go

@@ -13,19 +13,9 @@ import (
 
 //设置CSRF信息
 func SetCsrf(ctx iris.Context) {
-	// ctx.Header("X-CSRF-Token", csrf.Token(ctx))
-	// fmt.Println(csrf.TemplateTag)
-	// fmt.Println(csrf.TemplateField(ctx))
+	ctx.Header("X-CSRF-Token", csrf.Token(ctx))
 	// fmt.Println(csrf.Token(ctx))
-	// ctx.Values().Set("csrf.Form", "csrfToken")
-	// fmt.Println(ctx.Values().Get("csrf.Form"))
 
 	ctx.ViewData(csrf.TemplateTag, csrf.TemplateField(ctx))
 	ctx.Next()
 }
-
-// func NewCsrf() iris.Handler {
-// 	protect := csrf.Protect([]byte("9AB0F421E53A477C084477AEA06096F5"))
-// 	csrf.Secure(false)
-// 	return protect
-// }

+ 108 - 38
web/middleware/sessions.go

@@ -7,6 +7,7 @@
 package middleware
 
 import (
+	"errors"
 	"net/url"
 	"strconv"
 
@@ -20,66 +21,135 @@ func SessionsAuth(ctx iris.Context) {
 	// 获得cookie
 	cookie, err := ctx.Request().Cookie("cm")
 	if err != nil {
-		comm.Redirect(ctx.ResponseWriter(), "/login")
+		ctx.JSON(iris.Map{"code": 1, "msg": ""})
+		return
 	}
 	// 格式化
 	params, err := url.ParseQuery(cookie.Value)
 	if err != nil {
-		comm.Redirect(ctx.ResponseWriter(), "/login")
+		ctx.JSON(iris.Map{"code": 1, "msg": ""})
+		return
 	}
 
+	// 获得用户信息--TODO 存放redis
 	// 解密用户标识
-	identity, err := comm.AesDecrypt(params.Get("identity"), conf.CookieSecret)
+	identityId, err := getDecryptId(params.Get("identity"))
 	if err != nil {
-		comm.Redirect(ctx.ResponseWriter(), "/login")
+		ctx.JSON(iris.Map{"code": 1, "msg": "账号发生异常1"})
+		return
 	}
-	digitalToken := comm.CreateSign(conf.CookieSecret + identity)
+	// 数字证书
+	digitalToken := comm.CreateSign(conf.CookieSecret + strconv.Itoa(identityId))
 
-	// 获得用户信息--TODO 存放redis
-	npaSer := services.NewProjectAccountService()
-	identityId, err := strconv.Atoi(identity)
+	// 解密副标识
+	attachedIdentityId, err := getDecryptId(params.Get("attachedIdentity"))
 	if err != nil {
-		comm.Redirect(ctx.ResponseWriter(), "/login")
+		ctx.JSON(iris.Map{"code": 1, "msg": "账号发生异常2"})
+		return
 	}
-	accountInfo := npaSer.Get(identityId)
+	npaSer := services.NewProjectAccountService()
+	accountInfo := npaSer.Get(identityId, attachedIdentityId)
 	if accountInfo.Id == "0" {
-		comm.Redirect(ctx.ResponseWriter(), "/login")
-	}
-	ctx.Values().Set("accountId", identity)
-	projectId, err := comm.AesDecrypt(accountInfo.ProjectId, conf.SignSecret)
-	if err != nil {
-		comm.Redirect(ctx.ResponseWriter(), "/login")
+		ctx.JSON(iris.Map{"code": 1, "msg": "账号不存在"})
+		return
 	}
-	ctx.Values().Set("projectId", projectId)
-	// 设置viewData
-	ctx.ViewData("Account", accountInfo)
-	// npaDao := dao.NewProjectAccountDao(datasource.InstanceDbMaster())
-	// identityId, err := strconv.Atoi(identity)
-	// if err != nil {
-	// 	comm.Redirect(ctx.ResponseWriter(), "/login")
-	// }
-	// accountInfo := npaDao.Get(identityId)
-	// if accountInfo.Id == 0 {
-	// 	comm.Redirect(ctx.ResponseWriter(), "/login")
-	// }
-	// ctx.Values().Set("accountId", identity)
+	ctx.Values().Set("accountId", identityId)
 
+	ctx.Values().Set("projectId", attachedIdentityId)
+	ctx.Values().Set("account", accountInfo)
 	// 设置viewData
-	// accountView := viewmodels.ProjectAccount{}
-	// accountView.Account = accountInfo.Account
-	// accountView.Name = accountInfo.Name
-	// accountView.Company = accountInfo.Company
-	// accountView.Role = accountInfo.Role
-	// accountView.Mobile = accountInfo.Mobile
-	// accountView.Telephone = accountInfo.Telephone
-	// ctx.ViewData("Account", accountView)
+	//ctx.ViewData("Account", accountInfo)
 
 	// 比对数字证书
 	if digitalToken != params.Get("digitalToken") {
-		comm.Redirect(ctx.ResponseWriter(), "/login")
+		ctx.JSON(iris.Map{"code": 1, "msg": "账号异常3"})
+		return
 	}
 	// TODO 分布式session
 
 	//通过后执行下一步
 	ctx.Next()
 }
+
+// 获得解密后的ID
+func getDecryptId(id string) (int, error) {
+	id, err := comm.AesDecrypt(id, conf.CookieSecret)
+	if err != nil {
+		return 0, errors.New("ID 解析错误")
+	}
+	idInt, err := strconv.Atoi(id)
+	if err != nil {
+		return 0, errors.New("ID 转换错误")
+	}
+	return idInt, nil
+}
+
+// 登陆态-认证
+// func SessionsAuth(ctx iris.Context) {
+// 	// 获得cookie
+// 	cookie, err := ctx.Request().Cookie("cm")
+// 	if err != nil {
+// 		comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	}
+// 	// 格式化
+// 	params, err := url.ParseQuery(cookie.Value)
+// 	if err != nil {
+// 		comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	}
+
+// 	// 解密用户标识
+// 	identity, err := comm.AesDecrypt(params.Get("identity"), conf.CookieSecret)
+// 	if err != nil {
+// 		comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	}
+// 	digitalToken := comm.CreateSign(conf.CookieSecret + identity)
+
+// 	// 获得用户信息--TODO 存放redis
+// 	npaSer := services.NewProjectAccountService()
+// 	identityId, err := strconv.Atoi(identity)
+// 	if err != nil {
+// 		comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	}
+// 	// TODO 项目ID的获得
+// 	accountInfo := npaSer.Get(identityId, 2)
+// 	if accountInfo.Id == "0" {
+// 		comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	}
+// 	ctx.Values().Set("accountId", identity)
+// 	projectId, err := comm.AesDecrypt(accountInfo.ProjectId, conf.SignSecret)
+// 	if err != nil {
+// 		comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	}
+// 	ctx.Values().Set("projectId", projectId)
+// 	// 设置viewData
+// 	ctx.ViewData("Account", accountInfo)
+// 	// npaDao := dao.NewProjectAccountDao(datasource.InstanceDbMaster())
+// 	// identityId, err := strconv.Atoi(identity)
+// 	// if err != nil {
+// 	// 	comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	// }
+// 	// accountInfo := npaDao.Get(identityId)
+// 	// if accountInfo.Id == 0 {
+// 	// 	comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	// }
+// 	// ctx.Values().Set("accountId", identity)
+
+// 	// 设置viewData
+// 	// accountView := viewmodels.ProjectAccount{}
+// 	// accountView.Account = accountInfo.Account
+// 	// accountView.Name = accountInfo.Name
+// 	// accountView.Company = accountInfo.Company
+// 	// accountView.Role = accountInfo.Role
+// 	// accountView.Mobile = accountInfo.Mobile
+// 	// accountView.Telephone = accountInfo.Telephone
+// 	// ctx.ViewData("Account", accountView)
+
+// 	// 比对数字证书
+// 	if digitalToken != params.Get("digitalToken") {
+// 		comm.Redirect(ctx.ResponseWriter(), "/login")
+// 	}
+// 	// TODO 分布式session
+
+// 	//通过后执行下一步
+// 	ctx.Next()
+// }

+ 12 - 5
web/routes/routes.go

@@ -70,30 +70,37 @@ func Configure(b *bootstrap.Bootstrapper) {
 	apiLogin := mvc.New(b.Party("/api/login"))
 	apiLogin.Register(ProjectAccountService)
 	apiLogin.Register(LoginService)
-	//apiLogin.Router.Use(middleware.JwtAuth().Serve)
+	apiLogin.Register(ProjectService)
 	apiLogin.Handle(new(api.LoginApi))
 
 	// TreeNode相关接口
+	// apiTree.Router.Use(middleware.JwtAuth().Serve)
 	apiTree := mvc.New(b.Party("/api/tree"))
 	apiTree.Register(TreeService)
-	apiTree.Router.Use(middleware.JwtAuth().Serve)
+	apiTree.Router.Use(middleware.SessionsAuth)
 	apiTree.Handle(new(api.TreeApi))
 
 	// 项目相关接口
 	apiProject := mvc.New(b.Party("/api/project"))
 	apiProject.Register(ProjectService)
-	apiProject.Router.Use(middleware.JwtAuth().Serve)
+	apiProject.Router.Use(middleware.SessionsAuth)
 	apiProject.Handle(new(api.ProjectApi))
 
 	// 项目账号相关接口
 	apiProjectAccount := mvc.New(b.Party("/api/projectAccount"))
 	apiProjectAccount.Register(ProjectAccountService)
-	apiProjectAccount.Router.Use(middleware.JwtAuth().Serve)
+	apiProjectAccount.Router.Use(middleware.SessionsAuth)
 	apiProjectAccount.Handle(new(api.ProjectAccountApi))
 
 	// 标段相关接口
 	apiBidsection := mvc.New(b.Party("/api/bidsection"))
 	apiBidsection.Register(BidsectionService)
-	apiBidsection.Router.Use(middleware.JwtAuth().Serve)
+	apiBidsection.Router.Use(middleware.SessionsAuth)
 	apiBidsection.Handle(new(api.BidsectionApi))
+
+	// 项目设置接口
+	apiSetting := mvc.New(b.Party("/api/projectSetting"))
+	apiSetting.Register(ProjectAccountService)
+	apiSetting.Router.Use(middleware.SessionsAuth)
+	apiSetting.Handle(new(api.ProjectSettingApi))
 }

+ 36 - 16
web/utils/utils.go

@@ -11,7 +11,6 @@ import (
 	"strconv"
 	"strings"
 
-	"github.com/dgrijalva/jwt-go"
 	"github.com/kataras/iris/v12"
 	"go.mod/comm"
 	"go.mod/conf"
@@ -30,28 +29,19 @@ func StringToMap(str string, split string) map[string]string {
 
 // 获得项目ID
 func GetProjectId(ctx iris.Context) (int, error) {
-	jwtInfo := ctx.Values().Get("jwt").(*jwt.Token)
-	project := jwtInfo.Claims.(jwt.MapClaims)["project"].(string)
-	projectId, err := comm.AesDecrypt(project, conf.CookieSecret)
+	//account := ctx.Values().Get("account").(*viewmodels.ProjectAccount)
+	// fmt.Println(account)
+	projectId, err := ctx.Values().GetInt("projectId")
 	if err != nil {
 		return 0, errors.New("项目不存在")
 	}
-	projectIdInt, err := strconv.Atoi(projectId)
-	if err != nil {
-		return 0, errors.New("项目不存在")
-	}
-	return projectIdInt, nil
+	return projectId, nil
 }
 
 // 获得项目账号ID
 func GetProjectAccountId(ctx iris.Context) (int, error) {
-	jwtInfo := ctx.Values().Get("jwt").(*jwt.Token)
-	identity := jwtInfo.Claims.(jwt.MapClaims)["identity"].(string)
-	identityId, err := comm.AesDecrypt(identity, conf.CookieSecret)
-	if err != nil {
-		return 0, errors.New("项目账号不存在")
-	}
-	identityIdInt, err := strconv.Atoi(identityId)
+
+	identityIdInt, err := ctx.Values().GetInt("accountId")
 	if err != nil {
 		return 0, errors.New("项目账号不存在")
 	}
@@ -70,3 +60,33 @@ func GetDecryptId(id string) (int, error) {
 	}
 	return idInt, nil
 }
+
+// // 获得项目ID
+// func GetProjectId(ctx iris.Context) (int, error) {
+// 	jwtInfo := ctx.Values().Get("jwt").(*jwt.Token)
+// 	project := jwtInfo.Claims.(jwt.MapClaims)["project"].(string)
+// 	projectId, err := comm.AesDecrypt(project, conf.CookieSecret)
+// 	if err != nil {
+// 		return 0, errors.New("项目不存在")
+// 	}
+// 	projectIdInt, err := strconv.Atoi(projectId)
+// 	if err != nil {
+// 		return 0, errors.New("项目不存在")
+// 	}
+// 	return projectIdInt, nil
+// }
+
+// // 获得项目账号ID
+// func GetProjectAccountId(ctx iris.Context) (int, error) {
+// 	jwtInfo := ctx.Values().Get("jwt").(*jwt.Token)
+// 	identity := jwtInfo.Claims.(jwt.MapClaims)["identity"].(string)
+// 	identityId, err := comm.AesDecrypt(identity, conf.CookieSecret)
+// 	if err != nil {
+// 		return 0, errors.New("项目账号不存在")
+// 	}
+// 	identityIdInt, err := strconv.Atoi(identityId)
+// 	if err != nil {
+// 		return 0, errors.New("项目账号不存在")
+// 	}
+// 	return identityIdInt, nil
+// }

+ 41 - 28
web/viewmodels/project_account.go

@@ -6,43 +6,56 @@
  */
 package viewmodels
 
-import validation "github.com/go-ozzo/ozzo-validation/v3"
+import (
+	"regexp"
+
+	validation "github.com/go-ozzo/ozzo-validation/v3"
+)
 
 type ProjectAccount struct {
-	Id        string `form:"id"`
-	ProjectId string `form:"projectid"`
-	Account   string `form:"account"`
-	Name      string `form:"name"`
-	Company   string `form:"company"`
-	Role      string `form:"role"`
-	Mobile    string `form:"mobile"`
-	Telephone string `form:"telephone"`
-	IsAdmin   int    `form:"isAdmin"`
+	Id           string `form:"id"`
+	ProjectId    string `form:"projectid"`
+	Account      string `form:"account"`
+	Password     string `form:"password"`
+	Name         string `form:"name"`
+	Company      string `form:"company"`
+	Position     string `form:"position"`
+	Role         string `form:"role"`
+	Mobile       string `form:"mobile"`
+	Telephone    string `form:"telephone"`
+	IsAdmin      int    `form:"isAdmin"`
+	AccountGroup int    `form:"accountGroup"`
 
-	MoveId string `form:"moveId"`
-	// LastLogin    int       `xorm:"comment('最后登录时间') INT(11)"`
-	// AccountGroup     int       `xorm:"comment('所属账号组') TINYINT(4)"`
-	// EnterpriseId     int       `xorm:"comment('企业id') INT(11)"`
-	// CreateTime   int       `xorm:"comment('创建时间') INT(11)"`
-	// IsAdmin      int       `xorm:"comment('是否为管理员 1为管理员') TINYINT(1)"`
-	// Enable       int       `xorm:"comment('是否启用 1为启用') TINYINT(1)"`
-	// AuthMobile   string    `xorm:"comment('认证手机') VARCHAR(32)"`
-	// Permission   string    `xorm:"comment('权限') TEXT"`
-	// Cooperation  int       `xorm:"comment('协作') TINYINT(4)"`
-	// LastNotice   time.Time `xorm:"comment('待办事项,通知') DATETIME"`
-	// SignPath     string    `xorm:"comment('电子签名图片地址') VARCHAR(512)"`
-	// SessionToken string    `xorm:"comment('token信息验证') VARCHAR(128)"`
-	// SmsType      string    `xorm:"comment('短信通知类型') TEXT"`
-	// WxType       string    `xorm:"comment('微信通知类型') TEXT"`
-	// Bind         int       `xorm:"comment('是否已绑定定制项目') TINYINT(1)"`
-	// WxOpenid     string    `xorm:"comment('微信绑定openid') VARCHAR(64)"`
-	// WxName       string    `xorm:"comment('微信昵称') VARCHAR(255)"`
 	Csrf string `form:"csrf"`
 }
 
 func (l ProjectAccount) Validate() error {
 	return validation.ValidateStruct(&l,
+		validation.Field(&l.Account, validation.Required.Error("账号不能为空"), validation.Match(regexp.MustCompile("^[A-Za-z0-9]+$")).Error("只支持英文数字组合")),
+		validation.Field(&l.Password, validation.Required.Error("密码不能为空"), validation.Match(regexp.MustCompile("^[a-zA-Z]\\w{5,17}$")).Error("密码支持英文数字及符号,6~18之间")),
 		validation.Field(&l.Name, validation.Required.Error("姓名不能为空")),
 		validation.Field(&l.Company, validation.Required.Error("单位不能为空")),
+		validation.Field(&l.Position, validation.Required.Error("职位不能为空")),
+		validation.Field(&l.Mobile, validation.Required.Error("手机不能为空"), validation.Match(regexp.MustCompile("^([1][3,4,5,6,7,8,9])\\d{9}$")).Error("只支持英文数字组合")),
+		validation.Field(&l.AccountGroup, validation.Required.Error("账号组不能为空")),
 	)
 }
+
+//MoveId string `form:"moveId"`
+// LastLogin    int       `xorm:"comment('最后登录时间') INT(11)"`
+
+// EnterpriseId     int       `xorm:"comment('企业id') INT(11)"`
+// CreateTime   int       `xorm:"comment('创建时间') INT(11)"`
+// IsAdmin      int       `xorm:"comment('是否为管理员 1为管理员') TINYINT(1)"`
+// Enable       int       `xorm:"comment('是否启用 1为启用') TINYINT(1)"`
+// AuthMobile   string    `xorm:"comment('认证手机') VARCHAR(32)"`
+// Permission   string    `xorm:"comment('权限') TEXT"`
+// Cooperation  int       `xorm:"comment('协作') TINYINT(4)"`
+// LastNotice   time.Time `xorm:"comment('待办事项,通知') DATETIME"`
+// SignPath     string    `xorm:"comment('电子签名图片地址') VARCHAR(512)"`
+// SessionToken string    `xorm:"comment('token信息验证') VARCHAR(128)"`
+// SmsType      string    `xorm:"comment('短信通知类型') TEXT"`
+// WxType       string    `xorm:"comment('微信通知类型') TEXT"`
+// Bind         int       `xorm:"comment('是否已绑定定制项目') TINYINT(1)"`
+// WxOpenid     string    `xorm:"comment('微信绑定openid') VARCHAR(64)"`
+// WxName       string    `xorm:"comment('微信昵称') VARCHAR(255)"`

+ 1 - 0
web/viewmodels/tree.go

@@ -22,6 +22,7 @@ type Tree struct {
 	Isfolder    int    `form:"isfolder"`
 	CreateTime  string `form:"createTime"`
 	UpdateTime  string `form:"updateTime"`
+	MoveId      string `form:"moveId"`
 
 	Csrf     string  `form:"csrf"`
 	Leaf     bool    `json:"leaf"`