feat(ik3cloud): 实现部门与员工的增删改查功能

- 添加部门新增、编辑、删除接口及逻辑实现
- 添加员工新增、编辑、启用、禁用、删除接口及逻辑实现
- 更新配置文件支持组织ID配置
- 初始化金蝶客户端连接配置
- 优化部门与员工数据查询结构
- 增加提交、审核、反审等业务流程处理
- 完善错误处理与日志记录机制
This commit is contained in:
2025-11-20 15:37:45 +08:00
parent 9968887665
commit b70ca388cf
8 changed files with 508 additions and 21 deletions

View File

@@ -8,4 +8,5 @@ type Ik3cloud struct {
AppSecret string `ini:"appSecret"` // 应用秘钥
LanguageId string `ini:"languageId"` // 语言ID
OrganizationNumber string `ini:"organizationNumber"` // 组织编码
OrganizationId int64 `ini:"organizationId"` // 组织ID
}

View File

@@ -15,3 +15,19 @@ func (d *Department) All(ctx context.Context, args int, reply *[]ik3cloud.Depart
*reply, err = logic.DepartmentLogic.All()
return err
}
// Add @TITLE 添加部门
func (d *Department) Add(ctx context.Context, args ik3cloud.ArgsDepartmentAdd, departmentId *int64) (err error) {
*departmentId, err = logic.DepartmentLogic.Add(args)
return err
}
// Edit @TITLE 编辑部门
func (d *Department) Edit(ctx context.Context, args ik3cloud.ArgsDepartmentEdit, reply *int) error {
return logic.DepartmentLogic.Edit(args.DepartmentId, args.ArgsDepartmentAdd)
}
// Delete @TITLE 删除部门
func (d *Department) Delete(ctx context.Context, numbers []string, reply *int) error {
return logic.DepartmentLogic.Delete(numbers)
}

View File

@@ -19,3 +19,29 @@ func (s *Staff) List(ctx context.Context, args ik3cloud.ArgsStaffList, reply *ik
}
return err
}
// Add @TITLE 添加员工
func (s *Staff) Add(ctx context.Context, args ik3cloud.ArgsStaffAdd, staffId *int64) (err error) {
*staffId, err = logic.StaffLogic.Add(args)
return
}
// Edit @TITLE 员工编辑
func (s *Staff) Edit(ctx context.Context, args ik3cloud.ArgsStaffEdit, reply *int) error {
return logic.StaffLogic.Edit(args.StaffId, args.ArgsStaffAdd)
}
// Disable @TITLE 禁用员工
func (s *Staff) Disable(ctx context.Context, numbers []string, reply *int) error {
return logic.StaffLogic.Disable(numbers)
}
// Enable @TITLE 启用员工
func (s *Staff) Enable(ctx context.Context, numbers []string, reply *int) error {
return logic.StaffLogic.Enable(numbers)
}
// Delete @TITLE 删除
func (s *Staff) Delete(ctx context.Context, numbers []string, reply *int) error {
return logic.StaffLogic.Delete(numbers)
}

View File

