mirror of
https://github.com/ZSCNetSupportDept/scheduler.git
synced 2025-10-28 20:45:05 +08:00
改进排班的算法:现在可以每周轮换一次片区,而且现在将结构体给模板
This commit is contained in:
@@ -1,57 +1,78 @@
|
|||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
//"fmt"
|
||||||
"github.com/gocarina/gocsv"
|
"github.com/gocarina/gocsv"
|
||||||
"github.com/golang-module/carbon/v2"
|
"github.com/golang-module/carbon/v2"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"zsxyww.com/scheduler/config"
|
"zsxyww.com/scheduler/config"
|
||||||
"zsxyww.com/scheduler/model"
|
"zsxyww.com/scheduler/model"
|
||||||
"zsxyww.com/scheduler/signals"
|
"zsxyww.com/scheduler/signals"
|
||||||
)
|
)
|
||||||
|
|
||||||
var data *[7][]string
|
var data *[7][]*model.Member
|
||||||
|
var mutex sync.RWMutex //lock for data
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
// /api/getAssignment GET 获取当日值班表,返回html
|
||||||
func GetAssignment(i echo.Context) error {
|
func GetAssignment(i echo.Context) error {
|
||||||
|
|
||||||
if (carbon.Now().ToDateString() != signals.Table.GetLastUpdated().ToDateString()) || signals.Table.IsNeedUpdate() == true {
|
if (carbon.Now().ToDateString() != signals.Table.GetLastUpdated().ToDateString()) || signals.Table.IsNeedUpdate() == true {
|
||||||
fmt.Printf("At %v:start regenerate table", carbon.Now())
|
|
||||||
data, err = generateTable()
|
mutex.Lock()
|
||||||
|
data, err = generateTable(carbon.Now())
|
||||||
|
mutex.Unlock()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
i.String(http.StatusInternalServerError, err.Error())
|
i.String(http.StatusInternalServerError, err.Error())
|
||||||
return echo.ErrInternalServerError
|
return echo.ErrInternalServerError
|
||||||
}
|
}
|
||||||
|
|
||||||
//signals.Table.SetUpdated(carbon.Now())
|
//signals.Table.SetUpdated(carbon.Now())
|
||||||
//测试时注释掉上面的状态更新方便调试
|
//测试时注释掉上面的状态更新方便调试
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex.RLock()
|
||||||
i.Render(http.StatusOK, "table.html", data)
|
i.Render(http.StatusOK, "table.html", data)
|
||||||
|
mutex.RUnlock()
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
func generateTable() (*[7][]string, error) {
|
|
||||||
|
|
||||||
table := [7][]string{} //结果放入这里
|
// 根据指定的时间来生成对应的值班表
|
||||||
members := []*model.Member{} //包含所有成员信息的切片
|
func generateTable(time carbon.Carbon) (*[7][]*model.Member, error) {
|
||||||
|
|
||||||
|
table := [7][]*model.Member{} //结果放入这里
|
||||||
|
members := []*model.Member{} //包含所有成员信息的切片
|
||||||
|
today := []*model.Member{} //今天值班的人
|
||||||
|
female := []*model.Member{} //今天的女生
|
||||||
|
male := []*model.Member{} //今天的男生
|
||||||
|
week, dayOfWeek := getWorkDay(time)
|
||||||
|
|
||||||
|
// 为了实现更换值班的片区,写的一个闭包切片访问器
|
||||||
|
iter := func(array []*model.Member, i int) *model.Member {
|
||||||
|
return array[(i+week)%len(array)]
|
||||||
|
}
|
||||||
|
|
||||||
|
//读取csv文件
|
||||||
err := readTableData(&members)
|
err := readTableData(&members)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
dayOfWeek := carbon.Now().DayOfWeek() //今天星期几
|
//添加标题
|
||||||
today := []*model.Member{} //今天值班的人
|
table[0] = append(table[0], &model.Member{Name: "凤翔"})
|
||||||
female := []*model.Member{} //今天的女生
|
table[1] = append(table[1], &model.Member{Name: "朝晖"})
|
||||||
male := []*model.Member{} //今天的男生
|
table[2] = append(table[2], &model.Member{Name: "香晖AB"})
|
||||||
|
table[3] = append(table[3], &model.Member{Name: "香晖CD"})
|
||||||
table[0] = append(table[0], "凤翔")
|
table[4] = append(table[4], &model.Member{Name: "东门"})
|
||||||
table[1] = append(table[1], "朝晖")
|
table[5] = append(table[5], &model.Member{Name: "北门"})
|
||||||
table[2] = append(table[2], "香晖AB")
|
table[6] = append(table[6], &model.Member{Name: "歧头"})
|
||||||
table[3] = append(table[3], "香晖CD")
|
|
||||||
table[4] = append(table[4], "东门")
|
|
||||||
table[5] = append(table[5], "北门")
|
|
||||||
table[6] = append(table[6], "歧头")
|
|
||||||
|
|
||||||
|
//初始化数据
|
||||||
for _, i := range members {
|
for _, i := range members {
|
||||||
if i.FreeDay == dayOfWeek {
|
if i.FreeDay == dayOfWeek {
|
||||||
today = append(today, i)
|
today = append(today, i)
|
||||||
@@ -67,43 +88,41 @@ func generateTable() (*[7][]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//为女生分配负责人
|
//为女生分配负责人
|
||||||
for c, i := range female {
|
for i := 0; i <= len(female); i++ {
|
||||||
if i.Access < model.FRESH { //是正式成员
|
if a := iter(female, i); a.Access < model.FRESH { //是正式成员
|
||||||
table[c%4] = append(table[c%4], i.Name) //轮流分配到女生片区
|
table[i%4] = append(table[i%4], a) //轮流分配到女生片区
|
||||||
i.Arranged = true
|
a.Arranged = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//为剩下的片区分配负责人
|
//为剩下的片区分配负责人
|
||||||
for _, i := range male {
|
for i := 0; i <= len(male); i++ {
|
||||||
if i.Access < model.FRESH {
|
if a := iter(male, i); a.Access < model.FRESH { //是正式成员
|
||||||
table[fewest(table)] = append(table[fewest(table)], i.Name)
|
table[fewest(table)] = append(table[fewest(table)], a)
|
||||||
i.Arranged = true
|
a.Arranged = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//分配剩下的所有女生到女生片区
|
//分配剩下的所有女生到女生片区
|
||||||
for _, i := range female {
|
for i := 0; i <= len(female); i++ {
|
||||||
if i.Arranged != true {
|
if a := iter(female, i); a.Arranged != true { //还没有安排
|
||||||
table[fewestF(table)] = append(table[fewestF(table)], i.Name)
|
table[fewestF(table)] = append(table[fewestF(table)], a)
|
||||||
i.Arranged = true
|
a.Arranged = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//分配剩下的所有男生
|
//分配剩下的所有男生
|
||||||
for _, i := range male {
|
for i := 0; i <= len(male); i++ {
|
||||||
if i.Arranged == false {
|
if a := iter(male, i); a.Arranged == false { //还没有安排
|
||||||
table[fewest(table)] = append(table[fewest(table)], i.Name)
|
table[fewest(table)] = append(table[fewest(table)], a)
|
||||||
|
a.Arranged = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Printf("today:%v\n", today)
|
|
||||||
fmt.Printf("table:%v\n", table)
|
|
||||||
|
|
||||||
//测试的时候先注释掉这里
|
|
||||||
//signals.Table.LastUpdated = carbon.Now()
|
|
||||||
return &table, nil
|
return &table, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 读取csv文件
|
||||||
func readTableData(m *[]*model.Member) error {
|
func readTableData(m *[]*model.Member) error {
|
||||||
data, err := os.OpenFile(config.File, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
data, err := os.OpenFile(config.File, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -115,14 +134,14 @@ func readTableData(m *[]*model.Member) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for index, member := range *m {
|
//for index, member := range *m {
|
||||||
fmt.Printf("%v:%v\n", index, member) // for debug concerns
|
// fmt.Printf("%v:%v\n", index, member) // for debug concerns
|
||||||
}
|
//}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 找出人数最少的片区
|
// 找出人数最少的片区
|
||||||
func fewest(a [7][]string) int {
|
func fewest(a [7][]*model.Member) int {
|
||||||
b := min(len(a[0]), len(a[1]), len(a[2]), len(a[3]), len(a[4]), len(a[5]), len(a[6]))
|
b := min(len(a[0]), len(a[1]), len(a[2]), len(a[3]), len(a[4]), len(a[5]), len(a[6]))
|
||||||
for i := range len(a) {
|
for i := range len(a) {
|
||||||
if b == len(a[i]) {
|
if b == len(a[i]) {
|
||||||
@@ -133,7 +152,7 @@ func fewest(a [7][]string) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 找出人数最少的女生片区
|
// 找出人数最少的女生片区
|
||||||
func fewestF(a [7][]string) int {
|
func fewestF(a [7][]*model.Member) int {
|
||||||
b := min(len(a[0]), len(a[1]), len(a[2]), len(a[3]))
|
b := min(len(a[0]), len(a[1]), len(a[2]), len(a[3]))
|
||||||
for i := range len(a) - 3 {
|
for i := range len(a) - 3 {
|
||||||
if b == len(a[i]) {
|
if b == len(a[i]) {
|
||||||
|
|||||||
14
handler/utils.go
Normal file
14
handler/utils.go
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/golang-module/carbon/v2"
|
||||||
|
"zsxyww.com/scheduler/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 输入一个时间,返回时间是第几周的第几天
|
||||||
|
func getWorkDay(in carbon.Carbon) (weekOffset int, dayOffset int) {
|
||||||
|
time := carbon.Parse(config.StartTime)
|
||||||
|
_weekOffset := time.DiffInWeeks(in)
|
||||||
|
_dayOffset := in.DayOfWeek()
|
||||||
|
return int(_weekOffset), _dayOffset
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
{{range .}} <!-- 遍历外层切片 -->
|
{{range .}} <!-- 遍历外层切片 -->
|
||||||
<tr>
|
<tr>
|
||||||
{{range .}} <!-- 遍历内层切片 -->
|
{{range .}} <!-- 遍历内层切片 -->
|
||||||
<td>{{.}}</td>
|
<td>{{.Name}}</td>
|
||||||
{{end}}
|
{{end}}
|
||||||
</tr>
|
</tr>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
Reference in New Issue
Block a user