更新若干事项
This commit is contained in:
1 parent
68cdaf38fa
commit
9898962836
30 files changed
+7715
No files matched your search
@@ -0,0 +1,206 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"server/models"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
)
|
||||
|
||||
// 租户端排班模板:只读调用,不允许修改平台模板。
|
||||
//
|
||||
// 调用模板时会把模板的每日规则转成方案周期的 pattern 快照,并把模板里的
|
||||
// 班次按「名称 + 上下班时间」匹配到租户自己的班次;匹配不到则自动创建,
|
||||
// 这样租户拿到方案后就能像普通方案一样自由修改。
|
||||
|
||||
func schedTplTypeLabel(value int8) string {
|
||||
return schedTplTypeText(value)
|
||||
}
|
||||
|
||||
func (c *BackendOaSchedulingController) schedTplQuery() orm.QuerySeter {
|
||||
return models.Orm.QueryTable(new(models.PlatformSchedTpl)).
|
||||
Filter("delete_time__isnull", true)
|
||||
}
|
||||
|
||||
func (c *BackendOaSchedulingController) schedTplDays(templateID uint64) []models.PlatformSchedTplDay {
|
||||
rows := []models.PlatformSchedTplDay{}
|
||||
_, err := models.Orm.QueryTable(new(models.PlatformSchedTplDay)).
|
||||
Filter("template_id", templateID).
|
||||
OrderBy("day_index").All(&rows)
|
||||
if err != nil && err != orm.ErrNoRows {
|
||||
return []models.PlatformSchedTplDay{}
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func (c *BackendOaSchedulingController) schedTplByID(id uint64) (*models.PlatformSchedTpl, bool) {
|
||||
var row models.PlatformSchedTpl
|
||||
if err := c.schedTplQuery().Filter("id", id).One(&row); err != nil {
|
||||
return nil, false
|
||||
}
|
||||
return &row, true
|
||||
}
|
||||
|
||||
func schedTplView(row *models.PlatformSchedTpl, days []models.PlatformSchedTplDay) map[string]interface{} {
|
||||
view := map[string]interface{}{
|
||||
"id": row.ID,
|
||||
"code": row.Code,
|
||||
"name": row.Name,
|
||||
"template_type": row.TemplateType,
|
||||
"template_type_text": schedTplTypeLabel(row.TemplateType),
|
||||
"align_mode": row.AlignMode,
|
||||
"cycle_days": row.CycleDays,
|
||||
"week_offset": row.WeekOffset,
|
||||
"month_rest_days": row.MonthRestDays,
|
||||
"month_rest_weekday": row.MonthRestWeekday,
|
||||
"summary": row.Summary,
|
||||
}
|
||||
if days != nil {
|
||||
view["days"] = days
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
// TemplateList 租户端可调用的排班模板(只返回启用的模板)。
|
||||
// GET /backend/oa/scheduling/templates?keyword=
|
||||
func (c *BackendOaSchedulingController) TemplateList() {
|
||||
if _, _, _, ok := c.scOperator(); !ok {
|
||||
return
|
||||
}
|
||||
qs := c.schedTplQuery().Filter("status", 1)
|
||||
if keyword := strings.TrimSpace(c.GetString("keyword")); keyword != "" {
|
||||
qs = qs.Filter("name__icontains", keyword)
|
||||
}
|
||||
|
||||
var rows []models.PlatformSchedTpl
|
||||
if _, err := qs.OrderBy("sort", "id").All(&rows); err != nil && err != orm.ErrNoRows {
|
||||
c.scFail(500, 500, "查询排班模板失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
list := make([]map[string]interface{}, 0, len(rows))
|
||||
for i := range rows {
|
||||
list = append(list, schedTplView(&rows[i], c.schedTplDays(rows[i].ID)))
|
||||
}
|
||||
c.scOK(map[string]interface{}{"list": list, "total": len(list)})
|
||||
}
|
||||
|
||||
// TemplateApply 调用模板:返回可直接用于方案的周期规则,并把模板班次
|
||||
// 匹配到租户班次(不存在时自动创建)。
|
||||
// POST /backend/oa/scheduling/templates/apply body: {"template_id": 1}
|
||||
func (c *BackendOaSchedulingController) TemplateApply() {
|
||||
tid, _, _, ok := c.scOperator()
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
id := scUintValue(c.scBody(), "template_id")
|
||||
if id == 0 {
|
||||
if raw := strings.TrimSpace(c.GetString("template_id")); raw != "" {
|
||||
id, _ = strconv.ParseUint(raw, 10, 64)
|
||||
}
|
||||
}
|
||||
if id == 0 {
|
||||
c.scFail(400, 400, "请选择排班模板")
|
||||
return
|
||||
}
|
||||
tpl, found := c.schedTplByID(id)
|
||||
if !found {
|
||||
c.scFail(404, 404, "排班模板不存在")
|
||||
return
|
||||
}
|
||||
if tpl.Status != 1 {
|
||||
c.scFail(400, 400, "该模板已停用")
|
||||
return
|
||||
}
|
||||
|
||||
var shifts []models.OaShift
|
||||
if _, err := c.shiftQuery(tid).OrderBy("sort", "id").All(&shifts); err != nil && err != orm.ErrNoRows {
|
||||
c.scFail(500, 500, "查询班次失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
shiftMap := make(map[string]*models.OaShift, len(shifts))
|
||||
maxSort := 0
|
||||
for i := range shifts {
|
||||
shift := &shifts[i]
|
||||
shiftMap[schedShiftKey(shift.Name, shift.WorkStart, shift.WorkEnd)] = shift
|
||||
if shift.Sort > maxSort {
|
||||
maxSort = shift.Sort
|
||||
}
|
||||
}
|
||||
|
||||
patterns := []scPatternDay{}
|
||||
createdShifts := 0
|
||||
matchedShifts := 0
|
||||
for _, day := range c.schedTplDays(tpl.ID) {
|
||||
if day.DayType != models.SchedTplDayWork {
|
||||
patterns = append(patterns, scPatternDay{DayIndex: day.DayIndex, DayType: models.SchedTplDayRest})
|
||||
continue
|
||||
}
|
||||
key := schedShiftKey(day.ShiftName, day.WorkStart, day.WorkEnd)
|
||||
shift, hit := shiftMap[key]
|
||||
if hit {
|
||||
matchedShifts++
|
||||
} else {
|
||||
maxSort += 10
|
||||
shift = &models.OaShift{
|
||||
Tid: int(tid),
|
||||
Name: day.ShiftName,
|
||||
ShortName: day.ShiftShort,
|
||||
Color: day.Color,
|
||||
WorkStart: day.WorkStart,
|
||||
WorkEnd: day.WorkEnd,
|
||||
RestStart: day.RestStart,
|
||||
RestEnd: day.RestEnd,
|
||||
WorkHours: day.WorkHours,
|
||||
IsDefault: 0,
|
||||
Status: 1,
|
||||
Sort: maxSort,
|
||||
IsDeleted: 0,
|
||||
}
|
||||
if shift.ShortName == "" {
|
||||
shift.ShortName = shift.Name
|
||||
}
|
||||
if shift.Color == "" {
|
||||
shift.Color = "#409EFF"
|
||||
}
|
||||
if _, err := models.Orm.Insert(shift); err != nil {
|
||||
c.scFail(500, 500, "创建班次失败: "+err.Error())
|
||||
return
|
||||
}
|
||||
shiftMap[key] = shift
|
||||
createdShifts++
|
||||
}
|
||||
patterns = append(patterns, scPatternDay{
|
||||
DayIndex: day.DayIndex,
|
||||
DayType: models.SchedTplDayWork,
|
||||
ShiftID: shift.ID,
|
||||
ShiftName: shift.Name,
|
||||
ShortName: shift.ShortName,
|
||||
Color: shift.Color,
|
||||
WorkStart: shift.WorkStart,
|
||||
WorkEnd: shift.WorkEnd,
|
||||
RestStart: shift.RestStart,
|
||||
RestEnd: shift.RestEnd,
|
||||
WorkHours: shift.WorkHours,
|
||||
})
|
||||
}
|
||||
if len(patterns) == 0 {
|
||||
c.scFail(400, 400, "该模板没有配置排班规则")
|
||||
return
|
||||
}
|
||||
|
||||
c.scOK(map[string]interface{}{
|
||||
"template": schedTplView(tpl, nil),
|
||||
"pattern": patterns,
|
||||
"days": patterns,
|
||||
"created_shift": createdShifts,
|
||||
"matched_shift": matchedShifts,
|
||||
})
|
||||
}
|
||||
|
||||
func schedShiftKey(name, workStart, workEnd string) string {
|
||||
return strings.TrimSpace(name) + "|" + strings.TrimSpace(workStart) + "|" + strings.TrimSpace(workEnd)
|
||||
}
|
||||
Reference in new issue
Block a user