package project import ( "context" "fmt" "net/http" "management/internal/db/model/view" "management/internal/pkg/convertor" "management/internal/pkg/tpl" ) func (h *projectHandler) Dashboard(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: pp, _ := h.biz.ProjectV1().ListHtml(r.Context()) h.render.HTML(w, r, "project/dashboard.tmpl", map[string]any{ "Projects": pp, }) case http.MethodPost: ctx := r.Context() t := r.PostFormValue("type") if t == "project" { var projectIncome float64 var projectExpense float64 projectID := convertor.ConvertInt[int64](r.PostFormValue("projectID"), 0) if projectID == 0 { si, _ := h.biz.IncomeV1().Sum(ctx) projectIncome = convertor.NumericToFloat64(si) se, _ := h.biz.ExpenseV1().Sum(ctx) projectExpense = convertor.NumericToFloat64(se) } else { pi, _ := h.biz.IncomeV1().SumByProjectID(ctx, projectID) projectIncome = convertor.NumericToFloat64(pi) pe, _ := h.biz.ExpenseV1().SumByProjectID(ctx, projectID) projectExpense = convertor.NumericToFloat64(pe) } projectProfit := projectIncome - projectExpense var projectProfitRate float64 = 0 if projectExpense > 0 { projectProfitRate = projectProfit / projectExpense } res := &view.DashboardProject{ ProjectIncome: projectIncome, ProjectExpense: projectExpense, ProjectProfit: projectProfit, ProjectProfitRate: fmt.Sprintf("%0.2f%%", projectProfitRate*100), IncomeExpenseEcharts: h.incomeExpenseEcharts(ctx, projectID), IncomeEcharts: h.incomeEcharts(ctx, projectID), ExpenseEcharts: h.expenseEcharts(ctx, projectID), } h.render.JSON(w, tpl.Response{Success: true, Message: "ok", Data: res}) return } else if t == "budget" { } h.render.JSONERR(w, "failed to valid type") default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } func (h *projectHandler) incomeExpenseEcharts(ctx context.Context, projectId int64) view.EchartsOption { var name []string var income []float64 var expense []float64 if projectId == 0 { rows, err := h.biz.ProjectV1().Statistics(ctx) if err != nil || len(rows) == 0 { return view.EchartsOption{} } for _, row := range rows { name = append(name, row.Name) income = append(income, convertor.NumericToFloat64(row.Income)) expense = append(expense, convertor.NumericToFloat64(row.Expense)) } } else { row, err := h.biz.ProjectV1().StatisticsItem(ctx, projectId) if err != nil || row == nil { return view.EchartsOption{} } name = append(name, row.Name) income = append(income, convertor.NumericToFloat64(row.Income)) expense = append(expense, convertor.NumericToFloat64(row.Expense)) } return view.EchartsOption{ Title: view.Title{ Text: "项目收支情况", Left: "center", Top: 2, FontSize: 15, TextStyle: view.TextStyle{ Color: "#666666", FontWeight: "normal", }, }, Color: []string{"#fed46b", "#2194ff"}, ToolTip: view.ToolTip{ Trigger: "axis", AxisPointer: view.AxisPointer{ Type: "shadow", }, }, Grid: view.Grid{ Left: "3%", Right: "4%", Bottom: "10%", ContainLabel: true, }, Legend: view.Legend{ Left: "center", Top: "bottom", Data: []string{"支出金额", "收入金额"}, }, XAxis: []view.XAxis{ { Type: "category", Data: name, AxisTick: view.AxisTick{ AlignWithLabel: true, }, }, }, YAxis: []view.YAxis{ { Type: "value", Name: "单位:元", }, }, BarMaxWidth: "30", Label: view.Label{ Show: true, Position: "top", }, Series: []view.Series{ { Name: "支出金额", Type: "bar", Data: expense, ItemStyle: view.ItemStyle{ Normal: view.Normal{ Color: "#f89588", }, }, }, { Name: "收入金额", Type: "bar", Data: income, ItemStyle: view.ItemStyle{ Normal: view.Normal{ Color: "#76da91", }, }, }, }, } } func (h *projectHandler) incomeEcharts(ctx context.Context, projectId int64) view.EchartsOption { var name []string data := []view.DataItem{} if projectId == 0 { rows, err := h.biz.IncomeV1().Statistics(ctx) if err != nil || len(rows) == 0 { return view.EchartsOption{} } for _, row := range rows { name = append(name, row.IncomeTypeName) data = append(data, view.DataItem{ Name: row.IncomeTypeName, Value: convertor.NumericToFloat64(row.TotalAmount), }) } } else { rows, err := h.biz.IncomeV1().StatisticsByProjectID(ctx, projectId) if err != nil || len(rows) == 0 { return view.EchartsOption{} } for _, row := range rows { name = append(name, row.IncomeTypeName) data = append(data, view.DataItem{ Name: row.IncomeTypeName, Value: convertor.NumericToFloat64(row.TotalAmount), }) } } return view.EchartsOption{ Title: view.Title{ Text: "收入分布", Left: "center", Orient: "vertical", FontSize: 15, TextStyle: view.TextStyle{ Color: "#666666", FontWeight: "normal", }, }, ToolTip: view.ToolTip{ Trigger: "item", }, Legend: view.Legend{ Left: "center", Top: "bottom", Data: name, }, Color: []string{"#63b2ee", "#76da91", "#f8cb7f", "#f89588", "#7cd6cf", "#9192ab", "#7898e1", "#efa666", "#eddd86", "#9987ce", "#63b2ee", "#76da91"}, Series: []view.Series{ { Type: "pie", Radius: "50%", Data: data, Label: view.Label{ Show: true, TextStyle: view.TextStyle{ Color: "#666666", }, Normal: view.LableNormal{ Formatter: "{c} ({d}%)", TextStyle: view.TextStyle{ Color: "#666666", FontWeight: "normal", }, }, }, }, }, } } func (h *projectHandler) expenseEcharts(ctx context.Context, projectId int64) view.EchartsOption { var name []string data := []view.DataItem{} if projectId == 0 { rows, err := h.biz.ExpenseV1().Statistics(ctx) if err != nil || len(rows) == 0 { return view.EchartsOption{} } for _, row := range rows { name = append(name, row.ExpensesTypeName) data = append(data, view.DataItem{ Name: row.ExpensesTypeName, Value: convertor.NumericToFloat64(row.TotalAmount), }) } } else { rows, err := h.biz.ExpenseV1().StatisticsByProjectID(ctx, projectId) if err != nil || len(rows) == 0 { return view.EchartsOption{} } for _, row := range rows { name = append(name, row.ExpensesTypeName) data = append(data, view.DataItem{ Name: row.ExpensesTypeName, Value: convertor.NumericToFloat64(row.TotalAmount), }) } } return view.EchartsOption{ Title: view.Title{ Text: "支出分布", Left: "center", Orient: "vertical", FontSize: 15, TextStyle: view.TextStyle{ Color: "#666666", FontWeight: "normal", }, }, ToolTip: view.ToolTip{ Trigger: "item", }, Legend: view.Legend{ Left: "center", Top: "bottom", Data: name, }, Color: []string{"#63b2ee", "#76da91", "#f8cb7f", "#f89588", "#7cd6cf", "#9192ab", "#7898e1", "#efa666", "#eddd86", "#9987ce", "#63b2ee", "#76da91"}, Series: []view.Series{ { Type: "pie", Radius: "50%", Data: data, Label: view.Label{ Show: true, TextStyle: view.TextStyle{ Color: "#666666", }, Normal: view.LableNormal{ Formatter: "{c} ({d}%)", TextStyle: view.TextStyle{ Color: "#666666", FontWeight: "normal", }, }, }, }, }, } // return view.EchartsOption{ // Title: view.Title{ // Text: "支出分布", // Left: "center", // Top: 2, // FontSize: 15, // TextStyle: view.TextStyle{ // Color: "#666666", // FontWeight: "normal", // }, // }, // Color: []string{"#fed46b", "#2194ff"}, // ToolTip: view.ToolTip{ // Trigger: "axis", // AxisPointer: view.AxisPointer{ // Type: "shadow", // }, // }, // Grid: view.Grid{ // Left: "3%", // Right: "4%", // Bottom: "10%", // ContainLabel: true, // }, // XAxis: []view.XAxis{ // { // Type: "category", // Data: name, // AxisTick: view.AxisTick{ // AlignWithLabel: true, // }, // }, // }, // YAxis: []view.YAxis{ // { // Type: "value", // Name: "单位:元", // }, // }, // BarMaxWidth: "30", // Label: view.Label{ // Show: true, // Position: "top", // }, // Series: []view.Series{ // { // Type: "bar", // Data: expense, // ItemStyle: view.ItemStyle{ // Normal: view.Normal{ // Color: "#f89588", // }, // }, // }, // }, // } }