houyaf 3 年之前
當前提交
b727d4e026
共有 100 個文件被更改,包括 4763 次插入 和 0 次删除
  1. 9 0
      .gitignore
  2. 50 0
      bootstrap/bootstrapper.go
  3. 105 0
      cache/redis.go
  4. 35 0
      conf/db.go
  5. 9 0
      conf/sysconf.go
  6. 27 0
      constant/constant.go
  7. 36 0
      datamodels/account.go
  8. 1 0
      datamodels/app.go
  9. 21 0
      datamodels/app_cat.go
  10. 29 0
      datamodels/app_permit.go
  11. 14 0
      datamodels/company.go
  12. 39 0
      datamodels/group.go
  13. 22 0
      datamodels/group_cat.go
  14. 15 0
      datamodels/group_member.go
  15. 16 0
      datamodels/group_member_position.go
  16. 16 0
      datamodels/group_member_position_grant.go
  17. 30 0
      datamodels/oc.go
  18. 22 0
      datamodels/position.go
  19. 24 0
      datamodels/role.go
  20. 14 0
      datamodels/role_member.go
  21. 110 0
      datasource/dbhelper.go
  22. 81 0
      go.mod
  23. 110 0
      repositories/apps/app_cat_repo.go
  24. 212 0
      repositories/system/account_repo.go
  25. 76 0
      repositories/system/app_permit_repo.go
  26. 33 0
      repositories/system/company_repo.go
  27. 116 0
      repositories/system/group_cat_repo.go
  28. 119 0
      repositories/system/group_member_position_repo.go
  29. 209 0
      repositories/system/group_member_repo.go
  30. 173 0
      repositories/system/group_repo.go
  31. 221 0
      repositories/system/oc_repo.go
  32. 115 0
      repositories/system/position_repo.go
  33. 101 0
      repositories/system/role_member_repo.go
  34. 124 0
      repositories/system/role_repo.go
  35. 152 0
      repositories/system/user_repo.go
  36. 52 0
      service/system/app_cat_service.go
  37. 29 0
      service/system/app_permit_service.go
  38. 29 0
      service/system/base_service.go
  39. 55 0
      service/system/company_profile_service.go
  40. 52 0
      service/system/group_cat_service.go
  41. 154 0
      service/system/group_service.go
  42. 134 0
      service/system/login_service.go
  43. 53 0
      service/system/position_service.go
  44. 52 0
      service/system/role_service.go
  45. 202 0
      service/system/user_service.go
  46. 17 0
      utils/hmacsha256.go
  47. 29 0
      utils/http_status.go
  48. 14 0
      utils/json.go
  49. 34 0
      utils/md5.go
  50. 9 0
      viewmodels/access_token.go
  51. 29 0
      viewmodels/account_info.go
  52. 12 0
      viewmodels/app_cat_info.go
  53. 15 0
      viewmodels/app_permit_info.go
  54. 13 0
      viewmodels/group_cat_info.go
  55. 24 0
      viewmodels/group_info.go
  56. 13 0
      viewmodels/group_member_info.go
  57. 34 0
      viewmodels/group_member_position_grant_info.go
  58. 12 0
      viewmodels/group_member_position_info.go
  59. 20 0
      viewmodels/oc_info.go
  60. 10 0
      viewmodels/page_result.go
  61. 13 0
      viewmodels/position_info.go
  62. 15 0
      viewmodels/role_info.go
  63. 11 0
      viewmodels/role_member_info.go
  64. 30 0
      viewmodels/user_data.go
  65. 31 0
      viewmodels/user_info.go
  66. 101 0
      web/controllers/app_cat_controller.go
  67. 27 0
      web/controllers/app_permit_controller.go
  68. 118 0
      web/controllers/base_controller.go
  69. 44 0
      web/controllers/company_profile_controller.go
  70. 105 0
      web/controllers/group_cat_controller.go
  71. 96 0
      web/controllers/group_controller.go
  72. 59 0
      web/controllers/login_controller.go
  73. 106 0
      web/controllers/position_controller.go
  74. 88 0
      web/controllers/role_controller.go
  75. 25 0
      web/controllers/upload_controller.go
  76. 89 0
      web/controllers/user_controller.go
  77. 65 0
      web/main.go
  78. 79 0
      web/middleware/auth.go
  79. 21 0
      web/middleware/identity/identity.go
  80. 1 0
      web/middleware/jwt.go
  81. 8 0
      web/public/assets/App-0c32545b.js
  82. 二進制
      web/public/assets/App-0c32545b.js.br
  83. 二進制
      web/public/assets/App-0c32545b.js.gz
  84. 8 0
      web/public/assets/AppCat-c3e9a25f.js
  85. 二進制
      web/public/assets/AppCat-c3e9a25f.js.br
  86. 二進制
      web/public/assets/AppCat-c3e9a25f.js.gz
  87. 8 0
      web/public/assets/DBType-83a4c03b.js
  88. 二進制
      web/public/assets/DBType-83a4c03b.js.br
  89. 二進制
      web/public/assets/DBType-83a4c03b.js.gz
  90. 8 0
      web/public/assets/DBType-c81c9104.js
  91. 二進制
      web/public/assets/DBType-c81c9104.js.br
  92. 二進制
      web/public/assets/DBType-c81c9104.js.gz
  93. 8 0
      web/public/assets/EntCat-93edb117.js
  94. 二進制
      web/public/assets/EntCat-93edb117.js.br
  95. 二進制
      web/public/assets/EntCat-93edb117.js.gz
  96. 8 0
      web/public/assets/Group-810bdc6e.js
  97. 二進制
      web/public/assets/Group-810bdc6e.js.br
  98. 二進制
      web/public/assets/Group-810bdc6e.js.gz
  99. 8 0
      web/public/assets/GroupCat-3bad56a0.js
  100. 二進制
      web/public/assets/GroupCat-3bad56a0.js.br

+ 9 - 0
.gitignore

@@ -0,0 +1,9 @@
+*.iml
+/bin/
+#忽略任意目录下的idea文件夹
+/.idea/
+#忽略以.class结尾的文件
+*.log
+*.sum
+/web/
+/logs/

+ 50 - 0
bootstrap/bootstrapper.go

@@ -0,0 +1,50 @@
+package bootstrap
+
+import (
+	"github.com/kataras/iris/v12"
+	recover2 "github.com/kataras/iris/v12/middleware/recover"
+	"github.com/kataras/iris/v12/sessions"
+	"time"
+)
+
+type Configurator func(*Bootstrapper)
+
+type Bootstrapper struct {
+	*iris.Application
+	AppName      string
+	AppOwner     string
+	AppSpawnDate time.Time
+
+	Sessions *sessions.Sessions
+}
+
+func New(appName, appOwner string, cfgs ...Configurator) *Bootstrapper {
+	b := &Bootstrapper{
+		Application:  iris.New(),
+		AppName:      appName,
+		AppOwner:     appOwner,
+		AppSpawnDate: time.Now(),
+	}
+
+	for _, cfg := range cfgs {
+		cfg(b)
+	}
+
+	return b
+}
+
+func (b *Bootstrapper) Configure(cs ...Configurator) {
+	for _, c := range cs {
+		c(b)
+	}
+}
+
+func (b *Bootstrapper) Bootstrap() *Bootstrapper {
+	b.Use(recover2.New())
+
+	return b
+}
+
+func (b *Bootstrapper) Listen(addr string, cfgs ...iris.Configurator) {
+	b.Run(iris.Addr(addr), cfgs...)
+}

+ 105 - 0
cache/redis.go

@@ -0,0 +1,105 @@
+package cache
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"github.com/go-redis/redis/v8"
+	"log"
+	"strings"
+	"sync"
+	"time"
+	"xps/viewmodels"
+)
+
+var ErrRedisInit = errors.New("缓存初始化失败")
+var (
+	once        sync.Once
+	cacheClient redis.UniversalClient
+)
+
+var CONFIG = Redis{
+	DB:       0,
+	Addr:     "127.0.0.1:6379",
+	Password: "",
+	PoolSize: 0,
+}
+
+type Redis struct {
+	DB       int    `mapstructure:"db"        json:"db"        yaml:"db"`
+	Addr     string `mapstructure:"addr"      json:"addr"      yaml:"addr"`
+	Password string `mapstructure:"password"  json:"password"  yaml:"password"`
+	PoolSize int    `mapstructure:"pool-size" json:"pool-size" yaml:"pool-size"`
+}
+
+func init() {
+	if Instance() == nil {
+		log.Fatal(ErrRedisInit)
+	}
+}
+
+func Instance() redis.UniversalClient {
+	once.Do(func() {
+		universalOptions := &redis.UniversalOptions{
+			Addrs:       strings.Split(CONFIG.Addr, ","),
+			Password:    CONFIG.Password,
+			PoolSize:    int(CONFIG.PoolSize),
+			IdleTimeout: 300 * time.Second,
+		}
+		cacheClient = redis.NewUniversalClient(universalOptions)
+	})
+
+	return cacheClient
+}
+
+func SetCache(key string, value interface{}, expiration time.Duration) error {
+	err := Instance().Set(context.Background(), key, value, expiration).Err()
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func GetCache(key string) (interface{}, error) {
+	return Instance().Get(context.Background(), key).Result()
+}
+
+func DeleteCache(key string) (int64, error) {
+	return Instance().Del(context.Background(), key).Result()
+}
+
+func GetCacheString(key string) (string, error) {
+	value, err := GetCacheBytes(key)
+	if err != nil {
+		return "", err
+	}
+	return string(value), nil
+}
+
+func GetCacheBytes(key string) ([]byte, error) {
+	return Instance().Get(context.Background(), key).Bytes()
+}
+
+func GetCacheUint(key string) (uint64, error) {
+	return Instance().Get(context.Background(), key).Uint64()
+}
+
+func SetUserData(userId int64, userData *viewmodels.UserData) error {
+	keyStr := fmt.Sprintf("user_%d", userId)
+	return SetCache(keyStr, userData, 0)
+}
+
+func GetUserData(userId int64) (*viewmodels.UserData, error) {
+	keyStr := fmt.Sprintf("user_%d", userId)
+	userData := &viewmodels.UserData{}
+	err := Instance().Get(context.Background(), keyStr).Scan(userData)
+	if err != nil {
+		return nil, err
+	}
+	return userData, nil
+}
+
+func DeleteUserData(userId int64) (int64, error) {
+	keyStr := fmt.Sprintf("user_%d", userId)
+	return Instance().Del(context.Background(), keyStr).Result()
+}

+ 35 - 0
conf/db.go

@@ -0,0 +1,35 @@
+package conf
+
+const DriverName = "mysql"
+
+type DbConf struct {
+	Host   string
+	Port   int
+	User   string
+	Pwd    string
+	DbName string
+}
+
+var MasterDbConfig DbConf = DbConf{
+	Host:   "1.15.92.205",
+	Port:   3306,
+	User:   "root",
+	Pwd:    "houyaf1!",
+	DbName: "daas",
+}
+
+var SlaveDbConfig DbConf = DbConf{
+	Host:   "1.15.92.205",
+	Port:   3306,
+	User:   "root",
+	Pwd:    "houyaf1!",
+	DbName: "daas",
+}
+
+var IDDbConfig DbConf = DbConf{
+	Host:   "1.15.92.205",
+	Port:   3306,
+	User:   "root",
+	Pwd:    "houyaf1!",
+	DbName: "daas",
+}

+ 9 - 0
conf/sysconf.go

@@ -0,0 +1,9 @@
+package conf
+
+import "time"
+
+const SysTimeform string = "2006-01-01 12:12:12"
+
+const SysTimeformShort string = "2006-01-01"
+
+var SysTimeLocation, _ = time.LoadLocation("Asia/Chongqing")

+ 27 - 0
constant/constant.go

@@ -0,0 +1,27 @@
+package constant
+
+type OCTYPE int64
+
+const (
+	OCTYPE_ADMIN   = 1
+	OCTYPE_ENT     = 2
+	OCTYPE_ORG     = 3
+	OCTYPE_PARTNER = 4
+)
+
+const (
+	ROLE_TYPE_SYS  = 1
+	ROLE_TYPE_USER = 2
+)
+
+const (
+	SUPER_ROLE         = 1
+	OP_ROLE_ADMIN      = 2
+	OP_ROLE_USER       = 3
+	ORG_ROLE_ADMIN     = 4
+	ORG_ROLE_USER      = 5
+	ENT_ROLE_ADMIN     = 6
+	ENT_USER_ROLE      = 7
+	PARTNER_ROLE_ADMIN = 8
+	PARTNER_ROLE_USER  = 9
+)

+ 36 - 0
datamodels/account.go

@@ -0,0 +1,36 @@
+package datamodels
+
+import "time"
+
+// Account Data Model
+type Account struct {
+	OcId            int64       `json:"ocId"             xorm:"'oc_id'             bigint         comment('组织ID:公司或机构或单位ID')"`
+	AccountId       int64       `json:"accountId"        xorm:"'account_id'        bigint not null pk comment('主键ID')"`
+	AccountName     string      `json:"accountName"      xorm:"'account_name'      varchar(128)   comment('帐号名称')"`
+	Password        string      `json:"password"         xorm:"'password'          varchar(128)   comment('密码')"`
+	AccountType     int64       `json:"accountType"      xorm:"'account_type'      bigint         comment('帐号类型:0:系统用户,1:企业用户,2:集团用户,3:政府用户,4:合作伙伴')"`
+	AccountRealName string      `json:"accountRealName"  xorm:"'account_real_name' varchar(64)    comment('姓名')"`
+	AccountIntro    string      `json:"accountIntro"     xorm:"'account_intro'     varchar(511)   comment('个人简介')"`
+	AccountAvatar   string      `json:"accountAvatar"    xorm:"'account_avatar'    varchar(255)   comment('头像')"`
+	AccountPhoto    string      `json:"accountPhoto"     xorm:"'account_photo'     varchar(255)   comment('照片')"`
+	AccountPhone    string      `json:"accountPhone"     xorm:"'account_phone'     varchar(32)    comment('手机号')"`
+	AccountLastIp   string      `json:"accountLastIp"    xorm:"'account_last_ip'   varchar(10)    comment('最近一次登录IP')"`
+	AccountLoc      string      `json:"accountLoc"       xorm:"'account_loc'       varchar(64)    comment('区域')"`
+	AccountMail     string      `json:"accountMail"      xorm:"'account_mail'      varchar(64)    comment('Email')"`
+	AccountStaffNo  string      `json:"accountStaffNo"   xorm:"'account_staff_no'  varchar(64)    comment('StaffNo')"`
+	Status          int64       `json:"status"           xorm:"'status'            bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+	WxId            int64       `json:"wxId"             xorm:"'wxId'              bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+	IsFixed         int64       `json:"isFixed"          xorm:"'isFixed'           bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+	CreatedBy       int64       `json:"createdBy"        xorm:"'created_by'"`
+	CreatedAt       time.Time   `json:"createdAt"        xorm:"'created_at'"`
+	UpdatedBy       int64       `json:"updatedBy"        xorm:"'updated_by'"`
+	UpdatedAt       time.Time   `json:"updatedAt"        xorm:"'updated_at'"`
+	DeletedFlag     int64       `json:"deletedFlag"      xorm:"'deleted_flag'"`
+	DeletedBy       int64       `json:"deletedBy"        xorm:"'deleted_by'"`
+	DeletedAt       time.Time   `json:"deletedAt"        xorm:"'deleted_at'"`
+}
+
+// TableName table name
+func (t *Account) TableName() string {
+	return "account"
+}

+ 1 - 0
datamodels/app.go

@@ -0,0 +1 @@
+package datamodels

+ 21 - 0
datamodels/app_cat.go

@@ -0,0 +1,21 @@
+package datamodels
+
+import "time"
+
+type AppCat struct {
+    AppCatId      int64     `json:"appCatId"        xorm:"'app_cat_id'      bigint     pk comment('主键ID')         "`
+    AppCatTitle   string    `json:"appCatTitle"     xorm:"'app_cat_title'   varchar(50)   comment('群组类型名称')     "`
+    AppCatDesc    string    `json:"appCatDesc"      xorm:"'app_cat_desc'    varchar(50)   comment('描述')            "`
+    IsFixed       int64     `json:"isFixed"         xorm:"'is_fixed'        int           comment('是否可修改')         "`
+    CreatedBy     int64     `json:"createdBy"       xorm:"'created_by'"`
+    CreatedAt     time.Time `json:"createdAt"       xorm:"'created_at'"`
+    UpdatedBy     int64     `json:"updatedBy"       xorm:"'updated_by'"`
+    UpdatedAt     time.Time `json:"updatedAt"       xorm:"'updated_at'"`
+    DeletedFlag   int64     `json:"deletedFlag"     xorm:"'deleted_flag'"`
+    DeletedBy     int64     `json:"deletedBy"       xorm:"'deleted_by'"`
+    DeletedAt     time.Time `json:"deletedAt"       xorm:"'deleted_at'"`
+}
+
+func (t *AppCat) TableName() string {
+    return "app_cat"
+}

+ 29 - 0
datamodels/app_permit.go

@@ -0,0 +1,29 @@
+package datamodels
+
+import "time"
+
+// AppPermit Data Model
+type AppPermit struct {
+	AppId       int64     `json:"appId"           form:"appId"           xorm:"'app_id'            bigint     pk comment('APP ID')"`
+	RoleId      int64     `json:"roleId"          form:"roleId"          xorm:"'role_id'           bigint     pk comment('Role ID')"`
+	PermitId    int64     `json:"permitId"        form:"permitId"        xorm:"'permit_id'         bigint     pk comment('Permit ID')  "`
+	PermitTitle string    `json:"permitTitle"     form:"permitTitle"     xorm:"'permit_title'      varchar(127)  comment('标题')      "`
+	PermitCode  string    `json:"permitCode"      form:"permitCode"      xorm:"'permit_code'       varchar(127)  comment('CODE')     "`
+	PermitDesc  string    `json:"permitDesc"      form:"permitDesc"      xorm:"'permit_desc'       varchar(511)  comment('描述')      "`
+	PermitType  int64     `json:"permitType"      form:"permitType"      xorm:"'permit_type'       int           comment('Type') "`
+	RootId      int64     `json:"rootId"          form:"rootId"          xorm:"'root_id'           int           comment('Root Id') "`
+	ParentId    int64     `json:"parentId"        form:"parentId"        xorm:"'parent_id'         int           comment('Parent Id') "`
+	SortNo      int64     `json:"sortNo"          form:"sortNo"          xorm:"'sort_no'           int           comment('Sort No') "`
+	CreatedBy   int64     `json:"createdBy"       form:"-"               xorm:"'created_by'"`
+	CreatedAt   time.Time `json:"createdAt"       form:"-"               xorm:"'created_at'"`
+	UpdatedBy   int64     `json:"updatedBy"       form:"-"               xorm:"'updated_by'"`
+	UpdatedAt   time.Time `json:"updatedAt"       form:"-"               xorm:"'updated_at'"`
+	DeletedFlag int64     `json:"deletedFlag"     form:"-"               xorm:"'deleted_flag'"`
+	DeletedBy   int64     `json:"deletedBy"       form:"-"               xorm:"'deleted_by'"`
+	DeletedAt   time.Time `json:"deletedAt"       form:"-"               xorm:"'deleted_at'"`
+}
+
+// TableName
+func (t *AppPermit) TableName() string {
+	return "app_permit"
+}

+ 14 - 0
datamodels/company.go

@@ -0,0 +1,14 @@
+package datamodels
+
+type Company struct {
+    OcId                int64       `json:"ocId"         xorm:"'oc_id'             bigint         not null pk comment('组织ID:公司或机构或单位ID')"`
+    CmpName             string      `json:"cmpName"      xorm:"'cmp_name'          varchar(255)   comment('公司名称')"`
+    CmpLogo             string      `json:"cmpLogo"      xorm:"'cmp_logo'          varchar(255)   comment('公司Logo')"`
+    CmpIntro            string      `json:"cmpIntro"     xorm:"'cmp_intro'         varchar(1023)  comment('公司介绍')"`
+    CmpContact          string      `json:"cmpContact"   xorm:"'cmp_contact'       varchar(256)   comment('联系方式')"`
+    CmpWebsite          string      `json:"cmpWebsite"   xorm:"'cmp_website'       varchar(256)   comment('官网')"`
+}
+
+func (t *Company) TableName() string{
+    return "company"
+}

+ 39 - 0
datamodels/group.go

@@ -0,0 +1,39 @@
+package datamodels
+
+import "time"
+
+// Group Account Data Model
+type Group struct {
+	OcId             int64   `json:"ocId"            xorm:"'oc_id'               bigint not null pk     comment('公司组织ID')  " `
+	GroupId          int64   `json:"groupId"         xorm:"'group_id'            bigint not null pk     comment('群组ID')      " `
+	GroupName        string  `json:"groupName"       xorm:"'group_name'          varchar(127) not null  comment('群组名称')    " `
+	GroupCatId       int64   `json:"groupCatId"      xorm:"'group_cat_id'        bigint not null        comment('群组类型ID')  " `
+	GroupCatTitle    string  `json:"groupCatTitle"   xorm:"'group_cat_title'     varchar(127) not null  comment('群组类型名称') " `
+	
+	GroupPath        string  `json:"groupPath"       xorm:"'group_path'          varchar(255) not null  comment('群组PATH')    " `
+	GroupDesc        string  `json:"groupDesc"       xorm:"'group_desc'          varchar(255) not null  comment('群组DESC')    " `
+	GroupCode        string  `json:"groupCode"       xorm:"'group_code'          varchar(127) not null  comment('群组CODE')    " `
+	GroupSelect      string  `json:"groupSelect"     xorm:"'group_select'        varchar(255) not null  comment('群组PATH')    " `
+	
+	RootId           int64   `json:"rootId"          xorm:"'root_id'             bigint not null        comment('Order')       " `
+	ParentId         int64   `json:"parentId"        xorm:"'parent_id'           bigint not null        comment('父群组ID')      " `
+	NodeLeft         int64   `json:"nodeLeft"        xorm:"'node_left'           bigint not null        comment('群组LEFT')    " `
+	NodeRight        int64   `json:"nodeRight"       xorm:"'node_right'          bigint not null        comment('群组RIGHT')   " `
+	NodeLevel        int64   `json:"nodeLevel"       xorm:"'node_level'          bigint not null        comment('群组LEVEL')   " `
+	
+	IsLeaf           int64   `json:"isLeaf"          xorm:"'is_leaf'             bigint not null        comment('LEAF群组')    " `
+	IsFixed          int64   `json:"isFixed"         xorm:"'is_fixed'            bigint not null        comment('群组STATUS')  " `
+
+	CreatedBy   int64     `json:"createdBy"      xorm:"'created_by'  " `
+	CreatedAt   time.Time `json:"createdAt"      xorm:"'created_at'  " `
+	UpdatedBy   int64     `json:"updatedBy"      xorm:"'updated_by'  " `
+	UpdatedAt   time.Time `json:"updatedAt"      xorm:"'updated_at'  " `
+	DeletedFlag int64     `json:"deletedFlag"    xorm:"'deleted_flag'" `
+	DeletedBy   int64     `json:"deletedBy"      xorm:"'deleted_by'  " `
+	DeletedAt   time.Time `json:"deletedAt"      xorm:"'deleted_at'  " `
+}
+
+// TableName table name
+func (t *Group) TableName() string {
+	return "s_group"
+}

+ 22 - 0
datamodels/group_cat.go

@@ -0,0 +1,22 @@
+package datamodels
+
+import "time"
+
+type GroupCat struct {
+	OcId          int64     `json:"-"               xorm:"'oc_id'             bigint     pk comment('组织ID:公司或机构或单位ID')"`
+	GroupCatId    int64     `json:"groupCatId"      xorm:"'group_cat_id'      bigint     pk comment('主键ID')         "`
+	GroupCatTitle string    `json:"groupCatTitle"   xorm:"'group_cat_title'   varchar(50)   comment('群组类型名称')     "`
+	GroupCatDesc  string    `json:"groupCatDesc"    xorm:"'group_cat_desc'    varchar(50)   comment('描述')            "`
+	IsFixed       int64     `json:"isFixed"         xorm:"'is_fixed'          int           comment('是否可修改')         "`
+	CreatedBy     int64     `json:"createdBy"       xorm:"'created_by'"`
+	CreatedAt     time.Time `json:"createdAt"       xorm:"'created_at'"`
+	UpdatedBy     int64     `json:"updatedBy"       xorm:"'updated_by'"`
+	UpdatedAt     time.Time `json:"updatedAt"       xorm:"'updated_at'"`
+	DeletedFlag   int64     `json:"deletedFlag"     xorm:"'deleted_flag'"`
+	DeletedBy     int64     `json:"deletedBy"       xorm:"'deleted_by'"`
+	DeletedAt     time.Time `json:"deletedAt"       xorm:"'deleted_at'"`
+}
+
+func (t *GroupCat) TableName() string {
+	return "s_group_cat"
+}

+ 15 - 0
datamodels/group_member.go

@@ -0,0 +1,15 @@
+package datamodels
+
+// GroupMember data struct
+type GroupMember struct {
+	GmId      int64 `json:"gmId"        form:"gmId"             xorm:"bigint       'gm_id'      not null comment('主键ID')"`
+	OcId      int64 `json:"ocId"        form:"ocId"             xorm:"bigint       'oc_id'      not null comment('组织ID:公司或机构或单位ID')"`
+	GroupId   int64 `json:"groupId"     form:"groupId"          xorm:"bigint       'group_id'   not null comment('主键ID')"`
+	AccountId int64 `json:"accountId"   form:"accountId"        xorm:"bigint       'account_id' not null comment('主键ID')"`
+	IsFixed   int64 `json:"isFixed"     form:"isFixed"          xorm:"bigint       'is_fixed'            comment('主键ID')"`
+}
+
+// TableName : table name of database
+func (t *GroupMember) TableName() string {
+	return "s_group_member"
+}

+ 16 - 0
datamodels/group_member_position.go

@@ -0,0 +1,16 @@
+package datamodels
+
+// GroupMemberPosition
+type GroupMemberPosition struct {
+	GmpId      int64 `json:"gmpid"         form:"gmpid"            xorm:"bigint       'gmp_id'      pk  not null comment('主键ID')"`
+	OcId       int64 `json:"ocId"          form:"ocId"             xorm:"bigint       'oc_id'       pk  not null comment('组织ID:公司或机构或单位ID')"`
+	GroupId    int64 `json:"groupId"       form:"groupId"          xorm:"bigint       'group_id'    not null comment('群组ID')"`
+	AccountId  int64 `json:"accountId"     form:"accountId"        xorm:"bigint       'account_id'  not null comment('帐号ID')"`
+	PositionId int64 `json:"positionId"    form:"positionId"       xorm:"bigint       'position_id' not null comment('岗位ID')"`
+	IsFixed    int64 `json:"isFixed"       form:"isFixed"          xorm:"bigint       'is_fixed'             comment('是否可修改')"`
+}
+
+// TableName: table name of database
+func (t *GroupMemberPosition) TableName() string {
+	return "s_group_member_position"
+}

+ 16 - 0
datamodels/group_member_position_grant.go

@@ -0,0 +1,16 @@
+package datamodels
+
+// Group Member Position Grant
+type GroupMemberPositionGrant struct {
+	OcId         int64 `form:"ocId"             xorm:"bigint       'oc_id'          pk not null comment('组织ID:公司或机构或单位ID')"`
+	GmpgId       int64 `form:"gmpgid"           xorm:"bigint       'gmpg_id'        pk not null comment('主键ID')"`
+	GroupId      int64 `form:"groupId"          xorm:"bigint       'group_id'       not null comment('群组ID')"`
+	AccountId    int64 `form:"accountId"        xorm:"bigint       'account_id'     not null comment('帐号ID')"`
+	PositionId   int64 `form:"positionId"       xorm:"bigint       'position_id'    not null comment('岗位ID')"`
+	GrantGroupId int64 `form:"grantGroupId"     xorm:"bigint       'grant_group_id' not null comment('授权群组ID')"`
+}
+
+// TableName: table name of database
+func (t *GroupMemberPositionGrant) TableName() string {
+	return "s_group_member_position_grant"
+}

+ 30 - 0
datamodels/oc.go

@@ -0,0 +1,30 @@
+package datamodels
+
+import "time"
+
+// Oc
+type Oc struct {
+	OcId      int64  `json:"ocId"          form:"ocTypeId"        xorm:"'oc_id'       bigint    pk  comment('主键ID')     " `
+	OcName    string `json:"ocName"        form:"ocName"          xorm:"'oc_name'     varchar(127)  comment('ENT类型名称') " `
+	OcTypeId  int64  `json:"ocTypeId"      form:"ocTypeId"        xorm:"'oc_type_id'  bigint        comment('Type ID')    " `
+	RootId    int64  `json:"rootId"        form:"rootId"          xorm:"'root_id'     bigint        comment('Root ID')     " `
+	ParentId  int64  `json:"parentId"      form:"parentId"        xorm:"'parent_id'   bigint        comment('Parent ID')   " `
+	AdminId   int64  `json:"adminId"       form:"adminId"         xorm:"'admin_id'    bigint        comment('Admin ID')    " `
+	AdminName string `json:"adminName"     form:"adminName"       xorm:"'admin_name'  varchar(127)  comment('Admin Name')  " `
+	GroupId   int64  `json:"groupId"       form:"groupId"         xorm:"'group_id'    bigint        comment('Root Group Id')" `
+	ifLic     int    `json:"ifLic"         form:"ifLic"           xorm:"'if_lic'      int           comment('Admin ID')    " `
+
+	NodeLeft  int `json:"nodeLeft"      form:"nodeLeft"        xorm:"'node_left'   int           comment('Admin ID')    " `
+	NodeRight int `json:"nodeRight"     form:"nodeRight"       xorm:"'node_right'  int           comment('Admin ID')    " `
+	IsLeaf    int `json:"isLeaf"        form:"isLeaf"          xorm:"'is_leaf'     int           comment('Admin ID')    " `
+	NodeLevel int `json:"nodeLevel"     form:"nodeLevel"       xorm:"'node_level'  int           comment('Admin ID')    " `
+	Status    int `json:"status"         form:"status"         xorm:"'status'      int           comment('OC Status')   " `
+
+	CreatedBy   int64     `json:"createdBy"     xorm:"'created_by'"`
+	CreatedAt   time.Time `json:"createdAt"     xorm:"'created_at'"`
+	UpdatedBy   int64     `json:"updatedBy"     xorm:"'updated_by'"`
+	UpdatedAt   time.Time `json:"updatedAt"     xorm:"'updated_at'"`
+	DeletedFlag int64     `json:"deletedFlag"   xorm:"'deleted_flag'"`
+	DeletedBy   int64     `json:"deletedBy"     xorm:"'deleted_by'"`
+	DeletedAt   time.Time `json:"deletedAt"     xorm:"'deleted_at'"`
+}

+ 22 - 0
datamodels/position.go

@@ -0,0 +1,22 @@
+package datamodels
+
+import "time"
+
+type Position struct {
+	OcId         int64     `json:"ocId"          form:"ocId"           xorm:"'oc_id'          bigint pk    comment('OC ID')"  `
+	PositionId   int64     `json:"positionId"    form:"positionId"     xorm:"'position_id'    bigint pk    comment('Position ID')"  `
+	PositionName string    `json:"positionName"  form:"positionName"   xorm:"'position_name'  varchar(127) comment('岗位名称') " `
+	PositionDesc string    `json:"positionDesc"  form:"positionDesc"   xorm:"'position_desc'  varchar(255) comment('描述')     " `
+	IsFixed      int64     `json:"isFixed"       form:"isFixed"        xorm:"'is_fixed'       int          comment('是否可修改') "`
+	CreatedBy    int64     `json:"createdBy"     xorm:"'created_by'"`
+	CreatedAt    time.Time `json:"createdAt"     xorm:"'created_at'"`
+	UpdatedBy    int64     `json:"updatedBy"     xorm:"'updated_by'"`
+	UpdatedAt    time.Time `json:"updatedAt"     xorm:"'updated_at'"`
+	DeletedFlag  int64     `json:"deletedFlag"   xorm:"'deleted_flag'"`
+	DeletedBy    int64     `json:"deletedBy"     xorm:"'deleted_by'"`
+	DeletedAt    time.Time `json:"deletedAt"     xorm:"'deleted_at'"`
+}
+
+func (m *Position) TableName() string {
+	return "s_position"
+}

+ 24 - 0
datamodels/role.go

@@ -0,0 +1,24 @@
+package datamodels
+
+import "time"
+
+type Role struct {
+	RoleId      int64     `json:"roleId"       xorm:"'role_id'        pk comment('主键ID')"`
+	RoleName    string    `json:"roleName"     xorm:"'role_name'      comment('角色名称')"`
+	RoleDesc    string    `json:"roleDesc"     xorm:"'role_desc'      comment('描述')"`
+	RoleTypeId  int64     `json:"roleTypeId"   xorm:"'role_type_id'   comment('角色类型')"`
+	SortNo      int64     `json:"sortNo"       xorm:"'sort_no'        default 0 comment('排序')"`
+	Status      int64     `json:"status"       xorm:"'status'         default 0 comment('状态, 默认 0 正常,1 锁定')"`
+	IsFixed     int64     `json:"isFixed"      xorm:"'is_fixed'       comment('锁定,默认为0不锁定')"`
+	CreatedBy   int64     `json:"createdBy"    xorm:"'created_by'"`
+	CreatedAt   time.Time `json:"createdAt"    xorm:"'created_at'"`
+	UpdatedBy   int64     `json:"updatedBy"    xorm:"'updated_by'"`
+	UpdatedAt   time.Time `json:"updatedAt"    xorm:"'updated_at'"`
+	DeletedFlag int64     `json:"deletedFlag"  xorm:"'deleted_flag'"`
+	DeletedBy   int64     `json:"deletedBy"    xorm:"'deleted_by'"`
+	DeletedAt   time.Time `json:"deletedAt"    xorm:"'deleted_at'"`
+}
+
+func (m *Role) TableName() string {
+	return "s_role"
+}

+ 14 - 0
datamodels/role_member.go

@@ -0,0 +1,14 @@
+package datamodels
+
+// RoleMember Data Model
+type RoleMember struct {
+	RmId      int64 `json:"rmId"      xorm:"'rm_id'      bigint not null pk comment('主键ID')" `
+	OcId      int64 `json:"ocId"      xorm:"'oc_id'      bigint  comment('OC ID')" `
+	RoleId    int64 `json:"roleId"    xorm:"'role_id'    bigint  comment('Role ID')" `
+	AccountId int64 `json:"accountId" xorm:"'account_id' bigint  comment('Account ID')" `
+}
+
+// TableName___
+func (t *RoleMember) TableName() string {
+	return "s_role_member"
+}

+ 110 - 0
datasource/dbhelper.go

@@ -0,0 +1,110 @@
+package datasource
+
+import (
+	"fmt"
+	_ "github.com/go-sql-driver/mysql"
+	"log"
+	"sync"
+	"xorm.io/xorm"
+	"xorm.io/xorm/caches"
+	"xps/conf"
+)
+
+var (
+	masterEngine *xorm.Engine
+	slaveEngine  *xorm.Engine
+	iddbEngine   *xorm.Engine
+	lock         sync.Mutex
+)
+
+func InstanceMaster() *xorm.Engine {
+	if masterEngine != nil {
+		return masterEngine
+	}
+
+	lock.Lock()
+	defer lock.Unlock()
+
+	if masterEngine != nil {
+		return masterEngine
+	}
+
+	c := conf.MasterDbConfig
+	driveSource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8",
+		c.User, c.Pwd, c.Host, c.Port, c.DbName)
+
+	engine, err := xorm.NewEngine(conf.DriverName, driveSource)
+	if err != nil {
+		log.Fatal("dbhelper", "DbInstanceMaster", err)
+		return nil
+	}
+
+	//Debug mode
+	engine.ShowSQL(true)
+
+	//Log
+	engine.SetTZLocation(conf.SysTimeLocation)
+
+	//performance
+	cacher := caches.NewLRUCacher(caches.NewMemoryStore(), 1000)
+	engine.SetDefaultCacher(cacher)
+
+	masterEngine = engine
+	return engine
+}
+
+// InstanceSlave Slave
+func InstanceSlave() *xorm.Engine {
+	if slaveEngine != nil {
+		return slaveEngine
+	}
+
+	lock.Lock()
+	defer lock.Unlock()
+
+	if slaveEngine != nil {
+		return slaveEngine
+	}
+
+	c := conf.SlaveDbConfig
+	driveSource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8",
+		c.User, c.Pwd, c.Host, c.Port, c.DbName)
+
+	engine, err := xorm.NewEngine(conf.DriverName, driveSource)
+	if err != nil {
+		log.Fatal("dbhelper", "DbInstanceMaster", err)
+		return nil
+	}
+
+	engine.SetTZLocation(conf.SysTimeLocation)
+	slaveEngine = engine
+	return engine
+}
+
+// Slave
+func InstanceIDServer() *xorm.Engine {
+	if iddbEngine != nil {
+		return iddbEngine
+	}
+
+	lock.Lock()
+	defer lock.Unlock()
+
+	if iddbEngine != nil {
+		return iddbEngine
+	}
+
+	c := conf.IDDbConfig
+	driveSource := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8",
+		c.User, c.Pwd, c.Host, c.Port, c.DbName)
+
+	engine, err := xorm.NewEngine(conf.DriverName, driveSource)
+	if err != nil {
+		log.Fatal("dbhelper", "DbInstanceIDServer", err)
+		return nil
+	}
+
+	engine.SetTZLocation(conf.SysTimeLocation)
+	iddbEngine = engine
+	return engine
+}

+ 81 - 0
go.mod

@@ -0,0 +1,81 @@
+module xps
+
+go 1.20
+
+require (
+	github.com/go-playground/validator/v10 v10.11.2
+	github.com/go-redis/redis/v8 v8.11.5
+	github.com/go-sql-driver/mysql v1.7.0
+	github.com/iris-contrib/go.uuid v2.0.0+incompatible
+	github.com/iris-contrib/middleware/cors v0.0.0-20230311205048-b568fe9b470f
+	github.com/kataras/iris/v12 v12.2.0
+	xorm.io/core v0.7.3
+	xorm.io/xorm v1.3.2
+)
+
+require (
+	github.com/BurntSushi/toml v1.2.1 // indirect
+	github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
+	github.com/CloudyKit/jet/v6 v6.2.0 // indirect
+	github.com/Joker/jade v1.1.3 // indirect
+	github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect
+	github.com/andybalholm/brotli v1.0.5 // indirect
+	github.com/aymerick/douceur v0.2.0 // indirect
+	github.com/blang/semver/v4 v4.0.0 // indirect
+	github.com/cespare/xxhash/v2 v2.1.2 // indirect
+	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
+	github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect
+	github.com/fatih/structs v1.1.0 // indirect
+	github.com/flosch/pongo2/v4 v4.0.2 // indirect
+	github.com/go-playground/locales v0.14.1 // indirect
+	github.com/go-playground/universal-translator v0.18.1 // indirect
+	github.com/gobwas/httphead v0.1.0 // indirect
+	github.com/gobwas/pool v0.2.1 // indirect
+	github.com/gobwas/ws v1.1.0 // indirect
+	github.com/goccy/go-json v0.8.1 // indirect
+	github.com/golang/snappy v0.0.4 // indirect
+	github.com/google/uuid v1.3.0 // indirect
+	github.com/gorilla/css v1.0.0 // indirect
+	github.com/gorilla/websocket v1.5.0 // indirect
+	github.com/iris-contrib/schema v0.0.6 // indirect
+	github.com/josharian/intern v1.0.0 // indirect
+	github.com/json-iterator/go v1.1.12 // indirect
+	github.com/kataras/blocks v0.0.7 // indirect
+	github.com/kataras/golog v0.1.8 // indirect
+	github.com/kataras/jwt v0.1.8 // indirect
+	github.com/kataras/neffos v0.0.21 // indirect
+	github.com/kataras/pio v0.0.11 // indirect
+	github.com/kataras/sitemap v0.0.6 // indirect
+	github.com/kataras/tunnel v0.0.4 // indirect
+	github.com/klauspost/compress v1.16.0 // indirect
+	github.com/leodido/go-urn v1.2.2 // indirect
+	github.com/mailgun/raymond/v2 v2.0.48 // indirect
+	github.com/mailru/easyjson v0.7.7 // indirect
+	github.com/mediocregopher/radix/v3 v3.8.1 // indirect
+	github.com/microcosm-cc/bluemonday v1.0.23 // indirect
+	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
+	github.com/modern-go/reflect2 v1.0.2 // indirect
+	github.com/nats-io/nats.go v1.23.0 // indirect
+	github.com/nats-io/nkeys v0.3.0 // indirect
+	github.com/nats-io/nuid v1.0.1 // indirect
+	github.com/russross/blackfriday/v2 v2.1.0 // indirect
+	github.com/schollz/closestmatch v2.1.0+incompatible // indirect
+	github.com/sirupsen/logrus v1.8.1 // indirect
+	github.com/syndtr/goleveldb v1.0.0 // indirect
+	github.com/tdewolff/minify/v2 v2.12.4 // indirect
+	github.com/tdewolff/parse/v2 v2.6.4 // indirect
+	github.com/valyala/bytebufferpool v1.0.0 // indirect
+	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
+	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
+	github.com/yosssi/ace v0.0.5 // indirect
+	golang.org/x/crypto v0.7.0 // indirect
+	golang.org/x/net v0.8.0 // indirect
+	golang.org/x/sys v0.6.0 // indirect
+	golang.org/x/text v0.8.0 // indirect
+	golang.org/x/time v0.3.0 // indirect
+	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
+	google.golang.org/protobuf v1.29.0 // indirect
+	gopkg.in/ini.v1 v1.67.0 // indirect
+	gopkg.in/yaml.v3 v3.0.1 // indirect
+	xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect
+)

+ 110 - 0
repositories/apps/app_cat_repo.go

@@ -0,0 +1,110 @@
+package apps
+
+import (
+    "fmt"
+    "time"
+    "xorm.io/xorm"
+    "xps/datamodels"
+    "xps/viewmodels"
+)
+
+type AppCatRepo struct {
+    engine *xorm.Engine
+}
+
+func NewAppCatRepo(engine *xorm.Engine) *AppCatRepo {
+    return &AppCatRepo{
+        engine: engine,
+    }
+}
+
+func (d *AppCatRepo) GetByPage(m map[string]interface{})(*viewmodels.PageResult, error) {
+    keywords := m["keywords"].(string)
+    limit    := m["limit"].(int)
+    page     := m["page"].(int)
+    
+    sqlSelect := `SELECT A.*`
+    sqlFrom   := `FROM   app_cat   AS A `
+    sqlWhere  := `WHERE A.deleted_flag = 0 `
+    if keywords != "" {
+        sqlWhere += ` AND A.app_cat_title like ` + "'%" + keywords + "%'"
+    }
+    
+    sqlCount := `SELECT COUNT(*) `
+    total, err1 := d.engine.SQL(sqlCount + sqlFrom + sqlWhere).Count(new(datamodels.AppCat))
+    if err1 != nil {
+        return nil, err1
+    }
+    
+    sqlOrderBy := " ORDER BY app_cat_id DESC "
+    pageStart := (page - 1) * limit
+    sqlLimit := fmt.Sprintf(" LIMIT %d OFFSET %d ", limit, pageStart)
+    
+    datalist := make([]datamodels.AppCat, 0)
+    err2 := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy + sqlLimit).Find(&datalist)
+    if err2 != nil {
+        return nil, err2
+    }
+    
+    pageResult := &viewmodels.PageResult{}
+    pageResult.Data     = datalist
+    pageResult.Total    = total
+    pageResult.PageSize = limit
+    pageResult.Page     = page
+    return pageResult, nil
+}
+
+func (d *AppCatRepo) GetByList(m map[string]interface{})([]viewmodels.AppCatInfo, error) {
+    keywords := m["keywords"].(string)
+    
+    sqlSelect := `SELECT A.* `
+    sqlFrom   := `FROM  app_cat   AS A    `
+    sqlWhere  := `WHERE A.deleted_flag = 0 `
+    if keywords != "" {
+        sqlWhere += ` AND   A.app_cat_title like ` + "'%" + keywords + "%'"
+    }
+    
+    sqlOrderBy := " ORDER BY app_cat_id DESC "
+    datalist   := make([]viewmodels.AppCatInfo, 0)
+    err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy).Find(&datalist)
+    if err != nil {
+        return nil, err
+    }
+    return datalist, nil
+}
+
+func (d *AppCatRepo) GetById(ocId int64, appCatId int64)(*viewmodels.AppCatInfo, error){
+    data := &viewmodels.AppCatInfo{}
+    ok, err := d.engine.Where("app_cat_id = ?", appCatId).Get(data)
+    if !ok && err == nil {
+        return nil, err
+    } else {
+        return data, nil
+    }
+}
+
+func (d *AppCatRepo) Create(data *datamodels.AppCat) error {
+    data.CreatedAt = time.Now()
+    _, err := d.engine.Insert(data)
+    return err
+}
+
+func (d *AppCatRepo) Update(data *datamodels.AppCat) error {
+    appCatId := data.AppCatId
+    
+    data.UpdatedAt = time.Now()
+    _, err := d.engine.Where("app_cat_id = ?", appCatId).Update(data)
+    return err
+}
+
+func (d *AppCatRepo) Delete(m map[string]interface{}) error {
+    appCatId   := m["appCatId"].(int64)
+    deletedBy  := m["deletedBy"].(int64)
+    
+    data := &datamodels.AppCat{}
+    data.DeletedFlag = 1
+    data.DeletedBy   = deletedBy
+    data.DeletedAt   = time.Now()
+    _, err := d.engine.Where("app_cat_id = ?", appCatId).Update(data)
+    return err
+}

+ 212 - 0
repositories/system/account_repo.go

