mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-17 06:00:25 +08:00
[账单]显示账单、手动生成账单
This commit is contained in:
@@ -10,13 +10,14 @@ import (
|
|||||||
type AdminModuleCode = string
|
type AdminModuleCode = string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
AdminModuleCodeServer AdminModuleCode = "server"
|
AdminModuleCodeServer AdminModuleCode = "server" // 网站
|
||||||
AdminModuleCodeNode AdminModuleCode = "node"
|
AdminModuleCodeNode AdminModuleCode = "node" // 节点
|
||||||
AdminModuleCodeDNS AdminModuleCode = "dns"
|
AdminModuleCodeDNS AdminModuleCode = "dns" // DNS
|
||||||
AdminModuleCodeAdmin AdminModuleCode = "admin" // 系统用户
|
AdminModuleCodeAdmin AdminModuleCode = "admin" // 系统用户
|
||||||
AdminModuleCodeUser AdminModuleCode = "user" // 平台用户
|
AdminModuleCodeUser AdminModuleCode = "user" // 平台用户
|
||||||
AdminModuleCodeLog AdminModuleCode = "log"
|
AdminModuleCodeFinance AdminModuleCode = "finance" // 财务
|
||||||
AdminModuleCodeSetting AdminModuleCode = "setting"
|
AdminModuleCodeLog AdminModuleCode = "log" // 日志
|
||||||
|
AdminModuleCodeSetting AdminModuleCode = "setting" // 设置
|
||||||
AdminModuleCodeCommon AdminModuleCode = "common" // 只要登录就可以访问的模块
|
AdminModuleCodeCommon AdminModuleCode = "common" // 只要登录就可以访问的模块
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -116,7 +117,6 @@ func FindFirstAdminModule(adminId int64) (module AdminModuleCode, ok bool) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 查找某个管理员名称
|
// 查找某个管理员名称
|
||||||
func FindAdminFullname(adminId int64) string {
|
func FindAdminFullname(adminId int64) string {
|
||||||
locker.Lock()
|
locker.Lock()
|
||||||
@@ -157,6 +157,11 @@ func AllModuleMaps() []maps.Map {
|
|||||||
"code": AdminModuleCodeAdmin,
|
"code": AdminModuleCodeAdmin,
|
||||||
"url": "/admins",
|
"url": "/admins",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "财务管理",
|
||||||
|
"code": AdminModuleCodeFinance,
|
||||||
|
"url": "/finance",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "日志审计",
|
"name": "日志审计",
|
||||||
"code": AdminModuleCodeLog,
|
"code": AdminModuleCodeLog,
|
||||||
|
|||||||
@@ -236,6 +236,10 @@ func (this *RPCClient) UserRPC() pb.UserServiceClient {
|
|||||||
return pb.NewUserServiceClient(this.pickConn())
|
return pb.NewUserServiceClient(this.pickConn())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (this *RPCClient) UserBillRPC() pb.UserBillServiceClient {
|
||||||
|
return pb.NewUserBillServiceClient(this.pickConn())
|
||||||
|
}
|
||||||
|
|
||||||
// 构造Admin上下文
|
// 构造Admin上下文
|
||||||
func (this *RPCClient) Context(adminId int64) context.Context {
|
func (this *RPCClient) Context(adminId int64) context.Context {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|||||||
38
internal/web/actions/default/finance/bills/generate.go
Normal file
38
internal/web/actions/default/finance/bills/generate.go
Normal 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()
|
||||||
|
}
|
||||||
65
internal/web/actions/default/finance/bills/index.go
Normal file
65
internal/web/actions/default/finance/bills/index.go
Normal 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()
|
||||||
|
}
|
||||||
22
internal/web/actions/default/finance/bills/init.go
Normal file
22
internal/web/actions/default/finance/bills/init.go
Normal 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()
|
||||||
|
})
|
||||||
|
}
|
||||||
18
internal/web/actions/default/finance/index.go
Normal file
18
internal/web/actions/default/finance/index.go
Normal 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()
|
||||||
|
}
|
||||||
20
internal/web/actions/default/finance/init.go
Normal file
20
internal/web/actions/default/finance/init.go
Normal 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()
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -203,6 +203,12 @@ func (this *userMustAuth) modules(adminId int64) []maps.Map {
|
|||||||
"name": "平台用户",
|
"name": "平台用户",
|
||||||
"icon": "users",
|
"icon": "users",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"code": "finance",
|
||||||
|
"module": configloaders.AdminModuleCodeFinance,
|
||||||
|
"name": "财务管理",
|
||||||
|
"icon": "yen sign",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"code": "admins",
|
"code": "admins",
|
||||||
"module": configloaders.AdminModuleCodeAdmin,
|
"module": configloaders.AdminModuleCodeAdmin,
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ import (
|
|||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dashboard"
|
_ "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/db"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/dns"
|
_ "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/index"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/log"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/log"
|
||||||
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/logout"
|
_ "github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/logout"
|
||||||
|
|||||||
4
web/views/@default/finance/bills/@menu.html
Normal file
4
web/views/@default/finance/bills/@menu.html
Normal 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>
|
||||||
8
web/views/@default/finance/bills/generate.html
Normal file
8
web/views/@default/finance/bills/generate.html
Normal 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>
|
||||||
16
web/views/@default/finance/bills/generate.js
Normal file
16
web/views/@default/finance/bills/generate.js
Normal 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"
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
30
web/views/@default/finance/bills/index.html
Normal file
30
web/views/@default/finance/bills/index.html
Normal 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>
|
||||||
Reference in New Issue
Block a user