[账单]显示账单、手动生成账单

This commit is contained in:
GoEdgeLab
2020-12-11 21:39:24 +08:00
parent ff6f15cc06
commit 60c160e4c5
13 changed files with 247 additions and 9 deletions

View File

@@ -10,14 +10,15 @@ import (
type AdminModuleCode = string
const (
AdminModuleCodeServer AdminModuleCode = "server"
AdminModuleCodeNode AdminModuleCode = "node"
AdminModuleCodeDNS AdminModuleCode = "dns"
AdminModuleCodeAdmin AdminModuleCode = "admin" // 系统用户
AdminModuleCodeUser AdminModuleCode = "user" // 平台用户
AdminModuleCodeLog AdminModuleCode = "log"
AdminModuleCodeSetting AdminModuleCode = "setting"
AdminModuleCodeCommon AdminModuleCode = "common" // 只要登录就可以访问的模块
AdminModuleCodeServer AdminModuleCode = "server" // 网站
AdminModuleCodeNode AdminModuleCode = "node" // 节点
AdminModuleCodeDNS AdminModuleCode = "dns" // DNS
AdminModuleCodeAdmin AdminModuleCode = "admin" // 系统用户
AdminModuleCodeUser AdminModuleCode = "user" // 平台用户
AdminModuleCodeFinance AdminModuleCode = "finance" // 财务
AdminModuleCodeLog AdminModuleCode = "log" // 日志
AdminModuleCodeSetting AdminModuleCode = "setting" // 设置
AdminModuleCodeCommon AdminModuleCode = "common" // 只要登录就可以访问的模块
)
var sharedAdminModuleMapping = map[int64]*AdminModuleList{} // adminId => AdminModuleList
@@ -116,7 +117,6 @@ func FindFirstAdminModule(adminId int64) (module AdminModuleCode, ok bool) {
return
}
// 查找某个管理员名称
func FindAdminFullname(adminId int64) string {
locker.Lock()
@@ -157,6 +157,11 @@ func AllModuleMaps() []maps.Map {
"code": AdminModuleCodeAdmin,
"url": "/admins",
},
{
"name": "财务管理",
"code": AdminModuleCodeFinance,
"url": "/finance",
},
{
"name": "日志审计",
"code": AdminModuleCodeLog,

View File

@@ -236,6 +236,10 @@ func (this *RPCClient) UserRPC() pb.UserServiceClient {
return pb.NewUserServiceClient(this.pickConn())
}
func (this *RPCClient) UserBillRPC() pb.UserBillServiceClient {
return pb.NewUserBillServiceClient(this.pickConn())
}
// 构造Admin上下文
func (this *RPCClient) Context(adminId int64) context.Context {
ctx := context.Background()

View File

@@ -0,0 +1,38 @@
package bills
import (
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/actions"
timeutil "github.com/iwind/TeaGo/utils/time"
"time"
)
type GenerateAction struct {
actionutils.ParentAction
}
func (this *GenerateAction) Init() {
this.Nav("", "", "generate")
}
func (this *GenerateAction) RunGet(params struct{}) {
this.Data["month"] = timeutil.Format("Ym", time.Now().AddDate(0, -1, 0))
this.Show()
}
func (this *GenerateAction) RunPost(params struct {
Month string
Must *actions.Must
}) {
defer this.CreateLogInfo("手动生成上个月(" + params.Month + ")账单")
_, err := this.RPC().UserBillRPC().GenerateAllUserBills(this.AdminContext(), &pb.GenerateAllUserBillsRequest{Month: params.Month})
if err != nil {
this.ErrorPage(err)
return
}
this.Success()
}

View File

@@ -0,0 +1,65 @@
package bills
import (
"fmt"
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
"github.com/iwind/TeaGo/maps"
)
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "", "index")
}
func (this *IndexAction) RunGet(params struct {
PaidFlag int32 `default:"-1"`
UserId int64
Month string
}) {
countResp, err := this.RPC().UserBillRPC().CountAllUserBills(this.AdminContext(), &pb.CountAllUserBillsRequest{})
if err != nil {
this.ErrorPage(err)
return
}
page := this.NewPage(countResp.Count)
this.Data["page"] = page.AsHTML()
billsResp, err := this.RPC().UserBillRPC().ListUserBills(this.AdminContext(), &pb.ListUserBillsRequest{
PaidFlag: params.PaidFlag,
UserId: params.UserId,
Month: params.Month,
Offset: page.Offset,
Size: page.Size,
})
if err != nil {
this.ErrorPage(err)
return
}
billMaps := []maps.Map{}
for _, bill := range billsResp.UserBills {
var userMap maps.Map = nil
if bill.User != nil {
userMap = maps.Map{
"id": bill.User.Id,
"fullname": bill.User.Fullname,
}
}
billMaps = append(billMaps, maps.Map{
"id": bill.Id,
"isPaid": bill.IsPaid,
"month": bill.Month,
"amount": fmt.Sprintf("%.2f", bill.Amount),
"typeName": bill.TypeName,
"user": userMap,
"description": bill.Description,
})
}
this.Data["bills"] = billMaps
this.Show()
}

View File

@@ -0,0 +1,22 @@
package bills
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeFinance)).
Data("teaMenu", "finance").
// 财务管理
Prefix("/finance/bills").
Get("", new(IndexAction)).
GetPost("/generate", new(GenerateAction)).
EndAll()
})
}

View File

@@ -0,0 +1,18 @@
package finance
import "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
type IndexAction struct {
actionutils.ParentAction
}
func (this *IndexAction) Init() {
this.Nav("", "", "")
}
func (this *IndexAction) RunGet(params struct{}) {
// TODO 暂时先跳转到账单页将来做成Dashboard
this.RedirectURL("/finance/bills")
this.Show()
}

View File

@@ -0,0 +1,20 @@
package finance
import (
"github.com/TeaOSLab/EdgeAdmin/internal/configloaders"
"github.com/TeaOSLab/EdgeAdmin/internal/web/helpers"
"github.com/iwind/TeaGo"
)
func init() {
TeaGo.BeforeStart(func(server *TeaGo.Server) {
server.
Helper(helpers.NewUserMustAuth(configloaders.AdminModuleCodeFinance)).
// 财务管理
Prefix("/finance").
Get("", new(IndexAction)).
EndAll()
})
}

View File

@@ -203,6 +203,12 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
"name": "平台用户",
"icon": "users",
},
{
"code": "finance",
"module": configloaders.AdminModuleCodeFinance,
"name": "财务管理",
"icon": "yen sign",
},
{
"code": "admins",
"module": configloaders.AdminModuleCodeAdmin,

View File

@@ -16,6 +16,8 @@ import (
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dashboard"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/db"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dns"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/finance"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/finance/bills"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/index"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/log"
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/logout"

View File

@@ -0,0 +1,4 @@
<first-menu>
<menu-item href="/finance/bills" code="index">账单</menu-item>
<menu-item href="/finance/bills/generate" code="generate">生成账单</menu-item>
</first-menu>

View File

@@ -0,0 +1,8 @@
{$layout}
{$template "menu"}
<div class="margin"></div>
<div>
<button type="button" class="ui primary button" @click.prevent="generateBills()">生成上个月({{month}})账单</button>
<p class="comment">多次点击不会重复生成同样的账单。</p>
</div>

View File

@@ -0,0 +1,16 @@
Tea.context(function () {
this.generateBills = function () {
let that = this
teaweb.confirm("确定要生成上个月的账单吗?", function () {
that.$post(".generate")
.params({
month: that.month
})
.success(function () {
teaweb.success("生成成功", function () {
window.location = "/finance/bills"
})
})
})
}
})

View File

@@ -0,0 +1,30 @@
{$layout}
{$template "menu"}
<p class="comment" v-if="bills.length == 0">暂时还没有账单。</p>
<table class="ui table selectable" v-if="bills.length > 0">
<thead>
<tr>
<th class="width10">用户</th>
<th class="width10">月份</th>
<th class="width10">项目</th>
<th class="width10">金额</th>
<th>描述</th>
<th class="width10">已支付</th>
</tr>
</thead>
<tr v-for="bill in bills">
<td>{{bill.user.fullname}}</td>
<td>{{bill.month}}</td>
<td>{{bill.typeName}}</td>
<td>¥{{bill.amount}}元</td>
<td>{{bill.description}}</td>
<td>
<span class="green" v-if="bill.isPaid">Y</span>
<span v-else class="disabled">N</span>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>