@@ -0,0 +1,212 @@
+package system
+
+import (
+	"fmt"
+	"log"
+	"time"
+	"xorm.io/core"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type AccountRepo struct {
+	engine *xorm.Engine
+}
+
+func NewAccountRepo(engine *xorm.Engine) *AccountRepo {
+	return &AccountRepo{
+		engine: engine,
+	}
+}
+
+func (d *AccountRepo) GetAccountByName(accountName string) *viewmodels.AccountInfo {
+	data := &viewmodels.AccountInfo{}
+
+	sqlSelect := ` SELECT   A.oc_id,
+                            B.oc_type_id,
+                            B.oc_name,
+                            A.account_id,
+                            A.account_name,
+                            A.account_real_name,
+                            A.password,
+                            A.account_type,
+                            A.account_staff_no,
+                            A.account_phone,
+                            A.account_last_ip,
+                            A.account_loc,
+                            A.status,
+                            A.account_avatar,
+                            A.account_photo,
+                            A.account_real_name,
+                            A.account_intro,
+                            A.wx_id,
+                            A.is_fixed `
+	sqlFrom := `  FROM      account AS A
+                  LEFT JOIN oc      AS B ON (A.oc_id = B.oc_id )
+               `
+	sqlWhere := `WHERE A.deleted_flag = 0  `
+
+	if accountName != "" {
+		sqlWhere += ` AND   A.account_name like ` + "'%" + accountName + "%'"
+	}
+
+	//err2 := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("role_id DESC").Limit(pageSize, pageStart).Find(&datalist)
+	ok, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Get(data)
+
+	if !ok && err != nil {
+		return nil
+	} else {
+		return data
+	}
+}
+
+func (d *AccountRepo) GetAccountByCode(code string) (*viewmodels.AccountInfo, error) {
+	data := &viewmodels.AccountInfo{}
+	sqlSelect := ` SELECT   A.oc_id,
+							B.oc_type_id,
+							B.oc_name,
+							A.account_id,
+							A.account_name,
+							A.account_real_name,
+							A.password,
+							A.account_type,
+							A.account_staff_no,
+							A.account_phone,
+							A.account_last_ip,
+							A.account_loc,
+							A.status,
+							A.account_avatar,
+							A.account_photo,
+							A.account_real_name,
+							A.account_intro,
+							A.wx_id,
+							A.is_fixed `
+	sqlFrom := `  FROM      account AS A
+                  LEFT JOIN oc      AS B ON (A.oc_id = B.oc_id ) `
+	sqlWhere := ` WHERE A.deleted_flag = 0  `
+	sqlWhere += ` AND  (A.account_name = ` + "'" + code + "'"
+	sqlWhere += ` OR    A.account_phone = ` + "'" + code + "'"
+	sqlWhere += ` OR    A.account_mail = ` + "'" + code + "'"
+	sqlWhere += ` OR    A.account_staff_no = ` + "'" + code + "')"
+
+	ok, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Get(data)
+	if !ok && err != nil {
+		return nil, err
+	}
+	return data, nil
+}
+
+func (d *AccountRepo) GetById(ocId int64, accountId int64) *viewmodels.AccountInfo {
+	var user = &viewmodels.AccountInfo{}
+
+	sqlSelect := ` SELECT   A.oc_id,
+                            B.oc_type_id,
+                            B.oc_name,
+                            A.account_id,
+                            A.account_name,
+                            A.account_real_name,
+                            A.password,
+                            A.account_type,
+                            A.account_staff_no,
+                            A.account_phone,
+                            A.account_last_ip,
+                            A.account_loc,
+                            A.status,
+                            A.account_avatar,
+                            A.account_photo,
+                            A.account_real_name,
+                            A.account_intro,
+                            A.wx_id,
+                            A.is_fixed `
+	sqlFrom := `  FROM      account AS A
+                  LEFT JOIN oc      AS B ON (A.oc_id = B.oc_id ) `
+	sqlWhere := ` WHERE A.deleted_flag = 0  AND A.oc_id = ` + fmt.Sprintf("%d", ocId)
+	sqlWhere += ` AND   A.account_id = ` + fmt.Sprintf("%d", accountId)
+
+	has, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Get(user)
+
+	if !has || err != nil {
+		return nil
+	} else {
+		return user
+	}
+
+}
+
+func (d *AccountRepo) GetByList(ocId int64) ([]viewmodels.AccountInfo, error) {
+	datalist := make([]viewmodels.AccountInfo, 0)
+
+	sqlSelect := ` SELECT   A.oc_id,
+                            B.oc_type_id,
+                            B.oc_name,
+                            A.account_id,
+                            A.account_name,
+                            A.account_real_name,
+                            A.password,
+                            A.account_type,
+                            A.account_staff_no,
+                            A.account_phone,
+                            A.account_last_ip,
+                            A.account_loc,
+                            A.status,
+                            A.account_avatar,
+                            A.account_photo,
+                            A.account_real_name,
+                            A.account_intro,
+                            A.wx_id,
+                            A.is_fixed `
+	sqlFrom := `  FROM      account AS A
+                  LEFT JOIN oc      AS B ON (A.oc_id = B.oc_id ) `
+	sqlWhere := ` WHERE A.deleted_flag = 0  `
+
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Asc("account_id").Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+
+	return datalist, nil
+}
+
+func (d *AccountRepo) Create(data *datamodels.Account) error {
+	_, err := d.engine.Insert(data)
+	return err
+}
+
+func (d *AccountRepo) Update(ocId, accountId int64, data *datamodels.Account) error {
+	_, err := d.engine.ID(core.PK{ocId, accountId}).Update(data)
+	return err
+}
+
+func (d *AccountRepo) Delete(m map[string]interface{}) error {
+	ocId      := m["ocId"].(int64)
+	accountId := m["accountId"].(int64)
+	deletedBy := m["deletedBy"].(int64)
+	data := &datamodels.Account{
+		OcId: ocId,
+		AccountId: accountId,
+		DeletedFlag: 1,
+		DeletedBy: deletedBy,
+		DeletedAt: time.Now(),
+	}
+	_, err := d.engine.ID(core.PK{ocId, accountId}).Update(data)
+	return err
+}
+
+func (d *AccountRepo) IsUserNameExist(ocId int64, accountName string) bool {
+	count, err := d.engine.Where("deleted_flag = 0").Where("account_name = ?", accountName).Count(new(datamodels.Account))
+	if err != nil {
+		log.Fatal(err)
+		return true
+	}
+	return count > 0
+}
+
+func (d *AccountRepo) IsUserPhoneExist(ocId int64, accountPhone string) bool {
+	count, err := d.engine.Where("deleted_flag = 0").Where("account_phone = ?", accountPhone).Count(new(datamodels.Account))
+	if err != nil {
+		log.Fatal(err)
+		return true
+	}
+	return count > 0
+}

+ 76 - 0
repositories/system/app_permit_repo.go

@@ -0,0 +1,76 @@
+package system
+
+import (
+	"fmt"
+	"log"
+	"time"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type AppPermitRepo struct {
+	engine *xorm.Engine
+}
+
+// New Instance
+func NewAppPermitRepo(engine *xorm.Engine) *AppPermitRepo {
+	return &AppPermitRepo{
+		engine: engine,
+	}
+}
+
+func (d *AppPermitRepo) GetByList(appKey string, roleId int64, keywords string) []viewmodels.AppPermitInfo {
+
+	var datalist = make([]viewmodels.AppPermitInfo, 0)
+
+	sqlSelect := `SELECT A.app_id,
+                         A.role_id,
+                         A.permit_id,
+                         A.permit_title,
+                         A.permit_code,
+                         A.permit_desc,
+                         A.permit_type,
+                         A.root_id,
+                         A.parent_id,
+                         A.sort_no
+                 `
+	sqlFrom := `FROM app_permit  AS A
+                JOIN app         AS B ON (A.app_id = B.app_id)
+                `
+	sqlWhere := `WHERE A.deleted_flag = 0
+                 AND   B.app_key = '` + appKey + "'"
+	if keywords != "" {
+		sqlWhere += ` AND   A.role_id = ` + fmt.Sprintf("%d", roleId)
+	}
+	if keywords != "" {
+		sqlWhere += ` AND   A.permit_title like ` + "'%" + keywords + "%'"
+	}
+
+	sqlOrderBy := " ORDER BY A.app_id, A.role_id, A.parent_id, A.sort_no "
+
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy).Find(&datalist)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	return datalist
+}
+
+// Delete
+func (d *AppPermitRepo) Delete(ocId int64, groupTypeId int64) error {
+	data := &datamodels.AppPermit{DeletedFlag: 1, DeletedAt: time.Now()}
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("group_cat_id = ?", groupTypeId).Update(data)
+	return err
+}
+
+// Update
+func (d *AppPermitRepo) Update(ocId int64, groupTypeId int64, data *datamodels.AppPermit) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("group_cat_id = ?", groupTypeId).Update(data)
+	return err
+}
+
+func (d *AppPermitRepo) Create(data *datamodels.AppPermit) error {
+	_, err := d.engine.Insert(data)
+	return err
+}

+ 33 - 0
repositories/system/company_repo.go

@@ -0,0 +1,33 @@
+package system
+
+import (
+    "xorm.io/xorm"
+    "xps/datamodels"
+)
+
+type CompanyRepo struct {
+    engine *xorm.Engine
+}
+
+func NewCompanyRepo(engine *xorm.Engine) *CompanyRepo {
+    return &CompanyRepo{
+        engine: engine,
+    }
+}
+
+func (d *CompanyRepo) GetById(ocId int64) (*datamodels.Company, error){
+    data := &datamodels.Company{}
+    
+    has ,err := d.engine.Where("oc_id = ?" ,ocId).Get(data)
+    
+    if !has || err != nil {
+        return nil, err
+    }else {
+        return data, nil
+    }
+}
+
+func (d *CompanyRepo) Update(ocId int64 ,data *datamodels.Company) error{
+    _, err := d.engine.Where("oc_id = ?", ocId).Update(data)
+    return err
+}

+ 116 - 0
repositories/system/group_cat_repo.go

@@ -0,0 +1,116 @@
+package system
+
+import (
+	"fmt"
+	"time"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type GroupCatRepo struct {
+	engine *xorm.Engine
+}
+
+func NewGroupCatRepo(engine *xorm.Engine) *GroupCatRepo {
+	return &GroupCatRepo{
+		engine: engine,
+	}
+}
+
+func (d *GroupCatRepo) GetByPage(m map[string]interface{})(*viewmodels.PageResult, error) {
+	ocId     := m["ocId"].(int64)
+	keywords := m["keywords"].(string)
+	limit    := m["limit"].(int)
+	page     := m["page"].(int)
+
+	sqlSelect := `SELECT A.*`
+	sqlFrom   := `FROM   s_group_cat   AS A `
+	sqlWhere  := `WHERE A.deleted_flag = 0  and A.oc_id = ` + fmt.Sprintf("%d", ocId)
+
+	if keywords != "" {
+		sqlWhere += ` AND   A.group_cat_title like ` + "'%" + keywords + "%'"
+	}
+
+	sqlCount := `SELECT COUNT(*) `
+	total, err1 := d.engine.SQL(sqlCount + sqlFrom + sqlWhere).Count(new(datamodels.GroupCat))
+	if err1 != nil {
+		return nil, err1
+	}
+	
+	sqlOrderBy := " ORDER BY group_cat_id DESC "
+	pageStart := (page - 1) * limit
+	sqlLimit := fmt.Sprintf(" LIMIT %d OFFSET %d ", limit, pageStart)
+	
+	datalist := make([]datamodels.GroupCat, 0)
+	err2 := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy + sqlLimit).Find(&datalist)
+	if err2 != nil {
+		return nil, err2
+	}
+	
+	pageResult := &viewmodels.PageResult{}
+	pageResult.Data     = datalist
+	pageResult.Total    = total
+	pageResult.PageSize = limit
+	pageResult.Page     = page
+	return pageResult, nil
+
+}
+
+func (d *GroupCatRepo) GetByList(m map[string]interface{})([]viewmodels.GroupCatInfo, error) {
+	ocId     := m["ocId"].(int64)
+	keywords := m["keywords"].(string)
+	
+	sqlSelect := `SELECT A.* `
+	sqlFrom   := `FROM  s_group_cat   AS A    `
+	sqlWhere  := `WHERE A.deleted_flag = 0  AND A.oc_id =` + fmt.Sprintf("%d", ocId)
+	if keywords != "" {
+		sqlWhere += ` AND   A.group_cat_title like ` + "'%" + keywords + "%'"
+	}
+
+	sqlOrderBy := " ORDER BY group_cat_id DESC "
+	datalist   := make([]viewmodels.GroupCatInfo, 0)
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy).Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+	return datalist, nil
+}
+
+func (d *GroupCatRepo) GetById(ocId int64, groupCatId int64)(*viewmodels.GroupCatInfo, error){
+	data := &viewmodels.GroupCatInfo{}
+	ok, err := d.engine.Where("oc_id = ?", ocId).Where("group_cat_id = ?", groupCatId).Get(data)
+	if !ok && err == nil {
+		return nil, err
+	} else {
+		return data, nil
+	}
+}
+
+func (d *GroupCatRepo) Create(data *datamodels.GroupCat) error {
+	data.CreatedAt = time.Now()
+	_, err := d.engine.Insert(data)
+	return err
+}
+
+func (d *GroupCatRepo) Update(data *datamodels.GroupCat) error {
+	ocId       := data.OcId
+	groupCatId := data.GroupCatId
+	
+	data.UpdatedAt = time.Now()
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("group_cat_id = ?", groupCatId).Update(data)
+	return err
+}
+
+func (d *GroupCatRepo) Delete(m map[string]interface{}) error {
+	ocId       := m["ocId"].(int64)
+	groupCatId := m["groupCatId"].(int64)
+	deletedBy  := m["deletedBy"].(int64)
+	
+	data := &datamodels.GroupCat{}
+	data.DeletedFlag = 1
+	data.DeletedBy   = deletedBy
+	data.DeletedAt   = time.Now()
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("group_cat_id = ?", groupCatId).Update(data)
+	return err
+}

+ 119 - 0
repositories/system/group_member_position_repo.go

@@ -0,0 +1,119 @@
+package system
+
+import (
+	"fmt"
+	"xorm.io/core"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type GroupMemberPositionRepo struct {
+	engine *xorm.Engine
+}
+
+func NewGroupMemberPositionRepo(engine *xorm.Engine) *GroupMemberPositionRepo {
+	return &GroupMemberPositionRepo{
+		engine: engine,
+	}
+}
+
+func (d *GroupMemberPositionRepo) GetById(ocId int64, gmpid int64)(*datamodels.GroupMemberPosition, error){
+	data := &datamodels.GroupMemberPosition{OcId: ocId, GmpId: gmpid}
+	ok, err := d.engine.Get(data)
+	if !ok && err != nil {
+		return nil, err
+	} else {
+		return data, nil
+	}
+}
+
+func (d *GroupMemberPositionRepo) GetFirstPositionByGroupIdAndAccountId(ocId, groupId, accountId int64) (*viewmodels.GroupMemberPositionInfo, error) {
+	sqlSelect := ` SELECT
+                          A.oc_id,
+                          A.gmp_id,
+                          A.group_id,
+                          B.group_name,
+                          A.account_id,
+                          C.account_name,
+                          A.position_id,
+                          D.position_name 
+                 `
+	sqlFrom := ` FROM      s_group_member_position AS A 
+                   LEFT JOIN s_group       AS B ON ( A.oc_id = B.oc_id AND A.group_id    = B.group_id   )
+                   LEFT JOIN account       AS C ON ( A.oc_id = C.oc_id AND A.account_id  = C.account_id ) 
+                   LEFT JOIN s_position    AS D ON ( A.oc_id = D.oc_id AND A.position_id = D.position_id)
+                 `
+	sqlWhere := ` WHERE A.oc_id      = ` + fmt.Sprintf("%d", ocId)
+	sqlWhere += `  AND  A.group_id   = ` + fmt.Sprintf("%d", groupId)
+	sqlWhere += `  AND  A.account_id = ` + fmt.Sprintf("%d", accountId)
+	
+	roleMemberPositionInfo := &viewmodels.GroupMemberPositionInfo{}
+	has, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Limit(1).Get(roleMemberPositionInfo)
+	if !has || err != nil {
+		return nil, err
+	}
+	return roleMemberPositionInfo, nil
+}
+
+func (d *GroupMemberPositionRepo) GetByAccountId(ocId int64, accountId int64)(*datamodels.GroupMemberPosition, error){
+	data := &datamodels.GroupMemberPosition{OcId: ocId, AccountId: accountId}
+	ok, err := d.engine.Get(data)
+	if !ok && err != nil {
+		return nil, err
+	} else {
+		return data, nil
+	}
+}
+
+func (d *GroupMemberPositionRepo) GetByList(m map[string]interface{})([]viewmodels.GroupMemberPositionInfo, error){
+	ocId     := m["ocId"].(int64)
+	keywords := m["keywords"].(string)
+	sqlSelect := `SELECT A.gm_id,
+                         A.group_id,
+                         A.group_name,
+                         A.account_id,
+                         A.group_member_remark `
+	sqlFrom := ` FROM      s_group_member AS A
+                 LEFT JOIN s_group  AS B ON (A.group_id = B.group_id) `
+	sqlWhere := `WHERE  A.deleted_flag = 0 AND A.oc_id = ` + fmt.Sprintf("%d", ocId)
+	if keywords != "" {
+		sqlWhere += ` AND   B.group_name like ` + "'%" + keywords + "%'"
+	}
+	
+	datalist := make([]viewmodels.GroupMemberPositionInfo, 0)
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("group_id DESC").Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+	return datalist, nil
+}
+
+func (d *GroupMemberPositionRepo) Create(data *datamodels.GroupMemberPosition) error {
+	_, err := d.engine.Insert(data)
+	return err
+}
+
+func (d *GroupMemberPositionRepo) Update(ocId int64, gmpId int64, data *datamodels.GroupMemberPosition) error {
+	_, err := d.engine.ID(core.PK{ocId, gmpId}).Update(data)
+	return err
+}
+
+func (d *GroupMemberPositionRepo) Delete(ocId int64, gmpId int64) error {
+	_, err := d.engine.ID(core.PK{ocId, gmpId}).Delete(new(datamodels.GroupMemberPosition))
+	return err
+}
+
+func (d *GroupMemberPositionRepo) DeleteByGroupId(ocId int64, groupId int64) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).
+		Where("group_id = ?", groupId).
+		Delete(new(datamodels.GroupMemberPosition))
+	return err
+}
+
+func (d *GroupMemberPositionRepo) DeleteByAccountId(ocId int64, accountId int64) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).
+		Where("account_id = ?", accountId).
+		Delete(new(datamodels.GroupMemberPosition))
+	return err
+}

+ 209 - 0
repositories/system/group_member_repo.go

@@ -0,0 +1,209 @@
+package system
+
+import (
+	"fmt"
+	"log"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+// Role repository data struct
+type GroupMemberRepo struct {
+	engine *xorm.Engine
+}
+
+// New role repository instance
+func NewGroupMemberRepo(engine *xorm.Engine) *GroupMemberRepo {
+	return &GroupMemberRepo{
+		engine: engine,
+	}
+}
+
+// Get role by id
+func (d *GroupMemberRepo) GetById(ocId int64, gmId int64) *datamodels.GroupMember {
+	data := &datamodels.GroupMember{GmId: gmId}
+	ok, err := d.engine.Get(data)
+	if ok && err == nil {
+		return data
+	} else {
+		data.GroupId = 0
+		return data
+	}
+}
+
+func (d *GroupMemberRepo) GetByList(m map[string]interface{})([]viewmodels.GroupMemberInfo, error) {
+    ocId      := m["ocId"].(int64)
+	keywords  := m["keywords"].(string)
+	sqlSelect := `SELECT A.gm_id,
+                         A.group_id,
+                         A.group_name,
+                         A.account_id,
+                         A.group_member_remark `
+	sqlFrom   := `FROM      s_group_member AS A
+                  LEFT JOIN s_group        AS B ON (A.group_id = B.group_id) `
+	sqlWhere  := `WHERE  A.deleted_flag = 0 and A.oc_id = ` + fmt.Sprintf("%d", ocId)
+	if keywords != "" {
+		sqlWhere += ` AND   B.group_name like ` + "'%" + keywords + "%'"
+	}
+	datalist := make([]viewmodels.GroupMemberInfo, 0)
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("group_id DESC").Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+
+	return datalist, nil
+}
+
+func (d *GroupMemberRepo) GetMembersOfSubordinateGroupByPage(ocId, groupId, groupLeft, groupRight int64, keyword string) []viewmodels.GroupMemberInfo {
+	var datalist = make([]viewmodels.GroupMemberInfo, 0)
+
+	sqlSelect := `
+        SELECT
+            DISTINCT(A.account_id),
+            A.gm_id,
+            A.oc_id,
+            A.group_id,
+            A.created_by,
+            A.created_time,
+            A.updated_by,
+            A.updated_time,
+            A.deleted_flag,
+            A.deleted_by,
+            A.deleted_time,
+    
+            B.account_name,
+            B.account_real_name,
+            B.account_phone,
+            B.account_pic,
+            B.status,    
+            C.group_name,
+            C.node_left,
+            C.node_right,
+
+            D.gmp_id,
+            D.position_id,
+            D.position_name,
+			
+			E.gmpg_id,
+            E.grant_group_id,
+            F.group_name as grant_group_name
+
+        `
+	sqlFrom := `
+        FROM
+            s_group_member                      AS A
+        LEFT JOIN account                       AS B ON (A.oc_id = B.oc_id AND A.account_id = B.account_id)
+        LEFT JOIN s_group                       AS C ON (A.oc_id = C.oc_id AND A.group_id    = C.group_id)
+        LEFT JOIN s_group_member_position_grant AS E ON (B.oc_id = E.oc_id AND B.account_id = E.account_id)
+        LEFT JOIN s_group                       AS F ON(E.oc_id = F.oc_id AND E.grant_group_id = F.group_id)
+        LEFT JOIN (
+            SELECT
+                M.oc_id,
+                M.account_id,
+                M.gmp_id,
+                M.group_id,
+                M.position_id,
+                P.position_name,
+                N.gmpg_id,
+                N.grant_group_id,
+                GP.group_name as grant_group_name
+            FROM
+                s_group_member_position AS M
+            LEFT JOIN s_group_member_position_grant AS N ON (
+                    M.oc_id = N.oc_id
+                AND M.account_id = N.account_id
+                AND M.group_id = N.group_id
+                AND M.position_id = N.position_id)
+            LEFT JOIN s_position AS P  ON(M.oc_id = P.oc_id  AND M.position_id    = P.position_id)
+            LEFT JOIN s_group    AS GP ON(M.oc_id = GP.oc_id AND N.grant_group_id = GP.group_id)
+         )      AS  D ON (A.oc_id= D.oc_id AND A.account_id = D.account_id AND A.group_id = D.group_id)
+                 `
+	sqlWhere := `WHERE  B.deleted_flag = 0 and A.oc_id = ` + fmt.Sprintf("%d", ocId)
+
+	if keyword != "" {
+		sqlWhere += ` AND ( B.account_real_name LIKE ` + "'%" + keyword + "%'"
+		sqlWhere += ` OR B.account_name             LIKE ` + "'%" + keyword + "%'"
+		sqlWhere += ` OR B.account_phone            LIKE ` + "'%" + keyword + "%'"
+		sqlWhere += ` OR D.position_title           LIKE ` + "'%" + keyword + "%'"
+	}
+
+	if groupLeft > 0 && groupRight > 0 {
+		sqlWhere += ` AND C.node_left  >= ` + fmt.Sprintf("%d", groupLeft)
+		sqlWhere += ` AND C.node_right <= ` + fmt.Sprintf("%d", groupRight)
+	}
+
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("A.group_id DESC").Find(&datalist)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	return datalist
+}
+
+func (d *GroupMemberRepo) GetFirstGroupByAccountId(ocId int64, aid int64) (*viewmodels.GroupMemberInfo, error) {
+	var groupMemberInfo = &viewmodels.GroupMemberInfo{}
+
+	sqlSelect := `
+        SELECT
+            A.gm_id,
+            A.oc_id,
+            A.account_id,
+            A.group_id,
+            B.group_name,
+            B.node_left,
+            B.node_right
+        `
+	sqlFrom := `
+        FROM
+            s_group_member    AS A
+        LEFT JOIN s_group     AS B ON (A.oc_id = B.oc_id AND A.group_id    = B.group_id)
+        `
+	sqlWhere := ` WHERE  A.oc_id      = ` + fmt.Sprintf("%d", ocId)
+	sqlWhere += ` AND    A.account_id = ` + fmt.Sprintf("%d", aid)
+
+	has, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("A.group_id DESC").Limit(1).Get(groupMemberInfo)
+	if !has || err != nil {
+		log.Fatal(err)
+		return nil, err
+	}
+
+	return groupMemberInfo, nil
+}
+
+// Create
+func (d *GroupMemberRepo) Create(data *datamodels.GroupMember) error {
+	_, err := d.engine.Insert(data)
+	return err
+}
+
+// Update
+func (d *GroupMemberRepo) Update(ocId int64, gmId int64, data *datamodels.GroupMember) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("gm_id =?", gmId).Update(data)
+	return err
+}
+
+// Delete
+func (d *GroupMemberRepo) Delete(ocId int64, gmId int64) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("gm_id =?", gmId).Delete(new(datamodels.GroupMember))
+	return err
+}
+
+// Delete
+func (d *GroupMemberRepo) DeleteByGroupId(ocId int64, groupId int64) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).
+		Where("group_id = ?", groupId).
+		Delete(new(datamodels.GroupMember))
+
+	return err
+}
+
+// Delete
+func (d *GroupMemberRepo) DeleteByAccountId(ocId int64, accountId int64) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).
+		Where("account_id = ?", accountId).
+		Delete(new(datamodels.GroupMember))
+	
+	return err
+}
+

