Commit cd6ba14e authored by 徐一鸣's avatar 徐一鸣

Merge branch 'xym' into dev

parents a8811239 51d3023d
src/assets/imgs/ic_true.png

1.51 KB | W: | H:

src/assets/imgs/ic_true.png

1.51 KB | W: | H:

src/assets/imgs/ic_true.png
src/assets/imgs/ic_true.png
src/assets/imgs/ic_true.png
src/assets/imgs/ic_true.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
<slot name="breadcrumb"></slot> <slot name="breadcrumb"></slot>
</div> </div>
<div class="main-container"> <div class="main-container">
<slot name="top"></slot>
<div class="header-container" v-if="!hideHeader"> <div class="header-container" v-if="!hideHeader">
<div class="header-left apass_button"> <div class="header-left apass_button">
<el-button <el-button
...@@ -18,6 +20,28 @@ ...@@ -18,6 +20,28 @@
" "
></i> ></i>
</el-button> </el-button>
<div
v-for="(item, index) in selectFilter"
:key="'select_' + index"
class="select_container"
>
<span class="select_title" v-text="item.name"></span>
<el-select
v-model="item.value"
placeholder="请选择"
@change="listAction"
>
<el-option
v-for="(v, i) in item.options"
:key="'select_' + index + '_option_' + i"
:label="v.name"
:value="v.value"
>
</el-option>
</el-select>
</div>
<slot name="header-left"></slot> <slot name="header-left"></slot>
</div> </div>
<div class="header-center"> <div class="header-center">
...@@ -51,7 +75,7 @@ ...@@ -51,7 +75,7 @@
<list-table <list-table
:header="listHeader" :header="listHeader"
:data="listData" :data="listData"
:padding-left="35" :padding-left="listPaddingLeft"
></list-table> ></list-table>
</div> </div>
...@@ -84,6 +108,10 @@ export default { ...@@ -84,6 +108,10 @@ export default {
type: Array, type: Array,
default: () => [], default: () => [],
}, },
otherFilter: {
type: Array,
default: () => [],
},
listHeader: { listHeader: {
type: Array, type: Array,
default: () => [], default: () => [],
...@@ -116,8 +144,21 @@ export default { ...@@ -116,8 +144,21 @@ export default {
currentPage: 1, currentPage: 1,
timer: null, timer: null,
pageSizes: [15, 50, 100], pageSizes: [15, 50, 100],
selectFilter: [],
}), }),
methods: { methods: {
initOtherFilter() {
this.otherFilter.forEach((item) => {
this.$set(this.filter, item.prop, item.default);
this.selectFilter.push({
name: item.name,
prop: item.prop,
value: item.default,
options: item.options,
});
});
},
searchAction(value) { searchAction(value) {
this.listAction(); this.listAction();
}, },
...@@ -140,8 +181,15 @@ export default { ...@@ -140,8 +181,15 @@ export default {
} }
this.timer = setTimeout(() => { this.timer = setTimeout(() => {
let selectFilter = {};
this.selectFilter.forEach((item) => {
selectFilter[item.prop] = item.value;
});
this.$emit("list-action", { this.$emit("list-action", {
...this.filter, ...this.filter,
...selectFilter,
keyword: this.searchValue, keyword: this.searchValue,
size: this.pageSize, size: this.pageSize,
page: this.currentPage, page: this.currentPage,
...@@ -150,6 +198,10 @@ export default { ...@@ -150,6 +198,10 @@ export default {
}, },
}, },
mounted() { mounted() {
if (this.otherFilter && this.otherFilter.length > 0) {
this.initOtherFilter();
}
this.listAction(); this.listAction();
}, },
}; };
...@@ -182,7 +234,17 @@ export default { ...@@ -182,7 +234,17 @@ export default {
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.header-container .el-button + .el-button { .header-container .select_container {
display: inline-block;
vertical-align: middle;
}
.header-container .select_container .select_title {
font-size: 14px;
color: #242c43;
margin-right: 10px;
}
.header-container .el-button + .el-button,
.header-container .select_container + .select_container {
margin-left: 25px; margin-left: 25px;
} }
.apass_filter { .apass_filter {
......
<template> <template>
<div class="apass_table"> <div class="apass_table">
<el-table :data="data"> <el-table :data="data">
<el-table-column :width="Math.max(paddingLeft - 10, 0)"></el-table-column> <el-table-column
v-if="paddingLeft > 10"
:width="paddingLeft - 10"
></el-table-column>
<el-table-column <el-table-column
v-for="(item, index) in header" v-for="(item, index) in header"
:label="item.label" :label="item.label"
...@@ -43,6 +46,33 @@ ...@@ -43,6 +46,33 @@
@click="item.callback && item.callback(scope.row)" @click="item.callback && item.callback(scope.row)"
></a> ></a>
</div> </div>
<div v-else-if="item.type === 'image'" class="img_content">
<img
:src="item.getImage && item.getImage(scope.row)"
:width="item.size"
/>
</div>
<div
v-else-if="
item.type === 'tooltip' &&
item.getLength &&
item.getLength(scope.row) > 1
"
>
<el-tooltip
placement="right-start"
popper-class="apass_table_tooltip"
>
<div
slot="content"
v-html="item.getContent && item.getContent(scope.row)"
></div>
<span
v-text="(item.getText && item.getText(scope.row)) + '..'"
style="text-decoration: underline;color: #515fe7;"
></span>
</el-tooltip>
</div>
<span <span
v-else v-else
v-text=" v-text="
...@@ -73,3 +103,19 @@ export default { ...@@ -73,3 +103,19 @@ export default {
}, },
}; };
</script> </script>
<style scoped>
.img_content {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
<style>
.apass_table_tooltip {
font-size: 12px;
line-height: 20px;
}
</style>
...@@ -50,11 +50,11 @@ export default { ...@@ -50,11 +50,11 @@ export default {
score: 0, score: 0,
starInfo: [ starInfo: [
{ {
star: 1, star: 5,
percent: 0, percent: 0,
}, },
{ {
star: 2, star: 4,
percent: 0, percent: 0,
}, },
{ {
...@@ -62,11 +62,11 @@ export default { ...@@ -62,11 +62,11 @@ export default {
percent: 0, percent: 0,
}, },
{ {
star: 4, star: 2,
percent: 0, percent: 0,
}, },
{ {
star: 5, star: 1,
percent: 0, percent: 0,
}, },
], ],
...@@ -79,7 +79,7 @@ export default { ...@@ -79,7 +79,7 @@ export default {
return { return {
score: data.avgScore || 0, score: data.avgScore || 0,
starInfo: [1, 2, 3, 4, 5].map((star) => { starInfo: [5,4,3,2,1].map((star) => {
let percent = let percent =
this.commentsTtotal > 0 this.commentsTtotal > 0
? (((data.scoreStatic && data.scoreStatic[star]) || 0) / ? (((data.scoreStatic && data.scoreStatic[star]) || 0) /
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
></service-tab-detail> ></service-tab-detail>
</el-tab-pane> </el-tab-pane>
<!-- 规格定价 --> <!-- 规格说明 -->
<el-tab-pane <el-tab-pane
:label="specificationTitle" :label="specificationTitle"
name="specification" name="specification"
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
></service-tab-specification> ></service-tab-specification>
</el-tab-pane> </el-tab-pane>
<!-- 提供机构 --> <!-- 提供组织 -->
<el-tab-pane :label="providerTitle" name="provider" v-if="providerData"> <el-tab-pane :label="providerTitle" name="provider" v-if="providerData">
<service-tab-provider <service-tab-provider
class="service_info" class="service_info"
...@@ -65,11 +65,11 @@ export default { ...@@ -65,11 +65,11 @@ export default {
}, },
specificationTitle: { specificationTitle: {
type: String, type: String,
default: () => "规格定价", default: () => "规格说明",
}, },
providerTitle: { providerTitle: {
type: String, type: String,
default: () => "提供机构", default: () => "提供组织",
}, },
commentsTitle: { commentsTitle: {
type: String, type: String,
......
...@@ -5,15 +5,63 @@ ...@@ -5,15 +5,63 @@
search-placeholder="请输入关键字" search-placeholder="请输入关键字"
:list-total="listTotal" :list-total="listTotal"
:list-filter="filterList" :list-filter="filterList"
:other-filter="filterList2"
:list-header="listHeader" :list-header="listHeader"
:list-data="listData" :list-data="listData"
:list-padding-left="35" :list-padding-left="paddingLeft"
@list-action="init" @list-action="init"
> >
<el-breadcrumb separator="/" slot="breadcrumb"> <el-breadcrumb separator="/" slot="breadcrumb">
<el-breadcrumb-item :to="`/fwgl/${level}`">我的服务</el-breadcrumb-item> <el-breadcrumb-item :to="`/fwgl/${level}`">我的服务</el-breadcrumb-item>
<el-breadcrumb-item>{{ pathName }}</el-breadcrumb-item> <el-breadcrumb-item>{{ pathName }}</el-breadcrumb-item>
</el-breadcrumb> </el-breadcrumb>
<template slot="top">
<div class="cloud_info" v-if="cloud_zuzhi">
<div class="info_container">
<p v-text="cloud_zuzhi.org_name"></p>
<p
v-text="'在用工作区域:' + (cloud_zuzhi.used_area || 0) + '个'"
></p>
</div>
<div class="dashboard_contaner">
<div
class="dashborad_list"
v-for="(item, index) in cloud_zuzhi.dashboard_list"
:key="index"
>
<dashboard style="width:150px;height:150px;"></dashboard>
<p v-text="item.value + ' / ' + item.total + item.unit"></p>
</div>
</div>
</div>
<div class="admin_info" v-if="cloud_admin">
<h1 class="admin_title">云上贵州</h1>
<div class="admin_header apass_button">
<span>云资源概览</span>
<el-button type="primary">
工作区域审批(1)
</el-button>
</div>
<div class="cloud_info">
<div class="dashboard_contaner">
<div
class="dashborad_list"
v-for="(item, index) in cloud_admin.dashboard_list"
:key="index"
>
<dashboard style="width:150px;height:150px;"></dashboard>
<p v-text="item.value + ' / ' + item.total + item.unit"></p>
</div>
</div>
</div>
</div>
</template>
<div slot="list" v-if="level == 2 && type == 2">
<p style="text-align: center;margin-top: 20px;">组织列表</p>
</div>
</apass-list> </apass-list>
<apass-dialog <apass-dialog
...@@ -26,20 +74,23 @@ ...@@ -26,20 +74,23 @@
</template> </template>
<script> <script>
import helper from "@/services/helper.js";
import { mapState } from "vuex"; import { mapState } from "vuex";
import helper from "@/services/helper.js";
import apassList from "@/components/apass-list"; import apassList from "@/components/apass-list";
import apassDialog from "@/components/apass-dialog"; import apassDialog from "@/components/apass-dialog";
import Dashboard from "@/components/e-charts/dashboard";
export default { export default {
components: { apassList, apassDialog }, components: { apassList, apassDialog, Dashboard },
data: () => ({ data: () => ({
level: 0, // 用户等级 level: 0, // 用户等级
type: 0, // 访问的页面 type: 0, // 访问的页面
paddingLeft: 35,
listTotal: 0, listTotal: 0,
listHeader: [], listHeader: [],
listData: [], listData: [],
filterList: [], filterList: [],
filterList2: [],
otherFilter: [], otherFilter: [],
dialogInfo: { dialogInfo: {
title: "", title: "",
...@@ -49,6 +100,8 @@ export default { ...@@ -49,6 +100,8 @@ export default {
listUrl: "", listUrl: "",
deleteUrl: "", deleteUrl: "",
tempFliter: null, tempFliter: null,
cloud_zuzhi: null,
cloud_admin: null,
}), }),
computed: { computed: {
...mapState({ ...mapState({
...@@ -71,27 +124,31 @@ export default { ...@@ -71,27 +124,31 @@ export default {
}, },
methods: { methods: {
initFilter() { initFilter() {
Promise.all([ if (this.type == 2) {
this.$http.get("/apaas/service/v3/service/manager/servtype"), //
this.$http.get("/apaas/service/v3/service/manager/servarea"), } else {
]) Promise.all([
.then((response) => { this.$http.get("/apaas/service/v3/service/manager/servtype"),
let data = response.map((item) => { this.$http.get("/apaas/service/v3/service/manager/servarea"),
return { ])
name: item.body.data[0].type_name, .then((response) => {
prop: item.body.data[0].type_code, let data = response.map((item) => {
data: item.body.data.map((v) => ({ return {
name: v.name, name: item.body.data[0].type_name,
value: v.id, prop: item.body.data[0].type_code,
})), data: item.body.data.map((v) => ({
}; name: v.name,
}); value: v.id,
})),
};
});
this.filterList = [...data, ...this.otherFilter]; this.filterList = [...data, ...this.otherFilter];
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
}); });
}
}, },
initHeader() { initHeader() {
let _self = this; let _self = this;
...@@ -149,9 +206,7 @@ export default { ...@@ -149,9 +206,7 @@ export default {
}, },
{ {
getLabel(item) { getLabel(item) {
return ( return ["申请上架", "申请下架", "审核中"][item.state] || "-";
["申请上架", "申请下架", "审核中"][item.state] || "-"
);
}, },
callback(item) { callback(item) {
if (item.state == 0) { if (item.state == 0) {
...@@ -322,18 +377,97 @@ export default { ...@@ -322,18 +377,97 @@ export default {
}, },
]; ];
} }
// TODO: 普通用户 --- 云资源服务 // 普通用户 --- 云资源服务
else if (level == 0 && type == 2) { else if (level == 0 && type == 2) {
this.listUrl = "xxxxxx"; this.listUrl = "";
this.paddingLeft = 0;
this.filterList2 = [
{
name: "初次申请状态",
prop: "state1",
default: 0,
options: [
{
name: "全部",
value: 0,
},
{
name: "待审批",
value: 1,
},
{
name: "审批通过",
value: 2,
},
{
name: "审批未通过",
value: 3,
},
],
},
{
name: "资源调整状态",
prop: "state2",
default: 0,
options: [
{
name: "全部",
value: 0,
},
{
name: "待审批",
value: 1,
},
{
name: "审批通过",
value: 2,
},
{
name: "审批未通过",
value: 3,
},
],
},
/* {
name: "申请状态",
prop: "state3",
default: 0,
options: [
{
name: "全部",
value: 0,
},
{
name: "待审批",
value: 1,
},
{
name: "审批通过",
value: 2,
},
{
name: "审批未通过",
value: 3,
},
],
}, */
];
this.listHeader = [ this.listHeader = [
{ {
label: "工作区域", label: "运行状态",
prop: "name", align: "center",
type: "image",
getImage(item) {
return item.state == 0
? require("@/assets/imgs/ic_true.png")
: require("@/assets/imgs/ic_guoqi.png");
},
}, },
{ {
label: "网络环境", label: "工作区域",
prop: "name", prop: "name",
align: "center", type: "button",
callback: this.cloudDetail,
}, },
{ {
label: "CPU(核)", label: "CPU(核)",
...@@ -346,14 +480,29 @@ export default { ...@@ -346,14 +480,29 @@ export default {
align: "center", align: "center",
}, },
{ {
label: "资源总量(GB", label: "容器组(个",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{ {
label: "实例数(个", label: "数据盘(块/GB",
prop: "name", type: "tooltip",
align: "center", align: "center",
getLength(item) {
return item.sjp.length;
},
getText(item) {
return item.sjp[0];
},
getContent(item) {
let htmlStr = `<span>数据盘(块/GB)</span><br />`;
item.sjp.forEach((v) => {
htmlStr += `<span>数据盘:${v}</span><br />`;
});
return htmlStr;
},
}, },
{ {
label: "申请时间", label: "申请时间",
...@@ -361,21 +510,31 @@ export default { ...@@ -361,21 +510,31 @@ export default {
align: "center", align: "center",
}, },
{ {
label: "申请状态", label: "初次申请状态",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{ {
label: "操作", label: "资源调整结果",
type: "buttons", prop: "name",
align: "center", align: "center",
width: 160, },
actionList: [ ];
{ this.listData = [
label: "查看详情", {
callback: this.detailItem, name: "区域1",
}, state: 0,
], sjp: ["8/60"],
},
{
name: "区域2",
state: 1,
sjp: ["2/3", "22/33"],
},
{
name: "区域3",
state: 0,
sjp: ["2/100", "22/33", "55/66"],
}, },
]; ];
} }
...@@ -509,7 +668,7 @@ export default { ...@@ -509,7 +668,7 @@ export default {
(item.service_apply_info && (item.service_apply_info &&
item.service_apply_info.approval_time) || item.service_apply_info.approval_time) ||
""; "";
return item.service_apply_info && return item.service_apply_info &&
item.service_apply_info.approval_status == 1 item.service_apply_info.approval_status == 1
? helper.dateStringTransform(date) ? helper.dateStringTransform(date)
...@@ -586,41 +745,111 @@ export default { ...@@ -586,41 +745,111 @@ export default {
}, },
]; ];
} }
// TODO: 组织管理员 --- 云资源管理 // 组织管理员 --- 云资源管理
else if (level == 1 && type == 2) { else if (level == 1 && type == 2) {
this.listUrl = "xxxxxx"; this.listUrl = "";
this.cloud_zuzhi = {
org_name: "北京比格大数据",
used_area: 2,
dashboard_list: [
{
name: "cpu使用量",
value: 6,
total: 10,
unit: "(核)",
},
{
name: "内存使用量",
value: 13,
total: 20,
unit: "(GB)",
},
{
name: "数据盘使用量",
value: 240,
total: 560,
unit: "(GB)",
},
{
name: "容器组使用量",
value: 10,
total: 18,
unit: "(个)",
},
],
};
this.filterList = [
{
name: "初次申请状态",
prop: "state1",
data: [
{
name: "待审批",
value: 1,
},
{
name: "审批通过",
value: 2,
},
{
name: "审批未通过",
value: 3,
},
],
},
{
name: "资源调整状态",
prop: "state2",
data: [
{
name: "待审批",
value: 1,
},
{
name: "审批通过",
value: 2,
},
{
name: "审批未通过",
value: 3,
},
],
},
];
this.listHeader = [ this.listHeader = [
{ {
label: "工作区域", label: "工作区域名称",
prop: "name", prop: "name",
type: "button",
callback: this.cloudDetail,
}, },
{ {
label: "网络环境", label: "CPU(核)",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{ {
label: "CPU(核", label: "内存(GB",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{ {
label: "内存(GB", label: "容器组(个",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{ {
label: "资源总量(GB)", label: "数据盘(块/GB)",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{ {
label: "实例数(个)", label: "申请用户",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{ {
label: "使用用户", label: "业务系统名",
prop: "name", prop: "name",
align: "center", align: "center",
}, },
...@@ -629,6 +858,21 @@ export default { ...@@ -629,6 +858,21 @@ export default {
prop: "name", prop: "name",
align: "center", align: "center",
}, },
{
label: "初次申请状态",
prop: "name",
align: "center",
},
{
label: "资源调整状态",
prop: "name",
align: "center",
},
{
label: "运行状态",
prop: "name",
align: "center",
},
{ {
label: "操作", label: "操作",
type: "buttons", type: "buttons",
...@@ -637,7 +881,7 @@ export default { ...@@ -637,7 +881,7 @@ export default {
actionList: [ actionList: [
{ {
label: "分配", label: "分配",
callback: this.allotItem, callback: this.cloudAllot,
}, },
], ],
}, },
...@@ -859,46 +1103,37 @@ export default { ...@@ -859,46 +1103,37 @@ export default {
}, },
]; ];
} }
// TODO: 超级管理员 --- 云资源管理 // 超级管理员 --- 云资源管理
else if (level == 2 && type == 2) { else if (level == 2 && type == 2) {
this.listUrl = "xxxxxx"; this.cloud_admin = {
this.listHeader = [ dashboard_list: [
{ {
label: "所属组织", name: "cpu使用量",
prop: "name", value: 6,
}, total: 10,
{ unit: "(核)",
label: "CPU使用量", },
prop: "name", {
align: "center", name: "内存使用量",
}, value: 13,
{ total: 20,
label: "内存使用量", unit: "(GB)",
prop: "name", },
align: "center", {
}, name: "数据盘使用量",
{ value: 240,
label: "工作区域数量", total: 560,
prop: "name", unit: "(GB)",
align: "center", },
}, {
{ name: "容器组使用量",
label: "创建时间", value: 10,
prop: "name", total: 18,
align: "center", unit: "(个)",
}, },
{ ],
label: "操作", histogram: {},
type: "buttons", };
align: "center",
actionList: [
{
label: "删除",
callback: this.deleteItem,
},
],
},
];
} }
// Error // Error
...@@ -907,6 +1142,12 @@ export default { ...@@ -907,6 +1142,12 @@ export default {
} }
}, },
init(filter) { init(filter) {
console.log(filter);
if (!this.listUrl) {
return;
}
this.tempFliter = filter; this.tempFliter = filter;
this.$http this.$http
...@@ -1130,9 +1371,12 @@ export default { ...@@ -1130,9 +1371,12 @@ export default {
`/fwgl/${this.level}/${this.type}/approvalserviceedit/${item.service_apply_info.id}` `/fwgl/${this.level}/${this.type}/approvalserviceedit/${item.service_apply_info.id}`
); );
}, // 审批服务 }, // 审批服务
allotItem(item) { cloudDetail(item) {
console.log("allotItem - " + item.name); console.log("cloudDetail - " + item.name);
}, // TODO: 云资源分配 },
cloudAllot(item) {
console.log("cloudAllot - " + item.name);
},
}, },
created() { created() {
this.level = parseInt(this.$route.params.level); this.level = parseInt(this.$route.params.level);
...@@ -1163,4 +1407,46 @@ export default { ...@@ -1163,4 +1407,46 @@ export default {
.service_management_list { .service_management_list {
height: 100%; height: 100%;
} }
.cloud_info {
display: flex;
justify-content: center;
align-items: center;
padding-top: 20px;
}
.cloud_info > .info_container {
flex-shrink: 0;
}
.cloud_info > .info_container > p:nth-child(1) {
font-size: 24px;
line-height: 36px;
}
.cloud_info > .info_container > p:nth-child(2) {
font-size: 18px;
line-height: 36px;
}
.cloud_info > .dashboard_contaner {
display: inline-flex;
justify-content: flex-start;
align-items: center;
}
.cloud_info > .dashboard_contaner > .dashborad_list {
text-align: center;
margin: 0 25px;
font-size: 18px;
}
.admin_title {
margin-top: 20px;
text-align: center;
}
.admin_header {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 20px;
}
.admin_header > span {
font-size: 24px;
}
</style> </style>
...@@ -8,9 +8,9 @@ const store = new Vuex.Store({ ...@@ -8,9 +8,9 @@ const store = new Vuex.Store({
userInfo: null, // 用户信息 userInfo: null, // 用户信息
serviceShopMenu: "/shop/data_service_list", // 服务超市侧边栏 serviceShopMenu: "/shop/data_service_list", // 服务超市侧边栏
fwglNav: [ fwglNav: [
["注册发布的服务", "申请的服务" /* , "云资源服务" */], // 普通用户 ["注册发布的服务", "申请的服务", "云资源服务"], // 普通用户
["组织服务管理", "服务审批管理" /* , "云资源管理" */], // 组织管理员 ["组织服务管理", "服务审批管理", "云资源管理"], // 组织管理员
["平台服务管理", "服务审批管理" /* , "云资源管理" */], // 超级管理员 ["平台服务管理", "服务审批管理", "云资源管理"], // 超级管理员
], // 服务管理列表,onlyRead ], // 服务管理列表,onlyRead
yyglNav: [ yyglNav: [
["应用仓库", "我部署的应用", "申请的应用"], // 普通用户 ["应用仓库", "我部署的应用", "申请的应用"], // 普通用户
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment