From 28fec27beb18e9db4d569f7df9cad73e4a4cd90e Mon Sep 17 00:00:00 2001 From: fuuzen <80118151@qq.com> Date: Thu, 27 Feb 2025 14:40:00 +0800 Subject: [PATCH] feat: optomize scheduling page for user and fix some bugs - fix some css problem when the window isn't wide enougth while scheduling - improve report of wrong schedule for user while scheduling by refactor `backend/internal/utils/validation.go` - add delete badge function while scheduling - update favicon as ecnc --- .../domain/availability_submission.go | 1 + backend/internal/handler/schedule_plans.go | 21 +- backend/internal/scheduler/scheduler.go | 20 +- backend/internal/utils/validation.go | 203 +++++++++++++----- frontend/index.html | 2 +- frontend/public/favicon.ico | Bin 0 -> 270622 bytes frontend/public/vite.svg | 1 - frontend/src/assets/react.svg | 1 - .../src/components/ui/badge-removable.tsx | 36 ++++ .../scheduling-area-drag-overlay.tsx | 2 +- .../scheduling-area-table-row-cell-item.tsx | 33 ++- .../scheduling-area-table-row.tsx | 6 +- .../scheduling-area/scheduling-area-table.tsx | 12 +- .../scheduling-area/scheduling-area-users.tsx | 2 +- frontend/vite.config.ts | 3 +- 15 files changed, 249 insertions(+), 94 deletions(-) create mode 100644 frontend/public/favicon.ico delete mode 100644 frontend/public/vite.svg delete mode 100644 frontend/src/assets/react.svg create mode 100644 frontend/src/components/ui/badge-removable.tsx diff --git a/backend/internal/domain/availability_submission.go b/backend/internal/domain/availability_submission.go index 6b37740..2aa86ec 100644 --- a/backend/internal/domain/availability_submission.go +++ b/backend/internal/domain/availability_submission.go @@ -11,6 +11,7 @@ type AvailabilitySubmission struct { ID int64 `json:"id"` SchedulePlanID int64 `json:"schedulePlanID"` UserID int64 `json:"userID"` + Username string `json:"username"` Items []AvailabilitySubmissionItem `json:"items"` CreatedAt time.Time `json:"createdAt"` Version int32 `json:"-"` diff --git a/backend/internal/handler/schedule_plans.go b/backend/internal/handler/schedule_plans.go index a46c409..71926c4 100644 --- a/backend/internal/handler/schedule_plans.go +++ b/backend/internal/handler/schedule_plans.go @@ -305,13 +305,13 @@ func (h *Handler) SubmitSchedulingResult(w http.ResponseWriter, r *http.Request) return } - if err := utils.ValidateSchedulingResultWithSubmissions(schedulingResult, submissions); err != nil { + if err := utils.ValidateSchedulingResultWithSubmissions(schedulingResult, submissions, template, h.repository); err != nil { h.badRequest(w, r, err) return } // 最后要检查是否存在重复的助理 - if err := utils.ValidIfExistsDuplicateAssistant(schedulingResult); err != nil { + if err := utils.ValidIfExistsDuplicateAssistant(schedulingResult, template, h.repository); err != nil { h.badRequest(w, r, err) return } @@ -401,8 +401,21 @@ func (h *Handler) GenerateSchedulingResult(w http.ResponseWriter, r *http.Reques return } - res, err := scheduler.Schedule() - if err != nil { + res := scheduler.Schedule() + + // 还需要检查一下结果是否满足约束条件(调用 validate 包中的方法就可以了) + schedulingResult := &domain.SchedulingResult{ + Shifts: make([]domain.SchedulingResultShift, len(res)), + } + for i, shift := range res { + schedulingResult.Shifts[i] = *shift + } + + if err := utils.ValidateSchedulingResultWithSubmissions(schedulingResult, submissions, template, h.repository); err != nil { + h.internalServerError(w, r, err) + return + } + if err := utils.ValidIfExistsDuplicateAssistant(schedulingResult, template, h.repository); err != nil { h.internalServerError(w, r, err) return } diff --git a/backend/internal/scheduler/scheduler.go b/backend/internal/scheduler/scheduler.go index a58caa2..6b794c0 100644 --- a/backend/internal/scheduler/scheduler.go +++ b/backend/internal/scheduler/scheduler.go @@ -7,7 +7,6 @@ import ( "sort" "github.com/sysu-ecnc-dev/shift-manager/backend/internal/domain" - "github.com/sysu-ecnc-dev/shift-manager/backend/internal/utils" ) type Scheduler struct { @@ -68,7 +67,7 @@ func New(parameters *Parameters, users []*domain.User, template *domain.Schedule return s, nil } -func (s *Scheduler) Schedule() ([]*domain.SchedulingResultShift, error) { +func (s *Scheduler) Schedule() []*domain.SchedulingResultShift { // 生成初始种群 pop := make([]*Chromosome, s.parameters.PopulationSize) for i := 0; i < int(s.parameters.PopulationSize); i++ { @@ -167,20 +166,5 @@ func (s *Scheduler) Schedule() ([]*domain.SchedulingResultShift, error) { }) } - // 还需要检查一下结果是否满足约束条件(调用 validate 包中的方法就可以了) - schedulingResult := &domain.SchedulingResult{ - Shifts: make([]domain.SchedulingResultShift, len(result)), - } - for i, shift := range result { - schedulingResult.Shifts[i] = *shift - } - - if err := utils.ValidateSchedulingResultWithSubmissions(schedulingResult, s.submissions); err != nil { - return nil, err - } - if err := utils.ValidIfExistsDuplicateAssistant(schedulingResult); err != nil { - return nil, err - } - - return result, nil + return result } diff --git a/backend/internal/utils/validation.go b/backend/internal/utils/validation.go index 97e4e2f..0633b82 100644 --- a/backend/internal/utils/validation.go +++ b/backend/internal/utils/validation.go @@ -7,6 +7,7 @@ import ( "time" "github.com/sysu-ecnc-dev/shift-manager/backend/internal/domain" + "github.com/sysu-ecnc-dev/shift-manager/backend/internal/repository" ) func ValidateScheduleTemplateShiftTime(st *domain.ScheduleTemplate) error { @@ -14,14 +15,14 @@ func ValidateScheduleTemplateShiftTime(st *domain.ScheduleTemplate) error { for id, shift := range st.Shifts { startTime, err := time.Parse("15:04:05", shift.StartTime) if err != nil { - return fmt.Errorf("班次 %d 的开始时间格式错误", id) + return fmt.Errorf("班次 %d 的开始时间格式错误: %s", id, shift.StartTime) } endTime, err := time.Parse("15:04:05", shift.EndTime) if err != nil { - return fmt.Errorf("班次 %d 的结束时间格式错误", id) + return fmt.Errorf("班次 %d 的结束时间格式错误: %s", id, shift.EndTime) } if endTime.Before(startTime) { - return fmt.Errorf("班次 %d 的结束时间不能小于开始时间", id) + return fmt.Errorf("班次 %d 的结束时间 %s 不能小于开始时间 %s", id, shift.EndTime, shift.StartTime) } } @@ -35,7 +36,7 @@ func ValidateScheduleTemplateShiftTime(st *domain.ScheduleTemplate) error { jEndTime, _ := time.Parse("15:04:05", st.Shifts[j].EndTime) if !(jStartTime.After(iEndTime) || jStartTime.Equal(iEndTime) || iStartTime.After(jEndTime) || iStartTime.Equal(jEndTime)) { - return fmt.Errorf("班次 %d 和班次 %d 之间的时间冲突", i, j) + return fmt.Errorf("班次 %d (%s~%s) 和班次 %d (%s~%s) 之间的时间冲突", i, iStartTime, iEndTime, j, jStartTime, jEndTime) } } } @@ -58,34 +59,62 @@ func ValidateSchedulePlanTime(plan *domain.SchedulePlan) error { return nil } +// 根据班次的 ID 获取模板中对应的班次 +func GetShiftByID(template *domain.ScheduleTemplate, shiftID int64) (*domain.ScheduleTemplateShift, error) { + var templateShift *domain.ScheduleTemplateShift = nil + + for _, shift := range template.Shifts { + if shift.ID == shiftID { + templateShift = &shift + break + } + } + + if templateShift == nil { + return nil, fmt.Errorf("班次 %d 不存在于该排班模版中", shiftID) + } + + return templateShift, nil +} + +func WeekDay(i int32) string { + switch i { + case 1: + return "周一" + case 2: + return "周二" + case 3: + return "周三" + case 4: + return "周四" + case 5: + return "周五" + case 6: + return "周六" + case 7: + return "周日" + default: + return "[未知]" + } +} + func ValidateSubmissionWithTemplate(submission *domain.AvailabilitySubmission, template *domain.ScheduleTemplate) error { if len(template.Shifts) != len(submission.Items) { return errors.New("提交的空闲时间中的班次数量和模板中的班次数量不匹配") } for i, item := range submission.Items { - isValid := false - - for _, shift := range template.Shifts { - if shift.ID == item.ShiftID { - containAllDays := true - - for _, day := range item.Days { - if !slices.Contains(shift.ApplicableDays, day) { - containAllDays = false - break - } - } - - if containAllDays { - isValid = true - break - } - } + shift, err := GetShiftByID(template, item.ShiftID) + if err != nil { + return fmt.Errorf("第 %d 项提交的班次 %d 不存在于该排班模版中", i, item.ShiftID) } - - if !isValid { - return fmt.Errorf("第 %d 项不符合模板中的班次", i+1) + for _, day := range item.Days { + if !slices.Contains(shift.ApplicableDays, day) { + return fmt.Errorf( + "第 %d 项提交的班次时间不存在, 对应模板中%s班次 %d (%s~%s) 无值班安排", + i+1, WeekDay(day), shift.ID, shift.StartTime, shift.EndTime, + ) + } } } @@ -98,17 +127,9 @@ func ValidateSchedulingResultWithTemplate(result *domain.SchedulingResult, templ } for _, resultShift := range result.Shifts { - // 找到模板中对应的班次 - var templateShift *domain.ScheduleTemplateShift = nil - - for _, shift := range template.Shifts { - if shift.ID == resultShift.ShiftID { - templateShift = &shift - } - } - - if templateShift == nil { - return fmt.Errorf("排班结果中的第 %d 项不存在于排班模板中", resultShift.ShiftID) + templateShift, err := GetShiftByID(template, resultShift.ShiftID) + if err != nil { + return err } for _, day := range templateShift.ApplicableDays { @@ -122,17 +143,26 @@ func ValidateSchedulingResultWithTemplate(result *domain.SchedulingResult, templ } if !containDay { - return fmt.Errorf("排班结果中的第 %d 项的班次存在没有提交结果的天数 %d", resultShift.ShiftID, day) + return fmt.Errorf( + "排班结果中%s班次 %d (%s~%s) 无人值班", + WeekDay(day), templateShift.ID, templateShift.StartTime, templateShift.EndTime, + ) } } for _, item := range resultShift.Items { if !slices.Contains(templateShift.ApplicableDays, item.Day) { - return fmt.Errorf("排班结果中的第 %d 项的第 %d 天不符合模板中的班次", resultShift.ShiftID, item.Day) + return fmt.Errorf( + "排班结果中%s班次 %d (%s~%s) 在排班模版中不需要安排值班", + WeekDay(item.Day), resultShift.ShiftID, templateShift.StartTime, templateShift.EndTime, + ) } // +1 是因为负责人也算一个助理 if len(item.AssistantIDs)+1 > int(templateShift.RequiredAssistantNumber) { - return fmt.Errorf("排班结果中的第 %d 项的第 %d 天的助理人数超过了模板中的要求", resultShift.ShiftID, item.Day) + return fmt.Errorf( + "排班结果中的%s班次 %d (%s~%s) 的的助理人数超过了模板中的要求", + WeekDay(item.Day), resultShift.ShiftID, templateShift.StartTime, templateShift.EndTime, + ) } } } @@ -149,14 +179,30 @@ func getSubmissionByAssistantID(submissions []*domain.AvailabilitySubmission, as return nil } -func ValidateSchedulingResultWithSubmissions(result *domain.SchedulingResult, submissions []*domain.AvailabilitySubmission) error { - for i, shift := range result.Shifts { +func ValidateSchedulingResultWithSubmissions( + result *domain.SchedulingResult, + submissions []*domain.AvailabilitySubmission, + template *domain.ScheduleTemplate, + repo *repository.Repository, +) error { + for _, shift := range result.Shifts { for _, item := range shift.Items { if item.PrincipalID != nil { // 找到这个负责人对应的提交 submission := getSubmissionByAssistantID(submissions, *item.PrincipalID) if submission == nil { - return fmt.Errorf("班次 %d 的第 %d 天的 id 为 %d 的负责人没有提交空闲时间", i+1, item.Day, item.PrincipalID) + templateShift, err := GetShiftByID(template, shift.ShiftID) + if err != nil { + return err + } + user, err := repo.GetUserByID(*item.PrincipalID) + if err != nil { + return err + } + return fmt.Errorf( + "负责人%s没有提交%s班次 %d (%s~%s) 的空闲时间", + user.FullName, WeekDay(item.Day), templateShift.ID, templateShift.StartTime, templateShift.EndTime, + ) } // 检查这个负责人是否在第 item.Day 天有空闲时间 @@ -168,14 +214,36 @@ func ValidateSchedulingResultWithSubmissions(result *domain.SchedulingResult, su } } if !ok { - return fmt.Errorf("id 为 %d 的负责人在班次 %d 的第 %d 天没有空闲时间", item.PrincipalID, shift.ShiftID, item.Day) + templateShift, err := GetShiftByID(template, shift.ShiftID) + if err != nil { + return err + } + user, err := repo.GetUserByID(*item.PrincipalID) + if err != nil { + return err + } + return fmt.Errorf( + "负责人%s在%s班次 %d (%s~%s) 没有空闲时间", + user.FullName, WeekDay(item.Day), templateShift.ID, templateShift.StartTime, templateShift.EndTime, + ) } } for _, assistantID := range item.AssistantIDs { // 找到这个助理对应的提交 submission := getSubmissionByAssistantID(submissions, assistantID) if submission == nil { - return fmt.Errorf("班次 %d 的第 %d 天的 id 为 %d 的助理没有提交空闲时间", i+1, item.Day, assistantID) + templateShift, err := GetShiftByID(template, shift.ShiftID) + if err != nil { + return err + } + user, err := repo.GetUserByID(assistantID) + if err != nil { + return err + } + return fmt.Errorf( + "助理%s没有提交%s班次 %d (%s~%s) 的空闲时间", + user.FullName, WeekDay(item.Day), templateShift.ID, templateShift.StartTime, templateShift.EndTime, + ) } // 检查这个助理是否在第 item.Day 天有空闲时间 @@ -187,7 +255,18 @@ func ValidateSchedulingResultWithSubmissions(result *domain.SchedulingResult, su } } if !ok { - return fmt.Errorf("id 为 %d 的助理在班次 %d 的第 %d 天没有空闲时间", assistantID, shift.ShiftID, item.Day) + templateShift, err := GetShiftByID(template, shift.ShiftID) + if err != nil { + return err + } + user, err := repo.GetUserByID(assistantID) + if err != nil { + return err + } + return fmt.Errorf( + "助理%s在%s班次 %d (%s~%s) 没有空闲时间", + user.FullName, WeekDay(item.Day), templateShift.ID, templateShift.StartTime, templateShift.EndTime, + ) } } } @@ -196,19 +275,45 @@ func ValidateSchedulingResultWithSubmissions(result *domain.SchedulingResult, su return nil } -func ValidIfExistsDuplicateAssistant(result *domain.SchedulingResult) error { +func ValidIfExistsDuplicateAssistant( + result *domain.SchedulingResult, + template *domain.ScheduleTemplate, + repo *repository.Repository, +) error { // 检查是否存在某个班次中的某一天有重复的助理 - for i, resultShift := range result.Shifts { + for _, resultShift := range result.Shifts { for _, resultShiftItem := range resultShift.Items { // 先检查负责人是不是存在于助理数组中 if resultShiftItem.PrincipalID != nil && slices.Contains(resultShiftItem.AssistantIDs, *resultShiftItem.PrincipalID) { - return fmt.Errorf("班次 %d 的第 %d 天中负责人和助理重复", i, resultShiftItem.Day) + templateShift, err := GetShiftByID(template, resultShift.ShiftID) + if err != nil { + return err + } + user, err := repo.GetUserByID(*resultShiftItem.PrincipalID) + if err != nil { + return err + } + return fmt.Errorf( + "%s班次 %d (%s~%s) 的负责人和助理重复(%s)", + WeekDay(resultShiftItem.Day), resultShift.ShiftID, templateShift.StartTime, templateShift.EndTime, user.FullName, + ) } // 检查助理之间是否有重复 seen := make(map[int64]bool) for _, assistantID := range resultShiftItem.AssistantIDs { if seen[assistantID] { - return fmt.Errorf("班次 %d 的第 %d 天中存在重复助理", i, resultShiftItem.Day) + templateShift, err := GetShiftByID(template, resultShift.ShiftID) + if err != nil { + return err + } + user, err := repo.GetUserByID(assistantID) + if err != nil { + return err + } + return fmt.Errorf( + "%s班次 %d (%s~%s) 的助理重复(%s)", + WeekDay(resultShiftItem.Day), resultShift.ShiftID, templateShift.StartTime, templateShift.EndTime, user.FullName, + ) } seen[assistantID] = true } diff --git a/frontend/index.html b/frontend/index.html index 8ac53d2..3dcca7b 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -2,7 +2,7 @@ - + ECNC 假勤系统 diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9128ae3ede89bfc46a744f3dc0adb70b5fafff59 GIT binary patch literal 270622 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 literal 0 HcmV?d00001 diff --git a/frontend/public/vite.svg b/frontend/public/vite.svg deleted file mode 100644 index e7b8dfb..0000000 --- a/frontend/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/assets/react.svg b/frontend/src/assets/react.svg deleted file mode 100644 index 6c87de9..0000000 --- a/frontend/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/src/components/ui/badge-removable.tsx b/frontend/src/components/ui/badge-removable.tsx new file mode 100644 index 0000000..0b73257 --- /dev/null +++ b/frontend/src/components/ui/badge-removable.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { type VariantProps } from "class-variance-authority" +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuItem, +} from "@/components/ui/dropdown-menu"; +import { cn } from "@/lib/utils" +import { badgeVariants } from "./badge"; + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps { + onRemove: () => void; + } + +function BadgeRemovable({ className, variant, onRemove, ...props }: BadgeProps) { + return ( + + +
+ + + + 删除 + + + + ) +} + +export { BadgeRemovable } diff --git a/frontend/src/feat/scheduling-area/scheduling-area-drag-overlay.tsx b/frontend/src/feat/scheduling-area/scheduling-area-drag-overlay.tsx index df77407..718b1cf 100644 --- a/frontend/src/feat/scheduling-area/scheduling-area-drag-overlay.tsx +++ b/frontend/src/feat/scheduling-area/scheduling-area-drag-overlay.tsx @@ -29,7 +29,7 @@ export default function SchedulingAreaDragOverlay() { return ( - + {roleIcons[activeUser.role]} {activeUser.fullName} ({assignedHours}) diff --git a/frontend/src/feat/scheduling-area/scheduling-area-table-row-cell-item.tsx b/frontend/src/feat/scheduling-area/scheduling-area-table-row-cell-item.tsx index c9a3cff..a6de8b5 100644 --- a/frontend/src/feat/scheduling-area/scheduling-area-table-row-cell-item.tsx +++ b/frontend/src/feat/scheduling-area/scheduling-area-table-row-cell-item.tsx @@ -1,4 +1,4 @@ -import { Badge } from "@/components/ui/badge"; +import { BadgeRemovable } from "@/components/ui/badge-removable"; import { getScheduleTemplateQueryOptions, getUsersQueryOptions, @@ -49,7 +49,7 @@ export default function SchedulingAreaTableRowCellItem({ const { data: scheduleTemplate } = useSuspenseQuery( getScheduleTemplateQueryOptions(schedulePlan.scheduleTemplateID) ); - const { schedulingSubmission } = useSchedulingSubmissionStore(); + const { schedulingSubmission, setSchedulingSubmission } = useSchedulingSubmissionStore(); const activeSubmission = active?.data?.current?.submission as | AvailabilitySubmission @@ -70,18 +70,37 @@ export default function SchedulingAreaTableRowCellItem({ ((activeUser && activeUser.role === "资深助理") || (activeUser && activeUser.role === "黑心")); + const onRemoveBadge = () => { + var submission = schedulingSubmission; + for (let i = 0; i < submission.length; i++) { + if (submission[i].shiftID === shiftID) { + for (let j = 0; j < submission[i].items.length; j++) { + if (submission[i].items[j].day === schedulingResultShiftItem.day) { + // 找到这一班次这一天后, 然后根据是负责人还是助理进行删除 + if (isPrincipal && schedulingResultShiftItem.principalID !== null) { + submission[i].items[j].principalID = null; + } else if (index !== undefined) { + submission[i].items[j].assistantIDs.splice(index, 1); + } + } + } + } + } + setSchedulingSubmission(submission); + } + return (
{isPrincipal ? ( schedulingResultShiftItem.principalID !== null ? ( - + { @@ -99,13 +118,13 @@ export default function SchedulingAreaTableRowCellItem({ )} ) - + ) : ( 缺少负责人 ) ) : index !== undefined && schedulingResultShiftItem.assistantIDs.at(index) !== undefined ? ( - + { @@ -124,7 +143,7 @@ export default function SchedulingAreaTableRowCellItem({ )} ) - + ) : ( 缺少助理 )} diff --git a/frontend/src/feat/scheduling-area/scheduling-area-table-row.tsx b/frontend/src/feat/scheduling-area/scheduling-area-table-row.tsx index 3be3e0e..41272f3 100644 --- a/frontend/src/feat/scheduling-area/scheduling-area-table-row.tsx +++ b/frontend/src/feat/scheduling-area/scheduling-area-table-row.tsx @@ -20,8 +20,10 @@ export default function SchedulingAreaTableRow({ return (
{/* 班次情况 */} -
- {templateShift.startTime}~{templateShift.endTime} +
+
{templateShift.startTime}
+
~
+
{templateShift.endTime}
{/* 每天的排班情况 */} diff --git a/frontend/src/feat/scheduling-area/scheduling-area-table.tsx b/frontend/src/feat/scheduling-area/scheduling-area-table.tsx index 8ce0089..4fa8f44 100644 --- a/frontend/src/feat/scheduling-area/scheduling-area-table.tsx +++ b/frontend/src/feat/scheduling-area/scheduling-area-table.tsx @@ -50,14 +50,14 @@ export default function SchedulingAreaTable({ return (
{/* 展示星期 */} -
+
{[{ key: 0, label: "班次" }, ...DayOfWeek].map((day) => ( -
+
{day.label}
))} @@ -70,15 +70,11 @@ export default function SchedulingAreaTable({ (shift) => shift.shiftID === scheduleTemplateShift.id ); - if (resultShift === undefined) { - return null; - } - return ( ); diff --git a/frontend/src/feat/scheduling-area/scheduling-area-users.tsx b/frontend/src/feat/scheduling-area/scheduling-area-users.tsx index 0520468..881c824 100644 --- a/frontend/src/feat/scheduling-area/scheduling-area-users.tsx +++ b/frontend/src/feat/scheduling-area/scheduling-area-users.tsx @@ -70,7 +70,7 @@ export default function SchedulingAreaUsers({ return (
{/* 排班基本情况 */}
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 7e138c4..79ffb1b 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -6,6 +6,7 @@ import viteReact from "@vitejs/plugin-react"; // https://vite.dev/config/ export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd()); + const API_URL = env.VITE_API_URL || "http://localhost:3000"; return { plugins: [TanStackRouterVite(), viteReact()], @@ -17,7 +18,7 @@ export default defineConfig(({ mode }) => { server: { proxy: { "/api": { - target: env.VITE_API_URL, + target: API_URL, changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, ""), },