+ 173 - 0
repositories/system/group_repo.go

@@ -0,0 +1,173 @@
+package system
+
+import (
+    "fmt"
+    "time"
+    "xorm.io/xorm"
+    "xps/datamodels"
+    "xps/viewmodels"
+)
+
+type GroupRepo struct {
+    engine *xorm.Engine
+}
+
+func NewGroupRepo(engine *xorm.Engine) *GroupRepo{
+    return &GroupRepo{
+        engine:engine,
+    }
+}
+
+func (d *GroupRepo) GetById(ocId int64 ,groupId int64)(*viewmodels.GroupInfo, error) {
+    
+    sqlSelect := ` SELECT A.oc_id,
+                          A.group_id ,
+                          A.group_name,
+                          A.group_cat_id,
+                          B.group_cat_title,
+                          A.group_code,
+                          A.group_select,
+                          A.group_path,
+                          A.group_desc,
+                          A.root_id,
+                          A.parent_id,
+                          C.group_name as parent_name,
+                          A.node_left,
+                          A.node_right,
+                          A.node_level,
+                          A.is_leaf,
+                          A.is_fixed           `
+    sqlFrom  :=  ` FROM       s_group      AS A
+                   LEFT JOIN  s_group_cat  AS B ON (A.oc_id = B.oc_id AND A.group_cat_id     = B.group_cat_id)
+                   LEFT JOIN  s_group      AS C ON (A.oc_id = C.oc_id AND A.parent_id  = C.group_id )`
+    sqlWhere :=  ` WHERE A.deleted_flag = 0 AND A.oc_id = ` + fmt.Sprintf("%d" ,ocId)
+    sqlWhere +=  ` AND   A.group_id = ` + fmt.Sprintf("%d" ,groupId)
+    
+    data := &viewmodels.GroupInfo{GroupId: groupId}
+    ok, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("group_id ASC").Get(data)
+    if !ok && err != nil {
+        return nil, err
+    } else {
+        return data, nil
+    }
+}
+
+func (d *GroupRepo) GetByList(m map[string]interface{})([]viewmodels.GroupInfo, error) {
+    ocId     := m["ocId"].(int64)
+    keywords := m["keywords"].(string)
+    
+    sqlSelect := ` SELECT A.oc_id,
+                          A.group_id ,
+                          A.group_name,
+                          A.group_cat_id,
+                          B.group_cat_title,
+                          A.group_code,
+                          A.group_select,
+                          A.group_path,
+                          A.group_desc,
+                          A.root_id,
+                          A.parent_id,
+                          C.group_name as parent_name,
+                          A.node_left,
+                          A.node_right,
+                          A.node_level,
+                          A.is_leaf,
+                          A.is_fixed           `
+    sqlFrom  :=  ` FROM       s_group      AS A
+                   LEFT JOIN  s_group_cat  AS B ON (A.oc_id = B.oc_id AND A.group_cat_id     = B.group_cat_id)
+                   LEFT JOIN  s_group      AS C ON (A.oc_id = C.oc_id AND A.parent_id  = C.group_id )`
+    sqlWhere :=  ` WHERE A.deleted_flag = 0 and A.oc_id = ` + fmt.Sprintf("%d" ,ocId)
+    if keywords != "" {
+        sqlWhere+= ` AND A.group_name like `+"'%"+keywords+"%'"
+    }
+    
+    datalist := make([]viewmodels.GroupInfo, 0)
+    err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("group_id ASC").Find(&datalist)
+    if err != nil{
+        return nil, err
+    }
+    return datalist, nil
+}
+
+
+// Delete
+func (d *GroupRepo) Delete(m map[string]interface{}) error {
+    ocId       := m["ocId"].(int64)
+    groupId    := m["groupId"].(int64)
+    deletedBy  := m["deletedBy"].(int64)
+    group := &datamodels.Group{}
+    group.OcId        = ocId
+    group.GroupId     = groupId
+    group.DeletedFlag = 1
+    group.DeletedBy   = deletedBy
+    group.DeletedAt   = time.Now()
+    _, err := d.engine.Where("oc_id = ?", ocId).Where("group_id =?", groupId).Update(group)
+    return err
+}
+
+func (d *GroupRepo) Update(data *datamodels.Group) error{
+    ocId    := data.OcId
+    groupId := data.GroupId
+    _, err := d.engine.Where("oc_id = ?", ocId).Where("group_id =?", groupId).Update(data)
+    return err
+}
+
+func (d *GroupRepo) RefreshLeafStatus(ocId int64 ,groupId int64 ,isLeaf bool) error {
+    var sql string
+    if isLeaf {
+        sql = fmt.Sprintf("UPDATE s_group SET is_leaf = 1 WHERE oc_id = %d AND group_id = %d" ,ocId ,groupId)
+    }else {
+        sql = fmt.Sprintf("UPDATE s_group SET is_leaf = 0 WHERE oc_id = %d AND group_id = %d" ,ocId ,groupId)
+    }
+    _ ,err := d.engine.Exec(sql)
+    return err
+}
+
+func (d *GroupRepo) Create(data *datamodels.Group) error {
+    _, err := d.engine.Insert(data)
+    return err
+}
+
+func (d *GroupRepo) IncrementGroupLeft(ocId int64 ,steps int64 ,nodeLeft int64) error {
+    
+    sql  := fmt.Sprintf("UPDATE s_group SET node_left = node_left + %d  WHERE oc_id =%d AND node_left >= %d AND deleted_flag = 0" ,steps ,ocId ,nodeLeft)
+    _, err :=d.engine.Exec(sql)
+    
+    return err
+}
+
+func (d *GroupRepo) IncrementGroupRight(ocId int64 ,steps int64 ,nodeRight int64) error {
+    sql  := fmt.Sprintf("UPDATE s_group SET node_right = node_right + %d WHERE oc_id =%d AND node_right >= %d AND deleted_flag = 0" ,steps ,ocId ,nodeRight)
+    _, err :=d.engine.Exec(sql)
+    return err
+}
+
+func (d *GroupRepo) DecrementGroupLeft(ocId int64 ,steps int64 ,nodeLeft int64) error {
+    sql  := fmt.Sprintf("UPDATE s_group SET node_left = node_left - %d  WHERE oc_id =%d AND node_left > %d AND deleted_flag = 0" ,steps ,ocId ,nodeLeft)
+    _, err :=d.engine.Exec(sql)
+    return err
+}
+
+func (d *GroupRepo) DecrementGroupRight(ocId int64 ,steps int64 ,nodeRight int64) error {
+    sql  := fmt.Sprintf("UPDATE s_group SET node_right = node_right - %d WHERE oc_id =%d AND node_right > %d AND deleted_flag = 0" ,steps ,ocId ,nodeRight)
+    _, err :=d.engine.Exec(sql)
+    return err
+}
+
+func (d *GroupRepo) BatchDelete(ocId ,nodeLeft ,nodeRight int64) error {
+    sql := fmt.Sprintf("DELETE FROM s_group WHERE oc_id = %d AND node_left >= %d AND node_right <= %d " ,ocId ,nodeLeft ,nodeRight)
+    _ ,err := d.engine.Exec(sql)
+    return err
+}
+
+func (d *GroupRepo) CountOfChildren(ocId, groupId int64)(int64, error){
+    count, err := d.engine.Where("oc_id = ?" ,ocId).
+        Where("group_parent_id = ?" ,groupId).
+        Where("deleted_flag = 0 ").
+        Count(new(datamodels.Group))
+    
+    if err != nil {
+        return 0, err
+    }
+    return count, nil
+}

+ 221 - 0
repositories/system/oc_repo.go

@@ -0,0 +1,221 @@
+package system
+
+import (
+	"fmt"
+	"time"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type OcRepo struct {
+	engine *xorm.Engine
+}
+
+func NewOcRepo(engine *xorm.Engine) *OcRepo {
+	return &OcRepo{
+		engine: engine,
+	}
+}
+
+func (d *OcRepo) GetById(ocId int64) (*viewmodels.OcInfo, error) {
+	sqlSelect := `  SELECT  A.oc_id,
+							A.oc_name,
+							A.oc_type_id,
+							A.root_id,
+							A.parent_id,
+							A.admin_id,
+							B.account_name AS admin_name,
+							A.group_id,
+							A.node_left,
+							A.node_right,
+							A.node_level,
+							A.is_leaf,
+							A.status,
+							A.if_lic
+                  `
+	sqlFrom := ` FROM      oc       AS A
+                 LEFT JOIN account  AS B ON(A.admin_id = B.account_id)
+               `
+	sqlWhere := ` WHERE A.deleted_flag = 0  AND A.oc_id = ` + fmt.Sprintf("%d", ocId)
+	
+	data := &viewmodels.OcInfo{}
+	has, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Get(data)
+
+	if !has || err != nil {
+		return nil, err
+	}
+
+	return data, nil
+
+}
+
+func (d *OcRepo) GetByPage(m map[string]interface{})(*viewmodels.PageResult, error) {
+	keywords := m["keywords"].(string)
+	limit    := m["limit"].(int)
+	page     := m["page"].(int)
+
+
+	sqlSelect := `  SELECT  A.oc_id,
+							A.oc_name,
+							A.oc_type_id,
+							A.root_id,
+							A.parent_id,
+							A.admin_id,
+							B.account_name AS admin_name,
+							A.group_id,
+							A.node_left,
+							A.node_right,
+							A.node_level,
+							A.is_leaf,
+							A.status,
+							A.if_lic
+                  `
+	sqlFrom := ` FROM      oc       AS A
+                 LEFT JOIN account  AS B ON(A.oc_admin_id = B.account_id)
+               `
+	sqlWhere := ` WHERE A.deleted_flag = 0 `
+
+	if keywords != "" {
+		sqlWhere += ` AND   A.oc_name like ` + "'%" + keywords + "%'"
+	}
+
+	sqlCount := `SELECT COUNT(*) `
+	total, err1 := d.engine.SQL(sqlCount + sqlFrom + sqlWhere).Count()
+	if err1 != nil {
+		return nil, err1
+	}
+
+	pageStart := (page - 1) * limit
+	sqlOrderBy := " ORDER BY oc_id ASC "
+	sqlLimit := fmt.Sprintf(" LIMIT %d OFFSET %d  ", limit, pageStart)
+	
+	var datalist []viewmodels.OcInfo
+	err2 := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy + sqlLimit).Find(&datalist)
+	if err2 != nil {
+		return nil, err2
+	}
+	
+	pageResult := &viewmodels.PageResult{}
+	pageResult.Data = datalist
+	pageResult.Total = total
+	pageResult.PageSize = limit
+	pageResult.Page = page
+	return pageResult, nil
+
+}
+
+func (d *OcRepo) GetByList(m map[string]interface{})([]viewmodels.OcInfo, error) {
+	keywords := m["keywords"].(string)
+	sqlSelect := `  SELECT  A.oc_id,
+							A.oc_name,
+							A.oc_type_id,
+							A.root_id,
+							A.parent_id,
+							A.admin_id,
+							B.account_name AS admin_name,
+							A.group_id,
+							A.node_left,
+							A.node_right,
+							A.node_level,
+							A.is_leaf,
+							A.status,
+							A.if_lic
+                  `
+	sqlFrom := ` FROM      oc       AS A
+                 LEFT JOIN account  AS B ON(A.oc_admin_id = B.account_id)
+               `
+	sqlWhere := ` WHERE A.deleted_flag = 0 `
+
+	if keywords != "" {
+		sqlWhere += ` AND   A.oc_name like ` + "'%" + keywords + "%'"
+	}
+
+	sqlOrderBy := " ORDER BY oc_id ASC "
+	datalist := make([]viewmodels.OcInfo, 0)
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy).Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+	return datalist, nil
+}
+
+func (d *OcRepo) Delete(m map[string]interface{}) error {
+	ocId := m["ocId"].(int64)
+	data := &datamodels.Oc{DeletedFlag: 1}
+	_, err := d.engine.Where("oc_id = ?", ocId).Update(data)
+	return err
+}
+
+func (d *OcRepo) Update(data *datamodels.Oc) error {
+	ocId := data.OcId
+	data.UpdatedAt = time.Now()
+	_, err := d.engine.Where("oc_id = ?", ocId).Update(data)
+	return err
+}
+
+func (d *OcRepo) Create(data *datamodels.Oc) error {
+	_, err := d.engine.Insert(data)
+	return err
+}
+
+func (d *OcRepo) IncrementLeft(iRoot, steps, iLeft int64) error {
+	sql := fmt.Sprintf("UPDATE oc SET node_left = node_left + %d  WHERE root_id = %d AND node_left >= %d AND deleted_flag = 0", iRoot, steps, iLeft)
+	_, err := d.engine.Exec(sql)
+	return err
+}
+
+func (d *OcRepo) IncrementRight(iRoot, steps, iRight int64) error {
+	sql := fmt.Sprintf("UPDATE oc SET node_right = node_right + %d WHERE root_id = %d AND node_right >= %d AND deleted_flag = 0", iRoot, steps, iRight)
+	_, err := d.engine.Exec(sql)
+	return err
+}
+
+func (d *OcRepo) DecrementLeft(iRoot, steps, iLeft int64) error {
+	sql := fmt.Sprintf("UPDATE oc SET node_left = node_left - %d  WHERE root_id = %d AND node_left > %d AND deleted_flag = 0", iRoot, steps, iLeft)
+	_, err := d.engine.Exec(sql)
+	return err
+}
+
+func (d *OcRepo) DecrementRight(iRoot, steps int64, iRight int64) error {
+	sql := fmt.Sprintf("UPDATE oc SET node_right = node_right - %d WHERE root_id = %d AND node_right > %d AND deleted_flag = 0", iRoot, steps, iRight)
+	_, err := d.engine.Exec(sql)
+	return err
+}
+
+func (d *OcRepo) BatchDelete(iRootId, iLeft, iRight int64) error {
+	sql := fmt.Sprintf("DELETE FROM oc WHERE root_id = %d AND node_left >= %d AND node_right <= %d ", iRootId, iLeft, iRight)
+	_, err := d.engine.Exec(sql)
+	return err
+}
+
+func (d *OcRepo) CountOfChildren(iRoot, iid int64) (int64, error) {
+	count, err := d.engine.
+		Where("root_id", iRoot).
+		Where("parent_id = ?", iid).
+		Where("deleted_flag = 0 ").
+		Count(new(datamodels.Oc))
+
+	if err != nil {
+		return 0, err
+	}
+
+	return count, nil
+}
+
+func (d *OcRepo) GetAdmin(ocId int64)(*datamodels.Account, error) {
+	sqlSelect := ` SELECT A.*       ,
+                          B.*            `
+	sqlFrom   := ` FROM       oc           AS A
+                   LEFT  JOIN account      AS B ON(A.oc_id     = B.oc_id   AND A.admin_id = B.account_id) `
+	sqlWhere  := ` WHERE A.deleted_flag = 0  AND A.oc_id = ` + fmt.Sprintf("%d", ocId)
+	
+	data := &datamodels.Account{}
+	has, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Get(data)
+
+	if !has || err != nil {
+		return nil, err
+	} else {
+		return data, nil
+	}
+}

+ 115 - 0
repositories/system/position_repo.go

@@ -0,0 +1,115 @@
+package system
+
+import (
+	"fmt"
+	"time"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type PositionRepo struct {
+	engine *xorm.Engine
+}
+
+func NewPositionRepo(engine *xorm.Engine) *PositionRepo {
+	return &PositionRepo{
+		engine: engine,
+	}
+}
+
+func (d *PositionRepo) GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error) {
+	ocId     := m["ocId"].(int64)
+	keywords := m["keywords"].(string)
+	limit    := m["limit"].(int)
+	page     := m["page"].(int)
+
+	sqlSelect := ` SELECT A.* `
+	sqlFrom   := ` FROM   s_position AS A   `
+	sqlWhere  := fmt.Sprintf(` WHERE A.deleted_flag = 0 and A.oc_id = %d`, ocId)
+	if keywords != "" {
+		sqlWhere += ` AND   A.position_name like ` + "'%" + keywords + "%'"
+	}
+
+	sqlCount := `SELECT COUNT(*) `
+	total, err := d.engine.SQL(sqlCount + sqlFrom + sqlWhere).Count()
+	if err != nil {
+		return nil, err
+	}
+
+	var pageStart = (limit - 1) * limit
+	sqlOrderBy := " ORDER BY position_id ASC "
+	sqlLimit := fmt.Sprintf(" LIMIT %d OFFSET %d  ", limit, pageStart)
+	
+	datalist := []viewmodels.PositionInfo{}
+	err = d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy + sqlLimit).Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+	
+	pageResult := &viewmodels.PageResult{}
+	pageResult.Data = datalist
+	pageResult.Total = total
+	pageResult.PageSize = limit
+	pageResult.Page = page
+	return pageResult, nil
+}
+
+func (d *PositionRepo) GetByList(m map[string]interface{}) ([]viewmodels.PositionInfo, error) {
+	ocId     := m["ocId"].(int64)
+	keywords := m["keywords"].(string)
+
+	sqlSelect := ` SELECT A.* `
+	sqlFrom   := ` FROM   s_position AS A   `
+	sqlWhere  := fmt.Sprintf(` WHERE A.deleted_flag = 0 and A.oc_id = %d`, ocId)
+	if keywords != "" {
+		sqlWhere += ` AND   A.position_name like ` + "'%" + keywords + "%'"
+	}
+
+	sqlOrderBy := " ORDER BY position_id ASC "
+	datalist := make([]viewmodels.PositionInfo, 0)
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy).Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+	return datalist, nil
+}
+
+func (d *PositionRepo) GetById(ocId int64, positionId int64) (*viewmodels.PositionInfo, error) {
+	data := &viewmodels.PositionInfo{}
+	data.OcId       = ocId
+	data.PositionId = positionId
+	ok, err := d.engine.Get(data)
+	if !ok || err != nil {
+		return nil, err
+	}
+	return data, nil
+}
+
+func (d *PositionRepo) Create(data *datamodels.Position) error {
+	data.CreatedAt = time.Now()
+	_, err := d.engine.Insert(data)
+	return err
+}
+
+func (d *PositionRepo) Update(data *datamodels.Position) error {
+	ocId       := data.OcId
+	positionId := data.PositionId
+	data.UpdatedAt = time.Now()
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("position_id =?", positionId).Update(data)
+	return err
+}
+
+func (d *PositionRepo) Delete(m map[string]interface{}) error {
+	ocId       := m["ocId"].(int64)
+	positionId := m["positionId"].(int64)
+	deletedBy  := m["deletedBy"].(int64)
+	
+	data := &datamodels.Position{}
+	data.DeletedFlag = 1
+	data.DeletedBy   = deletedBy
+	data.DeletedAt   = time.Now()
+	_, err := d.engine.Where("oc_id = ?", ocId).Where("position_id =?", positionId).Update(data)
+	return err
+}
+

+ 101 - 0
repositories/system/role_member_repo.go

@@ -0,0 +1,101 @@
+package system
+
+import (
+	"fmt"
+	"log"
+	"xorm.io/core"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type RoleMemberRepo struct {
+	engine *xorm.Engine
+}
+
+func NewRoleMemberRepo(engine *xorm.Engine) *RoleMemberRepo {
+	return &RoleMemberRepo{
+		engine: engine,
+	}
+}
+
+func (d *RoleMemberRepo) GetAll(ocId int64, keyword string) []viewmodels.RoleMemberInfo {
+	var datalist = make([]viewmodels.RoleMemberInfo, 0)
+	
+	sqlSelect := `SELECT A.rm_id,
+                         A.role_id,
+                         B.role_name,
+                         A.account_id,
+                         C.account_name `
+	sqlFrom := `FROM      s_role_member AS A 
+                  LEFT JOIN s_role        AS B ON (A.role_id    = B.role_id)
+                  LEFT JOIN account       AS C ON (A.account_id = C.account_id AND A.oc_id = C.oc_id)
+                 `
+	sqlWhere := `WHERE A.oc_id = ` + fmt.Sprintf("%d", ocId)
+	
+	if keyword != "" {
+		sqlWhere += ` AND   B.role_name like ` + "'%" + keyword + "%'"
+	}
+	
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).OrderBy("role_id DESC").Find(&datalist)
+	if err != nil {
+		log.Fatal(err)
+	}
+	
+	return datalist
+}
+
+func (d *RoleMemberRepo) GetAccountFirstRole(ocId int64, accountId int64) (*viewmodels.RoleMemberInfo, error) {
+	var roleMemberInfo = &viewmodels.RoleMemberInfo{}
+	
+	sqlSelect := `SELECT A.rm_id,
+                         A.role_id,
+                         B.role_name,
+                         A.account_id,
+                         C.account_name  `
+	sqlFrom := `  FROM      s_role_member AS A
+                  LEFT JOIN s_role        AS B ON (A.role_id    = B.role_id)
+                  LEFT JOIN account       AS C ON (A.account_id = C.account_id AND A.oc_id = C.oc_id) 
+                 `
+	sqlWhere := `WHERE A.oc_id      = ` + fmt.Sprintf("%d", ocId)
+	sqlWhere += `  AND A.account_id = ` + fmt.Sprintf("%d", accountId)
+	
+	has, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Limit(1).Get(roleMemberInfo)
+	if !has || err != nil {
+		return nil, err
+	}
+	
+	return roleMemberInfo, nil
+}
+
+func (d *RoleMemberRepo) Update(ocId int64, rmId int64, rm *datamodels.RoleMember) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).
+		Where("rm_id  = ?", rmId).
+		Update(rm)
+	return err
+}
+
+func (d *RoleMemberRepo) Delete(ocId int64, rmId int64) error {
+	_, err := d.engine.Where("oc_id = ?", ocId).
+		Where("rm_id  = ?", rmId).
+		Delete(new(datamodels.RoleMember))
+	return err
+}
+
+func (d *RoleMemberRepo) DeleteById(ocId int64, roleId int64, accountId int64) error {
+	_, err := d.engine.ID(core.PK{ocId, roleId, accountId}).Delete(new(datamodels.RoleMember))
+	return err
+}
+
+func (d *RoleMemberRepo) DeleteByAccountId(ocId int64, accountId int64) error {
+	_, err := d.engine.
+		Where("oc_id = ?", ocId).
+		Where("account_id  = ?", accountId).
+		Delete(new(datamodels.RoleMember))
+	return err
+}
+
+func (d *RoleMemberRepo) Create(data *datamodels.RoleMember) error {
+	_, err := d.engine.Insert(data)
+	return err
+}

