Commit 1a750064 by cocomilk2012

Merge branch 'dev'

parents 817fab6b b8626e50
...@@ -31,6 +31,7 @@ appid=app_register_id ...@@ -31,6 +31,7 @@ appid=app_register_id
authcode authcode
测试线账号及参数 测试线账号及参数
http://106.120.107.150:7773?appId=70770&authCode=001e6816b6324a92a681ac1a470f4715
appId=70770 appId=70770
userName=13522476236 userName=13522476236
password=qqxb123456 password=qqxb123456
......
...@@ -4769,7 +4769,7 @@ ...@@ -4769,7 +4769,7 @@
}, },
"fastclick": { "fastclick": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/fastclick/-/fastclick-1.0.6.tgz", "resolved": "https://registry.npm.taobao.org/fastclick/download/fastclick-1.0.6.tgz",
"integrity": "sha1-FhYlsnsaWAZAWTa9qaLBkm0Gvmo=" "integrity": "sha1-FhYlsnsaWAZAWTa9qaLBkm0Gvmo="
}, },
"faye-websocket": { "faye-websocket": {
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head>
<head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no,viewport-fit=cover"> content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no,viewport-fit=cover">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>业务账单</title> <title>业务账单</title>
</head> <style>
<body> /* Absolute Center Spinner */
.loading {
position: fixed;
z-index: 999;
height: 2em;
width: 2em;
overflow: visible;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
}
/* Transparent Overlay */
.loading:before {
content: '';
display: block;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.3);
}
/* :not(:required) hides these rules from IE9 and below */
.loading:not(:required) {
/* hide "loading..." text */
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}
.loading:not(:required):after {
content: '';
display: block;
font-size: 10px;
width: 1em;
height: 1em;
margin-top: -0.5em;
-webkit-animation: spinner 1500ms infinite linear;
-moz-animation: spinner 1500ms infinite linear;
-ms-animation: spinner 1500ms infinite linear;
-o-animation: spinner 1500ms infinite linear;
animation: spinner 1500ms infinite linear;
border-radius: 0.5em;
-webkit-box-shadow: rgba(0, 0, 0, 0.75) 1.5em 0 0 0, rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) 0 1.5em 0 0, rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, rgba(0, 0, 0, 0.5) -1.5em 0 0 0, rgba(0, 0, 0, 0.5) -1.1em -1.1em 0 0, rgba(0, 0, 0, 0.75) 0 -1.5em 0 0, rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0;
box-shadow: rgba(0, 0, 0, 0.75) 1.5em 0 0 0, rgba(0, 0, 0, 0.75) 1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) 0 1.5em 0 0, rgba(0, 0, 0, 0.75) -1.1em 1.1em 0 0, rgba(0, 0, 0, 0.75) -1.5em 0 0 0, rgba(0, 0, 0, 0.75) -1.1em -1.1em 0 0, rgba(0, 0, 0, 0.75) 0 -1.5em 0 0, rgba(0, 0, 0, 0.75) 1.1em -1.1em 0 0;
}
/* Animation */
@-webkit-keyframes spinner {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-moz-keyframes spinner {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-o-keyframes spinner {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes spinner {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<noscript> <noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript> </noscript>
<div id="app"></div> <div id="app">
<div class="loading">Loading&#8230;</div>
</div>
<!-- built files will be auto injected --> <!-- built files will be auto injected -->
</body> </body>
</html> </html>
\ No newline at end of file
...@@ -26,7 +26,6 @@ http.interceptors.response.use( ...@@ -26,7 +26,6 @@ http.interceptors.response.use(
if (response.error == 400 || response.status == 400) { if (response.error == 400 || response.status == 400) {
Toast.fail({ Toast.fail({
message:'授权失效!请先退出。', message:'授权失效!请先退出。',
position:{top:200}
}); });
} }
let { data } = response; let { data } = response;
...@@ -55,7 +54,6 @@ http.interceptors.response.use( ...@@ -55,7 +54,6 @@ http.interceptors.response.use(
message: '授权失效!请先退出。', message: '授权失效!请先退出。',
duration: 0, duration: 0,
overlay: true, overlay: true,
position:{top:200}
}) })
} }
......
...@@ -11,7 +11,7 @@ class Bridge { ...@@ -11,7 +11,7 @@ class Bridge {
* @param {Object=} args 请求数据 * @param {Object=} args 请求数据
* @param {String} args.barColor 栏颜色 #0978e7 * @param {String} args.barColor 栏颜色 #0978e7
*/ */
setBarColor(args = {}) { setBarColor (args = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
jsBridge.callHandler('setBarColor', args, function (response) { jsBridge.callHandler('setBarColor', args, function (response) {
...@@ -28,7 +28,7 @@ class Bridge { ...@@ -28,7 +28,7 @@ class Bridge {
* *
* @param {Object=} args 请求参数 * @param {Object=} args 请求参数
*/ */
getBarHeight(args = {}) { getBarHeight (args = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
jsBridge.callHandler("getBarHeight", args, function (response) { jsBridge.callHandler("getBarHeight", args, function (response) {
...@@ -51,7 +51,7 @@ class Bridge { ...@@ -51,7 +51,7 @@ class Bridge {
* @param {Boolean} args.isShowNav 是否显示导航栏 * @param {Boolean} args.isShowNav 是否显示导航栏
* @param {Boolean} args.isCloseWebView 是否关闭WebView * @param {Boolean} args.isCloseWebView 是否关闭WebView
*/ */
setPageNavState(args = {}) { setPageNavState (args = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
jsBridge.callHandler("setPageNavState", args, function (response) { jsBridge.callHandler("setPageNavState", args, function (response) {
...@@ -69,7 +69,7 @@ class Bridge { ...@@ -69,7 +69,7 @@ class Bridge {
* *
* @param {Object=} args 请求对象 * @param {Object=} args 请求对象
*/ */
closeWebView(args = {}) { closeWebView (args = {}) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
try { try {
jsBridge.callHandler("closeWebView", args, function (response) { jsBridge.callHandler("closeWebView", args, function (response) {
...@@ -80,6 +80,25 @@ class Bridge { ...@@ -80,6 +80,25 @@ class Bridge {
} }
}) })
} }
/**
* 使APP调用URL
*
* @param {Object=} args 请求对象
*/
getActionUrl (args = {}) {
console.log('bridge.getActionUrl');
return new Promise((resolve, reject) => {
try {
console.log('try bridge.getActionUrl');
jsBridge.callHandler("getActionUrl", args, function (response) {
resolve(response);
});
} catch (err) {
reject(err);
}
})
}
} }
export default new Bridge(); export default new Bridge();
......
...@@ -53,10 +53,10 @@ Vue.prototype.setPageNavState = function () { ...@@ -53,10 +53,10 @@ Vue.prototype.setPageNavState = function () {
Vue.prototype.$bridge = bridge; Vue.prototype.$bridge = bridge;
// if (process.env.NODE_ENV === 'development'||process.env.NODE_ENV === 'staging') { if (process.env.NODE_ENV === 'development'||process.env.NODE_ENV === 'staging') {
// const VConsole = require('vconsole') const VConsole = require('vconsole')
// const my_console = new VConsole(); const my_console = new VConsole();
// } }
new Vue({ new Vue({
......
...@@ -34,6 +34,7 @@ const router = new VueRouter({ ...@@ -34,6 +34,7 @@ const router = new VueRouter({
}) })
function getAccessToken(authcode) { function getAccessToken(authcode) {
console.log('getAccessToken');
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let commonPms = GetCommonPms(); let commonPms = GetCommonPms();
let url = `${oidc_config.authority}/connect/token?${commonPms}`; let url = `${oidc_config.authority}/connect/token?${commonPms}`;
...@@ -69,7 +70,7 @@ async function getToken(access_token, appid, redirectPath) { ...@@ -69,7 +70,7 @@ async function getToken(access_token, appid, redirectPath) {
}; };
let commonPms = GetCommonPms(); let commonPms = GetCommonPms();
let url = `${oidc_config.authority}/connect/token?${commonPms}`; let url = `${oidc_config.authority}/connect/token?${commonPms}`;
console.log('url=', url); console.log('pms=', JSON.stringify(pms));
await axios await axios
.post(url, qs.stringify(pms)) .post(url, qs.stringify(pms))
.then( .then(
......
...@@ -7,17 +7,29 @@ ...@@ -7,17 +7,29 @@
<div class="header"> <div class="header">
<div class="header_date_time"> <div class="header_date_time">
<div class="choose-month"> <div class="choose-month">
<div class="arrow-l" :class="hideL?'hideDiv':''" @click="chooseMonth('left')"> <div
class="arrow-l"
:class="hideL ? 'hideDiv' : ''"
@click="chooseMonth('left')"
>
<img src="../../assets/images/triangle-arrow-l.png" alt /> <img src="../../assets/images/triangle-arrow-l.png" alt />
</div> </div>
<div class="month">{{period[currentPerIndex].name}}</div> <div class="month">{{ period[currentPerIndex].name }}</div>
<div class="arrow-r" :class="hideR?'hideDiv':''" @click="chooseMonth('right')"> <div
class="arrow-r"
:class="hideR ? 'hideDiv' : ''"
@click="chooseMonth('right')"
>
<img src="../../assets/images/triangle-arrow-r.png" alt /> <img src="../../assets/images/triangle-arrow-r.png" alt />
</div> </div>
</div> </div>
<div class="cycle"> <div class="cycle">
<span>入账周期:</span> <span>入账周期:</span>
<span>{{period[currentPerIndex].beginDate | periodMoment}}-{{period[currentPerIndex].endDate | periodMoment}}</span> <span
>{{ period[currentPerIndex].beginDate | periodMoment }}-{{
period[currentPerIndex].endDate | periodMoment
}}</span
>
</div> </div>
</div> </div>
<div class="header_box"> <div class="header_box">
...@@ -25,18 +37,19 @@ ...@@ -25,18 +37,19 @@
<div class="header_content"> <div class="header_content">
<div class="fund"> <div class="fund">
<span>账户余额</span> <span>账户余额</span>
<i>{{data.balance|moneyNum}}</i> <i>{{ data.balance | moneyNum }}</i>
</div> </div>
<div class="paid"> <div class="paid">
<span>待付金额</span> <span>待付金额</span>
<i class="paid_color">{{data.waitPay|moneyNum}}</i> <i class="paid_color">{{ data.waitPay | moneyNum }}</i>
</div> </div>
</div> </div>
<div class="header_info"> <div class="header_info">
<div class="left" @click="toPay()"> <div class="left" @click="toPay_old()">
<img src="../../assets/images/icon01.png" alt /> <img src="../../assets/images/icon01.png" alt />
<span>充值</span> <span>充值</span>
</div> </div>
<div class="right" @click="toPage(2)"> <div class="right" @click="toPage(2)">
<img src="../../assets/images/icon02.png" alt /> <img src="../../assets/images/icon02.png" alt />
<span>资金记录</span> <span>资金记录</span>
...@@ -53,7 +66,7 @@ ...@@ -53,7 +66,7 @@
</div> </div>
<p> <p>
<span>托收金额</span> <span>托收金额</span>
<i>{{data.hosting.amount|moneyNum}}</i> <i>{{ data.hosting.amount | moneyNum }}</i>
</p> </p>
</div> </div>
...@@ -66,11 +79,11 @@ ...@@ -66,11 +79,11 @@
</div> </div>
<p> <p>
<span>应付金额</span> <span>应付金额</span>
<i>{{data.socical.total|moneyNum}}</i> <i>{{ data.socical.total | moneyNum }}</i>
</p> </p>
<p> <p>
<span>待付金额</span> <span>待付金额</span>
<i>{{data.socical.waitPay|moneyNum}}</i> <i>{{ data.socical.waitPay | moneyNum }}</i>
</p> </p>
</div> </div>
<!--公积金代理 accumulation--> <!--公积金代理 accumulation-->
...@@ -81,11 +94,11 @@ ...@@ -81,11 +94,11 @@
</div> </div>
<p> <p>
<span>应付金额</span> <span>应付金额</span>
<i>{{data.fund.total|moneyNum}}</i> <i>{{ data.fund.total | moneyNum }}</i>
</p> </p>
<p> <p>
<span>待付金额</span> <span>待付金额</span>
<i>{{data.fund.waitPay|moneyNum}}</i> <i>{{ data.fund.waitPay | moneyNum }}</i>
</p> </p>
</div> </div>
<!--个税代理 income--> <!--个税代理 income-->
...@@ -96,11 +109,11 @@ ...@@ -96,11 +109,11 @@
</div> </div>
<p> <p>
<span>应付金额</span> <span>应付金额</span>
<i>{{data.tax.total|moneyNum}}</i> <i>{{ data.tax.total | moneyNum }}</i>
</p> </p>
<p> <p>
<span>待付金额</span> <span>待付金额</span>
<i>{{data.tax.waitPay|moneyNum}}</i> <i>{{ data.tax.waitPay | moneyNum }}</i>
</p> </p>
</div> </div>
<!--服务费 service--> <!--服务费 service-->
...@@ -111,11 +124,11 @@ ...@@ -111,11 +124,11 @@
</div> </div>
<p> <p>
<span>应付金额</span> <span>应付金额</span>
<i>{{data.service.total|moneyNum}}</i> <i>{{ data.service.total | moneyNum }}</i>
</p> </p>
<p> <p>
<span>待付金额</span> <span>待付金额</span>
<i>{{data.service.waitPay|moneyNum}}</i> <i>{{ data.service.waitPay | moneyNum }}</i>
</p> </p>
</div> </div>
<!--会员年费 vip--> <!--会员年费 vip-->
...@@ -126,11 +139,11 @@ ...@@ -126,11 +139,11 @@
</div> </div>
<p> <p>
<span>应付金额</span> <span>应付金额</span>
<i>{{data.annual.total|moneyNum}}</i> <i>{{ data.annual.total | moneyNum }}</i>
</p> </p>
<p> <p>
<span>待付金额</span> <span>待付金额</span>
<i>{{data.annual.waitPay|moneyNum}}</i> <i>{{ data.annual.waitPay | moneyNum }}</i>
</p> </p>
</div> </div>
<!--其他事务办理 general--> <!--其他事务办理 general-->
...@@ -141,11 +154,11 @@ ...@@ -141,11 +154,11 @@
</div> </div>
<p> <p>
<span>应付金额</span> <span>应付金额</span>
<i>{{data.other.total|moneyNum}}</i> <i>{{ data.other.total | moneyNum }}</i>
</p> </p>
<p> <p>
<span>待付金额</span> <span>待付金额</span>
<i>{{data.other.waitPay|moneyNum}}</i> <i>{{ data.other.waitPay | moneyNum }}</i>
</p> </p>
</div> </div>
</div> </div>
...@@ -155,7 +168,7 @@ ...@@ -155,7 +168,7 @@
</template> </template>
<script> <script>
import { Icon, Loading } from "vant"; import { Icon, Loading, Toast } from "vant";
import { TabHeader } from "@/components"; import { TabHeader } from "@/components";
import * as utils from "../../utils/common"; import * as utils from "../../utils/common";
import { mapGetters, mapActions } from "vuex"; import { mapGetters, mapActions } from "vuex";
...@@ -175,6 +188,7 @@ export default { ...@@ -175,6 +188,7 @@ export default {
currentPerName: "", currentPerName: "",
period: [{ name: "" }], period: [{ name: "" }],
payUrl: "", payUrl: "",
nativePayUrl: "",
data: { data: {
balance: 0, balance: 0,
waitPay: 0, waitPay: 0,
...@@ -234,6 +248,39 @@ export default { ...@@ -234,6 +248,39 @@ export default {
"loadPayUrl" "loadPayUrl"
]), ]),
toPay() { toPay() {
window.onpageshow = null;
window.onpageshow = function(event) {
//event.persisted是否是缓存
location.reload();
};
//TODO:根据UA判断:如果App版本<2.1.9就走原来的充值逻辑;如果App版本>=2.1.9就走新的充值逻辑;
const userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("qqxbua") != -1) {
let tempArr = userAgent.split("qqxbua:");
if (tempArr.length > 1) {
const tempStr = tempArr[1];
const QQXBUA = JSON.parse(tempStr);
let version = QQXBUA.version;
console.log("version=", version);
if (version < "2.1.9") {
this.toPay_old();
} else {
this.toPay_new();
}
}
} else {
this.toPay_old();
}
},
toPay_new() {
console.log("topay_new");
//TODO:先弹出一个遮罩层,点击任意按钮刷新页面
this.$bridge.getActionUrl(this.nativePayUrl).then(res => {
console.log("getActionUrl in bill index");
});
},
toPay_old() {
console.log("topay_old");
this.$bridge this.$bridge
.setPageNavState({ .setPageNavState({
headerColor: "#fff", headerColor: "#fff",
...@@ -253,7 +300,7 @@ export default { ...@@ -253,7 +300,7 @@ export default {
barColor: "#ffffff" barColor: "#ffffff"
}) })
.then(res => {}); .then(res => {});
console.log("setBarColor");
const failUrl = encodeURIComponent( const failUrl = encodeURIComponent(
"https://pay.qinqinxiaobao.com/callback/fail" "https://pay.qinqinxiaobao.com/callback/fail"
); );
...@@ -265,11 +312,12 @@ export default { ...@@ -265,11 +312,12 @@ export default {
const selected = 0; const selected = 0;
const fee = this.data.waitPay; const fee = this.data.waitPay;
let payUrl = `${this.payUrl}&accountId=${this.currentPerId}&payMethod=${payMethod}&payType=${payType}&fee=${fee}&selected=0&failUrl=${failUrl}&successUrl=${successUrl}`; let payUrl = `${this.payUrl}&accountId=${this.currentPerId}&payMethod=${payMethod}&payType=${payType}&fee=${fee}&selected=0&failUrl=${failUrl}&successUrl=${successUrl}`;
window.onpageshow=null; console.log("old_pay_url=", payUrl);
window.onpageshow=function(event){
location.reload(); console.log("window.onpageshow ");
} Toast.loading({ duration: 0, message: "正在跳转到支付页面,请等待..." });
window.location.href = payUrl; window.location.href = payUrl;
console.log("页面跳转走了");
}, },
toPage(flag) { toPage(flag) {
switch (flag) { switch (flag) {
...@@ -385,6 +433,8 @@ export default { ...@@ -385,6 +433,8 @@ export default {
data => { data => {
this.data.balance = data.balance; this.data.balance = data.balance;
this.data.waitPay = data.waitPay; this.data.waitPay = data.waitPay;
this.nativePayUrl = `hrs100://native/SelectRechargeMode?periodId=${this.currentPerId}&fee=${this.data.waitPay}`;
console.log("this.nativePayUrl=", this.nativePayUrl);
}, },
err => { err => {
console.log(err); console.log(err);
...@@ -447,7 +497,7 @@ export default { ...@@ -447,7 +497,7 @@ export default {
setBarHeightLowBee() { setBarHeightLowBee() {
setTimeout(() => { setTimeout(() => {
const barHeight = localStorage.getItem("barHeight"); const barHeight = localStorage.getItem("barHeight");
console.log('barHeight=',barHeight); console.log("barHeight=", barHeight);
const conHeight = 46 + parseInt(barHeight); const conHeight = 46 + parseInt(barHeight);
const dom = document.getElementsByClassName("iosStyle")[0]; const dom = document.getElementsByClassName("iosStyle")[0];
if (dom) { if (dom) {
...@@ -514,11 +564,10 @@ export default { ...@@ -514,11 +564,10 @@ export default {
this.setBarHeightLowBee(); this.setBarHeightLowBee();
this.globalNavLeftArrowClick(this.navLeftArrowClick); this.globalNavLeftArrowClick(this.navLeftArrowClick);
await this.loadPeriodData(); await this.loadPeriodData();
}, },
async created() { async created() {
this.payUrl = localStorage.getItem("payUrl"); this.payUrl = localStorage.getItem("payUrl");
console.log('this.payUrl=',this.payUrl); console.log("this.payUrl=", this.payUrl);
if (!this.payUrl) { if (!this.payUrl) {
this.payUrl = await this.loadPayUrl(); this.payUrl = await this.loadPayUrl();
localStorage.setItem("payUrl", this.payUrl); localStorage.setItem("payUrl", this.payUrl);
...@@ -546,6 +595,7 @@ export default { ...@@ -546,6 +595,7 @@ export default {
display: grid; display: grid;
grid-template-columns: 5% 90% 5%; grid-template-columns: 5% 90% 5%;
justify-items: center; justify-items: center;
align-items: center;
.arrow-l, .arrow-l,
.arrow_right { .arrow_right {
widows: 16px; widows: 16px;
......
...@@ -248,6 +248,7 @@ export default { ...@@ -248,6 +248,7 @@ export default {
display: grid; display: grid;
grid-template-columns: 5% 90% 5%; grid-template-columns: 5% 90% 5%;
justify-items: center; justify-items: center;
align-items: center;
.arrow-l, .arrow-l,
.arrow_right { .arrow_right {
widows: 16px; widows: 16px;
......
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 sign in to comment