diff --git a/internal/rpc/rpc_client.go b/internal/rpc/rpc_client.go index b39278b1..ecf8e7f7 100644 --- a/internal/rpc/rpc_client.go +++ b/internal/rpc/rpc_client.go @@ -386,6 +386,10 @@ func (this *RPCClient) UserBillRPC() pb.UserBillServiceClient { return pb.NewUserBillServiceClient(this.pickConn()) } +func (this *RPCClient) ServerBillRPC() pb.ServerBillServiceClient { + return pb.NewServerBillServiceClient(this.pickConn()) +} + func (this *RPCClient) UserAccountRPC() pb.UserAccountServiceClient { return pb.NewUserAccountServiceClient(this.pickConn()) } diff --git a/web/public/js/components/plans/plan-bandwidth-ranges.js b/web/public/js/components/plans/plan-bandwidth-ranges.js new file mode 100644 index 00000000..7d373136 --- /dev/null +++ b/web/public/js/components/plans/plan-bandwidth-ranges.js @@ -0,0 +1,139 @@ +Vue.component("plan-bandwidth-ranges", { + props: ["v-ranges"], + data: function () { + let ranges = this.vRanges + if (ranges == null) { + ranges = [] + } + return { + ranges: ranges, + isAdding: false, + + minMB: "", + maxMB: "", + pricePerMB: "", + addingRange: { + minMB: 0, + maxMB: 0, + pricePerMB: 0, + totalPrice: 0 + } + } + }, + methods: { + add: function () { + this.isAdding = !this.isAdding + let that = this + setTimeout(function () { + that.$refs.minMB.focus() + }) + }, + cancelAdding: function () { + this.isAdding = false + }, + confirm: function () { + this.isAdding = false + this.minMB = "" + this.maxMB = "" + this.pricePerMB = "" + this.ranges.push(this.addingRange) + this.ranges.$sort(function (v1, v2) { + if (v1.minMB < v2.minMB) { + return -1 + } + if (v1.minMB == v2.minMB) { + return 0 + } + return 1 + }) + this.change() + this.addingRange = { + minMB: 0, + maxMB: 0, + pricePerMB: 0, + totalPrice: 0 + } + }, + remove: function (index) { + this.ranges.$remove(index) + this.change() + }, + change: function () { + this.$emit("change", this.ranges) + } + }, + watch: { + minMB: function (v) { + let minMB = parseInt(v.toString()) + if (isNaN(minMB) || minMB < 0) { + minMB = 0 + } + this.addingRange.minMB = minMB + }, + maxMB: function (v) { + let maxMB = parseInt(v.toString()) + if (isNaN(maxMB) || maxMB < 0) { + maxMB = 0 + } + this.addingRange.maxMB = maxMB + }, + pricePerMB: function (v) { + let pricePerMB = parseFloat(v.toString()) + if (isNaN(pricePerMB) || pricePerMB < 0) { + pricePerMB = 0 + } + this.addingRange.pricePerMB = pricePerMB + } + }, + template: `
+ +
+
+ {{range.minMB}}MB - {{range.maxMB}}MB   价格:{{range.pricePerMB}}元/MB +   +
+
+
+ + +
+ + + + + + + + + + + + + +
带宽下限 +
+ + MB +
+
带宽上限 +
+ + MB +
+

如果填0,表示上不封顶。

+
单位价格 +
+ + 元/MB +
+
+   + +
+ + +
+ +
+
` +}) \ No newline at end of file diff --git a/web/public/js/components/plans/plan-price-config-box.js b/web/public/js/components/plans/plan-price-config-box.js index 8b5a87bc..f56bb39b 100644 --- a/web/public/js/components/plans/plan-price-config-box.js +++ b/web/public/js/components/plans/plan-price-config-box.js @@ -1,12 +1,13 @@ // 套餐价格配置 Vue.component("plan-price-config-box", { - props: ["v-price-type", "v-monthly-price", "v-seasonally-price", "v-yearly-price", "v-traffic-price"], + props: ["v-price-type", "v-monthly-price", "v-seasonally-price", "v-yearly-price", "v-traffic-price", "v-bandwidth-price"], data: function () { let priceType = this.vPriceType if (priceType == null) { priceType = "period" } + // 按时间周期计费 let monthlyPriceNumber = 0 let monthlyPrice = this.vMonthlyPrice if (monthlyPrice == null || monthlyPrice <= 0) { @@ -43,6 +44,7 @@ Vue.component("plan-price-config-box", { } } + // 按流量计费 let trafficPrice = this.vTrafficPrice let trafficPriceBaseNumber = 0 if (trafficPrice != null) { @@ -57,6 +59,17 @@ Vue.component("plan-price-config-box", { trafficPriceBase = trafficPriceBaseNumber.toString() } + // 按带宽计费 + let bandwidthPrice = this.vBandwidthPrice + if (bandwidthPrice == null) { + bandwidthPrice = { + percentile: 95, + ranges: [] + } + } else if (bandwidthPrice.ranges == null) { + bandwidthPrice.ranges = [] + } + return { priceType: priceType, monthlyPrice: monthlyPrice, @@ -68,7 +81,15 @@ Vue.component("plan-price-config-box", { yearlyPriceNumber: yearlyPriceNumber, trafficPriceBase: trafficPriceBase, - trafficPrice: trafficPrice + trafficPrice: trafficPrice, + + bandwidthPrice: bandwidthPrice, + bandwidthPercentile: bandwidthPrice.percentile + } + }, + methods: { + changeBandwidthPriceRanges: function (ranges) { + this.bandwidthPrice.ranges = ranges } }, watch: { @@ -99,6 +120,15 @@ Vue.component("plan-price-config-box", { price = 0 } this.trafficPrice.base = price + }, + bandwidthPercentile: function (v) { + let percentile = parseInt(v) + if (isNaN(percentile) || percentile <= 0) { + percentile = 95 + } else if (percentile > 100) { + percentile = 100 + } + this.bandwidthPrice.percentile = percentile } }, template: `
@@ -107,10 +137,12 @@ Vue.component("plan-price-config-box", { +
 按时间周期     -  按流量 +  按流量     +  按带宽
@@ -152,7 +184,7 @@ Vue.component("plan-price-config-box", {
- +
基础流量费用基础流量费用 *
@@ -162,5 +194,27 @@ Vue.component("plan-price-config-box", {
+ + +
+
+ + + + + + + + + +
带宽百分位 * +
+ + th +
+
带宽价格 + +
+
` }) \ No newline at end of file diff --git a/web/public/js/components/plans/plan-price-view.js b/web/public/js/components/plans/plan-price-view.js index 58a8913b..fbc2c2b1 100644 --- a/web/public/js/components/plans/plan-price-view.js +++ b/web/public/js/components/plans/plan-price-view.js @@ -7,12 +7,28 @@ Vue.component("plan-price-view", { }, template: `
- 月度:¥{{plan.monthlyPrice}}元
- 季度:¥{{plan.seasonallyPrice}}元
- 年度:¥{{plan.yearlyPrice}}元 + 按时间周期计费 +
+ + 月度:¥{{plan.monthlyPrice}}元
+ 季度:¥{{plan.seasonallyPrice}}元
+ 年度:¥{{plan.yearlyPrice}}元 +
+
- 基础价格:¥{{plan.trafficPrice.base}}元/GB + 按流量计费 +
+ 基础价格:¥{{plan.trafficPrice.base}}元/GB +
+
+ 按{{plan.bandwidthPrice.percentile}}th带宽计费 +
+
+ {{range.minMB}} - {{range.maxMB}}MB: {{range.pricePerMB}}元/MB +
+
+
` }) \ No newline at end of file