Commit 3aa39181 authored by shiyuelong's avatar shiyuelong
parents ff289290 41d927be
......@@ -25,8 +25,8 @@ class AppConfig {
const val SinaCallBackUrl = "https://api.weibo.com/oauth2/default.html"
const val FileProvider = "com.shenghuoquan.business.provider"
const val privacyPolicyStatement = "http://www.yidianzixun.com/landing_privacy?yidian_fs=2"
const val userProtocol = "http://www.yidianzixun.com/landing_agreement?yidian_fs=2"
const val privacyPolicyStatement = "https://www.appgc.cn/plugins/privacy/content?type=privacy&appId=1080334&ver=210601"
const val userProtocol = "https://www.appgc.cn/plugins/privacy/content?type=mp&appId=1080334&ver=210601"
const val UMAppKey = "60c8479fe044530ff0a49936"//umeng统计key注释
const val UMChannel = "ANDROID_CHANNEL"
......
......@@ -53,5 +53,7 @@ class XRouterPathConstants {
const val MERCHANT_INFO = "/merchantInfo"
// 生活号修改名称
const val LIFE_ACCOUNT_MODIFY_NAME = "/lifeAccountModifyName"
// 商户认证信息
const val MERCHANT_AUTH_INFO = "/merchantAuthInfo"
}
}
package com.yidian.common.http
import android.annotation.SuppressLint
import android.app.Activity
import androidx.fragment.app.Fragment
import com.google.gson.Gson
import com.google.gson.JsonParseException
import com.google.gson.reflect.TypeToken
import com.yidian.common.XRouterPathConstants
import com.yidian.common.YdBaseApplication
import com.yidian.common.constant.ResultCode
import com.yidian.utils.ToastUtil
import com.yidian.xpage.XPageManager
import io.reactivex.rxjava3.core.Observer
import io.reactivex.rxjava3.disposables.Disposable
import java.lang.reflect.ParameterizedType
import kotlin.reflect.typeOf
abstract class HttpResultSubscriber<T>(private var showProgress: Boolean = false) : Observer<HttpResult<Any?>> {
private var isShowErrorMsg = true
......@@ -55,6 +52,8 @@ abstract class HttpResultSubscriber<T>(private var showProgress: Boolean = false
val type = (this.javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
val decodeResult = HttpParamsUtils.rsaDecryptResult<T>(res, type)
onRequestSuccess(decodeResult)
} else if (res.code == ResultCode.INVALID) {
XPageManager.push(XRouterPathConstants.LOGIN_LIFE_CIRCLE, null)
} else {
val decodeResult = HttpResult<T>()
decodeResult.code = res.code
......
......@@ -46,5 +46,6 @@ class URLs {
const val authEnterpriseLiveIdentity = "/merchant/enterprise/live"
const val authIndividualBusinessComplete = "/merchant/enterprise/employed_complate"
const val getConfigList = "/config/switch/list"
const val getLifeAccountInfoById = "/merchant/enterprise/get_account_by_lid"
}
}
......@@ -132,6 +132,10 @@
android:theme="@style/Transparent"
android:windowSoftInputMode="stateVisible" />
<activity
android:name=".ui.center.MerchantAuthInfoActivity"
android:theme="@style/Transparent" />
</application>
</manifest>
\ No newline at end of file
......@@ -15,6 +15,7 @@ import com.yidian.common.XRouterPathConstants.Companion.LIFE_ACCOUNT_MODIFY_NAME
import com.yidian.common.XRouterPathConstants.Companion.LIFE_ACCOUNT_PERSONAL_AUTH
import com.yidian.common.XRouterPathConstants.Companion.LIFE_ACCOUNT_PERSONAL_AUTH_COMPLETE
import com.yidian.common.XRouterPathConstants.Companion.LOGIN_LIFE_CIRCLE
import com.yidian.common.XRouterPathConstants.Companion.MERCHANT_AUTH_INFO
import com.yidian.common.XRouterPathConstants.Companion.MERCHANT_CENTER
import com.yidian.common.XRouterPathConstants.Companion.MERCHANT_INFO
import com.yidian.common.XRouterPathConstants.Companion.NEWS_CONTENT
......@@ -37,6 +38,7 @@ import com.yidian.shenghuoquan.newscontent.service.*
import com.yidian.shenghuoquan.newscontent.ui.*
import com.yidian.shenghuoquan.newscontent.ui.auth.*
import com.yidian.shenghuoquan.newscontent.ui.center.LifeAccountModifyNameActivity
import com.yidian.shenghuoquan.newscontent.ui.center.MerchantAuthInfoActivity
import com.yidian.shenghuoquan.newscontent.ui.center.MerchantCenterActivity
import com.yidian.shenghuoquan.newscontent.ui.center.MerchantInfoActivity
import com.yidian.shenghuoquan.newscontent.ui.idcard.IDCardTestActivity
......@@ -363,6 +365,17 @@ class NewsContentApplication : YdBaseApplication() {
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(intent)
}
}),
XPageNode(MERCHANT_AUTH_INFO, XPageNodePageType.NATIVE, object : XPageHandler {
override fun handler(params: Map<String, Any?>?) {
val intent = Intent()
if (params != null) {
intent.putExtra(XRouterPathConstants.ParamsKey, params as HashMap)
}
intent.setClass(context, MerchantAuthInfoActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(intent)
}
})
)
)
......
......@@ -472,6 +472,25 @@ class ApiService {
})
}
// 418 根据生活号id返回认证信息
fun getLifeAccountInfoById(apiCallback: IGetLifeAccountInfoByIdCallback, requestParams: HashMap<String, String?>) {
val timeStamp = System.currentTimeMillis()
val publicParamsMap = HttpParamsUtils.getPublicParamsMap(timeStamp)
val privateParamsMap = HttpParamsUtils.getPrivateParamsMap(requestParams, timeStamp)
ServiceFactory.getInstance().createService(CommonService::class.java)
.getLifeAccountInfoById(publicParamsMap, privateParamsMap)
.compose(TransformUtil.defaultSchedulers())
.subscribe(object : HttpResultSubscriber<GetLifeAccountInfoByIdBean.Response?>() {
override fun onSuccess(result: HttpResult<GetLifeAccountInfoByIdBean.Response?>?) {
apiCallback.getLifeAccountInfoByIdSuccess(result?.result)
}
override fun onFailer(result: HttpResult<GetLifeAccountInfoByIdBean.Response?>?) {
apiCallback.getLifeAccountInfoByIdFailure(result?.reason)
}
})
}
// 521 管理中心开关接口
fun getConfigList(apiCallback: IGetConfigListCallback) {
val timeStamp = System.currentTimeMillis()
......
......@@ -130,4 +130,11 @@ interface CommonService {
@GET(URLs.getConfigList)
fun getConfigList(@QueryMap commonParams: Map<String, String>): Observable<HttpResult<Any?>>
@Headers("Content-Type: application/json")
@POST(URLs.getLifeAccountInfoById)
fun getLifeAccountInfoById(
@QueryMap commonParams: Map<String, String>,
@Body requestParams: Map<String, String?>
): Observable<HttpResult<Any?>>
}
package com.yidian.shenghuoquan.newscontent.http.callback
import com.yidian.shenghuoquan.newscontent.http.httpbean.GetLifeAccountInfoByIdBean
/**
* author: yinjiacheng
* date: 6/15/21 4:10 PM
* description: API /merchant/enterprise/get_account_by_lid
*/
interface IGetLifeAccountInfoByIdCallback {
fun getLifeAccountInfoByIdSuccess(result: GetLifeAccountInfoByIdBean.Response?)
fun getLifeAccountInfoByIdFailure(message: String?)
}
\ No newline at end of file
package com.yidian.shenghuoquan.newscontent.http.httpbean
import java.io.Serializable
/**
* author: yinjiacheng
* date: 6/15/21 4:11 PM
* description: API /merchant/enterprise/get_account_by_lid
*/
class GetLifeAccountInfoByIdBean {
data class Request(val life_account_id: Long)
data class Response(
val code: String,
val create_time: String,
val create_user_mobile: String,
val create_user_nick_name: String,
val full_name: String,
val id_card: String,
val id_type: Int,
val life_account_auth_status: Int,
val life_account_id: Long,
val life_account_name: String,
val life_account_status: Int,
val life_account_type: Int,
val name: String,
val occupation: String,
val legal_person: String
) : Serializable
}
\ No newline at end of file
......@@ -2,6 +2,7 @@ package com.yidian.shenghuoquan.newscontent.ui
import android.os.Bundle
import com.orhanobut.hawk.Hawk
import com.yidian.common.AppConfig
import com.yidian.common.HawkConfig
import com.yidian.common.XRouterPathConstants
import com.yidian.common.XRouterPathConstants.Companion.LOGIN_LIFE_CIRCLE
......@@ -105,11 +106,15 @@ class LoginLifeCircleActivity : BaseActivity<ActivityLoginBinding>(), IGetLifeAc
}
viewBind.tvProtocol.setOnClickListener {
ToastUtil.showToast(this, "用户协议")
val urlMap = HashMap<String, String>()
urlMap[ProtocolActivity.ProtocolUrlKey] = AppConfig.userProtocol
XPageManager.push(XRouterPathConstants.PROTOCOL, urlMap)
}
viewBind.tvPrivacy.setOnClickListener {
ToastUtil.showToast(this, "隐私政策")
val urlMap = HashMap<String, String>()
urlMap[ProtocolActivity.ProtocolUrlKey] = AppConfig.privacyPolicyStatement
XPageManager.push(XRouterPathConstants.PROTOCOL, urlMap)
}
}
......
package com.yidian.shenghuoquan.newscontent.ui.center
import android.os.Bundle
import com.yidian.common.XRouterPathConstants
import com.yidian.common.base.BaseActivity
import com.yidian.shenghuoquan.newscontent.databinding.ActivityMerchantAuthInfoBinding
import com.yidian.shenghuoquan.newscontent.http.httpbean.GetLifeAccountInfoByIdBean
/**
* author: yinjiacheng
* date: 6/15/21 9:52 AM
* description: 商户认证信息详情页
*/
class MerchantAuthInfoActivity : BaseActivity<ActivityMerchantAuthInfoBinding>() {
private val lifeAccountInfo by lazy {
intent.getSerializableExtra(XRouterPathConstants.ParamsKey)?.let {
it as GetLifeAccountInfoByIdBean.Response
}
}
override fun createViewBinding(): ActivityMerchantAuthInfoBinding {
return ActivityMerchantAuthInfoBinding.inflate(layoutInflater)
}
override fun getXPageName(): String {
return XRouterPathConstants.MERCHANT_AUTH_INFO
}
override fun init(savedInstanceState: Bundle?) {
super.init(savedInstanceState)
initView()
initListener()
initData()
}
private fun initView() {
}
private fun initListener() {
}
private fun initData() {
viewBind.ivPersonAuthInfo.fillAuthInfo(
lifeAccountInfo?.occupation,
lifeAccountInfo?.legal_person,
lifeAccountInfo?.id_card,
lifeAccountInfo?.create_user_mobile
)
}
}
\ No newline at end of file
......@@ -10,7 +10,9 @@ import com.yidian.shenghuoquan.newscontent.constant.Constant
import com.yidian.shenghuoquan.newscontent.databinding.ActivityMerchantInfoBinding
import com.yidian.shenghuoquan.newscontent.http.ApiService
import com.yidian.shenghuoquan.newscontent.http.callback.IAuthMerchantCheckCallback
import com.yidian.shenghuoquan.newscontent.http.callback.IGetLifeAccountInfoByIdCallback
import com.yidian.shenghuoquan.newscontent.http.httpbean.AuthMerchantCheckBean
import com.yidian.shenghuoquan.newscontent.http.httpbean.GetLifeAccountInfoByIdBean
import com.yidian.shenghuoquan.newscontent.http.httpbean.LifeAccountItemBean
import com.yidian.shenghuoquan.newscontent.ui.auth.LifeAccountEnterpriseAuthActivity
import com.yidian.shenghuoquan.newscontent.widget.MerchantInfoView
......@@ -22,7 +24,8 @@ import com.yidian.xpage.XPageManager
* description: 商户基本信息
*/
class MerchantInfoActivity : BaseActivity<ActivityMerchantInfoBinding>(), View.OnClickListener,
MerchantInfoView.OnMerchantInfoViewListener, IAuthMerchantCheckCallback {
MerchantInfoView.OnMerchantInfoViewListener, IAuthMerchantCheckCallback,
IGetLifeAccountInfoByIdCallback {
companion object {
const val EXTRA_LIFE_ACCOUNT_INFO = "lifeAccountInfo"
......@@ -61,6 +64,9 @@ class MerchantInfoActivity : BaseActivity<ActivityMerchantInfoBinding>(), View.O
private fun initListener() {
viewBind.viewCommonHeader.ivBack.setOnClickListener(this)
viewBind.ivLifeAccountName.setOnMerchantInfoViewListener(this)
viewBind.ivLifeAccountAuth.setOnMerchantInfoViewListener(this)
viewBind.ivLifeAccountAuthUpgrade.setOnMerchantInfoViewListener(this)
}
private fun initData() {
......@@ -113,6 +119,28 @@ class MerchantInfoActivity : BaseActivity<ActivityMerchantInfoBinding>(), View.O
override fun onEnterDetail(from: MerchantInfoView) {
// 进入生活号名称修改页或认证信息详情
if (from == viewBind.ivLifeAccountName) {
// 跳转生活号名称修改页
XPageManager.push(
XRouterPathConstants.LIFE_ACCOUNT_MODIFY_NAME,
hashMapOf(
Pair(
LifeAccountModifyNameActivity.EXTRA_LIFE_ACCOUNT_ID,
lifeAccountInfo?.life_account_id
),
Pair(
LifeAccountModifyNameActivity.EXTRA_LIFE_ACCOUNT_NAME,
lifeAccountInfo?.life_account_name
)
)
)
} else if (from == viewBind.ivLifeAccountAuth) {
// 请求生活号详情接口 跳转认证详情页
ApiService.getLifeAccountInfoById(
this,
hashMapOf(Pair(PARAMS_LIFE_ACCOUNT_ID, lifeAccountInfo?.life_account_id.toString()))
)
}
}
override fun onEnterAuth(from: MerchantInfoView) {
......@@ -164,4 +192,16 @@ class MerchantInfoActivity : BaseActivity<ActivityMerchantInfoBinding>(), View.O
}
override fun getLifeAccountInfoByIdSuccess(result: GetLifeAccountInfoByIdBean.Response?) {
// 跳转认证详情页
XPageManager.push(
XRouterPathConstants.MERCHANT_AUTH_INFO,
hashMapOf(Pair(XRouterPathConstants.ParamsKey, result))
)
}
override fun getLifeAccountInfoByIdFailure(message: String?) {
}
}
\ No newline at end of file
......@@ -35,7 +35,7 @@ class CommonTopBarView @JvmOverloads constructor(
val typeArray = context.obtainStyledAttributes(attrs, R.styleable.CommonTopBarView)
viewBinding.tvTitle.text =
typeArray.getText(R.styleable.CommonTopBarView_CommonTopBarView_title_text)
typeArray.getText(R.styleable.CommonTopBarView_CommonTopBarView_action_text).let {
typeArray.getText(R.styleable.CommonTopBarView_CommonTopBarView_action_text)?.let {
if (it.isNotEmpty()) visibility = View.VISIBLE
viewBinding.tvAction.text = it
}
......
......@@ -72,7 +72,7 @@ class LifeAccountLabelView @JvmOverloads constructor(
curLifeAccount = data
viewBinding.tvLifeAccountName.text = data.life_account_name
viewBinding.tvLifeAccountStatus.apply {
when (data.life_account_status) {
when (data.life_account_auth_status) {
STATUS_LIFE_ACCOUNT_NOT_AUTH -> {
// 未认证
setBackgroundResource(R.drawable.shape_life_account_status_unauth)
......
package com.yidian.shenghuoquan.newscontent.widget
import android.content.Context
import android.util.AttributeSet
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import com.yidian.shenghuoquan.newscontent.R
import com.yidian.shenghuoquan.newscontent.databinding.ViewLifeAccountPersonalAuthInfoBinding
/**
* author: yinjiacheng
* date: 6/15/21 10:48 AM
* description: 生活号个人认证信息
*/
class LifeAccountPersonalAuthInfoView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : ConstraintLayout(context, attrs, defStyle) {
private val viewBinding by lazy {
ViewLifeAccountPersonalAuthInfoBinding.bind(
View.inflate(
getContext(),
R.layout.view_life_account_personal_auth_info,
this
)
)
}
/**
* 填充认证信息
* @param occupation 职业
* @param realName 真实姓名
* @param idCardNo 身份证号
* @param phoneNo 手机号
*/
fun fillAuthInfo(occupation: String?, realName: String?, idCardNo: String?, phoneNo: String?) {
viewBinding.tvContentOccupationLabel.text = occupation
viewBinding.tvContentRealName.text = realName
viewBinding.tvContentIdCardNo.text = idCardNo
viewBinding.tvContentPhoneNo.text = phoneNo
}
}
\ No newline at end of file
......@@ -30,6 +30,8 @@ class MerchantInfoView @JvmOverloads constructor(
viewBinding.tvTitle.text =
typeArray.getString(R.styleable.MerchantInfoView_MerchantInfoView_name_text)
typeArray.recycle()
viewBinding.ivNext.setOnClickListener(this)
viewBinding.tvAuth.setOnClickListener(this)
}
/**
......
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/color_FFF26E3D" />
<corners android:radius="12dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.yidian.shenghuoquan.newscontent.widget.CommonTopBarView
android:id="@+id/bv_top_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:CommonTopBarView_title_text="@string/life_account_auth_info"
app:layout_constraintTop_toTopOf="parent" />
<com.yidian.shenghuoquan.newscontent.widget.LifeAccountPersonalAuthInfoView
android:id="@+id/iv_person_auth_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp29"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/bv_top_bar" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="@dimen/dp283"
android:layout_height="@dimen/dp259"
android:layout_marginTop="32dp"
android:background="@drawable/shape_bg_merchant_info"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp19"
android:layout_marginTop="@dimen/dp47"
android:includeFontPadding="false"
android:text="@string/personal_shop"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_title_occupation_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp22"
android:includeFontPadding="false"
android:text="@string/occupation_label"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="@id/tv_title"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<TextView
android:id="@+id/tv_content_occupation_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp92"
android:layout_marginTop="@dimen/dp22"
android:includeFontPadding="false"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<TextView
android:id="@+id/tv_title_real_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp19"
android:includeFontPadding="false"
android:text="@string/real_name"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="@id/tv_title"
app:layout_constraintTop_toBottomOf="@id/tv_title_occupation_label" />
<TextView
android:id="@+id/tv_content_real_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp92"
android:layout_marginTop="@dimen/dp19"
android:includeFontPadding="false"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title_occupation_label" />
<TextView
android:id="@+id/tv_title_id_card_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp19"
android:includeFontPadding="false"
android:text="@string/id_card_number"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="@id/tv_title"
app:layout_constraintTop_toBottomOf="@id/tv_content_real_name" />
<TextView
android:id="@+id/tv_content_id_card_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp92"
android:layout_marginTop="@dimen/dp19"
android:includeFontPadding="false"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_content_real_name" />
<TextView
android:id="@+id/tv_title_phone_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp19"
android:includeFontPadding="false"
android:text="@string/phone_number"
android:textColor="@color/color_999999"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="@id/tv_title"
app:layout_constraintTop_toBottomOf="@id/tv_title_id_card_no" />
<TextView
android:id="@+id/tv_content_phone_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp92"
android:layout_marginTop="@dimen/dp19"
android:includeFontPadding="false"
android:textColor="@color/color_333333"
android:textSize="@dimen/sp15"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title_id_card_no" />
<View
android:layout_width="@dimen/dp49"
android:layout_height="@dimen/dp59"
android:layout_marginTop="@dimen/dp36"
android:background="@mipmap/icon_seal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/view_top"
android:layout_width="@dimen/dp322"
android:layout_height="@dimen/dp54"
android:background="@mipmap/icon_shop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
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