Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
U
uni-app-base
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tangfh
uni-app-base
Commits
47b144a0
Commit
47b144a0
authored
May 18, 2023
by
tangfh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
+
parent
f391fe76
Pipeline
#252
failed with stages
Changes
5
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
488 additions
and
9 deletions
+488
-9
base-page.vue
pages/template/base-page.vue
+4
-6
base-tab.vue
pages/template/base-tab.vue
+2
-3
common.scss
static/common.scss
+0
-0
constant.js
utils/constant.js
+54
-0
util.js
utils/util.js
+428
-0
No files found.
pages/template/base-page.vue
View file @
47b144a0
...
@@ -8,8 +8,8 @@
...
@@ -8,8 +8,8 @@
@
refresherrefresh=
"onRefresh"
@
scrolltolower=
"onLoadMore"
:refresher-triggered=
"refresherTriggered"
@
refresherrefresh=
"onRefresh"
@
scrolltolower=
"onLoadMore"
:refresher-triggered=
"refresherTriggered"
:style=
"
{'height':(scrollViewHeight+'px')}">
:style=
"
{'height':(scrollViewHeight+'px')}">
<view
class=
"flex-column"
v-if=
"items.length > 0"
:style=
"
{'min-height': (scrollViewHeight + 'px')}">
<view
class=
"flex-column"
v-if=
"items.length > 0"
:style=
"
{'min-height': (scrollViewHeight + 'px')}">
<
repair-order-item
v-for=
"(item, index) in items"
:index=
"index"
:key=
"index"
:item=
"item
"
<
view
class=
"view-tmp1 active"
v-for=
"(item, index) in tab.data"
:index=
"index"
:key=
"index
"
@
onItemClick=
"onItemClick"
></repair-order-item
>
:item=
"item"
@
onItemClick=
"onItemClick"
></view
>
</view>
</view>
<c-empty
v-if=
"items.length == 0"
@
onEmptyClick=
"onEmptyClick"
></c-empty>
<c-empty
v-if=
"items.length == 0"
@
onEmptyClick=
"onEmptyClick"
></c-empty>
<uni-load-more
:status=
"loadMoreViewStatus"
:icon-size=
"16"
v-if=
"items.length > 0"
<uni-load-more
:status=
"loadMoreViewStatus"
:icon-size=
"16"
v-if=
"items.length > 0"
...
@@ -20,7 +20,6 @@
...
@@ -20,7 +20,6 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
repair_constant
from
'./../../utils/repair_constant.js'
import
constant
from
'./../../utils/constant.js'
import
constant
from
'./../../utils/constant.js'
import
util
from
'./../../utils/util.js'
import
util
from
'./../../utils/util.js'
export
default
{
export
default
{
...
@@ -51,8 +50,7 @@
...
@@ -51,8 +50,7 @@
},
},
methods
:
{
methods
:
{
init
()
{
init
()
{
util
.
showRequestLoading
()
this
.
onRefresh
()
this
.
getList
()
},
},
onNavBarLeftClick
()
{
onNavBarLeftClick
()
{
uni
.
navigateBack
();
uni
.
navigateBack
();
...
@@ -89,7 +87,7 @@
...
@@ -89,7 +87,7 @@
},
},
getList
()
{
getList
()
{
this
.
page
=
this
.
page
>
this
.
total_page
?
this
.
total_page
:
this
.
page
;
this
.
page
=
this
.
page
>
this
.
total_page
?
this
.
total_page
:
this
.
page
;
let
url
=
repair_constant
.
URLS
.
getList
;
let
url
=
""
;
let
param
=
{
let
param
=
{
channel
:
this
.
channel
,
channel
:
this
.
channel
,
page
:
this
.
page
page
:
this
.
page
...
...
pages/template/base-tab.vue
View file @
47b144a0
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
@
scrolltolower=
"loadMore(index)"
:style=
"
{height: (swiperHeight) + 'px'}">
@
scrolltolower=
"loadMore(index)"
:style=
"
{height: (swiperHeight) + 'px'}">
<view
class=
"flex-column"
v-if=
"tab.data.length > 0"
:style=
"
{'min-height': (svHeight + 'rpx')}">
<view
class=
"flex-column"
v-if=
"tab.data.length > 0"
:style=
"
{'min-height': (svHeight + 'rpx')}">
<view
class=
"view-tmp1 active"
v-for=
"(item2, index2) in tab.data"
:index=
"index2"
:key=
"index2"
<view
class=
"view-tmp1 active"
v-for=
"(item2, index2) in tab.data"
:index=
"index2"
:key=
"index2"
:item=
"item2"
@
onItemClick=
"onItemClick"
></
repair-order-item
>
:item=
"item2"
@
onItemClick=
"onItemClick"
></
view
>
</view>
</view>
<c-empty
v-if=
"tab.data.length == 0"
@
onEmptyClick=
"onEmptyClick"
></c-empty>
<c-empty
v-if=
"tab.data.length == 0"
@
onEmptyClick=
"onEmptyClick"
></c-empty>
<uni-load-more
:status=
"tab.loadStatus"
:icon-size=
"16"
v-if=
"tab.isLoading || tab.data.length > 0"
<uni-load-more
:status=
"tab.loadStatus"
:icon-size=
"16"
v-if=
"tab.isLoading || tab.data.length > 0"
...
@@ -26,7 +26,6 @@
...
@@ -26,7 +26,6 @@
</
template
>
</
template
>
<
script
>
<
script
>
import
repair_constant
from
'./../../utils/repair_constant.js'
import
constant
from
'./../../utils/constant.js'
import
constant
from
'./../../utils/constant.js'
import
util
from
'./../../utils/util.js'
import
util
from
'./../../utils/util.js'
// 缓存每页最多
// 缓存每页最多
...
@@ -158,7 +157,7 @@
...
@@ -158,7 +157,7 @@
this
.
getList
(
this
.
tabIndex
)
this
.
getList
(
this
.
tabIndex
)
},
},
getList
(
index
)
{
getList
(
index
)
{
let
url
=
repair_constant
.
URLS
.
allocList
;
let
url
=
""
;
let
param
=
{
let
param
=
{
channel
:
this
.
tabList
[
index
].
channel
,
channel
:
this
.
tabList
[
index
].
channel
,
keywords
:
""
,
keywords
:
""
,
...
...
static/common.css
→
static/common.
s
css
View file @
47b144a0
File moved
utils/constant.js
0 → 100644
View file @
47b144a0
// Environment
const
IS_RELEASE
=
false
;
const
BASR_URL_TEST
=
"https://wxmishang-test-api.guoguodz.com"
;
const
BASR_URL_RELEASE
=
"https://ticketapi.guoguodz.com"
;
const
BASE_URL_DEV_TEST
=
BASR_URL_TEST
+
"/v1"
;
// Test Develop
// const BASE_URL_DEV_TEST = "http://ticket-test-api.guoguodz.com/v2/api/" // Test Develop
const
BASE_URL_RELEASE
=
BASR_URL_RELEASE
+
"/v1"
;
// Release
const
SECRET_KEY_DEV_TEST
=
"xJLj0sb71w78sdf045"
;
const
SECRET_KEY_RELEASE
=
"xJLj0sb71w78sdf045"
;
const
LOOP
=
true
;
const
IFTRUE
=
!
IS_RELEASE
;
const
BASE_URL
=
IS_RELEASE
?
BASE_URL_RELEASE
:
BASE_URL_DEV_TEST
;
const
SECRET_KEY
=
IS_RELEASE
?
SECRET_KEY_RELEASE
:
SECRET_KEY_DEV_TEST
;
const
KEY_USER
=
'USER'
;
const
KEY_SECRET
=
'SECRET'
;
const
KEY_SESSION_ID
=
'SESSION_ID'
;
const
LOAD_STATUS
=
{
more
:
'more'
,
loading
:
'loading'
,
noMore
:
'noMore'
};
const
LOAD_TEXTS
=
{
contentdown
:
'上拉加载更多'
,
contentrefresh
:
'加载中'
,
contentnomore
:
'没有更多~'
};
const
IS_VERIFY
=
{
};
//弹窗显示的位置
const
C_POP_DIRECTIONS
=
{
center
:
"center"
,
//正中间
centerTop
:
"centerTop"
,
//中间往上一点的位置
bottom
:
"bottom"
,
//最底部
}
export
default
{
// KEY
KEY_USER
,
KEY_SECRET
,
KEY_SESSION_ID
,
SECRET_KEY
,
BASE_URL
,
LOAD_STATUS
,
LOAD_TEXTS
,
LOOP
,
IS_VERIFY
,
C_POP_DIRECTIONS
,
}
\ No newline at end of file
utils/util.js
0 → 100644
View file @
47b144a0
import
constant
from
'./constant.js'
import
repair_constant
from
'./repair_constant.js'
import
{
Base64
}
from
'js-base64'
;
import
md5
from
'js-md5'
;
/**
* 发起请求
* @param {Object} url
* @param {Object} param
* @param {Object} callback
*/
function
request
(
url
,
param
,
callback
,
complete
,
option
)
{
option
=
optionInit
(
option
);
if
(
param
&&
!
param
.
timestamp
)
{
param
.
timestamp
=
timestamp
();
}
var
paramWrapper
=
getParamWrapper
(
url
,
param
,
option
)
param
.
token
=
paramWrapper
.
token
;
param
.
sign
=
paramWrapper
.
sign
;
if
(
option
.
isNeedLog
)
{
logObj
(
"util.js >>> request() >>> data(真正传递到后端的参数)"
,
param
)
}
// url = "http://my.com:8080/login"
uni
.
request
({
method
:
'POST'
,
url
:
url
,
data
:
param
,
//dataType: "",
timeout
:
30000
,
header
:
{
'content-type'
:
"application/x-www-form-urlencoded"
},
success
:
(
res
)
=>
{
if
(
option
&&
option
.
isNeedShowLoading
)
{
uni
.
hideLoading
();
}
if
(
option
.
isNeedLog
)
{
console
.
error
(
"+ 响应:"
+
url
)
console
.
log
(
res
);
}
if
(
option
&&
option
.
isNeedToastError
&&
res
.
data
.
code
!=
0
&&
res
.
data
.
code
!=
0
)
{
toastError
(
res
.
data
.
msg
,
res
.
data
.
code
)
}
if
(
res
.
data
.
code
==
10004
)
{
//10004 请重新登录 | 10025 用户未认证成功
if
(
option
.
isNeedSignOut
)
{
signOut
(
url
);
}
if
(
option
&&
!
option
.
isInPageGuide
)
{
//var route = getCurrentPages()[getCurrentPages().length - 1].route;
}
}
callback
(
res
)
},
fail
:
(
res
)
=>
{
if
(
option
&&
option
.
isNeedToastError
)
{
toastError
(
res
.
errMsg
,
-
1
)
}
if
(
option
.
isNeedLog
)
{
console
.
error
(
"+ 响应:"
+
url
)
console
.
log
(
res
);
}
},
complete
:
(
res
)
=>
{
if
(
complete
)
{
complete
()
}
}
});
}
function
upload
(
filePath
,
param
,
callback
,
option
)
{
option
=
optionInit
(
option
);
if
(
param
&&
!
param
.
timestamp
)
{
param
.
timestamp
=
timestamp
();
}
let
url
=
repair_constant
.
URLS
.
upload
;
var
paramWrapper
=
getParamWrapper
(
url
,
param
,
option
)
param
.
token
=
paramWrapper
.
token
;
param
.
sign
=
paramWrapper
.
sign
;
if
(
option
.
isNeedLog
)
{
logObj
(
"util.js >>> request() >>> data(真正传递到后端的参数)"
,
param
)
}
uni
.
uploadFile
({
url
:
url
,
filePath
:
filePath
,
name
:
'file'
,
formData
:
param
,
success
:
(
uploadFileRes
)
=>
{
console
.
log
(
uploadFileRes
.
data
);
callback
(
uploadFileRes
.
data
)
}
});
}
function
optionInit
(
option
)
{
if
(
!
option
)
{
option
=
{
isNeedToken
:
true
,
isNeedSignOut
:
true
,
isNeedShowLoading
:
false
,
isNeedToastError
:
true
}
}
if
(
option
.
isNeedToken
==
undefined
)
{
option
.
isNeedToken
=
true
;
}
if
(
option
.
isNeedToastError
==
undefined
)
{
option
.
isNeedToastError
=
true
;
}
if
(
option
.
isNeedLog
==
undefined
)
{
option
.
isNeedLog
=
true
;
}
if
(
option
&&
option
.
isNeedShowLoading
)
{
showRequestLoading
();
}
return
option
;
}
function
showRequestLoading
()
{
uni
.
showLoading
({
mask
:
true
,
title
:
'请稍候'
})
}
function
getParamWrapper
(
url
,
param
,
option
)
{
//isNeedToken, isNeedSecretKey
//判断是否登录
const
user
=
getUser
();
var
isLogin_
=
isLogin
(
user
);
var
key
=
constant
.
SECRET_KEY
;
//'系统默认给出的secret_key';
var
token
=
''
//'登录后后台返回的token,没登录前为空字符串';
if
(
isLogin_
&&
option
&&
option
.
isNeedToken
)
{
token
=
user
.
token
;
//
}
param
.
token
=
token
;
const
keyCache
=
get
(
constant
.
KEY_SECRET
);
key
=
keyCache
?
keyCache
:
key
;
//
//参数按后台要求处理:
var
paramJson
=
JSON
.
stringify
(
param
)
var
paramKeySortedArr
=
sort
(
param
)
var
paramSortedCombineStr
=
combine
(
param
,
paramKeySortedArr
)
var
paramSorted
=
sortedJsonObj
(
param
,
paramKeySortedArr
)
var
paramSortedJson
=
JSON
.
stringify
(
paramSorted
)
var
sign
=
md5
(
paramSortedCombineStr
+
key
)
var
encrypt_data
=
Base64
.
encode
(
paramSortedJson
,
key
);
var
paramWrapper
=
{
token
:
token
,
param
:
encrypt_data
,
sign
:
sign
,
};
if
(
option
&&
option
.
isNeedLog
)
{
console
.
error
(
"+ 请求:"
+
url
)
console
.
log
(
"+ paramSorted = "
)
console
.
log
(
paramSorted
)
console
.
log
(
"+ paramWrapperJson = "
)
console
.
log
(
paramWrapper
)
console
.
log
(
"+ isLogin = "
+
isLogin_
)
console
.
log
(
"+ secret = "
+
key
)
console
.
log
(
"+ secretKeyCache = "
+
keyCache
)
console
.
log
(
"+ token = "
+
token
)
if
(
true
)
{
console
.
log
(
"+ "
)
console
.
log
(
"+ paramJson = "
+
paramJson
)
console
.
log
(
"+ paramKeySortedArr = "
+
paramKeySortedArr
)
console
.
log
(
"+ parmKeySortedCombineStr = "
+
paramSortedCombineStr
)
console
.
log
(
"+ sign = "
+
sign
)
console
.
log
(
"+ paramSorted = "
+
paramSorted
)
console
.
log
(
"+ paramSortedJson = "
+
paramSortedJson
)
console
.
log
(
"+ encrypt_data = "
+
encrypt_data
)
}
}
return
paramWrapper
;
}
function
isLogin
(
user
)
{
const
user_
=
user
?
user
:
getUser
();
return
user_
.
token
?
true
:
false
;
}
function
signOut
(
url
)
{
logMsg
(
"清空用户数据 > url="
+
(
url
?
url
:
""
))
save
(
constant
.
KEY_USER
,
'{}'
)
save
(
constant
.
KEY_SECRET
,
''
)
save
(
constant
.
KEY_SESSION_ID
,
''
)
save
(
'encryptedData'
,
''
);
save
(
'iv'
,
''
);
getApp
().
globalData
.
user
=
{};
}
function
getUser
()
{
try
{
var
user
=
getApp
().
globalData
.
user
.
token
?
getApp
().
globalData
.
user
:
JSON
.
parse
(
get
(
constant
.
KEY_USER
));
dealUserInfo
(
user
);
return
user
;
}
catch
(
e
)
{
return
{}
}
}
/**
* 数据转换处理,这里需要结合产品文档和业务逻辑
* @param {Object} user
*/
function
dealUserInfo
(
user
,
app
)
{
//console.log(user);
}
/**
* 1. 将 json 对象中的 key 提取出来、存入数组、按升序排序
* @param {Object} jsonObj 原json对象
*/
function
sort
(
jsonObj
)
{
let
arr
=
[];
for
(
var
key
in
jsonObj
)
{
arr
.
push
(
key
)
}
arr
.
sort
();
return
arr
;
}
/**
* 将 jsonObj 中的 键值对,通过 key=value&key=value&... 的形式拼接起来
* @param {Object} jsonObj 原json对象
* @param {Object} keyArr 排序后的 key 的数组
*/
function
combine
(
jsonObj
,
keyArr
)
{
let
str
=
''
;
for
(
var
i
in
keyArr
)
{
str
+=
keyArr
[
i
]
+
"="
+
jsonObj
[
keyArr
[
i
]]
+
"&"
}
//return str.substr(0, str.length - 1)
return
str
;
//(保留最后的&字符)
}
/**
* @param {Object} jsonObj 原json对象
* @param {Object} paramKeySortedArr
*/
function
sortedJsonObj
(
jsonObj
,
paramKeySortedArr
)
{
var
result
=
{}
for
(
var
i
in
paramKeySortedArr
)
{
//console.log("i = " + i)
const
key
=
paramKeySortedArr
[
i
];
//console.log("key = " + key)
result
[
key
]
=
jsonObj
[
key
]
}
return
result
;
}
function
timestamp
()
{
return
(
new
Date
().
getTime
()).
toString
()
}
/**
* 保存key value
*
* @param {Object} key
* @param {Object} value
*/
function
saveSync
(
key
,
value
)
{
try
{
uni
.
setStorageSync
(
key
,
value
)
}
catch
(
e
)
{
console
.
log
(
"utils.js >>> save() >>> "
+
key
+
" = "
+
value
+
"保存失败!!!!!!!"
)
}
}
function
save
(
key
,
value
)
{
uni
.
setStorage
({
key
:
key
,
data
:
value
,
success
:
function
()
{
console
.
log
(
key
+
'数据缓存成功'
);
}
})
}
/**
* 保存key value
*
* @param {Object} key
*/
function
get
(
key
,
def
)
{
try
{
let
get
=
uni
.
getStorageSync
(
key
);
return
get
==
null
||
get
==
undefined
||
get
.
length
==
0
?
(
def
?
def
:
""
)
:
get
;
}
catch
(
e
)
{
console
.
log
(
e
);
console
.
log
(
"utils.js >>> get() >>> "
+
key
+
"获取失败!!!!!!!"
)
return
def
?
def
:
{};
}
}
function
showToast
(
title
,
duration
,
delay
)
{
if
(
!
title
)
{
return
;
}
var
duration
=
duration
?
duration
:
2500
;
var
delay
=
delay
?
delay
:
1000
;
setTimeout
(
function
()
{
uni
.
showToast
({
title
:
title
,
icon
:
'none'
,
duration
:
duration
})
},
delay
)
}
function
toastError
(
msg
,
code
)
{
if
(
code
!=
200
)
{
console
.
error
(
"util.js >>> toastError() >>> msg = "
+
msg
+
" code = "
+
code
);
var
title
=
msg
?
msg
:
"服务器开小差,请稍候再试"
+
(
code
?
":"
+
code
:
''
);
setTimeout
(
function
()
{
showToast
(
title
);
},
200
)
}
}
function
logMsg
(
where
,
msg
)
{
console
.
log
(
where
,
msg
);
}
function
logObj
(
where
,
obj
)
{
console
.
error
(
where
+
" ↓↓↓↓↓↓↓↓↓ "
,
obj
?
obj
:
""
)
}
function
getSystemInfo
(
app
)
{
uni
.
getSystemInfo
({
success
(
res
)
{
console
.
log
(
"getSystemInfo: "
,
res
);
let
pxToRpxScale
=
750
/
res
.
windowWidth
;
let
screenWidth
=
res
.
screenWidth
*
pxToRpxScale
;
let
screenHeight
=
res
.
screenHeight
*
pxToRpxScale
;
app
.
globalData
.
pxToRpxScale
=
pxToRpxScale
;
app
.
globalData
.
screenWidth
=
screenWidth
;
app
.
globalData
.
screenHeight
=
screenHeight
;
}
})
}
/**
* @param {Object} str 字符串
* @param {Object} max 最大显示字符
*/
function
combine3
(
str
,
max
)
{
if
(
!
str
)
{
return
""
;
}
return
str
.
length
>
max
?
(
str
.
substr
(
0
,
max
-
1
)
+
"..."
)
:
str
}
function
moneyFormat
(
value
,
isNeedSubLastDot
,
isNeedAddZero
)
{
// 金额 格式化
if
(
value
==
'.'
)
{
return
""
;
}
var
valueType
=
typeof
value
;
var
isNumber
=
valueType
==
'number'
;
var
value_
=
isNumber
?
(
value
+
''
)
:
value
;
//如果value_是number类型,需要转换为string
if
(
value_
!=
''
&&
value_
.
substr
(
0
,
1
)
==
'.'
)
{
value_
=
0
}
if
(
value_
==
''
)
{
value_
=
0
}
value_
=
value_
.
replace
(
/^0*
(
0
\.
|
[
1-9
])
/
,
'$1'
)
// 禁止粘贴
value_
=
value_
.
replace
(
/
[^\d
.
]
/g
,
'0.00'
)
// 禁止输入非数字
value_
=
value_
.
replace
(
/
\.{2,}
/g
,
'.'
)
// 只保留第一个. 清除多余的
value_
=
value_
.
replace
(
'.'
,
'$#$'
).
replace
(
/
\.
/g
,
''
).
replace
(
'$#$'
,
'.'
)
value_
=
value_
.
replace
(
/^
(\-)
*
(\d
+
)\.(\d\d)
.*$/
,
'$1$2.$3'
)
// 只能输入两个小数
var
isEndOfDot
=
value_
[
value_
.
length
-
1
]
==
'.'
;
if
(
isEndOfDot
&&
isNeedSubLastDot
)
{
value_
=
value_
.
substr
(
0
,
value_
.
length
-
1
)
}
if
(
value_
.
indexOf
(
'.'
)
<
0
&&
value_
!=
''
)
{
// 以上已经过滤,此处控制的是如果没有小数点,首位不能为类似于 01、02的金额
if
(
value_
.
substr
(
0
,
1
)
==
'0'
&&
value_
.
length
==
2
)
{
value_
=
value_
.
substr
(
1
,
value_
.
length
)
}
}
if
(
!
value_
)
{
value_
=
0
}
var
isContainDotZero
=
value_
.
endsWith
(
".00"
)
var
dotIndex
=
value_
.
indexOf
(
'.'
);
var
isHadDotNumber
=
dotIndex
>
0
&&
dotIndex
!=
(
value_
.
length
-
1
);
//是否已经有了小数位
if
(
isNeedAddZero
&&
!
isContainDotZero
&&
!
isHadDotNumber
)
{
var
suffix
=
isEndOfDot
?
"00"
:
".00"
;
value_
=
value_
+
suffix
;
}
else
if
(
isNeedAddZero
&&
isHadDotNumber
&&
dotIndex
==
(
value_
.
length
-
2
))
{
//11.1
//如果已经有了小数位,并且只有一位小数末尾,在添加一个0
value_
=
value_
+
"0"
;
}
return
value_
;
}
export
default
{
getSystemInfo
,
combine3
,
request
,
showRequestLoading
,
upload
,
getParamWrapper
,
isLogin
,
getUser
,
timestamp
,
save
,
saveSync
,
get
,
showToast
,
toastError
,
logMsg
,
logObj
,
signOut
,
moneyFormat
,
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment