1079 lines
27 KiB
Go
1079 lines
27 KiB
Go
package controllers
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"server/models"
|
|
|
|
"github.com/beego/beego/v2/client/orm"
|
|
beego "github.com/beego/beego/v2/server/web"
|
|
)
|
|
|
|
// BackendErpController 兼容 backend 前端 /admin/erp/* 组织机构、员工、职位接口。
|
|
type BackendErpController struct {
|
|
beego.Controller
|
|
}
|
|
|
|
type erpOrganizationDTO struct {
|
|
ID uint64 `json:"id"`
|
|
Tid uint64 `json:"tid"`
|
|
TenantID uint64 `json:"tenant_id"`
|
|
OrgName string `json:"org_name"`
|
|
OrgCode string `json:"org_code"`
|
|
ParentID uint64 `json:"parent_id"`
|
|
ParentName string `json:"parent_name"`
|
|
LeaderID uint64 `json:"leader_id"`
|
|
LeaderName string `json:"leader_name"`
|
|
IsCompany int `json:"is_company"`
|
|
Sort uint `json:"sort"`
|
|
Status int8 `json:"status"`
|
|
Remark string `json:"remark"`
|
|
}
|
|
|
|
type erpEmployeeDTO struct {
|
|
ID uint `json:"id"`
|
|
Tid int `json:"tid"`
|
|
TenantID int `json:"tenant_id"`
|
|
Account string `json:"account"`
|
|
Name string `json:"name"`
|
|
Gender int8 `json:"gender"`
|
|
Sex int8 `json:"sex"`
|
|
Birthday string `json:"birthday"`
|
|
AffiliateUnit string `json:"affiliate_unit"`
|
|
AffiliateUnitName string `json:"affiliate_unit_name"`
|
|
Department string `json:"department"`
|
|
DepartmentName string `json:"department_name"`
|
|
Position string `json:"position"`
|
|
Education string `json:"education"`
|
|
Nation string `json:"nation"`
|
|
Phone string `json:"phone"`
|
|
Wechat string `json:"wechat"`
|
|
Email string `json:"email"`
|
|
HomeAddress string `json:"home_address"`
|
|
AccountStatus int8 `json:"account_status"`
|
|
Status int8 `json:"status"`
|
|
}
|
|
|
|
type erpPositionDTO struct {
|
|
ID uint64 `json:"id"`
|
|
TenantID uint64 `json:"tenant_id"`
|
|
Tid uint64 `json:"tid"`
|
|
DepartmentID uint64 `json:"department_id"`
|
|
PositionCode string `json:"position_code"`
|
|
PositionName string `json:"position_name"`
|
|
PositionType int8 `json:"position_type"`
|
|
Status int8 `json:"status"`
|
|
Sort uint `json:"sort"`
|
|
}
|
|
|
|
// GetOrganization 获取组织机构列表。
|
|
// GET /admin/erp/getOrganization
|
|
func (c *BackendErpController) GetOrganization() {
|
|
tid, _ := c.GetInt("tid")
|
|
|
|
qs := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("delete_time__isnull", true).
|
|
Exclude("status", 0)
|
|
if tid > 0 {
|
|
qs = qs.Filter("tid", tid)
|
|
}
|
|
|
|
var rows []models.BackendErpOrganization
|
|
_, err := qs.OrderBy("sort", "id").All(&rows)
|
|
if err != nil {
|
|
c.jsonError(500, "查询组织机构失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
list := make([]erpOrganizationDTO, 0, len(rows))
|
|
for _, row := range rows {
|
|
list = append(list, c.organizationDTO(row))
|
|
}
|
|
|
|
c.jsonOK(list)
|
|
}
|
|
|
|
// GetOrganizationDetail 获取组织机构详情。
|
|
// GET /admin/erp/getOrganizationDetail/:id
|
|
func (c *BackendErpController) GetOrganizationDetail() {
|
|
id, ok := c.pathUint64(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
var row models.BackendErpOrganization
|
|
err := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
Exclude("status", 0).
|
|
One(&row)
|
|
if err != nil {
|
|
c.jsonError(404, "组织机构不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(c.organizationDTO(row))
|
|
}
|
|
|
|
// CreateOrganization 创建组织机构。
|
|
// POST /admin/erp/createOrganization
|
|
func (c *BackendErpController) CreateOrganization() {
|
|
body := c.parseJSONBody()
|
|
|
|
orgName, _ := c.getStringValue(body, "org_name", "name")
|
|
orgName = strings.TrimSpace(orgName)
|
|
if orgName == "" {
|
|
c.jsonError(400, "组织名称不能为空")
|
|
return
|
|
}
|
|
|
|
orgCode, _ := c.getStringValue(body, "org_code", "code")
|
|
orgCode = strings.TrimSpace(orgCode)
|
|
if orgCode == "" {
|
|
orgCode = "ORG" + c.nowCompactString()
|
|
}
|
|
|
|
tid, _ := c.getUint64Value(body, "tid", "tenant_id")
|
|
parentID, _ := c.getUint64Value(body, "parent_id")
|
|
leaderID, hasLeader := c.getUint64Value(body, "leader_id")
|
|
sortVal, _ := c.getUintValue(body, "sort")
|
|
isCompany, hasCompany := c.getIntValue(body, "is_company")
|
|
status, hasStatus := c.getIntValue(body, "status")
|
|
remark, _ := c.getStringValue(body, "remark")
|
|
|
|
row := models.BackendErpOrganization{
|
|
Tid: tid,
|
|
OrgName: orgName,
|
|
OrgCode: orgCode,
|
|
ParentID: parentID,
|
|
Sort: sortVal,
|
|
IsCompany: boolInt(parentID == 0),
|
|
Status: 1,
|
|
Remark: strPtrIfNotEmpty(remark),
|
|
}
|
|
if hasLeader && leaderID > 0 {
|
|
row.LeaderID = &leaderID
|
|
}
|
|
if hasCompany {
|
|
row.IsCompany = isCompany
|
|
}
|
|
if hasStatus {
|
|
row.Status = int8(status)
|
|
}
|
|
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
c.jsonError(500, "创建组织机构失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
c.jsonOK(map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// EditOrganization 更新组织机构。
|
|
// POST /admin/erp/editOrganization/:id
|
|
func (c *BackendErpController) EditOrganization() {
|
|
id, ok := c.pathUint64(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
body := c.parseJSONBody()
|
|
update := orm.Params{}
|
|
|
|
if v, has := c.getStringValue(body, "org_name", "name"); has {
|
|
v = strings.TrimSpace(v)
|
|
if v == "" {
|
|
c.jsonError(400, "组织名称不能为空")
|
|
return
|
|
}
|
|
update["org_name"] = v
|
|
}
|
|
if v, has := c.getStringValue(body, "org_code", "code"); has {
|
|
update["org_code"] = strings.TrimSpace(v)
|
|
}
|
|
if v, has := c.getUint64Value(body, "parent_id"); has {
|
|
update["parent_id"] = v
|
|
}
|
|
if v, has := c.getUint64Value(body, "tid", "tenant_id"); has {
|
|
update["tid"] = v
|
|
}
|
|
if v, has := c.getUint64Value(body, "leader_id"); has {
|
|
update["leader_id"] = nullableUint64(v)
|
|
}
|
|
if v, has := c.getUintValue(body, "sort"); has {
|
|
update["sort"] = v
|
|
}
|
|
if v, has := c.getIntValue(body, "is_company"); has {
|
|
update["is_company"] = v
|
|
}
|
|
if v, has := c.getIntValue(body, "status"); has {
|
|
update["status"] = int8(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "remark"); has {
|
|
update["remark"] = nullableString(v)
|
|
}
|
|
|
|
if len(update) == 0 {
|
|
c.jsonError(400, "无更新字段")
|
|
return
|
|
}
|
|
|
|
num, err := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
Update(update)
|
|
if err != nil {
|
|
c.jsonError(500, "更新组织机构失败: "+err.Error())
|
|
return
|
|
}
|
|
if num == 0 {
|
|
c.jsonError(404, "组织机构不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(nil)
|
|
}
|
|
|
|
// DeleteOrganization 删除组织机构。
|
|
// DELETE /admin/erp/deleteOrganization/:id
|
|
func (c *BackendErpController) DeleteOrganization() {
|
|
id, ok := c.pathUint64(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
childCount, err := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("parent_id", id).
|
|
Filter("delete_time__isnull", true).
|
|
Exclude("status", 0).
|
|
Count()
|
|
if err != nil {
|
|
c.jsonError(500, "检查子组织失败: "+err.Error())
|
|
return
|
|
}
|
|
if childCount > 0 {
|
|
c.jsonError(400, "请先删除下级组织")
|
|
return
|
|
}
|
|
|
|
now := c.nowString()
|
|
num, err := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
Update(orm.Params{"delete_time": now, "status": int8(0)})
|
|
if err != nil {
|
|
c.jsonError(500, "删除组织机构失败: "+err.Error())
|
|
return
|
|
}
|
|
if num == 0 {
|
|
c.jsonError(404, "组织机构不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(nil)
|
|
}
|
|
|
|
// GetCompanys 获取企业单位列表。
|
|
// GET /admin/erp/getCompanys
|
|
func (c *BackendErpController) GetCompanys() {
|
|
tid, _ := c.GetInt("tid")
|
|
|
|
qs := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("delete_time__isnull", true).
|
|
Exclude("status", 0).
|
|
Filter("is_company", 1)
|
|
if tid > 0 {
|
|
qs = qs.Filter("tid", tid)
|
|
}
|
|
|
|
var rows []models.BackendErpOrganization
|
|
_, err := qs.OrderBy("sort", "id").All(&rows)
|
|
if err != nil {
|
|
c.jsonError(500, "查询企业单位失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
list := make([]erpOrganizationDTO, 0, len(rows))
|
|
for _, row := range rows {
|
|
list = append(list, c.organizationDTO(row))
|
|
}
|
|
|
|
c.jsonOK(list)
|
|
}
|
|
|
|
// GetDepartments 获取部门列表。
|
|
// GET /admin/erp/getDepartments?parent_id=1
|
|
func (c *BackendErpController) GetDepartments() {
|
|
parentID, _ := c.GetInt("parent_id")
|
|
tid, _ := c.GetInt("tid")
|
|
|
|
qs := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("delete_time__isnull", true).
|
|
Exclude("status", 0)
|
|
if parentID > 0 {
|
|
qs = qs.Filter("parent_id", parentID)
|
|
} else {
|
|
qs = qs.Filter("is_company", 0)
|
|
}
|
|
if tid > 0 {
|
|
qs = qs.Filter("tid", tid)
|
|
}
|
|
|
|
var rows []models.BackendErpOrganization
|
|
_, err := qs.OrderBy("sort", "id").All(&rows)
|
|
if err != nil {
|
|
c.jsonError(500, "查询部门失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
list := make([]erpOrganizationDTO, 0, len(rows))
|
|
for _, row := range rows {
|
|
list = append(list, c.organizationDTO(row))
|
|
}
|
|
|
|
c.jsonOK(list)
|
|
}
|
|
|
|
// GetEmployee 获取员工列表。
|
|
// GET /admin/erp/getEmployee?tid=1
|
|
func (c *BackendErpController) GetEmployee() {
|
|
tid, _ := c.GetInt("tid")
|
|
|
|
qs := models.Orm.QueryTable(new(models.BackendErpEmployee)).Filter("delete_time__isnull", true)
|
|
if tid > 0 {
|
|
qs = qs.Filter("tid", tid)
|
|
}
|
|
|
|
var rows []models.BackendErpEmployee
|
|
_, err := qs.OrderBy("-id").All(&rows)
|
|
if err != nil {
|
|
c.jsonError(500, "查询员工失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
list := make([]erpEmployeeDTO, 0, len(rows))
|
|
for _, row := range rows {
|
|
list = append(list, c.employeeDTO(row))
|
|
}
|
|
|
|
c.jsonOK(list)
|
|
}
|
|
|
|
// GetEmployeeDetail 获取员工详情。
|
|
// GET /admin/erp/getEmployeeDetail/:id
|
|
func (c *BackendErpController) GetEmployeeDetail() {
|
|
id, ok := c.pathUint(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
var row models.BackendErpEmployee
|
|
err := models.Orm.QueryTable(new(models.BackendErpEmployee)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
One(&row)
|
|
if err != nil {
|
|
c.jsonError(404, "员工不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(c.employeeDTO(row))
|
|
}
|
|
|
|
// CreateEmployee 创建员工。
|
|
// POST /admin/erp/createEmployee
|
|
func (c *BackendErpController) CreateEmployee() {
|
|
body := c.parseJSONBody()
|
|
|
|
name, _ := c.getStringValue(body, "name")
|
|
name = strings.TrimSpace(name)
|
|
if name == "" {
|
|
c.jsonError(400, "姓名不能为空")
|
|
return
|
|
}
|
|
|
|
account, _ := c.getStringValue(body, "account")
|
|
account = strings.TrimSpace(account)
|
|
if account == "" {
|
|
account = "EMP" + c.nowCompactString()
|
|
}
|
|
|
|
tid, _ := c.getIntValue(body, "tid", "tenant_id")
|
|
gender, hasGender := c.getIntValue(body, "gender", "sex")
|
|
status, hasStatus := c.getIntValue(body, "account_status", "status")
|
|
password, _ := c.getStringValue(body, "password")
|
|
birthday, _ := c.getStringValue(body, "birthday")
|
|
affiliateUnit, _ := c.getStringValue(body, "affiliate_unit")
|
|
department, _ := c.getStringValue(body, "department")
|
|
position, _ := c.getStringValue(body, "position")
|
|
education, _ := c.getStringValue(body, "education")
|
|
nation, _ := c.getStringValue(body, "nation")
|
|
phone, _ := c.getStringValue(body, "phone")
|
|
wechat, _ := c.getStringValue(body, "wechat")
|
|
email, _ := c.getStringValue(body, "email")
|
|
homeAddress, _ := c.getStringValue(body, "home_address")
|
|
|
|
row := models.BackendErpEmployee{
|
|
Tid: nullableIntPtr(tid),
|
|
Account: account,
|
|
Password: hashEmployeePassword(password),
|
|
Name: name,
|
|
Gender: 0,
|
|
Birthday: parseDatePtr(birthday),
|
|
AffiliateUnit: strPtrIfNotEmpty(affiliateUnit),
|
|
Department: strPtrIfNotEmpty(department),
|
|
Position: strPtrIfNotEmpty(position),
|
|
Education: strPtrIfNotEmpty(education),
|
|
Nation: strPtrIfNotEmpty(nation),
|
|
Phone: strPtrIfNotEmpty(phone),
|
|
Wechat: strPtrIfNotEmpty(wechat),
|
|
Email: strPtrIfNotEmpty(email),
|
|
HomeAddress: strPtrIfNotEmpty(homeAddress),
|
|
AccountStatus: 1,
|
|
}
|
|
if hasGender {
|
|
row.Gender = int8(gender)
|
|
}
|
|
if hasStatus {
|
|
row.AccountStatus = int8(status)
|
|
}
|
|
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
c.jsonError(500, "创建员工失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
c.jsonOK(map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// EditEmployee 更新员工。
|
|
// POST /admin/erp/editEmployee/:id
|
|
func (c *BackendErpController) EditEmployee() {
|
|
id, ok := c.pathUint(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
body := c.parseJSONBody()
|
|
update := orm.Params{}
|
|
|
|
if v, has := c.getStringValue(body, "account"); has && strings.TrimSpace(v) != "" {
|
|
update["account"] = strings.TrimSpace(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "name"); has {
|
|
v = strings.TrimSpace(v)
|
|
if v == "" {
|
|
c.jsonError(400, "姓名不能为空")
|
|
return
|
|
}
|
|
update["name"] = v
|
|
}
|
|
if v, has := c.getIntValue(body, "tid", "tenant_id"); has {
|
|
update["tid"] = nullableInt(v)
|
|
}
|
|
if v, has := c.getIntValue(body, "gender", "sex"); has {
|
|
update["gender"] = int8(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "birthday"); has {
|
|
update["birthday"] = parseDatePtr(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "affiliate_unit"); has {
|
|
update["affiliate_unit"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "department"); has {
|
|
update["department"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "position"); has {
|
|
update["position"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "education"); has {
|
|
update["education"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "nation"); has {
|
|
update["nation"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "phone"); has {
|
|
update["phone"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "wechat"); has {
|
|
update["wechat"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "email"); has {
|
|
update["email"] = nullableString(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "home_address"); has {
|
|
update["home_address"] = nullableString(v)
|
|
}
|
|
if v, has := c.getIntValue(body, "account_status", "status"); has {
|
|
update["account_status"] = int8(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "password"); has && strings.TrimSpace(v) != "" {
|
|
update["password"] = hashEmployeePassword(v)
|
|
}
|
|
|
|
if len(update) == 0 {
|
|
c.jsonError(400, "无更新字段")
|
|
return
|
|
}
|
|
|
|
num, err := models.Orm.QueryTable(new(models.BackendErpEmployee)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
Update(update)
|
|
if err != nil {
|
|
c.jsonError(500, "更新员工失败: "+err.Error())
|
|
return
|
|
}
|
|
if num == 0 {
|
|
c.jsonError(404, "员工不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(nil)
|
|
}
|
|
|
|
// DeleteEmployee 删除员工。
|
|
// DELETE /admin/erp/deleteEmployee/:id
|
|
func (c *BackendErpController) DeleteEmployee() {
|
|
id, ok := c.pathUint(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
num, err := models.Orm.QueryTable(new(models.BackendErpEmployee)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
Update(orm.Params{"delete_time": c.nowString(), "account_status": int8(2)})
|
|
if err != nil {
|
|
c.jsonError(500, "删除员工失败: "+err.Error())
|
|
return
|
|
}
|
|
if num == 0 {
|
|
c.jsonError(404, "员工不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(nil)
|
|
}
|
|
|
|
// GetPosition 获取职位列表。
|
|
// GET /admin/erp/getPosition
|
|
func (c *BackendErpController) GetPosition() {
|
|
tid, _ := c.GetInt("tid")
|
|
departmentID, _ := c.GetInt("department_id")
|
|
|
|
qs := models.Orm.QueryTable(new(models.BackendErpPosition))
|
|
if tid > 0 {
|
|
qs = qs.Filter("tenant_id", tid)
|
|
}
|
|
if departmentID > 0 {
|
|
qs = qs.Filter("department_id", departmentID)
|
|
}
|
|
|
|
var rows []models.BackendErpPosition
|
|
_, err := qs.OrderBy("sort", "id").All(&rows)
|
|
if err != nil {
|
|
c.jsonError(500, "查询职位失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
list := make([]erpPositionDTO, 0, len(rows))
|
|
for _, row := range rows {
|
|
list = append(list, c.positionDTO(row))
|
|
}
|
|
|
|
c.jsonOK(list)
|
|
}
|
|
|
|
// GetPositionDetail 获取职位详情。
|
|
// GET /admin/erp/getPositionDetail/:id
|
|
func (c *BackendErpController) GetPositionDetail() {
|
|
id, ok := c.pathUint64(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
var row models.BackendErpPosition
|
|
err := models.Orm.QueryTable(new(models.BackendErpPosition)).Filter("id", id).One(&row)
|
|
if err != nil {
|
|
c.jsonError(404, "职位不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(c.positionDTO(row))
|
|
}
|
|
|
|
// CreatePosition 创建职位。
|
|
// POST /admin/erp/createPosition
|
|
func (c *BackendErpController) CreatePosition() {
|
|
body := c.parseJSONBody()
|
|
|
|
tenantID, _ := c.getUint64Value(body, "tenant_id", "tid")
|
|
departmentID, _ := c.getUint64Value(body, "department_id")
|
|
positionName, _ := c.getStringValue(body, "position_name", "name")
|
|
positionName = strings.TrimSpace(positionName)
|
|
if positionName == "" {
|
|
c.jsonError(400, "职位名称不能为空")
|
|
return
|
|
}
|
|
|
|
positionCode, _ := c.getStringValue(body, "position_code", "code")
|
|
positionCode = strings.TrimSpace(positionCode)
|
|
if positionCode == "" {
|
|
positionCode = "POS" + c.nowCompactString()
|
|
}
|
|
positionType, _ := c.getIntValue(body, "position_type")
|
|
status, hasStatus := c.getIntValue(body, "status")
|
|
sortVal, _ := c.getUintValue(body, "sort")
|
|
|
|
row := models.BackendErpPosition{
|
|
TenantID: tenantID,
|
|
DepartmentID: departmentID,
|
|
PositionCode: positionCode,
|
|
PositionName: positionName,
|
|
PositionType: int8(positionType),
|
|
Status: 1,
|
|
Sort: sortVal,
|
|
}
|
|
if hasStatus {
|
|
row.Status = int8(status)
|
|
}
|
|
|
|
id, err := models.Orm.Insert(&row)
|
|
if err != nil {
|
|
c.jsonError(500, "创建职位失败: "+err.Error())
|
|
return
|
|
}
|
|
|
|
c.jsonOK(map[string]interface{}{"id": id})
|
|
}
|
|
|
|
// EditPosition 更新职位。
|
|
// POST /admin/erp/editPosition/:id
|
|
func (c *BackendErpController) EditPosition() {
|
|
id, ok := c.pathUint64(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
body := c.parseJSONBody()
|
|
update := orm.Params{}
|
|
|
|
if v, has := c.getUint64Value(body, "tenant_id", "tid"); has {
|
|
update["tenant_id"] = v
|
|
}
|
|
if v, has := c.getUint64Value(body, "department_id"); has {
|
|
update["department_id"] = v
|
|
}
|
|
if v, has := c.getStringValue(body, "position_code", "code"); has {
|
|
update["position_code"] = strings.TrimSpace(v)
|
|
}
|
|
if v, has := c.getStringValue(body, "position_name", "name"); has {
|
|
v = strings.TrimSpace(v)
|
|
if v == "" {
|
|
c.jsonError(400, "职位名称不能为空")
|
|
return
|
|
}
|
|
update["position_name"] = v
|
|
}
|
|
if v, has := c.getIntValue(body, "position_type"); has {
|
|
update["position_type"] = int8(v)
|
|
}
|
|
if v, has := c.getIntValue(body, "status"); has {
|
|
update["status"] = int8(v)
|
|
}
|
|
if v, has := c.getUintValue(body, "sort"); has {
|
|
update["sort"] = v
|
|
}
|
|
|
|
if len(update) == 0 {
|
|
c.jsonError(400, "无更新字段")
|
|
return
|
|
}
|
|
|
|
num, err := models.Orm.QueryTable(new(models.BackendErpPosition)).Filter("id", id).Update(update)
|
|
if err != nil {
|
|
c.jsonError(500, "更新职位失败: "+err.Error())
|
|
return
|
|
}
|
|
if num == 0 {
|
|
c.jsonError(404, "职位不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(nil)
|
|
}
|
|
|
|
// DeletePosition 删除职位。
|
|
// DELETE /admin/erp/deletePosition/:id
|
|
func (c *BackendErpController) DeletePosition() {
|
|
id, ok := c.pathUint64(":id")
|
|
if !ok {
|
|
c.jsonError(400, "无效ID")
|
|
return
|
|
}
|
|
|
|
num, err := models.Orm.QueryTable(new(models.BackendErpPosition)).Filter("id", id).Delete()
|
|
if err != nil {
|
|
c.jsonError(500, "删除职位失败: "+err.Error())
|
|
return
|
|
}
|
|
if num == 0 {
|
|
c.jsonError(404, "职位不存在")
|
|
return
|
|
}
|
|
|
|
c.jsonOK(nil)
|
|
}
|
|
|
|
func (c *BackendErpController) organizationDTO(row models.BackendErpOrganization) erpOrganizationDTO {
|
|
parentName := ""
|
|
if row.ParentID > 0 {
|
|
var parent models.BackendErpOrganization
|
|
if err := models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("id", row.ParentID).
|
|
One(&parent); err == nil {
|
|
parentName = parent.OrgName
|
|
}
|
|
}
|
|
|
|
leaderID := uint64(0)
|
|
leaderName := ""
|
|
if row.LeaderID != nil {
|
|
leaderID = *row.LeaderID
|
|
var employee models.BackendErpEmployee
|
|
if err := models.Orm.QueryTable(new(models.BackendErpEmployee)).
|
|
Filter("id", leaderID).
|
|
One(&employee); err == nil {
|
|
leaderName = employee.Name
|
|
}
|
|
}
|
|
|
|
return erpOrganizationDTO{
|
|
ID: row.ID,
|
|
Tid: row.Tid,
|
|
TenantID: row.Tid,
|
|
OrgName: row.OrgName,
|
|
OrgCode: row.OrgCode,
|
|
ParentID: row.ParentID,
|
|
ParentName: parentName,
|
|
LeaderID: leaderID,
|
|
LeaderName: leaderName,
|
|
IsCompany: row.IsCompany,
|
|
Sort: row.Sort,
|
|
Status: row.Status,
|
|
Remark: derefString(row.Remark),
|
|
}
|
|
}
|
|
|
|
func (c *BackendErpController) employeeDTO(row models.BackendErpEmployee) erpEmployeeDTO {
|
|
tid := 0
|
|
if row.Tid != nil {
|
|
tid = *row.Tid
|
|
}
|
|
|
|
birthday := ""
|
|
if row.Birthday != nil {
|
|
birthday = row.Birthday.Format("2006-01-02")
|
|
}
|
|
|
|
affiliateUnit := derefString(row.AffiliateUnit)
|
|
department := derefString(row.Department)
|
|
affiliateUnitName := c.organizationNameByIDString(affiliateUnit)
|
|
departmentName := c.organizationNameByIDString(department)
|
|
|
|
return erpEmployeeDTO{
|
|
ID: row.ID,
|
|
Tid: tid,
|
|
TenantID: tid,
|
|
Account: row.Account,
|
|
Name: row.Name,
|
|
Gender: row.Gender,
|
|
Sex: row.Gender,
|
|
Birthday: birthday,
|
|
AffiliateUnit: affiliateUnit,
|
|
AffiliateUnitName: affiliateUnitName,
|
|
Department: department,
|
|
DepartmentName: departmentName,
|
|
Position: derefString(row.Position),
|
|
Education: derefString(row.Education),
|
|
Nation: derefString(row.Nation),
|
|
Phone: derefString(row.Phone),
|
|
Wechat: derefString(row.Wechat),
|
|
Email: derefString(row.Email),
|
|
HomeAddress: derefString(row.HomeAddress),
|
|
AccountStatus: row.AccountStatus,
|
|
Status: row.AccountStatus,
|
|
}
|
|
}
|
|
|
|
func (c *BackendErpController) organizationNameByIDString(idValue string) string {
|
|
idValue = strings.TrimSpace(idValue)
|
|
if idValue == "" {
|
|
return ""
|
|
}
|
|
|
|
id, err := strconv.ParseUint(idValue, 10, 64)
|
|
if err != nil || id == 0 {
|
|
return ""
|
|
}
|
|
|
|
var org models.BackendErpOrganization
|
|
err = models.Orm.QueryTable(new(models.BackendErpOrganization)).
|
|
Filter("id", id).
|
|
Filter("delete_time__isnull", true).
|
|
One(&org)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
|
|
return org.OrgName
|
|
}
|
|
|
|
func (c *BackendErpController) positionDTO(row models.BackendErpPosition) erpPositionDTO {
|
|
return erpPositionDTO{
|
|
ID: row.ID,
|
|
TenantID: row.TenantID,
|
|
Tid: row.TenantID,
|
|
DepartmentID: row.DepartmentID,
|
|
PositionCode: row.PositionCode,
|
|
PositionName: row.PositionName,
|
|
PositionType: row.PositionType,
|
|
Status: row.Status,
|
|
Sort: row.Sort,
|
|
}
|
|
}
|
|
|
|
func (c *BackendErpController) parseJSONBody() map[string]interface{} {
|
|
body := map[string]interface{}{}
|
|
contentType := strings.ToLower(c.Ctx.Input.Header("Content-Type"))
|
|
if !strings.Contains(contentType, "json") {
|
|
return body
|
|
}
|
|
if len(c.Ctx.Input.RequestBody) == 0 {
|
|
return body
|
|
}
|
|
_ = json.Unmarshal(c.Ctx.Input.RequestBody, &body)
|
|
return body
|
|
}
|
|
|
|
func (c *BackendErpController) getStringValue(body map[string]interface{}, keys ...string) (string, bool) {
|
|
for _, key := range keys {
|
|
if v, ok := body[key]; ok {
|
|
switch val := v.(type) {
|
|
case string:
|
|
return val, true
|
|
case float64:
|
|
return strconv.FormatFloat(val, 'f', -1, 64), true
|
|
case bool:
|
|
return strconv.FormatBool(val), true
|
|
default:
|
|
return strings.TrimSpace(strings.Trim(strings.ReplaceAll(strings.ReplaceAll(toJSON(val), "\n", ""), "\r", ""), "\"")), true
|
|
}
|
|
}
|
|
if c.Ctx.Request.Form == nil && c.Ctx.Request.PostForm == nil && c.Ctx.Request.MultipartForm == nil {
|
|
_ = c.Ctx.Request.ParseMultipartForm(32 << 20)
|
|
}
|
|
if val := c.GetString(key); val != "" {
|
|
return val, true
|
|
}
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func (c *BackendErpController) getIntValue(body map[string]interface{}, keys ...string) (int, bool) {
|
|
for _, key := range keys {
|
|
if v, ok := body[key]; ok {
|
|
switch val := v.(type) {
|
|
case float64:
|
|
return int(val), true
|
|
case int:
|
|
return val, true
|
|
case string:
|
|
if strings.TrimSpace(val) == "" {
|
|
return 0, true
|
|
}
|
|
parsed, err := strconv.Atoi(strings.TrimSpace(val))
|
|
return parsed, err == nil
|
|
}
|
|
}
|
|
if c.Ctx.Request.Form == nil && c.Ctx.Request.PostForm == nil && c.Ctx.Request.MultipartForm == nil {
|
|
_ = c.Ctx.Request.ParseMultipartForm(32 << 20)
|
|
}
|
|
if val := c.GetString(key); val != "" {
|
|
parsed, err := strconv.Atoi(strings.TrimSpace(val))
|
|
return parsed, err == nil
|
|
}
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
func (c *BackendErpController) getUintValue(body map[string]interface{}, keys ...string) (uint, bool) {
|
|
v, ok := c.getIntValue(body, keys...)
|
|
if !ok || v < 0 {
|
|
return 0, ok
|
|
}
|
|
return uint(v), true
|
|
}
|
|
|
|
func (c *BackendErpController) getUint64Value(body map[string]interface{}, keys ...string) (uint64, bool) {
|
|
for _, key := range keys {
|
|
if v, ok := body[key]; ok {
|
|
switch val := v.(type) {
|
|
case float64:
|
|
if val < 0 {
|
|
return 0, false
|
|
}
|
|
return uint64(val), true
|
|
case int:
|
|
if val < 0 {
|
|
return 0, false
|
|
}
|
|
return uint64(val), true
|
|
case string:
|
|
if strings.TrimSpace(val) == "" {
|
|
return 0, true
|
|
}
|
|
parsed, err := strconv.ParseUint(strings.TrimSpace(val), 10, 64)
|
|
return parsed, err == nil
|
|
}
|
|
}
|
|
if c.Ctx.Request.Form == nil && c.Ctx.Request.PostForm == nil && c.Ctx.Request.MultipartForm == nil {
|
|
_ = c.Ctx.Request.ParseMultipartForm(32 << 20)
|
|
}
|
|
if val := c.GetString(key); val != "" {
|
|
parsed, err := strconv.ParseUint(strings.TrimSpace(val), 10, 64)
|
|
return parsed, err == nil
|
|
}
|
|
}
|
|
return 0, false
|
|
}
|
|
|
|
func (c *BackendErpController) pathUint(name string) (uint, bool) {
|
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(name), 10, 64)
|
|
return uint(id), err == nil && id > 0
|
|
}
|
|
|
|
func (c *BackendErpController) pathUint64(name string) (uint64, bool) {
|
|
id, err := strconv.ParseUint(c.Ctx.Input.Param(name), 10, 64)
|
|
return id, err == nil && id > 0
|
|
}
|
|
|
|
func (c *BackendErpController) jsonOK(data interface{}) {
|
|
resp := map[string]interface{}{"code": 200, "msg": "success"}
|
|
if data != nil {
|
|
resp["data"] = data
|
|
}
|
|
c.Data["json"] = resp
|
|
_ = c.ServeJSON()
|
|
}
|
|
|
|
func (c *BackendErpController) jsonError(code int, msg string) {
|
|
c.Data["json"] = map[string]interface{}{"code": code, "msg": msg}
|
|
_ = c.ServeJSON()
|
|
}
|
|
|
|
func (c *BackendErpController) nowString() string {
|
|
return time.Now().Format("2006-01-02 15:04:05")
|
|
}
|
|
|
|
func (c *BackendErpController) nowCompactString() string {
|
|
return strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(c.nowString(), "-", ""), ":", ""), " ", "")
|
|
}
|
|
|
|
func strPtrIfNotEmpty(v string) *string {
|
|
v = strings.TrimSpace(v)
|
|
if v == "" {
|
|
return nil
|
|
}
|
|
return &v
|
|
}
|
|
|
|
func nullableString(v string) interface{} {
|
|
v = strings.TrimSpace(v)
|
|
if v == "" {
|
|
return nil
|
|
}
|
|
return v
|
|
}
|
|
|
|
func nullableInt(v int) interface{} {
|
|
if v <= 0 {
|
|
return nil
|
|
}
|
|
return v
|
|
}
|
|
|
|
func nullableIntPtr(v int) *int {
|
|
if v <= 0 {
|
|
return nil
|
|
}
|
|
return &v
|
|
}
|
|
|
|
func nullableUint64(v uint64) interface{} {
|
|
if v == 0 {
|
|
return nil
|
|
}
|
|
return v
|
|
}
|
|
|
|
func derefString(v *string) string {
|
|
if v == nil {
|
|
return ""
|
|
}
|
|
return *v
|
|
}
|
|
|
|
func boolInt(v bool) int {
|
|
if v {
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func toJSON(v interface{}) string {
|
|
b, _ := json.Marshal(v)
|
|
return string(b)
|
|
}
|
|
|
|
func parseDatePtr(v string) *time.Time {
|
|
v = strings.TrimSpace(v)
|
|
if v == "" {
|
|
return nil
|
|
}
|
|
if t, err := time.Parse("2006-01-02", v); err == nil {
|
|
return &t
|
|
}
|
|
if t, err := time.Parse("2006-01-02 15:04:05", v); err == nil {
|
|
return &t
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// hashEmployeePassword 适配 yz_backend_erp_employee.password varchar(64),使用 sha256 hex。
|
|
// 如果密码为空则返回空字符串,符合表默认值。
|
|
func hashEmployeePassword(plain string) string {
|
|
plain = strings.TrimSpace(plain)
|
|
if plain == "" {
|
|
return ""
|
|
}
|
|
sum := sha256.Sum256([]byte(plain))
|
|
return hex.EncodeToString(sum[:])
|
|
}
|