@@ -1,6 +1,8 @@
package ik3cloud
import (
"encoding/json"
"github.com/deep-project/kingdee"
"github.com/deep-project/kingdee/adapters"
client2 "github.com/deep-project/kingdee/pkg/client"
@@ -22,6 +24,7 @@ type Config struct {
LanguageId string // 语言ID
}
// InitClient @TITLE 初始化
func InitClient(config *Config) (*client, error) {
var err error
Client.Client, err = kingdee.New(config.Host, &adapters.LoginBySign{
@@ -37,3 +40,33 @@ func InitClient(config *Config) (*client, error) {
Client.config = config
return Client, nil
}
// GetResult @TITLE 获取结果
func (c *client) GetResult(raw []byte) (res result, err error) {
err = json.Unmarshal(raw, &res)
return
}
type result struct {
Result struct {
ResponseStatus struct {
ErrorCode int `json:"ErrorCode"`
IsSuccess bool `json:"IsSuccess"`
Errors []struct {
FieldName string `json:"FieldName"`
Message string `json:"Message"`
DIndex int `json:"DIndex"`
} `json:"Errors"`
SuccessEntitys []struct {
Id int `json:"Id"`
Number string `json:"Number"`
DIndex int `json:"DIndex"`
} `json:"SuccessEntitys"`
SuccessMessages []interface{} `json:"SuccessMessages"`
MsgCode int `json:"MsgCode"`
} `json:"ResponseStatus"`
Id int64 `json:"Id"`
Number string `json:"Number"`
NeedReturnData []any `json:"NeedReturnData"`
} `json:"Result"`
}

View File

@@ -2,24 +2,36 @@ package logic
import (
"encoding/json"
"errors"
"ik3cloud/app/common"
"ik3cloud/app/config"
"ik3cloud/app/lib/ik3cloud"
"ik3cloud/app/lib/logger"
"strings"
"time"
ik3cloud2 "git.kumo.work/shama/service/ik3cloud"
"go.uber.org/zap"
)
var DepartmentLogic = &departmentLogic{}
type departmentLogic struct {
}
type departmentItem struct {
Id int64 `json:"FDEPTID"`
Number *string `json:"FNumber"`
Name *string `json:"FName"`
ParentNumber *string `json:"FParentID.FNumber"`
ParentName *string `json:"FParentID.FName"`
}
// All @TITLE 全部部门
func (d *departmentLogic) All() (result []ik3cloud2.DepartmentItem, err error) {
raw, err := ik3cloud.Client.ExecuteBillQuery(map[string]interface{}{
raw, err := ik3cloud.Client.BillQuery(map[string]any{
"FormId": "BD_Department",
"FieldKeys": "FNumber,FName,FParentID.FNumber,FParentID.FName",
"FilterString": []map[string]interface{}{{
"FieldKeys": "FNumber,FName,FParentID.FNumber,FParentID.FName,FDEPTID",
"FilterString": []map[string]any{{
"FieldName": "FUseOrgId.FNumber",
"Compare": "67",
"Value": config.Config.Ik3cloud.OrganizationNumber,
@@ -31,21 +43,125 @@ func (d *departmentLogic) All() (result []ik3cloud2.DepartmentItem, err error) {
if err != nil {
return
}
var data [][]*string
var data []departmentItem
if err = json.Unmarshal(raw, &data); err != nil {
return
}
for _, item := range data {
result = append(result, ik3cloud2.DepartmentItem{
Number: item[0],
Name: item[1],
ParentNumber: item[2],
ParentName: item[3],
Number: item.Number,
Name: item.Name,
ParentNumber: item.ParentNumber,
ParentName: item.ParentName,
Id: item.Id,
})
}
return d.getTree(result), nil
}
// Add @TITLE 添加部门
func (d *departmentLogic) Add(data ik3cloud2.ArgsDepartmentAdd) (departmentId int64, err error) {
raw, err := ik3cloud.Client.Save("BD_Department", map[string]any{
"Model": map[string]any{
"FCreateOrgId": map[string]any{
"FNumber": config.Config.Ik3cloud.OrganizationNumber,
},
"FNumber": data.Number,
"FName": data.Name,
"FUseOrgId": map[string]any{
"FNumber": config.Config.Ik3cloud.OrganizationNumber,
},
"FEffectDate": time.Now().Format("2006-01-02 15:04:05"),
"FLapseDate": "9999-12-31 00:00:00",
"FGroup": map[string]any{
"FNumber": data.GroupNumber,
},
"FParentID": map[string]any{
"FNumber": data.ParentNumber,
},
"FIsCopyFlush": false,
"FIsDetailDpt": false,
},
})
if err != nil {
err = errors.New("添加部门失败")
return
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
err = errors.New("添加部门失败")
return
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return departmentId, errors.New(item.Message)
}
}
departmentId = result.Result.Id
if err1 := d.submit([]string{data.Number}); err1 != nil {
logger.Logger.Error("部门提交失败", zap.Error(err1))
return
}
if err1 := d.audit([]string{data.Number}); err1 != nil {
logger.Logger.Error("部门审核失败", zap.Error(err1))
return
}
return
}
// Edit @TITLE 编辑部门
func (d *departmentLogic) Edit(departmentId int64, data ik3cloud2.ArgsDepartmentAdd) error {
if departmentId == 0 {
return errors.New("部门错误")
}
raw, err := ik3cloud.Client.Save("BD_Department", map[string]any{
"NeedUpDateFields": []string{"FName", "FNumber", "FParentID.FNumber"},
"Model": map[string]any{
"FDEPTID": departmentId,
"FNumber": data.Number,
"FName": data.Name,
"FParentID": map[string]any{
"FNumber": data.ParentNumber,
},
},
})
if err != nil {
return errors.New("编辑部门失败")
}
result, _ := ik3cloud.Client.GetResult(raw)
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
return errors.New("编辑部门失败")
}
return nil
}
// Delete @TITLE 删除部门
func (d *departmentLogic) Delete(numbers []string) error {
if err := d.unAudit(numbers); err != nil {
logger.Logger.Error("部门反审失败", zap.Error(err))
}
raw, err := ik3cloud.Client.Delete("BD_Department", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("删除部门失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}
// @Title 获取菜单树
func (d *departmentLogic) getTree(datas []ik3cloud2.DepartmentItem) (result []ik3cloud2.DepartmentItem) {
result = []ik3cloud2.DepartmentItem{}
@@ -60,9 +176,72 @@ func (d *departmentLogic) getTree(datas []ik3cloud2.DepartmentItem) (result []ik
}
}
for _, item := range datas {
if item.ParentNumber != nil {
if item.ParentNumber == nil {
result = append(result, item)
}
}
return
}
// @Title 提交
func (d *departmentLogic) submit(numbers []string) error {
raw, err := ik3cloud.Client.Submit("BD_Department", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("部门提交失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}
// @Title 审核
func (d *departmentLogic) audit(numbers []string) error {
raw, err := ik3cloud.Client.Audit("BD_Department", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("部门审核失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}
// @Title 反审
func (d *departmentLogic) unAudit(numbers []string) error {
raw, err := ik3cloud.Client.UnAudit("BD_Department", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("部门反审失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}

View File

@@ -2,18 +2,33 @@ package logic
import (
"encoding/json"
"errors"
"ik3cloud/app/common"
"ik3cloud/app/config"
"ik3cloud/app/lib/ik3cloud"
"ik3cloud/app/lib/logger"
"log"
"strings"
"time"
ik3cloud2 "git.kumo.work/shama/service/ik3cloud"
"git.kumo.work/shama/service/lib/bean"
"go.uber.org/zap"
)
var StaffLogic = &staffLogic{}
type staffLogic struct {
}
type staffItem struct {
Id int64 `json:"FID"` // id
Number *string `json:"FStaffNumber"` // 工号
Name *string `json:"FName"` // 姓名
Position *string `json:"FBaseProperty"` // 职位
Mobile *string `json:"FMobile"` // 手机号
Tel *string `json:"FTel"` // 账号
Status *string `json:"FForbidStatus"` // 状态
}
// List @TITLE 员工列表
func (s *staffLogic) List(page bean.Page, search ik3cloud2.StaffSearch) (list []ik3cloud2.StaffItem, total int64, err error) {
@@ -69,9 +84,9 @@ func (s *staffLogic) List(page bean.Page, search ik3cloud2.StaffSearch) (list []
})
}
}
raw, err := ik3cloud.Client.ExecuteBillQuery(map[string]interface{}{
raw, err := ik3cloud.Client.BillQuery(map[string]interface{}{
"FormId": "BD_Empinfo",
"FieldKeys": "FNumber,FName,FParentID.FNumber,FParentID.FName",
"FieldKeys": "FName,FStaffNumber,FBaseProperty,FMobile,FTel,FForbidStatus",
"FilterString": where,
"StartRow": page.GetStart(),
"Limit": page.GetLimit(),
@@ -79,23 +94,226 @@ func (s *staffLogic) List(page bean.Page, search ik3cloud2.StaffSearch) (list []
if err != nil {
return
}
var data [][]*string
log.Println(string(raw))
var data []staffItem
if err = json.Unmarshal(raw, &data); err != nil {
return
}
for _, item := range data {
status := "禁用"
if common.PtrCmp(item[5], common.Ptr("A")) {
if common.PtrCmp(item.Status, common.Ptr("A")) {
status = "启用"
}
list = append(list, ik3cloud2.StaffItem{
Number: item[0],
Name: item[1],
Position: item[2],
Phone: item[3],
Mobile: item[4],
Status: common.Ptr(status),
Id: item.Id,
Number: item.Number,
Name: item.Name,
Position: item.Position,
Mobile: item.Mobile,
Tel: item.Tel,
Status: &status,
})
}
return
}
// Add @TITLE 添加员工
func (s *staffLogic) Add(data ik3cloud2.ArgsStaffAdd) (staffId int64, err error) {
raw, err := ik3cloud.Client.Save("BD_Empinfo", map[string]any{
"Model": map[string]any{
"FCreateOrgId": map[string]any{
"FNumber": config.Config.Ik3cloud.OrganizationNumber,
},
"FName": data.Name,
"FStaffNumber": data.Number,
"FUseOrgId": map[string]any{
"FNumber": config.Config.Ik3cloud.OrganizationNumber,
},
"FMobile": data.Mobile,
"FTel": data.Tel,
"FEmail": data.Email,
"FCreateSaler": false,
"FCreateUser": false,
"FCreateCashier": false,
"FJoinDate": time.Now().Format("2006-01-02 15:04:05"),
},
})
if err != nil {
err = errors.New("添加员工失败")
return
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
err = errors.New("添加员工失败")
return
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return staffId, errors.New(item.Message)
}
}
staffId = result.Result.Id
if err1 := s.submit([]string{data.Number}); err1 != nil {
logger.Logger.Error("员工提交失败", zap.Error(err1))
return
}
if err1 := s.audit([]string{data.Number}); err1 != nil {
logger.Logger.Error("员工审核失败", zap.Error(err1))
return
}
return
}
// Edit @TITLE 员工编辑
func (s *staffLogic) Edit(staffId int64, data ik3cloud2.ArgsStaffAdd) error {
if staffId == 0 {
return errors.New("员工错误")
}
raw, err := ik3cloud.Client.Save("BD_Empinfo", map[string]any{
"NeedUpDateFields": []string{"FStaffNumber", "FName", "FMobile", "FTel", "FEmail"},
"Model": map[string]any{
"FID": staffId,
"FStaffNumber": data.Number,
"FName": data.Name,
"FMobile": data.Mobile,
"FTel": data.Tel,
"FEmail": data.Email,
},
})
if err != nil {
return errors.New("编辑员工失败")
}
result, _ := ik3cloud.Client.GetResult(raw)
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
return errors.New("编辑员工失败")
}
return nil
}
// Disable @TITLE 禁用账户
func (s *staffLogic) Disable(numbers []string) error {
raw, err := ik3cloud.Client.ExecuteOperation("BD_Empinfo", "Forbid", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("禁用员工失败")
}
result, _ := ik3cloud.Client.GetResult(raw)
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
return errors.New("禁用员工失败")
}
return nil
}
// Enable @TITLE 启用账户
func (s *staffLogic) Enable(numbers []string) error {
raw, err := ik3cloud.Client.ExecuteOperation("BD_Empinfo", "Enable", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("启用员工失败")
}
result, _ := ik3cloud.Client.GetResult(raw)
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
return errors.New("启用员工失败")
}
return nil
}
// Delete @TITLE 删除
func (s *staffLogic) Delete(numbers []string) error {
if err := s.unAudit(numbers); err != nil {
logger.Logger.Error("部门反审失败", zap.Error(err))
}
raw, err := ik3cloud.Client.Delete("BD_Empinfo", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("删除员工失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}
// @Title 提交
func (s *staffLogic) submit(numbers []string) error {
raw, err := ik3cloud.Client.Submit("BD_Empinfo", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("员工提交失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}
// @Title 审核
func (s *staffLogic) audit(numbers []string) error {
raw, err := ik3cloud.Client.Audit("BD_Empinfo", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("员工审核失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}
// @Title 反审
func (s *staffLogic) unAudit(numbers []string) error {
raw, err := ik3cloud.Client.UnAudit("BD_Empinfo", map[string]any{
"CreateOrgId": config.Config.Ik3cloud.OrganizationId,
"Numbers": strings.Join(numbers, ","),
})
if err != nil {
return errors.New("员工反审失败")
}
result, err := ik3cloud.Client.GetResult(raw)
if err != nil {
return err
}
if !result.Result.ResponseStatus.IsSuccess {
for _, item := range result.Result.ResponseStatus.Errors {
return errors.New(item.Message)
}
}
return nil
}

View File

@@ -25,8 +25,9 @@ defaultLimit=15
[ik3cloud]
host=https://zjyc.ik3cloud.com/k3cloud/
accountId=58f38bcd87527c
username=朱继峰
username=administrator
appId=342005_7eduWcHKQlGeR5XtXZ0qSwWtSM0YTOPL
appSecret=a3d7dbf55b60406b8981d864c72b2047
languageId=2052
organizationNumber=666
organizationNumber=666
organizationId=8091720

13
init.go
View File

@@ -4,6 +4,7 @@ import (
"encoding"
"fmt"
"ik3cloud/app/config"
"ik3cloud/app/lib/ik3cloud"
"ik3cloud/app/lib/logger"
"ik3cloud/app/lib/rpcplugin"
"io"
@@ -90,6 +91,18 @@ func InitApp() (closes []func()) {
// 注册序列化
RegisterBinaryExt[decimal.Decimal](1)
// 初始化金蝶
if _, err := ik3cloud.InitClient(&ik3cloud.Config{
Host: config.Config.Ik3cloud.Host,
AccountId: config.Config.Ik3cloud.AccountId,
Username: config.Config.Ik3cloud.Username,
AppId: config.Config.Ik3cloud.AppId,
AppSecret: config.Config.Ik3cloud.AppSecret,
LanguageId: config.Config.Ik3cloud.LanguageId,
}); err != nil {
logger.Logger.Fatal("金蝶初始化失败", zap.Error(err))
}
return
}