流量池修改
This commit is contained in:
parent
368d0d2567
commit
1f4841bf4c
@ -251,7 +251,7 @@ class FlowPoolController extends Controller
|
|||||||
|
|
||||||
$setting['cards'] = $chunk;
|
$setting['cards'] = $chunk;
|
||||||
|
|
||||||
$news = $cards[$package_id] ?? 0 - array_sum(array_pluck($setting['cards'], 'counts'));
|
$news = ($cards[$package_id] ?? 0) - array_sum(array_pluck($setting['cards'], 'counts'));
|
||||||
|
|
||||||
$setting['news'] = $news < 0 ? 0 : $news;
|
$setting['news'] = $news < 0 ? 0 : $news;
|
||||||
|
|
||||||
|
@ -151,9 +151,7 @@ class PropertyService extends Service
|
|||||||
|
|
||||||
PropertySetting::upsert($data, 'name');
|
PropertySetting::upsert($data, 'name');
|
||||||
|
|
||||||
$this->propertySettingRepository->forgetCached();
|
$settings = $this->propertySettingRepository->getAll(true);
|
||||||
|
|
||||||
$settings = $this->propertySettingRepository->getAll();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ class CreateFlowPoolTables extends Migration
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DB::unprepared(File::get(__DIR__ . '/create_flow_pool_settings_view.pgsql'));
|
DB::unprepared(File::get(__DIR__ . '/create_flow_pool_func.pgsql'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
58
database/migrations/create_flow_pool_func.pgsql
Normal file
58
database/migrations/create_flow_pool_func.pgsql
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
CREATE OR REPLACE FUNCTION GET_FLOW_POOL_MONTH_STAT(INT)
|
||||||
|
RETURNS TABLE
|
||||||
|
(
|
||||||
|
pool_id INT,
|
||||||
|
members NUMERIC,
|
||||||
|
minimum_flows NUMERIC,
|
||||||
|
minimum_price NUMERIC,
|
||||||
|
excess_flows NUMERIC,
|
||||||
|
excess_price NUMERIC
|
||||||
|
)
|
||||||
|
AS
|
||||||
|
$$
|
||||||
|
DECLARE
|
||||||
|
query TEXT;
|
||||||
|
BEGIN
|
||||||
|
query := 'WITH settings AS (
|
||||||
|
SELECT pool_id,
|
||||||
|
json_array_elements(minimum_settings::json) ->> ''package_id'' AS package_id,
|
||||||
|
json_array_elements(minimum_settings::json) ->> ''flows'' AS flows,
|
||||||
|
json_array_elements(minimum_settings::json) ->> ''price'' AS price,
|
||||||
|
gradient * pow(1024, gradient_unit) as gradient,
|
||||||
|
gradient_price / pow(1024, gradient_unit) as gradient_price,
|
||||||
|
start_at,
|
||||||
|
end_at
|
||||||
|
FROM virtual_flow_pool_settings
|
||||||
|
), pool_package AS (
|
||||||
|
SELECT virtual_flow_pool_months.pool_id,
|
||||||
|
virtual_flow_pool_months.package_id,
|
||||||
|
COUNT(*) as members,
|
||||||
|
SUM(settings.flows::NUMERIC) AS minimum_flows,
|
||||||
|
SUM(settings.price::NUMERIC) AS minimum_price,
|
||||||
|
SUM(virtual_flow_pool_months.mebibyte) AS total_flows,
|
||||||
|
AVG(settings.gradient::int) AS gradient,
|
||||||
|
AVG(settings.gradient_price::NUMERIC) AS gradient_price
|
||||||
|
FROM virtual_flow_pool_months
|
||||||
|
JOIN settings ON
|
||||||
|
settings.package_id::int = virtual_flow_pool_months.package_id AND
|
||||||
|
settings.pool_id::int = virtual_flow_pool_months.pool_id AND
|
||||||
|
settings.start_at <= (overlay($1::text placing ''-'' from 5 for 0) || ''-01 00:00:00'')::TIMESTAMP AND
|
||||||
|
(settings.end_at >= (overlay($1::text placing ''-'' from 5 for 0) || ''-01 23:59:59'')::TIMESTAMP OR settings.end_at IS NULL)
|
||||||
|
WHERE virtual_flow_pool_months.month = $1
|
||||||
|
GROUP BY virtual_flow_pool_months.pool_id, virtual_flow_pool_months.package_id
|
||||||
|
)
|
||||||
|
SELECT pool_id,
|
||||||
|
SUM(members) as members,
|
||||||
|
SUM(minimum_flows) as minimum_flows,
|
||||||
|
SUM(minimum_price) as minimum_price,
|
||||||
|
CASE WHEN SUM(total_flows) - SUM(minimum_flows) < 0 THEN 0 ELSE SUM(total_flows) - SUM(minimum_flows) END as excess_flows,
|
||||||
|
CEIL((CASE WHEN SUM(total_flows) - SUM(minimum_flows) < 0 THEN 0 ELSE SUM(total_flows) - SUM(minimum_flows) END)/AVG(gradient))*AVG(gradient)*AVG(gradient_price) as excess_price
|
||||||
|
FROM pool_package AS t GROUP BY pool_id
|
||||||
|
';
|
||||||
|
|
||||||
|
RETURN QUERY EXECUTE query USING $1;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
|||||||
CREATE OR REPLACE VIEW virtual_flow_pool_settings_view AS
|
|
||||||
SELECT pool_id,
|
|
||||||
json_array_elements(minimum_settings::json) ->> 'package_id' AS package_id,
|
|
||||||
json_array_elements(minimum_settings::json) ->> 'flows' AS flows,
|
|
||||||
json_array_elements(minimum_settings::json) ->> 'price' AS price,
|
|
||||||
gradient * pow(1024, gradient_unit) as gradient,
|
|
||||||
gradient_price / pow(1024, gradient_unit) as gradient_price,
|
|
||||||
start_at,
|
|
||||||
end_at
|
|
||||||
FROM virtual_flow_pool_settings;
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION GET_FLOW_POOL_MONTH_STAT(INT)
|
|
||||||
RETURNS TABLE
|
|
||||||
(
|
|
||||||
pool_id INT,
|
|
||||||
members NUMERIC,
|
|
||||||
minimum_flows NUMERIC,
|
|
||||||
minimum_price NUMERIC,
|
|
||||||
excess_flows NUMERIC,
|
|
||||||
excess_price NUMERIC
|
|
||||||
)
|
|
||||||
AS
|
|
||||||
$$
|
|
||||||
DECLARE
|
|
||||||
query TEXT;
|
|
||||||
BEGIN
|
|
||||||
query := 'SELECT virtual_flow_pool_months.pool_id,
|
|
||||||
virtual_flow_pool_months.package_id,
|
|
||||||
COUNT(*) as members,
|
|
||||||
SUM(virtual_flow_pool_settings_view.flows::NUMERIC) AS minimum_flows,
|
|
||||||
SUM(virtual_flow_pool_settings_view.price::NUMERIC) AS minimum_price,
|
|
||||||
CASE WHEN SUM(virtual_flow_pool_months.mebibyte) - SUM(virtual_flow_pool_settings_view.flows::NUMERIC) < 0 THEN 0
|
|
||||||
ELSE SUM(virtual_flow_pool_months.mebibyte) - SUM(virtual_flow_pool_settings_view.flows::NUMERIC) END AS excess_flows,
|
|
||||||
AVG(virtual_flow_pool_settings_view.gradient::int) AS gradient,
|
|
||||||
AVG(virtual_flow_pool_settings_view.gradient_price::NUMERIC) AS gradient_price
|
|
||||||
FROM virtual_flow_pool_months
|
|
||||||
JOIN virtual_flow_pool_settings_view ON
|
|
||||||
virtual_flow_pool_settings_view.package_id::int = virtual_flow_pool_months.package_id AND
|
|
||||||
virtual_flow_pool_settings_view.pool_id::int = virtual_flow_pool_months.pool_id AND
|
|
||||||
virtual_flow_pool_settings_view.start_at <=
|
|
||||||
(overlay($1::text placing ''-'' from 5 for 0) || ''-01 00:00:00'')::TIMESTAMP AND
|
|
||||||
(virtual_flow_pool_settings_view.end_at >=
|
|
||||||
(overlay($1::text placing ''-'' from 5 for 0) || ''-01 23:59:59'')::TIMESTAMP OR
|
|
||||||
virtual_flow_pool_settings_view.end_at IS NULL)
|
|
||||||
WHERE virtual_flow_pool_months.month = $1
|
|
||||||
GROUP BY virtual_flow_pool_months.pool_id, virtual_flow_pool_months.package_id
|
|
||||||
';
|
|
||||||
|
|
||||||
query := 'SELECT pool_id,
|
|
||||||
SUM(members) as members,
|
|
||||||
SUM(minimum_flows) as minimum_flows,
|
|
||||||
SUM(minimum_price) as minimum_price,
|
|
||||||
SUM(excess_flows) as excess_flows,
|
|
||||||
CEIL(SUM(excess_flows)/AVG(gradient))*AVG(gradient)*AVG(gradient_price) as excess_price
|
|
||||||
FROM (' || query || ') AS t GROUP BY pool_id';
|
|
||||||
|
|
||||||
RAISE NOTICE '%s', query;
|
|
||||||
|
|
||||||
RETURN QUERY EXECUTE query USING $1;
|
|
||||||
END;
|
|
||||||
$$ LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
import * as API from 'api/virtual/properties';
|
import * as API from "api/virtual/properties";
|
||||||
import draggable from 'vuedraggable';
|
import draggable from "vuedraggable";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -20,7 +20,7 @@ export default {
|
|||||||
my_show: false,
|
my_show: false,
|
||||||
loading: false,
|
loading: false,
|
||||||
settings: {},
|
settings: {},
|
||||||
selectedTab: '',
|
selectedTab: "",
|
||||||
completePackagesFilter: [],
|
completePackagesFilter: [],
|
||||||
dragOptions: {
|
dragOptions: {
|
||||||
animation: 0,
|
animation: 0,
|
||||||
@ -35,7 +35,7 @@ export default {
|
|||||||
return this.settings.package ? this.settings.package : {};
|
return this.settings.package ? this.settings.package : {};
|
||||||
},
|
},
|
||||||
set(value) {
|
set(value) {
|
||||||
console.log('packages', value);
|
console.log("packages", value);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
products: {
|
products: {
|
||||||
@ -88,37 +88,46 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
ok() {
|
ok() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
API.settingsStore({ data: this.settings }).then(res => {
|
API.settingsStore({ data: this.settings })
|
||||||
this.loading = false;
|
.then(res => {
|
||||||
if (res.code == 0) {
|
this.loading = false;
|
||||||
this.$Message.success('修改成功');
|
if (res.code == 0) {
|
||||||
this.clear();
|
this.$Message.success("修改成功");
|
||||||
this.$emit('store-success', this.settings);
|
this.clear();
|
||||||
}
|
this.$emit("store-success", this.settings);
|
||||||
}).catch(err => {
|
}
|
||||||
this.loading = false;
|
})
|
||||||
});
|
.catch(err => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
visibleChange(bool) {
|
visibleChange(bool) {
|
||||||
if (!bool) {
|
if (!bool) {
|
||||||
this.$emit('update:show', false);
|
this.$emit("update:show", false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clear() {
|
clear() {
|
||||||
this.my_show = false;
|
this.my_show = false;
|
||||||
},
|
},
|
||||||
handelRemove(key, value) {
|
handelRemove(key, value) {
|
||||||
|
console.log(key, value);
|
||||||
this.$Modal.confirm({
|
this.$Modal.confirm({
|
||||||
title: '提示',
|
title: "提示",
|
||||||
content: '已设置的属性值不会因删除改变,确认是否还要删除',
|
content: "已设置的属性值不会因删除改变,确认是否还要删除",
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
let node = key === 'package' ? this.settings[key][this.selectedTab] : this.settings[key];
|
let node =
|
||||||
|
key === "package"
|
||||||
|
? this.settings[key][this.selectedTab]
|
||||||
|
: this.settings[key];
|
||||||
let index = node.indexOf(value);
|
let index = node.indexOf(value);
|
||||||
node.splice(index, 1);
|
node.splice(index, 1);
|
||||||
|
|
||||||
if (key === 'package') {
|
if (key === "package") {
|
||||||
this.settings[key][this.selectedTab] = node;
|
this.settings[key][this.selectedTab] = node;
|
||||||
this.settings.product.splice(this.settings.product.indexOf(value), 1);
|
this.settings.product.splice(
|
||||||
|
this.settings.product.indexOf(value),
|
||||||
|
1
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
this.settings[key] = node;
|
this.settings[key] = node;
|
||||||
}
|
}
|
||||||
@ -126,32 +135,35 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleAdd(key) {
|
handleAdd(key) {
|
||||||
let value = '';
|
let value = "";
|
||||||
let node = key === 'package' ? this.settings[key][this.selectedTab] : this.settings[key];
|
let node =
|
||||||
|
key === "package"
|
||||||
|
? this.settings[key][this.selectedTab]
|
||||||
|
: this.settings[key];
|
||||||
|
|
||||||
this.$Modal.confirm({
|
this.$Modal.confirm({
|
||||||
render: (h) => {
|
render: h => {
|
||||||
return h('Input', {
|
return h("Input", {
|
||||||
props: {
|
props: {
|
||||||
value: value,
|
value: value,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
placeholder: '请输入名称'
|
placeholder: "请输入名称"
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
input: (val) => {
|
input: val => {
|
||||||
value = val;
|
value = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
if (value === '') {
|
if (value === "") {
|
||||||
return this.$Message.error('名称不能为空');
|
return this.$Message.error("名称不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
node.push(value);
|
node.push(value);
|
||||||
|
|
||||||
if (key === 'package') {
|
if (key === "package") {
|
||||||
this.settings[key][this.selectedTab] = node;
|
this.settings[key][this.selectedTab] = node;
|
||||||
this.settings.product.push(value);
|
this.settings.product.push(value);
|
||||||
} else {
|
} else {
|
||||||
@ -160,12 +172,30 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleRemovePackageType(val) {
|
handleRemovePackageType(key) {
|
||||||
|
let value = this.settings.package_type[key];
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
this.$Modal.confirm({
|
this.$Modal.confirm({
|
||||||
title: '提示',
|
title: "提示",
|
||||||
content: '删除套餐分类将同时删除分类及分类下的产品,但已设置的属性值不会因删除改变,请谨慎操作',
|
content:
|
||||||
|
"删除套餐分类将同时删除分类及分类下的产品,但已设置的属性值不会因删除改变,请谨慎操作",
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
|
let products = this.settings.package[value];
|
||||||
|
|
||||||
|
if (products) {
|
||||||
|
for (let i = 0; i < products.length; i++) {
|
||||||
|
const element = products[i];
|
||||||
|
let index = this.settings.product.indexOf(element);
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
this.settings.product.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.settings.package_type.splice(key, 1);
|
||||||
|
delete this.settings.package[value];
|
||||||
|
|
||||||
resolve(true);
|
resolve(true);
|
||||||
},
|
},
|
||||||
onCannel: () => {
|
onCannel: () => {
|
||||||
@ -175,29 +205,31 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleAddPackageType() {
|
handleAddPackageType() {
|
||||||
let value = '';
|
let value = "";
|
||||||
|
|
||||||
this.$Modal.confirm({
|
this.$Modal.confirm({
|
||||||
render: (h) => {
|
render: h => {
|
||||||
return h('Input', {
|
return h("Input", {
|
||||||
props: {
|
props: {
|
||||||
value: value,
|
value: value,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
placeholder: '请输入套餐分类名称'
|
placeholder: "请输入套餐分类名称"
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
input: (val) => {
|
input: val => {
|
||||||
value = val;
|
value = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onOk: () => {
|
onOk: () => {
|
||||||
if (value === '') {
|
if (value === "") {
|
||||||
return this.$Message.error('名称不能为空');
|
return this.$Message.error("名称不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
let package_type = this.settings.package_type ? this.settings.package_type : [];
|
let package_type = this.settings.package_type
|
||||||
|
? this.settings.package_type
|
||||||
|
: [];
|
||||||
|
|
||||||
package_type.push(value);
|
package_type.push(value);
|
||||||
|
|
||||||
|
1
public/js/app.d09afebb.js
Normal file
1
public/js/app.d09afebb.js
Normal file
File diff suppressed because one or more lines are too long
14
public/js/chunk-2cc41ab2.a9a06de3.js
Normal file
14
public/js/chunk-2cc41ab2.a9a06de3.js
Normal file
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
|||||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=\favicon.ico><script src=\config.js></script><title></title><link href=/css/chunk-2cc41ab2.bcb99373.css rel=prefetch><link href=/css/chunk-996b1e80.5cadf3d0.css rel=prefetch><link href=/js/chunk-00ae0766.d130b440.js rel=prefetch><link href=/js/chunk-07a274ec.55e1b3b0.js rel=prefetch><link href=/js/chunk-2cc41ab2.bec32fc2.js rel=prefetch><link href=/js/chunk-996b1e80.92847c4e.js rel=prefetch><link href=/css/app.8e379248.css rel=preload as=style><link href=/css/chunk-vendors.3c3b2e85.css rel=preload as=style><link href=/js/app.8955fa7e.js rel=preload as=script><link href=/js/chunk-vendors.ed6443e8.js rel=preload as=script><link href=/css/chunk-vendors.3c3b2e85.css rel=stylesheet><link href=/css/app.8e379248.css rel=stylesheet></head><body><noscript><strong>很抱歉,如果没有启用JavaScript,程序不能正常工作,若要继续使用请启用它。</strong></noscript><div id=app></div><script src=/js/chunk-vendors.ed6443e8.js></script><script src=/js/app.8955fa7e.js></script></body></html>
|
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=\favicon.ico><script src=\config.js></script><title></title><link href=/css/chunk-2cc41ab2.bcb99373.css rel=prefetch><link href=/css/chunk-996b1e80.5cadf3d0.css rel=prefetch><link href=/js/chunk-00ae0766.d130b440.js rel=prefetch><link href=/js/chunk-07a274ec.55e1b3b0.js rel=prefetch><link href=/js/chunk-2cc41ab2.a9a06de3.js rel=prefetch><link href=/js/chunk-996b1e80.92847c4e.js rel=prefetch><link href=/css/app.8e379248.css rel=preload as=style><link href=/css/chunk-vendors.3c3b2e85.css rel=preload as=style><link href=/js/app.d09afebb.js rel=preload as=script><link href=/js/chunk-vendors.ed6443e8.js rel=preload as=script><link href=/css/chunk-vendors.3c3b2e85.css rel=stylesheet><link href=/css/app.8e379248.css rel=stylesheet></head><body><noscript><strong>很抱歉,如果没有启用JavaScript,程序不能正常工作,若要继续使用请启用它。</strong></noscript><div id=app></div><script src=/js/chunk-vendors.ed6443e8.js></script><script src=/js/app.d09afebb.js></script></body></html>
|
Loading…
x
Reference in New Issue
Block a user