+ 124 - 0
repositories/system/role_repo.go

@@ -0,0 +1,124 @@
+package system
+
+import (
+	"fmt"
+	"time"
+	"xorm.io/xorm"
+	"xps/datamodels"
+	"xps/viewmodels"
+)
+
+type RoleRepo struct {
+	engine *xorm.Engine
+}
+
+func NewRoleRepo(engine *xorm.Engine) *RoleRepo {
+	return &RoleRepo{
+		engine: engine,
+	}
+}
+
+func (d *RoleRepo) GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error){
+	keywords   := m["keywords"].(string)
+	limit      := m["limit"].(int)
+	page       := m["page"].(int)
+	
+	sqlSelect := ` SELECT A.role_id ,
+                          A.role_name,
+                          A.role_desc,
+                          A.role_type_id,
+                          B.role_type_title,
+                          A.sort_no,
+                          A.status,
+                          A.is_fixed `
+	sqlFrom   := ` FROM      s_role       AS A
+                   LEFT JOIN s_role_type  AS B ON (A.role_type_id = B.role_type_id )`
+	sqlWhere  := `WHERE A.deleted_flag = 0`
+
+	if keywords != "" {
+		sqlWhere += ` AND   A.role_name like ` + "'%" + keywords + "%'"
+	}
+
+	sqlCount := `SELECT COUNT(*) `
+	total, err := d.engine.SQL(sqlCount + sqlFrom + sqlWhere).Count(new(datamodels.Role))
+	if err != nil {
+		return nil, err
+	}
+	
+	sqlOrderBy := " ORDER BY role_id ASC "
+	pageStart := (limit - 1) * limit
+	sqlLimit := fmt.Sprintf(" LIMIT %d OFFSET %d ", limit, pageStart)
+	
+	datalist   := make([]viewmodels.RoleInfo, 0)
+	err = d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy + sqlLimit).Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+	
+	pageResult := &viewmodels.PageResult{}
+	pageResult.Data = datalist
+	pageResult.Total = total
+	pageResult.PageSize = limit
+	pageResult.Page = page
+	return pageResult, nil
+}
+
+func (d *RoleRepo) GetByList(m map[string]interface{}) ([]viewmodels.RoleInfo, error) {
+	datalist := make([]viewmodels.RoleInfo, 0)
+	keywords := m["keywords"].(string)
+
+	sqlSelect := ` SELECT A.role_id ,
+                          A.role_name,
+                          A.role_desc,
+                          A.role_type_id,
+                          B.role_type_title,
+                          A.sort_no,
+                          A.status,
+                          A.is_fixed `
+	sqlFrom := ` FROM      s_role       AS A
+                 LEFT JOIN s_role_type  AS B ON (A.role_type_id = B.role_type_id )`
+	sqlWhere := `WHERE A.deleted_flag = 0 `
+	if keywords != "" {
+		sqlWhere += ` AND   A.role_name like ` + "'%" + keywords + "%'"
+	}
+	sqlOrderBy := " ORDER BY role_id ASC "
+	err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy).Find(&datalist)
+	if err != nil {
+		return nil, err
+	}
+
+	return datalist, nil
+}
+
+func (d *RoleRepo) GetById(roleId int64) (*viewmodels.RoleInfo, error) {
+	data := &viewmodels.RoleInfo{RoleId: roleId}
+	ok, err := d.engine.Get(data)
+	if !ok && err != nil {
+		return nil, err
+	}
+	return data, nil
+}
+
+func (d *RoleRepo) Create(data *datamodels.Role) error {
+	_, err := d.engine.Insert(data)
+	return err
+}
+
+func (d *RoleRepo) Update(data *datamodels.Role) error {
+	roleId := data.RoleId
+	data.UpdatedAt = time.Now()
+	_, err := d.engine.Where("role_id = ?", roleId).Update(data)
+	return err
+}
+
+func (d *RoleRepo) Delete(m map[string]interface{}) error {
+	roleId    := m["roleId"].(int64)
+	deletedBy := m["deletedBy"].(int64)
+	
+	data := &datamodels.Role{}
+	data.DeletedFlag = 1
+	data.DeletedBy   = deletedBy
+	data.DeletedAt   = time.Now()
+	_, err := d.engine.Where("role_id = ?", roleId).Update(data)
+	return err
+}

+ 152 - 0
repositories/system/user_repo.go

@@ -0,0 +1,152 @@
+package system
+
+import (
+    "fmt"
+    "xorm.io/xorm"
+    "xps/datamodels"
+    "xps/viewmodels"
+)
+
+type UserRepo struct {
+    engine *xorm.Engine
+}
+
+func NewUserRepo(engine *xorm.Engine) *UserRepo {
+    return &UserRepo{
+        engine: engine,
+    }
+}
+
+func (d *UserRepo) GetById(ocId int64, userId int64)(*viewmodels.UserInfo, error){
+    sqlSelect := ` SELECT A.gm_id,
+                        A.oc_id,
+                        A.group_id,
+                        A.account_id,
+                        B.account_name,
+                        B.account_real_name,
+                        B.account_staff_no,
+                        B.account_phone,
+                        B.account_type,
+                        B.account_avatar,
+                        B.account_photo,
+                        B.account_loc,
+                        B.status,
+                        B.is_fixed,
+                        C.group_name,
+                        C.node_left,
+                        C.node_right,
+                        E.gmp_id,
+                        E.position_id,
+                        H.position_name,
+                        F.gmpg_id,
+                        F.grant_group_id,
+                        G.group_name  AS grant_group_name`
+    sqlFrom := `  FROM  s_group_member                        AS  A
+                  LEFT  JOIN account                          AS  B  ON ( A.oc_id = B.oc_id AND A.account_id  = B.account_id  )
+                  LEFT  JOIN s_group                          AS  C  ON ( A.oc_id = C.oc_id AND A.group_id    = C.group_id )
+                  LEFT  JOIN s_group_member_position          AS  E  ON ( A.oc_id = E.oc_id AND A.account_id  = E.account_id AND E.group_id= #{groupId ,jdbcType=BIGINT} )
+                  LEFT  JOIN s_group_member_position_grant    AS  F  ON ( E.oc_id = F.oc_id AND E.account_id  = F.account_id AND E.position_id = F.position_id  AND F.group_id = #{groupId ,jdbcType=BIGINT} )
+                  LEFT  JOIN s_group                          AS  G  ON ( G.oc_id = F.oc_id AND G.group_id    = F.grant_group_id )
+                  LEFT  JOIN s_position                       AS  H  ON ( A.oc_id = E.oc_id AND H.position_id = E.position_id    ) `
+    sqlWhere := ` WHERE B.deleted_flag = 0 AND A.oc_id      = ` + fmt.Sprintf("%d", ocId)
+    sqlWhere += `  AND  A.account_id = ` + fmt.Sprintf("%d", userId)
+    
+    data := &viewmodels.UserInfo{}
+    has, err := d.engine.SQL(sqlSelect + sqlFrom + sqlWhere).Limit(1).Get(data)
+    if !has || err != nil {
+        return nil, err
+    }
+    return data, nil
+}
+
+func (d *UserRepo) GetByPage(m map[string]interface{})(*viewmodels.PageResult, error){
+    ocId       := m["ocId"].(int64)
+    keywords   := m["keywords"].(string)
+    limit      := m["limit"].(int)
+    page       := m["page"].(int)
+    nodeLeft   := m["nodeLeft"].(int64)
+    nodeRight  := m["nodeRight"].(int64)
+    
+    sqlSelect := `SELECT
+                    DISTINCT(A.account_id),
+                    A.gm_id,
+                    A.oc_id,
+                    A.group_id,
+                    B.account_name,
+                    B.account_real_name,
+                    B.account_phone,
+                    B.account_staff_no,
+                    B.account_avatar,
+                    B.status,
+                    B.is_fixed,
+                    C.group_name,
+                    C.node_left,
+                    C.node_right,
+                    D.gmp_id,
+                    D.position_id,
+                    D.position_name,
+                    E.gmpg_id,
+                    E.grant_group_id,
+                    F.group_name as grant_group_name  `
+    sqlFrom := `FROM      s_group_member                AS A
+                LEFT JOIN account                       AS B ON (A.oc_id = B.oc_id AND A.account_id     = B.account_id)
+                LEFT JOIN s_group                       AS C ON (A.oc_id = C.oc_id AND A.group_id       = C.group_id)
+                LEFT JOIN s_group_member_position_grant AS E ON (B.oc_id = E.oc_id AND B.account_id     = E.account_id)
+                LEFT JOIN s_group                       AS F ON (E.oc_id = F.oc_id AND E.grant_group_id = F.group_id)
+                LEFT JOIN (
+                    SELECT
+                        M.oc_id,
+                        M.account_id,
+                        M.gmp_id,
+                        M.group_id,
+                        M.position_id,
+                        P.position_name,
+                        N.gmpg_id,
+                        N.grant_group_id,
+                        GP.group_name as grant_group_name
+                    FROM      s_group_member_position       AS M
+                    LEFT JOIN s_group_member_position_grant AS N ON (
+                            M.oc_id       = N.oc_id
+                        AND M.account_id  = N.account_id
+                        AND M.group_id    = N.group_id
+                        AND M.position_id = N.position_id )
+                    LEFT JOIN s_position AS P  ON(M.oc_id = P.oc_id  AND M.position_id    = P.position_id)
+                    LEFT JOIN s_group    AS GP ON(M.oc_id = GP.oc_id AND N.grant_group_id = GP.group_id)
+                )      AS  D ON (A.oc_id = D.oc_id AND A.account_id = D.account_id AND A.group_id = D.group_id) `
+    sqlWhere := ` WHERE B.deleted_flag = 0 AND A.oc_id = ` + fmt.Sprintf("%d", ocId)
+    
+    if keywords != "" {
+        sqlWhere+= ` AND ( B.account_real_name LIKE ` + "'%"+keywords+"%'"
+        sqlWhere+= ` OR B.account_name             LIKE ` + "'%"+keywords+"%'"
+        sqlWhere+= ` OR B.account_phone            LIKE ` + "'%"+keywords+"%'"
+        sqlWhere+= ` OR D.position_name            LIKE ` + "'%"+keywords+"%'"
+    }
+    
+    if nodeLeft > 0 && nodeRight > 0 {
+        sqlWhere+= ` AND C.node_left  >= ` + fmt.Sprintf("%d", nodeLeft)
+        sqlWhere+= ` AND C.node_right <= ` + fmt.Sprintf("%d", nodeRight)
+    }
+    
+    sqlCount := `SELECT COUNT(*) `
+    total, err := d.engine.SQL(sqlCount + sqlFrom + sqlWhere).Count(new(datamodels.GroupMember))
+    if err != nil {
+        return nil, err
+    }
+    
+    sqlOrderBy := " ORDER BY A.account_id, A.group_id "
+    pageStart := (page - 1) * limit
+    sqlLimit := fmt.Sprintf(" LIMIT %d OFFSET %d ", limit, pageStart)
+    
+    datalist   := make([]viewmodels.UserInfo, 0)
+    err = d.engine.SQL(sqlSelect + sqlFrom + sqlWhere + sqlOrderBy + sqlLimit).Find(&datalist)
+    if err != nil {
+        return nil, err
+    }
+    
+    pageResult := &viewmodels.PageResult{}
+    pageResult.Data = datalist
+    pageResult.Total = total
+    pageResult.PageSize = limit
+    pageResult.Page = page
+    return pageResult, nil
+}

+ 52 - 0
service/system/app_cat_service.go

@@ -0,0 +1,52 @@
+package system
+
+import (
+    "xps/datamodels"
+    "xps/datasource"
+    "xps/repositories/apps"
+    "xps/viewmodels"
+)
+
+type AppCatService interface {
+    GetByList(m map[string]interface{}) ([]viewmodels.AppCatInfo, error)
+    GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error)
+    GetById(ocId int64, appCatId int64) (*viewmodels.AppCatInfo, error)
+    Create(d *datamodels.AppCat) error
+    Update(d *datamodels.AppCat) error
+    Delete(m map[string]interface{}) error
+}
+
+type appCatService struct {
+    repo *apps.AppCatRepo
+}
+
+func NewAppCatService() AppCatService {
+    return &appCatService{
+        repo: apps.NewAppCatRepo(datasource.InstanceMaster()),
+    }
+}
+
+func (s *appCatService) GetByList(m map[string]interface{}) ([]viewmodels.AppCatInfo, error) {
+    return s.repo.GetByList(m)
+}
+
+func (s *appCatService) GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error) {
+    return s.repo.GetByPage(m)
+}
+
+func (s *appCatService) GetById(ocId int64, appCatId int64) (*viewmodels.AppCatInfo, error) {
+    return s.repo.GetById(ocId, appCatId)
+}
+
+func (s *appCatService) Create(AppCat *datamodels.AppCat) error {
+    AppCat.AppCatId = NewID()
+    return s.repo.Create(AppCat)
+}
+
+func (s *appCatService) Update(AppCat *datamodels.AppCat) error {
+    return s.repo.Update(AppCat)
+}
+
+func (s *appCatService) Delete(m map[string]interface{}) error {
+    return s.repo.Delete(m)
+}

+ 29 - 0
service/system/app_permit_service.go

@@ -0,0 +1,29 @@
+package system
+
+import (
+	"xps/datasource"
+	"xps/repositories/system"
+	"xps/viewmodels"
+)
+
+// AppPermit interface
+type AppPermitService interface {
+	GetByList(appKey string, roleId int64, keywords string) []viewmodels.AppPermitInfo
+}
+
+// AppPermitService data struct definition
+type appPermitService struct {
+	repo *system.AppPermitRepo
+}
+
+// Create Instance
+func NewAppPermitService() AppPermitService {
+	return &appPermitService{
+		repo: system.NewAppPermitRepo(datasource.InstanceMaster()),
+	}
+}
+
+// GetAll
+func (s *appPermitService) GetByList(appKey string, roleId int64, keywords string) []viewmodels.AppPermitInfo {
+	return s.repo.GetByList(appKey, roleId, keywords)
+}

+ 29 - 0
service/system/base_service.go

@@ -0,0 +1,29 @@
+package system
+
+import (
+	"log"
+	"xps/cache"
+	"xps/datasource"
+	"xps/viewmodels"
+)
+
+func NewID() int64 {
+	engine := datasource.InstanceIDServer()
+	ret, err := engine.Exec("replace into uid_sequence(stub) values('a')")
+	if err != nil {
+		log.Fatal(err.Error())
+	}
+	uid, err := ret.LastInsertId()
+	if err != nil {
+		log.Fatal(err.Error())
+	}
+	return uid
+}
+
+func GetCurUser(userId int64) *viewmodels.UserData{
+	userData, err  := cache.GetUserData(userId)
+	if err != nil {
+		log.Fatal(err.Error())
+	}
+	return userData
+}

+ 55 - 0
service/system/company_profile_service.go

@@ -0,0 +1,55 @@
+package system
+
+import (
+    "xps/datamodels"
+    "xps/datasource"
+    "xps/repositories/system"
+)
+
+type CompanyProfileService interface{
+    GetById(ocId int64)(*datamodels.Company, error)
+    Update(data *datamodels.Company) error
+}
+
+type cmpProfileService struct {
+    companyRepo *system.CompanyRepo
+    ocRepo      *system.OcRepo
+    groupRepo   *system.GroupRepo
+}
+
+func NewCompanyProfileService() CompanyProfileService{
+    engine := datasource.InstanceMaster()
+    
+    return &cmpProfileService{
+        companyRepo: system.NewCompanyRepo(engine),
+        ocRepo:      system.NewOcRepo(engine),
+        groupRepo:   system.NewGroupRepo(engine),
+    }
+}
+
+func (s *cmpProfileService) GetById(ocId int64)(*datamodels.Company, error){
+    return s.companyRepo.GetById(ocId)
+}
+
+func (s *cmpProfileService) Update(data *datamodels.Company) error{
+    ocId := data.OcId
+    
+    oc  := &datamodels.Oc{}
+    oc.OcId   = ocId
+    oc.OcName = data.CmpName
+    err := s.ocRepo.Update(oc)
+    if err != nil {
+        return err
+    }
+    
+    group := &datamodels.Group{GroupName: data.CmpName}
+    group.OcId      = ocId
+    group.GroupId   = ocId
+    group.GroupName = data.CmpName
+    err = s.groupRepo.Update(group)
+    if err != nil {
+        return err
+    }
+    
+    return s.companyRepo.Update(ocId, data)
+}

+ 52 - 0
service/system/group_cat_service.go

@@ -0,0 +1,52 @@
+package system
+
+import (
+    "xps/datamodels"
+    "xps/datasource"
+    "xps/repositories/system"
+    "xps/viewmodels"
+)
+
+type GroupCatService interface {
+    GetByList(m map[string]interface{}) ([]viewmodels.GroupCatInfo, error)
+    GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error)
+    GetById(ocId int64, groupCatId int64) (*viewmodels.GroupCatInfo, error)
+    Create(d *datamodels.GroupCat) error
+    Update(d *datamodels.GroupCat) error
+    Delete(m map[string]interface{}) error
+}
+
+type groupCatService struct {
+    repo *system.GroupCatRepo
+}
+
+func NewGroupCatService() GroupCatService {
+    return &groupCatService{
+        repo: system.NewGroupCatRepo(datasource.InstanceMaster()),
+    }
+}
+
+func (s *groupCatService) GetByList(m map[string]interface{}) ([]viewmodels.GroupCatInfo, error) {
+    return s.repo.GetByList(m)
+}
+
+func (s *groupCatService) GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error) {
+    return s.repo.GetByPage(m)
+}
+
+func (s *groupCatService) GetById(ocId int64, groupCatId int64) (*viewmodels.GroupCatInfo, error) {
+    return s.repo.GetById(ocId, groupCatId)
+}
+
+func (s *groupCatService) Create(GroupCat *datamodels.GroupCat) error {
+    GroupCat.GroupCatId = NewID()
+    return s.repo.Create(GroupCat)
+}
+
+func (s *groupCatService) Update(GroupCat *datamodels.GroupCat) error {
+    return s.repo.Update(GroupCat)
+}
+
+func (s *groupCatService) Delete(m map[string]interface{}) error {
+    return s.repo.Delete(m)
+}

+ 154 - 0
service/system/group_service.go

@@ -0,0 +1,154 @@
+package system
+
+import (
+    "errors"
+    "xps/datamodels"
+    "xps/datasource"
+    "xps/repositories/system"
+    "xps/viewmodels"
+)
+
+type GroupService interface {
+    GetByList(m map[string]interface{})([]viewmodels.GroupInfo, error)
+    GetById(ocId int64 ,groupId int64)(*viewmodels.GroupInfo, error)
+    Create(group *datamodels.Group) error
+    Update(group *datamodels.Group) error
+    Delete(m map[string]interface{}) error
+}
+
+type groupService struct {
+    groupRepo *system.GroupRepo
+    groupMemberRepo *system.GroupMemberRepo
+    groupMemberPositionRepo *system.GroupMemberPositionRepo
+    //groupMemberPositionGrantRepo *base.GroupMemberPositionGrantRepo
+}
+
+func NewGroupService() GroupService{
+    return &groupService{
+        groupRepo:                     system.NewGroupRepo(datasource.InstanceMaster()),
+        groupMemberRepo :              system.NewGroupMemberRepo(datasource.InstanceMaster()),
+        groupMemberPositionRepo :      system.NewGroupMemberPositionRepo(datasource.InstanceMaster()),
+        //groupMemberPositionGrantRepo : base.NewGroupMemberPositionGrantRepo(datasource.InstanceMaster()),
+    }
+}
+
+func (s *groupService) GetByList(m map[string]interface{})([]viewmodels.GroupInfo, error) {
+    return s.groupRepo.GetByList(m)
+}
+
+func (s *groupService) GetById(ocId int64 ,gid int64)(*viewmodels.GroupInfo, error) {
+    return s.groupRepo.GetById(ocId ,gid)
+}
+
+func (s *groupService) Update(a *datamodels.Group) error{
+    return s.groupRepo.Update(a)
+}
+
+// Create the group
+func (s *groupService) Create(g *datamodels.Group) error {
+    ocId     := g.OcId
+    parentId := g.ParentId
+    
+    var parentNodeRight = int64(0)
+    var parentNodeLevel = int64(0)
+    
+    parent, err := s.groupRepo.GetById(ocId, parentId)
+    if err != nil {
+        return err
+    }
+    
+    if parent != nil {
+        parentNodeRight = parent.NodeRight
+        parentNodeLevel = parent.NodeLevel
+        
+        err := s.groupRepo.IncrementGroupRight(ocId ,2 ,parentNodeRight)
+        if err != nil {
+            return err
+        }
+        
+        err = s.groupRepo.IncrementGroupLeft(ocId ,2 ,parentNodeRight)
+        if err != nil {
+            return err
+        }
+        
+        // refresh parent node as non-leaf status
+        err = s.groupRepo.RefreshLeafStatus(ocId ,parentId, false)
+        if err != nil {
+            return err
+        }
+    }
+    
+    g.GroupId    = NewID()
+    g.NodeLeft   = parentNodeRight
+    g.NodeRight  = parentNodeRight + 1
+    g.NodeLevel  = parentNodeLevel + 1
+    g.RootId     = ocId
+    g.IsLeaf     = 1
+    return s.groupRepo.Create(g)
+}
+
+func (s *groupService) Delete(m map[string]interface{}) error {
+    ocId    := m["ocId"].(int64)
+    groupId := m["groupId"].(int64)
+    group, err := s.groupRepo.GetById(ocId ,groupId)
+    if err != nil{
+        return err
+    }
+    
+    if group.IsFixed == 1 {
+        return errors.New("不能删除锁定群组")
+    }
+    
+    nodeLeft   := group.NodeLeft
+    nodeRight  := group.NodeRight
+    parentId   := group.ParentId
+    
+    // delete the groups
+    err = s.groupRepo.BatchDelete(ocId ,nodeLeft ,nodeRight)
+    if err != nil {
+        return err
+    }
+    
+    steps := nodeRight - nodeLeft + 1
+    
+    // update the left
+    err = s.groupRepo.DecrementGroupLeft(ocId ,steps ,nodeLeft)
+    if err != nil {
+        return err
+    }
+    
+    // update the right
+    err = s.groupRepo.DecrementGroupRight(ocId ,steps ,nodeRight)
+    if err != nil {
+        return err
+    }
+    
+    // update the group parent leaf status
+    countOfBrothers, err := s.groupRepo.CountOfChildren(ocId ,parentId)
+    if err != nil {
+        return err
+    }
+    if (countOfBrothers < 1){
+        err = s.groupRepo.RefreshLeafStatus(ocId ,parentId, true)
+        if err != nil {
+            return err
+        }
+    }
+    
+    // delete the group members
+    err = s.groupMemberRepo.DeleteByGroupId(ocId ,groupId)
+    if err != nil {
+        return err
+    }
+    
+    // delete the group member position
+    err = s.groupMemberPositionRepo.DeleteByGroupId(ocId ,groupId)
+    if err != nil {
+        return err
+    }
+    
+    // delete the group member position grant
+    //err = s.groupMemberPositionGrantRepo.DeleteByGroupId(ocId ,gid)
+    
+    return err
+}

+ 134 - 0
service/system/login_service.go

@@ -0,0 +1,134 @@
+package system
+
+import (
+	"time"
+	"xps/cache"
+	"xps/datasource"
+	"xps/repositories/system"
+	"xps/utils"
+	"xps/viewmodels"
+	"xps/web/middleware"
+)
+
+type LoginService interface {
+	GetAccountByName(cond string) *viewmodels.AccountInfo
+	CheckLogin(username, password string) (bRet bool, msg string, data *viewmodels.AccessToken)
+	Logout(userId int64) error
+}
+
+type loginService struct {
+	accountRepo             *system.AccountRepo
+	ocRepo                  *system.OcRepo
+	roleMemberRepo          *system.RoleMemberRepo
+	groupMemberRepo         *system.GroupMemberRepo
+	groupMemberPositionRepo *system.GroupMemberPositionRepo
+}
+
+func NewLoginService() LoginService {
+	return &loginService{
+		accountRepo:             system.NewAccountRepo(datasource.InstanceMaster()),
+		ocRepo:                  system.NewOcRepo(datasource.InstanceMaster()),
+		roleMemberRepo:          system.NewRoleMemberRepo(datasource.InstanceMaster()),
+		groupMemberRepo:         system.NewGroupMemberRepo(datasource.InstanceMaster()),
+		groupMemberPositionRepo: system.NewGroupMemberPositionRepo(datasource.InstanceMaster()),
+	}
+}
+
+func (s *loginService) GetAccountByName(cond string) *viewmodels.AccountInfo {
+	return s.accountRepo.GetAccountByName(cond)
+}
+
+func (s *loginService) CheckLogin(code, password string) (bRet bool, msg string, data *viewmodels.AccessToken) {
+	account, err := s.accountRepo.GetAccountByCode(code)
+	if err != nil {
+		return false, "用户不存在", nil
+	}
+
+	pwd := utils.GetMD5String(password)
+	if pwd != account.Password {
+		return false, "密码错误", nil
+	}
+
+	if account.Status == 2 {
+		return false, "账号被锁定,无法登陆,请联系管理员", nil
+	}
+
+	ocId            := account.OcId
+	accountId       := account.AccountId
+	accountName     := account.AccountName
+	accountRealName := account.AccountRealName
+	accountAvatar   := account.AccountAvatar
+	accountPhoto    := account.AccountPhoto
+	accountIntro    := account.AccountIntro
+	accountPhone    := account.AccountPhone
+
+	oc, err := s.ocRepo.GetById(ocId)
+	if err != nil {
+		return false, "单位信息不完整,请联系管理员", nil
+	}
+	ocName   := oc.OcName
+	ocTypeId := oc.OcTypeId
+
+	roleMember, err := s.roleMemberRepo.GetAccountFirstRole(ocId, accountId)
+	if err != nil {
+		return false, "帐号没有配置角色信息", nil
+	}
+	curRoleId := roleMember.RoleId
+	curRoleName := roleMember.RoleName
+
+	groupMember, err := s.groupMemberRepo.GetFirstGroupByAccountId(ocId, accountId)
+	if err != nil {
+		return false, "账号没有所属部门", nil
+	}
+
+	curGroupId := groupMember.GroupId
+	curGroupName := groupMember.GroupName
+
+	groupMemberPosition, err := s.groupMemberPositionRepo.GetFirstPositionByGroupIdAndAccountId(ocId, curGroupId, accountId)
+	if err != nil {
+		return false, "账号没有岗位信息", nil
+	}
+
+	curPositionId := groupMemberPosition.PositionId
+	curPositionName := groupMemberPosition.PositionName
+
+	userData := &viewmodels.UserData{}
+	userData.OcId         = ocId
+	userData.OcName       = ocName
+	userData.UserId       = accountId
+	userData.UserName     = accountName
+	userData.UserRealName = accountRealName
+	userData.UserPhone    = accountPhone
+	userData.UserPhoto    = accountPhoto
+	userData.UserAvatar   = accountAvatar
+	userData.UserIntro    = accountIntro
+	userData.GroupId      = curGroupId
+	userData.GroupName    = curGroupName
+	userData.PositionId   = curPositionId
+	userData.PositionName = curPositionName
+	userData.RoleId       = curRoleId
+	userData.RoleName     = curRoleName
+	
+	err = cache.SetUserData(accountId, userData)
+	if err != nil {
+		return false, "Redis缓存用户数据失败", nil
+	}
+	
+	tokenStr, err := middleware.GenerateToken(ocId, ocTypeId, accountId)
+	if err != nil {
+		return false, "没有生成Token", nil
+	}
+	
+	expiresIn := time.Now().Add(time.Hour*24).UnixNano() / 1e6
+	tokenResult := &viewmodels.AccessToken{}
+	tokenResult.AccessToken = tokenStr
+	tokenResult.User = userData
+	tokenResult.ExpiresIn = expiresIn
+	tokenResult.LeaseTime = expiresIn
+	return true, "", tokenResult
+}
+
+func (s *loginService) Logout(userId int64) error {
+	_, err := cache.DeleteUserData(userId)
+	return err
+}

+ 53 - 0
service/system/position_service.go

@@ -0,0 +1,53 @@
+package system
+
+import (
+	"xps/datamodels"
+	"xps/datasource"
+	"xps/repositories/system"
+	"xps/viewmodels"
+)
+
+type PositionService interface {
+	GetByList(m map[string]interface{}) ([]viewmodels.PositionInfo, error)
+	GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error)
+	GetById(ocId int64, positionId int64) (*viewmodels.PositionInfo, error)
+	Create(d *datamodels.Position) error
+	Update(d *datamodels.Position) error
+	Delete(m map[string]interface{}) error
+}
+
+type positionService struct {
+	repo *system.PositionRepo
+}
+
+func NewPositionService() PositionService {
+	return &positionService{
+		repo: system.NewPositionRepo(datasource.InstanceMaster()),
+	}
+}
+
+func (s *positionService) GetByList(m map[string]interface{}) ([]viewmodels.PositionInfo, error) {
+	return s.repo.GetByList(m)
+}
+
+func (s *positionService) GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error) {
+	return s.repo.GetByPage(m)
+}
+
+func (s *positionService) GetById(ocId int64, positionId int64) (*viewmodels.PositionInfo, error) {
+	return s.repo.GetById(ocId, positionId)
+}
+
+
+func (s *positionService) Create(position *datamodels.Position) error {
+	position.PositionId = NewID()
+	return s.repo.Create(position)
+}
+
+func (s *positionService) Update(position *datamodels.Position) error {
+	return s.repo.Update(position)
+}
+
+func (s *positionService) Delete(m map[string]interface{}) error {
+	return s.repo.Delete(m)
+}

+ 52 - 0
service/system/role_service.go

@@ -0,0 +1,52 @@
+package system
+
+import (
+	"xps/datamodels"
+	"xps/datasource"
+	"xps/repositories/system"
+	"xps/viewmodels"
+)
+
+type RoleService interface {
+	GetByList(m map[string]interface{}) ([]viewmodels.RoleInfo, error)
+	GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error)
+	GetById(roleId int64) (*viewmodels.RoleInfo, error)
+	Update(user *datamodels.Role) error
+	Create(user *datamodels.Role) error
+	Delete(m map[string]interface{}) error
+}
+
+type roleService struct {
+	repo *system.RoleRepo
+}
+
+func NewRoleService() RoleService {
+	return &roleService{
+		repo: system.NewRoleRepo(datasource.InstanceMaster()),
+	}
+}
+
+func (s *roleService) GetByList(m map[string]interface{}) ([]viewmodels.RoleInfo, error) {
+	return s.repo.GetByList(m)
+}
+
+func (s *roleService) GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error) {
+	return s.repo.GetByPage(m)
+}
+
+func (s *roleService) GetById(roleId int64) (*viewmodels.RoleInfo, error) {
+	return s.repo.GetById(roleId)
+}
+
+func (s *roleService) Create(role *datamodels.Role) error {
+	role.RoleId = NewID()
+	return s.repo.Create(role)
+}
+
+func (s *roleService) Update(r *datamodels.Role) error {
+	return s.repo.Update(r)
+}
+
+func (s *roleService) Delete(m map[string]interface{}) error {
+	return s.repo.Delete(m)
+}

+ 202 - 0
service/system/user_service.go

@@ -0,0 +1,202 @@
+package system
+
+import (
+    "time"
+    "xps/constant"
+    "xps/datamodels"
+    "xps/datasource"
+    "xps/repositories/system"
+    "xps/viewmodels"
+)
+
+type UserService interface {
+    GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error)
+    GetById(ocId, groupId, userId int64) (*viewmodels.UserInfo, error)
+    Create(ocTypeId int64, user *viewmodels.UserInfo) error
+    Update(user *viewmodels.UserInfo) error
+    Delete(m map[string]interface{}) error
+}
+
+type userService struct {
+    userRepo *system.UserRepo
+    accountRepo *system.AccountRepo
+    roleMemberRepo *system.RoleMemberRepo
+    groupRepo *system.GroupRepo
+    groupMemberRepo *system.GroupMemberRepo
+    groupMemberPositionRepo *system.GroupMemberPositionRepo
+}
+
+func NewUserService() UserService {
+    return &userService{
+        userRepo: system.NewUserRepo(datasource.InstanceMaster()),
+        accountRepo: system.NewAccountRepo(datasource.InstanceMaster()),
+        roleMemberRepo: system.NewRoleMemberRepo(datasource.InstanceMaster()),
+        groupRepo: system.NewGroupRepo(datasource.InstanceMaster()),
+        groupMemberRepo: system.NewGroupMemberRepo(datasource.InstanceMaster()),
+        groupMemberPositionRepo: system.NewGroupMemberPositionRepo(datasource.InstanceMaster()),
+    }
+}
+
+func (s *userService) GetByPage(m map[string]interface{}) (*viewmodels.PageResult, error) {
+    ocId    := m["ocId"].(int64)
+    groupId := m["groupId"].(int64)
+    group, err := s.groupRepo.GetById(ocId, groupId)
+    if err != nil {
+        return nil, err
+    }
+    
+    nodeLeft  := group.NodeLeft
+    nodeRight := group.NodeRight
+    m["nodeLeft"]  = nodeLeft
+    m["nodeRight"] = nodeRight
+    return s.userRepo.GetByPage(m)
+}
+
+func (s *userService) GetById(ocId, groupId, userId int64) (*viewmodels.UserInfo, error) {
+    return s.GetById(ocId, groupId, userId)
+}
+
+func (s *userService) Create(ocTypeId int64, user *viewmodels.UserInfo) error {
+    ocId      := user.OcId
+    userId    := ocId //管理员ID同公司ID,只有管理员可以作账号管理
+    newId     := NewID()
+    accountId := newId
+    
+    userRole := constant.ENT_USER_ROLE
+    if ocTypeId == constant.OCTYPE_ADMIN {
+        userRole = constant.OP_ROLE_USER
+    }else if ocTypeId == constant.OCTYPE_ORG{
+        userRole = constant.ORG_ROLE_USER
+    }else if ocTypeId == constant.OCTYPE_ENT{
+        userRole = constant.ENT_USER_ROLE
+    }else if ocTypeId == constant.OCTYPE_PARTNER{
+        userRole = constant.PARTNER_ROLE_USER
+    }
+    
+    // 1.Account
+    account := &datamodels.Account{
+        OcId:           ocId,
+        AccountId:      accountId,
+        AccountName:     user.AccountName,
+        Password:        "21218cca77804d2ba1922c33e0151105",
+        AccountType:     0,
+        AccountRealName: user.AccountRealName,
+        AccountPhone:    user.AccountPhone,
+        AccountLastIp:   "",
+        AccountLoc:      user.AccountLoc,
+        AccountIntro:    user.AccountIntro,
+        AccountPhoto:    user.AccountPhoto,
+        AccountAvatar:   user.AccountAvatar,
+        AccountMail:     user.AccountMail,
+        AccountStaffNo:  user.AccountStaffNo,
+        Status:          1,
+        IsFixed:         0,
+        CreatedBy:       userId,
+        CreatedAt:       time.Time{},
+    }
+    
+    err := s.accountRepo.Create(account)
+    if err != nil {
+        return err
+    }
+    
+    // 2. Role member
+    roleMember := &datamodels.RoleMember{
+        RmId     : newId,
+        OcId     : ocId,
+        RoleId   : int64(userRole),
+        AccountId: accountId,
+    }
+    err = s.roleMemberRepo.Create(roleMember)
+    if err != nil {
+        return err
+    }
+    
+    // 3. Group Member
+    groupId := user.GroupId
+    groupMember := &datamodels.GroupMember{
+        GmId     : newId,
+        OcId     : ocId,
+        GroupId  : groupId,
+        AccountId: accountId,
+    }
+    err = s.groupMemberRepo.Create(groupMember)
+    if err != nil {
+        return err
+    }
+    
+    // 4. Group Member Position
+    positionId := user.PositionId
+    groupMemberPosition := &datamodels.GroupMemberPosition{
+        GmpId     : newId,
+        OcId      : ocId,
+        GroupId   : groupId,
+        AccountId : accountId,
+        PositionId: positionId,
+    }
+    err = s.groupMemberPositionRepo.Create(groupMemberPosition)
+    return err
+}
+
+func (s *userService) Update(user *viewmodels.UserInfo) error {
+    ocId       := user.OcId
+    accountId  := user.AccountId
+    groupId    := user.GroupId
+    positionId := user.PositionId
+    userId     := ocId//管理员ID同公司ID,只有管理员可以作账号管理
+    
+    // 1. update account
+    account := &datamodels.Account{
+        OcId:            ocId,
+        AccountId:       accountId,
+        AccountName:     user.AccountName,
+        AccountType:     0,
+        AccountRealName: user.AccountRealName,
+        AccountPhone:    user.AccountPhone,
+        AccountLastIp:   "",
+        AccountLoc:      user.AccountLoc,
+        AccountIntro:    user.AccountIntro,
+        AccountPhoto:    user.AccountPhoto,
+        AccountAvatar:   user.AccountAvatar,
+        AccountMail:     user.AccountMail,
+        AccountStaffNo:  user.AccountStaffNo,
+        Status:          user.Status,
+        UpdatedBy:       userId,
+        UpdatedAt:       time.Time{},
+    }
+    err := s.accountRepo.Update(ocId, accountId, account)
+    if err == nil {
+        return err
+    }
+    
+    // 2. update group member
+    gmId := user.GmId
+    groupMember := &datamodels.GroupMember{
+        GmId:      gmId,
+        OcId:      ocId,
+        GroupId:   groupId,
+        AccountId: accountId,
+    }
+    err = s.groupMemberRepo.Update(ocId, gmId, groupMember)
+    if err != nil {
+        return err
+    }
+    
+    // 3. update the group member position
+    gmpId := user.GmpId
+    groupMemberPosition := &datamodels.GroupMemberPosition{
+        OcId:       ocId,
+        GmpId:      gmpId,
+        GroupId:    groupId,
+        AccountId:  accountId,
+        PositionId: positionId,
+    }
+    err = s.groupMemberPositionRepo.Update(ocId, gmpId, groupMemberPosition)
+    return err
+}
+
+func (s *userService) Delete(m map[string]interface{}) error {
+    err := s.accountRepo.Delete(m)
+    return err
+}
+

+ 17 - 0
utils/hmacsha256.go

@@ -0,0 +1,17 @@
+package utils
+
+import (
+	"crypto/hmac"
+	"crypto/sha256"
+	"encoding/base64"
+	"encoding/hex"
+)
+
+func HmacSha256Encode(strings string, secret string) string {
+	key := []byte(secret)
+	h := hmac.New(sha256.New, key)
+	h.Write([]byte(strings))
+	sha := hex.EncodeToString(h.Sum(nil))
+
+	return base64.StdEncoding.EncodeToString([]byte(sha))
+}

+ 29 - 0
utils/http_status.go

@@ -0,0 +1,29 @@
+package utils
+
+// RetCode Result Code
+type HttpStatusCode int
+
+// Result Code List
+const (
+	HTTP_STATUS_OK           = 0
+	HTTP_STATUS_UNAUTHORIZED = 401
+	HTTP_STATUS_404          = 404
+	HTTP_STATUS_ERR          = 500
+)
+
+type HttpResult struct {
+	Code HttpStatusCode `json:"code"`
+	Msg  interface{}    `json:"msg"`
+	Data interface{}    `json:"data"`
+}
+
+func HttpStatusOk(msg string, objects interface{}) (r *HttpResult) {
+	r = &HttpResult{Code: HTTP_STATUS_OK, Msg: msg, Data: objects}
+	return
+}
+
+// ResultErr JRet Result
+func HttpStatusErr(code HttpStatusCode, msg string, objects interface{}) (r *HttpResult) {
+	r = &HttpResult{Code: code, Msg: msg, Data: objects}
+	return
+}

+ 14 - 0
utils/json.go

@@ -0,0 +1,14 @@
+package utils
+
+import "encoding/json"
+
+// interface{} can be any type data
+func JsonEncode(code int, data interface{}, msg string) ([]byte, error) {
+	result := struct {
+		Code int
+		Data interface{}
+		Msg  string
+	}{code, data, msg}
+
+	return json.Marshal(result)
+}

+ 34 - 0
utils/md5.go

@@ -0,0 +1,34 @@
+package utils
+
+import (
+	"crypto/md5"
+	"crypto/rand"
+	"encoding/base64"
+	"encoding/hex"
+	"io"
+)
+
+func GetMD5String(strings string) string {
+	md5Ctx := md5.New()
+	md5Ctx.Write([]byte(strings))
+	cipherStr := md5Ctx.Sum(nil)
+
+	return hex.EncodeToString(cipherStr)
+}
+
+func MD5ByByte(bytes []byte) string {
+	md5Ctx := md5.New()
+	md5Ctx.Write(bytes)
+	cipherStr := md5Ctx.Sum(nil)
+
+	return hex.EncodeToString(cipherStr)
+}
+
+func UniqueId() string {
+	b := make([]byte, 48)
+	if _, err := io.ReadFull(rand.Reader, b); err != nil {
+		return ""
+	}
+
+	return GetMD5String(base64.URLEncoding.EncodeToString(b))
+}

+ 9 - 0
viewmodels/access_token.go

@@ -0,0 +1,9 @@
+package viewmodels
+
+// UserToken RoleMember Data Model
+type AccessToken struct {
+	AccessToken string      `json:"accessToken"     `
+	User        interface{} `json:"user"            `
+	ExpiresIn   int64       `json:"expiresIn"       `
+	LeaseTime   int64       `json:"leaseTime"       `
+}

+ 29 - 0
viewmodels/account_info.go

@@ -0,0 +1,29 @@
+package viewmodels
+
+// AccountInfo Account Data Model
+type AccountInfo struct {
+	OcId            int64  `json:"ocId"             xorm:"'oc_id'             bigint         comment('组织ID:公司或机构或单位ID')"`
+	OcTypeId        int64  `json:"ocTypeId"         xorm:"'oc_type_id'        bigint         comment('OC TYPE ID')"`
+	OcTypeTitle     string `json:"ocTypeTitle"      xorm:"'oc_type_title'     varchar(128)   comment('OC TYPE TITLE')"`
+	AccountId       int64  `json:"accountId"        xorm:"'account_id'        bigint not null pk comment('主键ID')"`
+	AccountName     string `json:"accountName"      xorm:"'account_name'      varchar(128)   comment('帐号名称')"`
+	Password        string `json:"password"         xorm:"'password'          varchar(255)   comment('密码')"`
+	AccountType     int64  `json:"accountType"      xorm:"'account_type'      bigint         comment('帐号类型:0:系统用户,1:企业用户,2:集团用户,3:政府用户,4:合作伙伴')"`
+	AccountRealName string `json:"accountRealName"  xorm:"'account_real_name' varchar(64)    comment('姓名')"`
+	AccountIntro    string `json:"accountIntro"     xorm:"'account_intro'     varchar(511)   comment('个人简介')"`
+	AccountAvatar   string `json:"accountAvatar"    xorm:"'account_avatar'    varchar(255)   comment('头像')"`
+	AccountPhoto    string `json:"accountPhoto"     xorm:"'account_photo'     varchar(255)   comment('照片')"`
+	AccountPhone    string `json:"accountPhone"     xorm:"'account_phone'     varchar(32)    comment('手机号')"`
+	AccountLastIp   string `json:"accountLastIp"    xorm:"'account_last_ip'   varchar(10)    comment('最近一次登录IP')"`
+	AccountLoc      string `json:"accountLoc"       xorm:"'account_loc'       varchar(64)    comment('区域')"`
+	AccountMail     string `json:"accountMail"      xorm:"'account_mail'      varchar(64)    comment('Email')"`
+	AccountStaffNo  string `json:"accountStaffNo"   xorm:"'account_staff_no'  varchar(64)    comment('Email')"`
+	Status          int64  `json:"status"           xorm:"'status'            bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+	WxId            int64  `json:"wxId"             xorm:"'wxId'              bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+	IsFixed         int64  `json:"isFixed"          xorm:"'isFixed'           bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+}
+
+// TableName table name
+func (t *AccountInfo) TableName() string {
+	return "account"
+}

+ 12 - 0
viewmodels/app_cat_info.go

@@ -0,0 +1,12 @@
+package viewmodels
+
+type AppCatInfo struct {
+    AppCatId      int64     `json:"appCatId"        xorm:"'app_cat_id'      bigint     pk comment('主键ID')         "`
+    AppCatTitle   string    `json:"appCatTitle"     xorm:"'app_cat_title'   varchar(50)   comment('群组类型名称')     "`
+    AppCatDesc    string    `json:"appCatDesc"      xorm:"'app_cat_desc'    varchar(50)   comment('描述')            "`
+    IsFixed       int64     `json:"isFixed"         xorm:"'is_fixed'        int           comment('是否可修改')         "`
+}
+
+func (t *AppCatInfo) TableName() string {
+    return "app_cat"
+}

+ 15 - 0
viewmodels/app_permit_info.go

@@ -0,0 +1,15 @@
+package viewmodels
+
+// AppPermit Data Model
+type AppPermitInfo struct {
+	AppId       int64  `json:"appId"           form:"appId"           xorm:"'app_id'            bigint     pk comment('APP ID')"`
+	RoleId      int64  `json:"roleId"          form:"roleId"          xorm:"'role_id'           bigint     pk comment('Role ID')"`
+	PermitId    int64  `json:"permitId"        form:"permitId"        xorm:"'permit_id'         bigint     pk comment('Permit ID')  "`
+	PermitTitle string `json:"permitTitle"     form:"permitTitle"     xorm:"'permit_title'      varchar(127)  comment('标题')      "`
+	PermitCode  string `json:"permitCode"      form:"permitCode"      xorm:"'permit_code'       varchar(127)  comment('CODE')     "`
+	PermitDesc  string `json:"permitDesc"      form:"permitDesc"      xorm:"'permit_desc'       varchar(511)  comment('描述')      "`
+	PermitType  int64  `json:"permitType"      form:"permitType"      xorm:"'permit_type'       int           comment('Type') "`
+	RootId      int64  `json:"rootId"          form:"rootId"          xorm:"'root_id'           int           comment('Root Id') "`
+	ParentId    int64  `json:"parentId"        form:"parentId"        xorm:"'parent_id'         int           comment('Parent Id') "`
+	SortNo      int64  `json:"sortNo"          form:"sortNo"          xorm:"'sort_no'           int           comment('Sort No') "`
+}

+ 13 - 0
viewmodels/group_cat_info.go

@@ -0,0 +1,13 @@
+package viewmodels
+
+type GroupCatInfo struct {
+    OcId          int64     `json:"-"               xorm:"'oc_id'             bigint     pk comment('组织ID:公司或机构或单位ID')"`
+    GroupCatId    int64     `json:"groupCatId"      xorm:"'group_cat_id'      bigint     pk comment('主键ID')         "`
+    GroupCatTitle string    `json:"groupCatTitle"   xorm:"'group_cat_title'   varchar(50)   comment('群组类型名称')     "`
+    GroupCatDesc  string    `json:"groupCatDesc"    xorm:"'group_cat_desc'    varchar(50)   comment('描述')            "`
+    IsFixed       int64     `json:"isFixed"         xorm:"'is_fixed'          int           comment('是否可修改')         "`
+}
+
+func (t *GroupCatInfo) TableName() string {
+    return "s_group_cat"
+}

+ 24 - 0
viewmodels/group_info.go

@@ -0,0 +1,24 @@
+package viewmodels
+
+type GroupInfo struct {
+    OcId             int64   `json:"ocId"            xorm:"'oc_id'               bigint not null pk     comment('公司组织ID')  " `
+    GroupId          int64   `json:"groupId"         xorm:"'group_id'            bigint not null pk     comment('群组ID')      " `
+    GroupName        string  `json:"groupName"       xorm:"'group_name'          varchar(127) not null  comment('群组名称')    " `
+    GroupCatId       int64   `json:"groupCatId"      xorm:"'group_cat_id'        bigint not null        comment('群组类型ID')  " `
+    GroupCatTitle    string  `json:"groupCatTitle"   xorm:"'group_cat_title'     varchar(127) not null  comment('群组类型名称') " `
+    
+    GroupPath        string  `json:"groupPath"       xorm:"'group_path'          varchar(255) not null  comment('群组PATH')    " `
+    GroupDesc        string  `json:"groupDesc"       xorm:"'group_desc'          varchar(255) not null  comment('群组DESC')    " `
+    GroupCode        string  `json:"groupCode"       xorm:"'group_code'          varchar(127) not null  comment('群组CODE')    " `
+    GroupSelect      string  `json:"groupSelect"     xorm:"'group_select'        varchar(255) not null  comment('群组PATH')    " `
+    
+    RootId           int64   `json:"rootId"          xorm:"'root_id'             bigint not null        comment('Order')       " `
+    ParentId         int64   `json:"parentId"        xorm:"'parent_id'           bigint not null        comment('父群组ID')      " `
+    ParentName       string  `json:"parentName"      xorm:"'parent_name'         varchar(127) not null  comment('父群组名称')   " `
+    NodeLeft         int64   `json:"nodeLeft"        xorm:"'node_left'           bigint not null        comment('群组LEFT')    " `
+    NodeRight        int64   `json:"nodeRight"       xorm:"'node_right'          bigint not null        comment('群组RIGHT')   " `
+    NodeLevel        int64   `json:"nodeLevel"       xorm:"'node_level'          bigint not null        comment('群组LEVEL')   " `
+    
+    IsLeaf           int64   `json:"isLeaf"          xorm:"'is_leaf'             bigint not null        comment('LEAF群组')    " `
+    IsFixed          int64   `json:"isFixed"         xorm:"'is_fixed'            bigint not null        comment('群组STATUS')  " `
+}

+ 13 - 0
viewmodels/group_member_info.go

@@ -0,0 +1,13 @@
+package viewmodels
+
+// Role Member Info View data models
+type GroupMemberInfo struct {
+	OcId      int64  `json:"ocId"         xorm:"'oc_id'         bigint not null pk comment('公司组织ID')  " `
+	GmId      int64  `json:"gmId"         xorm:"'gm_id'         bigint not null pk comment('PK ID')      " `
+	GroupId   int64  `json:"groupId"      xorm:"'group_id'      bigint not null    comment('群组ID')      " `
+	GroupName string `json:"groupName"    xorm:"'group_name'    string not null    comment('群组名称')     " `
+	NodeLeft  int64  `json:"nodeLeft"     xorm:"'node_left'     bigint not null    comment('群组LEFT')    " `
+	NodeRight int64  `json:"nodeRight"    xorm:"'node_right'    bigint not null    comment('群组RIGHT')   " `
+	AccountId int64  `json:"accountId"    xorm:"'account_id'    bigint not null    comment('帐号ID')      " `
+	IsFixed   int64  `json:"isFixed"      xorm:"'is_fixed'      bigint             comment('是否可修改')   "`
+}

+ 34 - 0
viewmodels/group_member_position_grant_info.go

@@ -0,0 +1,34 @@
+// Copyright 2020. HouYafeng. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// License that can be found in the LICENSE file.
+
+// Package tar implements access to tar archives .
+// It aims to cover most of the variations, including those produced.
+// by GUN and BSD tars.
+//
+// References:
+//    https://www.58yunkang.com
+
+package viewmodels
+
+type GroupMemberPositionGrantInfo struct {
+    OcId             int64   `xorm:"'oc_id'               bigint not null pk comment('公司组织ID')  " `
+    GmId             int64   `xorm:"'gm_id'               bigint not null pk comment('GM PK ID')   " `
+    GroupId          int64   `xorm:"'group_id'            bigint not null pk comment('群组ID')      " `
+    GroupName        string  `xorm:"'group_name'          string not null    comment('群组名称')   " `
+    AccountId        int64   `xorm:"'account_id'          bigint not null pk comment('帐号ID')    " `
+    AccountRealName  string  `xorm:"'account_real_name'   varchar(64)   comment('姓名')"`
+    AccountPhone     string  `xorm:"'account_phone'       varchar(64)   comment('手机号')"`
+    AccountLastIp    string  `xorm:"'account_last_ip'     varchar(64)   comment('最近一次登录IP')"`
+    AccountLoc       string  `xorm:"'account_loc'         varchar(64)   comment('区域')"`
+    AccountPic       string  `xorm:"'account_pic'         varchar(64)   comment('头像')"`
+    Status           int64   `xorm:"'status'              bigint        default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+    
+    GmpId            int64   `xorm:"'gmp_id'              bigint not null comment('GMP PK ID') " `
+    PositionId       int64   `xorm:"'account_id'          bigint not null  comment('岗位ID')    " `
+    PositionName     string  `xorm:"'position_name'       string not null  comment('岗位名称')   " `
+    
+    GmpgId           int64   `xorm:"'gmpg_id'              bigint not null comment('GMPG PK ID')  " `
+    GrantGroupId     int64   `xorm:"'grant_group_id'      bigint not null  comment('授权群组ID')    " `
+    GrantGroupName   string  `xorm:"'grant_group_name'    string not null  comment('授权群组名称')   " `
+}

+ 12 - 0
viewmodels/group_member_position_info.go

@@ -0,0 +1,12 @@
+package viewmodels
+
+// Role Member Info View data models
+type GroupMemberPositionInfo struct {
+	OcId         int64  `form:"ocId"         xorm:"'oc_id'         bigint not null pk comment('公司组织ID') " `
+	GmpId        int64  `form:"gmpId"        xorm:"'gmp_id'        bigint not null pk comment('公司组织ID') " `
+	GroupId      int64  `form:"groupId"      xorm:"'group_id'      bigint not null pk comment('群组ID')    " `
+	GroupName    string `form:"groupName"    xorm:"'group_name'    string not null    comment('群组名称')   " `
+	AccountId    int64  `form:"accountId"    xorm:"'account_id'    bigint not null pk comment('帐号ID')     " `
+	PositionId   int64  `form:"positionId"   xorm:"'account_id'    bigint not null pk comment('岗位ID')     " `
+	PositionName string `form:"positionName" xorm:"'position_name' string not null    comment('岗位名称')   " `
+}

+ 20 - 0
viewmodels/oc_info.go

@@ -0,0 +1,20 @@
+package viewmodels
+
+// OcInfo
+type OcInfo struct {
+	OcId      int64  `json:"ocId"          form:"ocTypeId"        xorm:"'oc_id'       bigint    pk  comment('主键ID')     " `
+	OcName    string `json:"ocName"        form:"ocName"          xorm:"'oc_name'     varchar(127)  comment('ENT类型名称') " `
+	OcTypeId  int64  `json:"ocTypeId"      form:"ocTypeId"        xorm:"'oc_type_id'  bigint        comment('Type ID')    " `
+	RootId    int64  `json:"rootId"        form:"rootId"          xorm:"'root_id'     bigint        comment('Root ID')     " `
+	ParentId  int64  `json:"parentId"      form:"parentId"        xorm:"'parent_id'   bigint        comment('Parent ID')   " `
+	AdminId   int64  `json:"adminId"       form:"adminId"         xorm:"'admin_id'    bigint        comment('Admin ID')    " `
+	AdminName string `json:"adminName"     form:"adminName"       xorm:"'admin_name'  varchar(127)  comment('Admin Name')  " `
+	GroupId   int64  `json:"groupId"       form:"groupId"         xorm:"'group_id'    bigint        comment('Root Group Id')" `
+	IfLic     int    `json:"ifLic"         form:"ifLic"           xorm:"'if_lic'      int           comment('Admin ID')    " `
+
+	NodeLeft  int `json:"nodeLeft"      form:"nodeLeft"        xorm:"'node_left'   int           comment('Admin ID')    " `
+	NodeRight int `json:"nodeRight"     form:"nodeRight"       xorm:"'node_right'  int           comment('Admin ID')    " `
+	IsLeaf    int `json:"isLeaf"        form:"isLeaf"          xorm:"'is_leaf'     int           comment('Admin ID')    " `
+	NodeLevel int `json:"nodeLevel"     form:"nodeLevel"       xorm:"'node_level'  int           comment('Admin ID')    " `
+	Status    int `json:"status"         form:"status"         xorm:"'status'      int           comment('OC Status')   " `
+}

+ 10 - 0
viewmodels/page_result.go

@@ -0,0 +1,10 @@
+package viewmodels
+
+// Page Result Data struct
+type PageResult struct {
+	Total     int64       `json:"total"`
+	PageSize  int         `json:"limit"`
+	Page      int         `json:"page"`
+	TotalPage int         `json:"totalPage"`
+	Data      interface{} `json:"data"`
+}

+ 13 - 0
viewmodels/position_info.go

@@ -0,0 +1,13 @@
+package viewmodels
+
+type PositionInfo struct {
+	OcId         int64  `json:"ocId"          xorm:"'oc_id'          bigint pk    comment('OC ID')"  `
+	PositionId   int64  `json:"positionId"    xorm:"'position_id'    bigint pk    comment('Position ID')"  `
+	PositionName string `json:"positionName"  xorm:"'position_name'  varchar(127) comment('岗位名称') " `
+	PositionDesc string `json:"positionDesc"  xorm:"'position_desc'  varchar(255) comment('描述')     " `
+	IsFixed      int64  `json:"isFixed"       xorm:"'is_fixed'       int          comment('是否可修改') "`
+}
+
+func (m *PositionInfo) TableName() string {
+	return "s_position"
+}

+ 15 - 0
viewmodels/role_info.go

@@ -0,0 +1,15 @@
+package viewmodels
+
+type RoleInfo struct {
+	RoleId      int64     `json:"roleId"       xorm:"'role_id'        pk comment('主键ID')"`
+	RoleName    string    `json:"roleName"     xorm:"'role_name'      comment('角色名称')"`
+	RoleDesc    string    `json:"roleDesc"     xorm:"'role_desc'      comment('描述')"`
+	RoleTypeId  int64     `json:"roleTypeId"   xorm:"'role_type_id'   comment('角色类型')"`
+	SortNo      int64     `json:"sortNo"       xorm:"'sort_no'        default 0 comment('排序')"`
+	Status      int64     `json:"status"       xorm:"'status'         default 0 comment('状态, 默认 0 正常,1 锁定')"`
+	IsFixed     int64     `json:"isFixed"      xorm:"'is_fixed'       comment('锁定,默认为0不锁定')"`
+}
+
+func (m *RoleInfo) TableName() string {
+	return "s_role"
+}

+ 11 - 0
viewmodels/role_member_info.go

@@ -0,0 +1,11 @@
+package viewmodels
+
+// Role Member Info View data models
+
+type RoleMemberInfo struct {
+	RmId        int64  `form:"rmId"      xorm:"'rm_id'      bigint not null pk comment('PK ID')  " `
+	RoleId      int64  `form:"roleId"    xorm:"'role_id'    bigint             comment('角色D')       " `
+	RoleName    string `form:"roleName"  xorm:"'role_name'  varchar(127)       comment('角色名称')    " `
+	AccountId   int64  `form:"accountId" xorm:"'account_id' bigint             comment('帐号ID')      " `
+	AccountName string `form:"accountId" xorm:"'account_id' varchar(127)       comment('帐号ID')      " `
+}

+ 30 - 0
viewmodels/user_data.go

@@ -0,0 +1,30 @@
+package viewmodels
+
+import "encoding/json"
+
+type UserData struct {
+	OcId         int64  `json:"ocId"              `
+	OcName       string `json:"ocName"            `
+	UserId       int64  `json:"userId"            `
+	UserName     string `json:"userName"          `
+	UserRealName string `json:"userRealName"      `
+	UserPhone    string `json:"userPhone"         `
+	UserAvatar   string `json:"userAvatar"        `
+	UserIntro    string `json:"userIntro"         `
+	UserPhoto    string `json:"userPhoto"         `
+	Status       int64  `json:"status"            `
+	GroupId      int64  `json:"groupId"           `
+	GroupName    string `json:"groupName"         `
+	PositionId   int64  `json:"positionId"        `
+	PositionName string `json:"positionName"      `
+	RoleId       int64  `json:"roleId"            `
+	RoleName     string `json:"roleName"          `
+}
+
+func (g *UserData) MarshalBinary() (data []byte, err error){
+	return json.Marshal(g)
+}
+
+func (g *UserData) UnmarshalBinary(data []byte) (err error){
+	return json.Unmarshal(data, g)
+}

+ 31 - 0
viewmodels/user_info.go

@@ -0,0 +1,31 @@
+package viewmodels
+
+type UserInfo struct {
+    OcId            int64  `json:"ocId"             xorm:"'oc_id'             bigint         comment('组织ID:公司或机构或单位ID')"`
+    AccountId       int64  `json:"accountId"        xorm:"'account_id'        bigint not null pk comment('主键ID')"`
+    AccountName     string `json:"accountName"      xorm:"'account_name'      varchar(128)   comment('帐号名称')"`
+    AccountType     int64  `json:"accountType"      xorm:"'account_type'      bigint         comment('帐号类型:0:系统用户,1:企业用户,2:集团用户,3:政府用户,4:合作伙伴')"`
+    AccountRealName string `json:"accountRealName"  xorm:"'account_real_name' varchar(64)    comment('姓名')"`
+    AccountIntro    string `json:"accountIntro"     xorm:"'account_intro'     varchar(511)   comment('个人简介')"`
+    AccountAvatar   string `json:"accountAvatar"    xorm:"'account_avatar'    varchar(255)   comment('头像')"`
+    AccountPhoto    string `json:"accountPhoto"     xorm:"'account_photo'     varchar(255)   comment('照片')"`
+    AccountPhone    string `json:"accountPhone"     xorm:"'account_phone'     varchar(32)    comment('手机号')"`
+    AccountLastIp   string `json:"accountLastIp"    xorm:"'account_last_ip'   varchar(10)    comment('最近一次登录IP')"`
+    AccountLoc      string `json:"accountLoc"       xorm:"'account_loc'       varchar(64)    comment('区域')"`
+    AccountMail     string `json:"accountMail"      xorm:"'account_mail'      varchar(64)    comment('Email')"`
+    AccountStaffNo  string `json:"accountStaffNo"   xorm:"'account_staff_no'  varchar(64)    comment('StaffNo')"`
+    Status          int64  `json:"status"           xorm:"'status'            bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+    WxId            int64  `json:"wxId"             xorm:"'wxId'              bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+    IsFixed         int64  `json:"isFixed"          xorm:"'isFixed'           bigint         default 1 comment('状态,默认值 1,[0:未激活; 1:正常; 2:锁定; -1:删除'])"`
+    GmId            int64  `json:"gmId"             xorm:"'gm_id'             bigint         comment('PK ID')      " `
+    GroupId         int64  `json:"groupId"          xorm:"'group_id'          bigint         comment('群组ID')      " `
+    GroupName       string `json:"groupName"        xorm:"'group_name'        string         comment('群组名称')     " `
+    NodeLeft        int64  `json:"nodeLeft"         xorm:"'node_left'         bigint         comment('群组LEFT')    " `
+    NodeRight       int64  `json:"nodeRight"        xorm:"'node_right'        bigint         comment('群组RIGHT')   " `
+    GmpId           int64  `json:"gmpId"            xorm:"'gmp_id'            bigint         comment('公司组织ID')  " `
+    PositionId      int64  `json:"positionId"       xorm:"'account_id'        bigint         comment('岗位ID')      " `
+    PositionName    string `json:"positionName"     xorm:"'position_name'     string         comment('岗位名称')     " `
+    GmpgId          int64  `json:"gmpgId"           xorm:"'gmpg_id'           bigint         comment('GMPG PK ID')   " `
+    GrantGroupId    int64  `json:"grantGroupId"     xorm:"'grant_group_id'    bigint         comment('授权群组ID')    " `
+    GrantGroupName  string `json:"grantGroupName"   xorm:"'grant_group_name'  string         comment('授权群组名称')   " `
+}

+ 101 - 0
web/controllers/app_cat_controller.go

@@ -0,0 +1,101 @@
+package controllers
+
+import (
+    "github.com/kataras/iris/v12/mvc"
+    "xps/datamodels"
+    "xps/service/system"
+)
+
+type AppCatController struct {
+    Base
+    Service system.AppCatService
+}
+
+func (c *AppCatController) BeforeActivation(b mvc.BeforeActivation) {
+    b.Handle("GET",     "/",                    "GetByList")
+    b.Handle("GET",     "/page",                "GetByPage")
+    b.Handle("GET",     "/{appCatId:int64}",    "GetById")
+    b.Handle("POST",    "/add",                 "Create")
+    b.Handle("PUT",     "/update",              "Update")
+    b.Handle("DELETE",  "/{appCatId:int64}",    "DeleteByID")
+}
+
+func (c *AppCatController) GetByList() *JsonResult {
+    params := c.buildParams()
+    data, err := c.Service.GetByList(params)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    }
+    return ResultOk("获取成功", data)
+}
+
+func (c *AppCatController) GetByPage() *JsonResult {
+    params := c.buildParams()
+    data, err := c.Service.GetByPage(params)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *AppCatController) GetById(appCatId int64) *JsonResult {
+    ocId := c.GetCurOcId()
+    data, err := c.Service.GetById(ocId, appCatId)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *AppCatController) Create() *JsonResult {
+    userId   := c.GetCurUserId()
+    
+    appCat := datamodels.AppCat{}
+    appCat.CreatedBy = userId
+    err := c.Ctx.ReadJSON(&appCat)
+    if err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    
+    err = c.Service.Create(&appCat)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("新增成功", nil)
+    }
+}
+
+func (c *AppCatController) Update() *JsonResult {
+    userId   := c.GetCurUserId()
+    
+    appCat := datamodels.AppCat{}
+    if err := c.Ctx.ReadJSON(&appCat); err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    
+    appCat.UpdatedBy = userId
+    err := c.Service.Update(&appCat)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("更新成功", nil)
+    }
+}
+
+func (c *AppCatController) DeleteByID(appCatId int64) *JsonResult {
+    ocId   := c.GetCurOcId()
+    userId := c.GetCurUserId()
+    
+    var m  = make(map[string]interface{})
+    m["ocId"]      = ocId
+    m["appCatId"]= appCatId
+    m["deletedBy"] = userId
+    err := c.Service.Delete(m)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("删除成功", nil)
+    }
+}

+ 27 - 0
web/controllers/app_permit_controller.go

@@ -0,0 +1,27 @@
+package controllers
+
+import (
+	"github.com/kataras/iris/v12/mvc"
+	"xps/service/system"
+)
+
+type AppPermitController struct {
+	Base
+	Service system.AppPermitService
+}
+
+func (c *AppPermitController) BeforeActivation(b mvc.BeforeActivation) {
+	b.Handle("GET", "/", "GetByList")
+}
+
+func (c *AppPermitController) GetByList() *JsonResult {
+	var appKey = c.Ctx.Values().GetString("appKey")
+	var keywords string
+
+	if c.Ctx.URLParamExists("keywords") {
+		keywords = c.Ctx.URLParam("keywords")
+	}
+
+	data := c.Service.GetByList(appKey, 1, keywords)
+	return ResultOk("获取成功", data)
+}

+ 118 - 0
web/controllers/base_controller.go

@@ -0,0 +1,118 @@
+package controllers
+
+import (
+	"github.com/go-playground/validator/v10"
+	"github.com/kataras/iris/v12"
+	"log"
+	"xps/cache"
+	"xps/viewmodels"
+)
+
+var (
+	validate *validator.Validate
+)
+
+func init() {
+	validate = validator.New()
+}
+
+func errorData(errs ...error) {
+	var s string
+	for _, err := range errs {
+		if err != nil {
+			s += err.Error() + "<br/>"
+		}
+	}
+}
+
+type Base struct {
+	Ctx iris.Context
+}
+
+func (b *Base) GetCurOcId() int64 {
+	ocId, _ := b.Ctx.Values().GetInt64("ocId")
+	return ocId
+}
+
+func (b *Base) GetCurUserId() int64 {
+	userId, _ := b.Ctx.Values().GetInt64("userId")
+	return userId
+}
+
+func (b *Base) GetOcTypeId() int64 {
+	ocTypeId, _ := b.Ctx.Values().GetInt64("ocTypeId")
+	return ocTypeId
+}
+
+func (b *Base) buildParams() map[string]interface{} {
+	var conditions QueryConditions
+	err := b.Ctx.ReadURL(&conditions)
+	if err != nil {
+		_ =b.Ctx.JSON(ResultErr(err.Error(), nil))
+	}
+	ocId, err := b.Ctx.Values().GetInt64("ocId")
+	if err != nil {
+		_ =b.Ctx.JSON(ResultErr(err.Error(), nil))
+		b.Ctx.Next()
+	}
+	userId, err := b.Ctx.Values().GetInt64("userId")
+	if err != nil {
+		_ =b.Ctx.JSON(ResultErr(err.Error(), nil))
+		b.Ctx.Next()
+	}
+
+	params := make(map[string]interface{})
+	params["ocId"]     = ocId
+	params["groupId"]  = conditions.GroupId
+	params["userId"]   = userId
+	params["limit"]    = conditions.Limit
+	params["page"]     = conditions.Page
+	params["keywords"] = conditions.Keywords
+	return params
+}
+
+// RetCode Result Code
+type RetCode int
+
+// Result Code List
+const (
+	RetOk  RetCode = 0
+	RetErr RetCode = 500
+)
+
+type QueryConditions struct {
+	OcId     int64  `url:"ocId"`
+	GroupId  int64  `url:"groupId"`
+	UserId   int64  `url:"userId"`
+	Page     int    `url:"page"`
+	Limit    int    `url:"limit"`
+	Keywords string `url:"keywords"`
+}
+
+type JsonResult struct {
+	Code RetCode     `json:"code"`
+	Msg  interface{} `json:"msg"`
+	Data interface{} `json:"data"`
+}
+
+type ClientToken struct {
+	token string `json:"token"`
+}
+
+func ResultOk(msg string, objects interface{}) (r *JsonResult) {
+	r = &JsonResult{Code: RetOk, Msg: msg, Data: objects}
+	return
+}
+
+func ResultErr(msg string, objects interface{}) (r *JsonResult) {
+	r = &JsonResult{Code: RetErr, Msg: msg, Data: objects}
+	return
+}
+
+func GetCurUser(userId int64) *viewmodels.UserData{
+	userData, err  := cache.GetUserData(userId)
+	if err != nil {
+		log.Fatal(err.Error())
+	}
+	return userData
+}

+ 44 - 0
web/controllers/company_profile_controller.go

