2025-04-01 14:13:41 +08:00

370 lines
8.6 KiB
Go

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",
// },
// },
// },
// },
// }
}