@@ -0,0 +1,44 @@
+package controllers
+
+import (
+    "github.com/kataras/iris/v12/mvc"
+    "xps/datamodels"
+    "xps/service/system"
+)
+
+type CompanyProfileController struct {
+    Base
+    Service system.CompanyProfileService
+}
+
+func (c *CompanyProfileController) BeforeActivation(b mvc.BeforeActivation) {
+    b.Handle("GET"      ,"/"                            ,"GetById"   )
+    b.Handle("PUT"      ,"/update"                      ,"Update" )
+}
+
+func (c *CompanyProfileController) GetById() *JsonResult {
+    ocId := c.GetCurOcId()
+    data, err := c.Service.GetById(ocId)
+    if err != nil {
+        return ResultErr("数据不存在", nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *CompanyProfileController) Update() *JsonResult {
+    ocId := c.GetCurOcId()
+    
+    cmp  := &datamodels.Company{OcId :ocId}
+    err  := c.Ctx.ReadJSON(cmp)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    }
+    
+    err = c.Service.Update(cmp)
+    if err != nil {
+        return ResultErr("更新失败", nil)
+    }
+    
+    return ResultOk("更新成功", nil)
+}

+ 105 - 0
web/controllers/group_cat_controller.go

@@ -0,0 +1,105 @@
+package controllers
+
+import (
+    "github.com/kataras/iris/v12/mvc"
+    "xps/datamodels"
+    "xps/service/system"
+)
+
+type GroupCatController struct {
+    Base
+    Service system.GroupCatService
+}
+
+func (c *GroupCatController) BeforeActivation(b mvc.BeforeActivation) {
+    b.Handle("GET",     "/",                    "GetByList")
+    b.Handle("GET",     "/page",                "GetByPage")
+    b.Handle("GET",     "/{groupCatId:int64}",  "GetById")
+    b.Handle("POST",    "/add",                 "Create")
+    b.Handle("PUT",     "/update",              "Update")
+    b.Handle("DELETE",  "/{groupCatId:int64}",  "DeleteByID")
+}
+
+func (c *GroupCatController) GetByList() *JsonResult {
+    params := c.buildParams()
+    data, err := c.Service.GetByList(params)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    }
+    return ResultOk("获取成功", data)
+}
+
+func (c *GroupCatController) GetByPage() *JsonResult {
+    params := c.buildParams()
+    data, err := c.Service.GetByPage(params)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *GroupCatController) GetById(groupCatId int64) *JsonResult {
+    ocId := c.GetCurOcId()
+    data, err := c.Service.GetById(ocId, groupCatId)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *GroupCatController) Create() *JsonResult {
+    ocId     := c.GetCurOcId()
+    userId   := c.GetCurUserId()
+    
+    groupCat := datamodels.GroupCat{}
+    err := c.Ctx.ReadJSON(&groupCat)
+    if err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    
+    groupCat.OcId = ocId
+    groupCat.CreatedBy = userId
+    err = c.Service.Create(&groupCat)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("新增成功", nil)
+    }
+}
+
+func (c *GroupCatController) Update() *JsonResult {
+    ocId     := c.GetCurOcId()
+    userId   := c.GetCurUserId()
+    
+    groupCat := datamodels.GroupCat{}
+    if err := c.Ctx.ReadJSON(&groupCat); err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    
+    groupCat.OcId = ocId
+    groupCat.UpdatedBy = userId
+    err := c.Service.Update(&groupCat)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("更新成功", nil)
+    }
+}
+
+func (c *GroupCatController) DeleteByID(groupCatId int64) *JsonResult {
+    ocId   := c.GetCurOcId()
+    userId := c.GetCurUserId()
+    
+    var m  = make(map[string]interface{})
+    m["ocId"]      = ocId
+    m["groupCatId"]= groupCatId
+    m["deletedBy"] = userId
+    err := c.Service.Delete(m)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("删除成功", nil)
+    }
+}

+ 96 - 0
web/controllers/group_controller.go

@@ -0,0 +1,96 @@
+package controllers
+
+import (
+    "github.com/kataras/iris/v12/mvc"
+    "xps/datamodels"
+    "xps/service/system"
+)
+
+type GroupController struct {
+    Base
+    Service system.GroupService
+}
+
+func (c *GroupController) BeforeActivation(b mvc.BeforeActivation) {
+    b.Handle("GET"      ,"/"                                ,"GetByList"   )
+    b.Handle("GET"      ,"/groupId:int64}"                  ,"GetById"     )
+    b.Handle("POST"     ,"/add"                             ,"Create"      )
+    b.Handle("PUT"      ,"/update"                          ,"Update"      )
+    b.Handle("DELETE"   ,"/{groupId:int64}"                 ,"DeleteById"  )
+}
+
+func (c *GroupController)  GetByList() *JsonResult {
+    ocId := c.GetCurOcId()
+    params := c.buildParams()
+    params["ocId"] = ocId
+    data, err := c.Service.GetByList(params)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    }
+    return ResultOk("获取成功", data)
+}
+
+func (c *GroupController) GetById(groupId int64) *JsonResult {
+    ocId := c.GetCurOcId()
+    data, err := c.Service.GetById(ocId, groupId)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *GroupController) Create() *JsonResult {
+    ocId     := c.GetCurOcId()
+    userId   := c.GetCurUserId()
+    
+    group := datamodels.Group{}
+    err := c.Ctx.ReadJSON(&group)
+    if err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    
+    group.OcId = ocId
+    group.CreatedBy = userId
+    err = c.Service.Create(&group)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("新增成功", nil)
+    }
+}
+
+func (c *GroupController) Update(groupId int64) *JsonResult {
+    ocId     := c.GetCurOcId()
+    userId   := c.GetCurUserId()
+    
+    group := datamodels.Group{}
+    if err := c.Ctx.ReadJSON(&group); err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    
+    group.OcId = ocId
+    group.UpdatedBy = userId
+    err := c.Service.Update(&group)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("更新成功", nil)
+    }
+}
+
+func (c *GroupController) DeleteById(groupId int64) *JsonResult {
+    ocId   := c.GetCurOcId()
+    userId := c.GetCurUserId()
+    
+    var m  = make(map[string]interface{})
+    m["ocId"]      = ocId
+    m["groupId"]= groupId
+    m["deletedBy"] = userId
+    err := c.Service.Delete(m)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("删除成功", nil)
+    }
+}

+ 59 - 0
web/controllers/login_controller.go

@@ -0,0 +1,59 @@
+package controllers
+
+import (
+	"github.com/kataras/iris/v12/mvc"
+	"xps/service/system"
+)
+
+type LoginController struct {
+	Base
+	Service system.LoginService
+}
+
+func (c *LoginController) BeforeActivation(b mvc.BeforeActivation) {
+	b.Handle("POST",    "/login",   "Login")
+	b.Handle("GET",     "/logout",  "Logout")
+	b.Handle("GET",     "/test",    "GetTest")
+	b.Handle("GET",     "/hello",   "GetHello")
+}
+
+func (c *LoginController) Login() *JsonResult {
+	username := c.Ctx.FormValue("username")
+	password := c.Ctx.FormValue("password")
+
+	userNameErr := validate.Var(username, "required,min=4,max=32")
+	if userNameErr != nil {
+		return ResultErr("用户名格式错误", nil)
+	}
+
+	pwdErr := validate.Var(password, "required,min=4,max=20")
+	if pwdErr != nil {
+		return ResultErr("密码格式错误", nil)
+	}
+
+	bRet, msg, data := c.Service.CheckLogin(username, password)
+	if !bRet {
+		return ResultErr(msg, data)
+	} else {
+		return ResultOk(msg, data)
+	}
+}
+
+func (c *LoginController) Logout() *JsonResult {
+	userId := c.GetCurOcId()
+	if userId > 0 {
+		_ = c.Service.Logout(userId)
+	}
+	return ResultOk("登出成功", nil)
+}
+
+func (c *LoginController) GetTest() mvc.Response {
+	return mvc.Response{
+		ContentType: "text/html",
+		Text:        "<h1>Test</h1>",
+	}
+}
+
+func (c *LoginController) GetHello() interface{} {
+	return map[string]string{"message": "hello iris"}
+}

+ 106 - 0
web/controllers/position_controller.go

@@ -0,0 +1,106 @@
+package controllers
+
+import (
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service/system"
+)
+
+type PositionController struct {
+	Base
+	Service system.PositionService
+}
+
+func (c *PositionController) BeforeActivation(b mvc.BeforeActivation) {
+	b.Handle("GET",     "/",                    "GetByList")
+	b.Handle("GET",     "/page",                "GetByPage")
+	b.Handle("GET",     "/{positionId:int64}",  "GetById")
+	b.Handle("POST",    "/add",                 "Create")
+	b.Handle("PUT",     "/update",              "Update")
+	b.Handle("DELETE",  "/{positionId:int64}",  "DeleteByID")
+}
+
+func (c *PositionController) GetByList() *JsonResult {
+	params := c.buildParams()
+	data, err := c.Service.GetByList(params)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	}
+	return ResultOk("获取成功", data)
+}
+
+func (c *PositionController) GetByPage() *JsonResult {
+	params := c.buildParams()
+	data, err := c.Service.GetByPage(params)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("获取成功", data)
+	}
+}
+
+func (c *PositionController) GetById(positionId int64) *JsonResult {
+	ocId := c.GetCurOcId()
+	data, err := c.Service.GetById(ocId, positionId)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("获取成功", data)
+	}
+}
+
+func (c *PositionController) Create() *JsonResult {
+	ocId     := c.GetCurOcId()
+	userId   := c.GetCurUserId()
+	
+	position := datamodels.Position{}
+	position.OcId = ocId
+	position.CreatedBy = userId
+	err := c.Ctx.ReadJSON(&position)
+	if err != nil {
+		return ResultErr("读取数据失败", nil)
+	}
+	
+	position.OcId = ocId
+	err = c.Service.Create(&position)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("新增成功", nil)
+	}
+}
+
+func (c *PositionController) Update() *JsonResult {
+	ocId     := c.GetCurOcId()
+	userId   := c.GetCurUserId()
+	
+	position := datamodels.Position{}
+	if err := c.Ctx.ReadJSON(&position); err != nil {
+		return ResultErr("读取数据失败", nil)
+	}
+	
+	position.OcId = ocId
+	position.UpdatedBy = userId
+	err := c.Service.Update(&position)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("更新成功", nil)
+	}
+}
+
+func (c *PositionController) DeleteByID(positionId int64) *JsonResult {
+	ocId   := c.GetCurOcId()
+	userId := c.GetCurUserId()
+	
+	var m  = make(map[string]interface{})
+	m["ocId"]      = ocId
+	m["positionId"]= positionId
+	m["deletedBy"] = userId
+	err := c.Service.Delete(m)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("删除成功", nil)
+	}
+}

+ 88 - 0
web/controllers/role_controller.go

@@ -0,0 +1,88 @@
+package controllers
+
+import (
+	"github.com/kataras/iris/v12/mvc"
+	"xps/datamodels"
+	"xps/service/system"
+)
+
+type RoleController struct {
+	Base
+	Service system.RoleService
+}
+
+func (c *RoleController) BeforeActivation(b mvc.BeforeActivation) {
+	b.Handle("GET",         "/",                "GetByList")
+	b.Handle("GET",         "/page",            "GetByPage")
+	b.Handle("GET",         "/{roleId:int64}",  "GetById")
+	b.Handle("POST",        "/add",             "Create")
+	b.Handle("PUT",         "/update",          "Update")
+	b.Handle("DELETE",      "/{roleId:int64}",  "DeleteById")
+}
+
+func (c *RoleController) GetByList() *JsonResult {
+	params := c.buildParams()
+	data, err := c.Service.GetByList(params)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	}
+	return ResultOk("获取成功", data)
+}
+
+func (c *RoleController) GetByPage() *JsonResult {
+	params := c.buildParams()
+	data, err := c.Service.GetByPage(params)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	}
+	return ResultOk("获取成功", data)
+}
+
+func (c *RoleController) GetById(roleId int64) *JsonResult {
+	data, err := c.Service.GetById(roleId)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	}
+	return ResultOk("获取成功", data)
+}
+
+func (c *RoleController) Create() *JsonResult {
+	role := &datamodels.Role{}
+	err := c.Ctx.ReadJSON(role)
+	if err != nil {
+		return ResultErr("读取数据失败", nil)
+	}
+	err = c.Service.Create(role)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("新增成功", nil)
+	}
+}
+
+func (c *RoleController) Update() *JsonResult {
+	role := &datamodels.Role{}
+	if err := c.Ctx.ReadJSON(role); err != nil {
+		return ResultErr("读取数据失败", nil)
+	}
+	err := c.Service.Update(role)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("更新成功", nil)
+	}
+}
+
+func (c *RoleController) DeleteById(roleId int64) *JsonResult {
+	userId := c.GetCurUserId()
+	
+	var m  = make(map[string]interface{})
+	m["roleId"]    = roleId
+	m["deletedBy"] = userId
+	err := c.Service.Delete(m)
+	if err != nil {
+		return ResultErr(err.Error(), nil)
+	} else {
+		return ResultOk("删除成功", nil)
+	}
+}

+ 25 - 0
web/controllers/upload_controller.go

@@ -0,0 +1,25 @@
+package controllers
+
+import (
+	"github.com/kataras/iris/v12"
+	"github.com/kataras/iris/v12/mvc"
+)
+
+// 文件
+type DstFile struct {
+	Name string `json:"name"`
+	Src  string `json:"src"`
+}
+
+// Role Controller Data struct
+type UploadController struct {
+	Ctx iris.Context
+	//Service   services.UploadService
+}
+
+// Before Activation
+func (c *UploadController) BeforeActivation(b mvc.BeforeActivation) {
+	b.Handle("POST", "/upload1", "Upload")
+	b.Handle("POST", "/upload2", "MultiUpload")
+	b.Handle("POST", "/upload3", "Upload3")
+}

+ 89 - 0
web/controllers/user_controller.go

@@ -0,0 +1,89 @@
+package controllers
+
+import (
+    "github.com/kataras/iris/v12/mvc"
+    "xps/service/system"
+    "xps/viewmodels"
+)
+
+type UserController struct {
+    Base
+    Service system.UserService
+}
+
+func (c *UserController) BeforeActivation(b mvc.BeforeActivation) {
+    b.Handle("GET",         "/page",                                "GetByPage")
+    b.Handle("GET",         "/{groupId:int64}/{accountId:int64}",   "GetById")
+    b.Handle("POST",        "/add",                                 "Create")
+    b.Handle("PUT",         "/update",                              "Update")
+    b.Handle("DELETE",      "/{accountId:int64}",                   "DeleteById")
+}
+
+func (c *UserController) GetByPage() *JsonResult {
+    params := c.buildParams()
+    data, err := c.Service.GetByPage(params)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *UserController) GetById(groupId, accountId int64) *JsonResult {
+    ocId := c.GetCurOcId()
+    data, err := c.Service.GetById(ocId, groupId, accountId)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("获取成功", data)
+    }
+}
+
+func (c *UserController) Create() *JsonResult {
+    ocId   := c.GetCurOcId()
+    ocTypeId := c.GetOcTypeId()
+    user := &viewmodels.UserInfo{}
+    err := c.Ctx.ReadJSON(user)
+    if err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    
+    user.OcId = ocId
+    err = c.Service.Create(ocTypeId, user)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("新增成功", nil)
+    }
+}
+
+func (c *UserController) Update() *JsonResult {
+    user := &viewmodels.UserInfo{}
+    err := c.Ctx.ReadJSON(user)
+    if err != nil {
+        return ResultErr("读取数据失败", nil)
+    }
+    err = c.Service.Update(user)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("更新成功", nil)
+    }
+}
+
+func (c *UserController) DeleteById(accountId int64) *JsonResult {
+    ocId   := c.GetCurOcId()
+    userId := c.GetCurUserId()
+    
+    var m  = make(map[string]interface{})
+    m["ocId"]      = ocId
+    m["accountId"] = accountId
+    m["deletedBy"] = userId
+    err := c.Service.Delete(m)
+    if err != nil {
+        return ResultErr(err.Error(), nil)
+    } else {
+        return ResultOk("删除成功", nil)
+    }
+}
+

+ 65 - 0
web/main.go

@@ -0,0 +1,65 @@
+package main
+
+import (
+	"github.com/kataras/iris/v12"
+	"github.com/kataras/iris/v12/middleware/accesslog"
+	"os"
+	"xps/bootstrap"
+	"xps/web/middleware/identity"
+	"xps/web/router"
+)
+
+const maxSize = 20 * 1024 * 1024
+
+func newApp() *bootstrap.Bootstrapper {
+	app := bootstrap.New("web", "yafeng")
+	app.Bootstrap()
+	//ac := makeAccessLog()
+	//defer ac.Close()
+
+	//app.UseRouter(ac.Handler)
+	app.Configure(identity.Configure, router.Configure)
+	return app
+}
+
+// Read the example and its comments carefully.
+func makeAccessLog() *accesslog.AccessLog {
+	// Initialize a new access log middleware.
+	ac := accesslog.File("./access.log")
+	// Remove this line to disable logging to console:
+	ac.AddOutput(os.Stdout)
+
+	// The default configuration:
+	ac.Delim = '|'
+	ac.TimeFormat = "2006-01-02 15:04:05"
+	ac.Async = false
+	ac.IP = true
+	ac.BytesReceivedBody = true
+	ac.BytesSentBody = true
+	ac.BytesReceived = false
+	ac.BytesSent = false
+	ac.BodyMinify = true
+	ac.RequestBody = true
+	ac.ResponseBody = false
+	ac.KeepMultiLineError = true
+	ac.PanicLog = accesslog.LogHandler
+
+	// Default line format if formatter is missing:
+	// Time|Latency|Code|Method|Path|IP|Path Params Query Fields|Bytes Received|Bytes Sent|Request|Response|
+	//
+	// Set Custom Formatter:
+	ac.SetFormatter(&accesslog.JSON{
+		Indent:    "  ",
+		HumanTime: true,
+	})
+	// ac.SetFormatter(&accesslog.CSV{})
+	// ac.SetFormatter(&accesslog.Template{Text: "{{.Code}}"})
+
+	return ac
+}
+
+func main() {
+	app := newApp()
+
+	app.Listen(":8080", iris.WithPostMaxMemory(maxSize))
+}

+ 79 - 0
web/middleware/auth.go

@@ -0,0 +1,79 @@
+package middleware
+
+import (
+	"github.com/kataras/iris/v12"
+	"github.com/kataras/iris/v12/middleware/jwt"
+	"time"
+	"xps/utils"
+)
+
+var (
+	sigKey = []byte("signature_hmac_secret_shared_key")
+	encKey = []byte("GCM_AES_256_secret_shared_key_32")
+)
+
+type XClaims struct {
+	OcId     int64 `json:"ocId"`
+	OcTypeId int64 `json:"ocTypeId"`
+	UserId   int64 `json:"userId"`
+}
+
+type xHeaders struct {
+	AppKey        string `header:"Appkey,required"`
+	AppSecret     string `header:"Appsecret,required"`
+	Authorization string `header:"Authorization,required"`
+}
+
+func GenerateToken(ocId, ocTypeId, userId int64) (string, error) {
+	signer := jwt.NewSigner(jwt.HS256, sigKey, 10*time.Minute)
+
+	claims := XClaims{OcId: ocId, OcTypeId: ocTypeId, UserId: userId}
+	token, err := signer.Sign(claims)
+	if err != nil {
+		return "", err
+	}
+	return string(token), nil
+}
+
+func AuthToken(ctx iris.Context) {
+
+	var hs xHeaders
+	if err := ctx.ReadHeaders(&hs); err != nil {
+		_ = ctx.JSON(utils.HttpStatusErr(utils.HTTP_STATUS_ERR, err.Error(), nil))
+		return
+	}
+
+	token := hs.Authorization[7:]
+	verifiedToken, err := jwt.Verify(jwt.HS256, sigKey, []byte(token))
+	if err != nil {
+		_ = ctx.JSON(utils.HttpStatusErr(utils.HTTP_STATUS_UNAUTHORIZED, "请重新登录", nil))
+		return
+	}
+
+	var claims XClaims
+	err = verifiedToken.Claims(&claims)
+	if err != nil {
+		_ = ctx.JSON(utils.HttpStatusErr(utils.HTTP_STATUS_UNAUTHORIZED, "请重新登录", nil))
+		return
+	}
+
+	ctx.Values().Set("appKey", hs.AppKey)
+	ctx.Values().Set("appSecret", hs.AppSecret)
+
+	// Get the verified and decoded claims.
+	//xClaims := jwt.Get(ctx).(*XClaims)
+
+	// Optionally, get token information if you want to work with them.
+	// Just an example on how you can retrieve all the standard claims (set by signer's max age, "exp").
+	//standardClaims := jwt.GetVerifiedToken(ctx).StandardClaims
+	//timeLeft := standardClaims.Timeleft()
+
+	ocId     := claims.OcId
+	ocTypeId := claims.OcTypeId
+	userId   := claims.UserId
+
+	ctx.Values().Set("ocId", ocId)
+	ctx.Values().Set("ocTypeId", ocTypeId)
+	ctx.Values().Set("userId", userId)
+	ctx.Next()
+}

+ 21 - 0
web/middleware/identity/identity.go

@@ -0,0 +1,21 @@
+package identity
+
+import (
+	"github.com/kataras/iris/v12"
+	"time"
+	"xps/bootstrap"
+)
+
+func New(b *bootstrap.Bootstrapper) iris.Handler {
+	return func(ctx iris.Context) {
+		ctx.Header("App-Name", b.AppName)
+		ctx.Header("App-Owner", b.AppOwner)
+		ctx.Header("App-since", time.Since(b.AppSpawnDate).String())
+		ctx.Next()
+	}
+}
+
+func Configure(b *bootstrap.Bootstrapper) {
+	h := New(b)
+	b.UseGlobal(h)
+}

+ 1 - 0
web/middleware/jwt.go

@@ -0,0 +1 @@
+package middleware

文件差異過大導致無法顯示
+ 8 - 0
web/public/assets/App-0c32545b.js


二進制
web/public/assets/App-0c32545b.js.br


二進制
web/public/assets/App-0c32545b.js.gz


文件差異過大導致無法顯示
+ 8 - 0
web/public/assets/AppCat-c3e9a25f.js


二進制
web/public/assets/AppCat-c3e9a25f.js.br


二進制
web/public/assets/AppCat-c3e9a25f.js.gz


文件差異過大導致無法顯示
+ 8 - 0
web/public/assets/DBType-83a4c03b.js


二進制
web/public/assets/DBType-83a4c03b.js.br


二進制
web/public/assets/DBType-83a4c03b.js.gz


文件差異過大導致無法顯示
+ 8 - 0
web/public/assets/DBType-c81c9104.js


二進制
web/public/assets/DBType-c81c9104.js.br


二進制
web/public/assets/DBType-c81c9104.js.gz


文件差異過大導致無法顯示
+ 8 - 0
web/public/assets/EntCat-93edb117.js


二進制
web/public/assets/EntCat-93edb117.js.br


二進制
web/public/assets/EntCat-93edb117.js.gz


文件差異過大導致無法顯示
+ 8 - 0
web/public/assets/Group-810bdc6e.js


二進制
web/public/assets/Group-810bdc6e.js.br


二進制
web/public/assets/Group-810bdc6e.js.gz


文件差異過大導致無法顯示
+ 8 - 0
web/public/assets/GroupCat-3bad56a0.js


二進制
web/public/assets/GroupCat-3bad56a0.js.br


部分文件因文件數量過多而無法顯示