新增模拟功能

This commit is contained in:
zhanglei
2025-12-30 09:39:58 +08:00
parent ca0e318bd0
commit 73f25d9e18
14 changed files with 2305 additions and 6 deletions
+2
View File
@@ -184,6 +184,8 @@
<activity
android:name="com.sw.healthyclients.ui.guidance.ViewLocationActivity"
android:screenOrientation="portrait" />
<activity android:name=".ui.activity.SimulateUserActivity"
android:screenOrientation="portrait" />
</application>
@@ -0,0 +1,41 @@
package com.xjjk.healthyclients.adapter
import com.chad.library.adapter.base.viewholder.BaseDataBindingHolder
import com.xjjk.healthyclients.R
import com.xjjk.healthyclients.adapter.common.BaseDataBindingAdapter
import com.xjjk.healthyclients.bean.UserListBean
import com.xjjk.healthyclients.databinding.ItemUserListBinding
import com.xjjk.healthyclients.superfuntion.loadRoundedImage
/**
* @author nanfeifei
* @time 2023/7/17 16:40
* @description
*/
class UserListAdapter : BaseDataBindingAdapter<UserListBean.RecordsDTO, ItemUserListBinding>(
R.layout.item_user_list
) {
override fun convert(
holder: BaseDataBindingHolder<ItemUserListBinding>,
item: UserListBean.RecordsDTO
) {
val mBinding = holder.dataBinding
mBinding?.let {
it.tvAccount.text = item.username
it.tvName.text = item.realname
it.userNum.text = "员工编号:" + item.workNo + " 手机号:" + item.phone
it.userIdCard.text = "身份证号:" + item.idCard
if (!item.departTree.isNullOrEmpty()) {
if (item.departTree.size > 2) {
it.tvUnit.text = item.departTree.get(1)
it.tvClass.text = item.departTree.get(2)
} else if (item.departTree.size > 1) {
it.tvUnit.text = item.departTree.get(0)
it.tvClass.text = item.departTree.get(1)
}
}
it.ivHead.loadRoundedImage(item.avatar, 5.0f)
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,47 @@
package com.xjjk.healthyclients.data.api
import com.xjjk.healthyclients.bean.UserListBean
import com.xjjk.healthyclients.data.bean.ApiResponse
import okhttp3.RequestBody
import retrofit2.http.Body
import retrofit2.http.FieldMap
import retrofit2.http.FormUrlEncoded
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.QueryMap
/**
* @author nanfeifei
* @time 2023/5/24 15:08
* @description 工作台接口定义
*/
interface OtherApi {
/**
* 获取模拟用户列表
*/
@GET("/health-system/sys/user/listAll")
suspend fun listAll(@QueryMap params: MutableMap<String, Any?>): ApiResponse<UserListBean>
/**
* 模拟用户信息
*/
@FormUrlEncoded
@POST("/health-system/test/fake")
suspend fun fake(@FieldMap params: MutableMap<String, Any?>): ApiResponse<Boolean>
/**
* 获取模拟用户信息
*/
@POST("/health-system/test/fakeUser")
suspend fun fakeUser(@Body requestBody: RequestBody): ApiResponse<UserListBean.RecordsDTO>
/**
* 重置模拟
*/
@POST("/health-system/test/restore")
suspend fun restore(@Body requestBody: RequestBody): ApiResponse<Boolean>
/**
* 校验token是否过期
*/
@GET("/health-consultation/api/consult/msgRecord/selectTokenExpire")
suspend fun selectTokenExpire(@QueryMap params: MutableMap<String, Any?>): ApiResponse<Boolean>
}
@@ -0,0 +1,60 @@
package com.xjjk.healthyclients.data.repository
import com.xjjk.healthyclients.base.repository.BaseRepository
import com.xjjk.healthyclients.bean.UserListBean
import com.xjjk.healthyclients.data.api.OtherApi
import com.xjjk.healthyclients.data.bean.ApiResponse
import com.xjjk.healthyclients.retrofit.RetrofitManager
import com.xjjk.healthyclients.retrofit.RetrofitManager.toRequestBody
import com.xjjk.healthyclients.superfuntion.toJson
object OtherRepository : BaseRepository() {
private val service by lazy { RetrofitManager.getService(OtherApi::class.java) }
suspend fun getList(
username: String
): ApiResponse<UserListBean> {
val params = mutableMapOf<String, Any?>()
params["personType"] = 1
params["username"] = username
params["pageNo"] = 1
params["pageSize"] = 100
return apiCall {
service.listAll(params)
}
}
suspend fun simulateUser(
userId: String
): ApiResponse<Boolean> {
val params = mutableMapOf<String, Any?>()
params["userId"] = userId
return apiCall { service.fake(params) }
}
suspend fun fakeUser(
): ApiResponse<UserListBean.RecordsDTO> {
val params = mutableMapOf<String, Any?>()
// params["X-Access-Token"] = DataStoreManager.getToken()
return apiCall { service.fakeUser(params.toJson().toRequestBody()) }
}
suspend fun restore(
): ApiResponse<Boolean> {
val params = mutableMapOf<String, Any?>()
// params["userId"] = userId
return apiCall { service.restore(params.toJson().toRequestBody()) }
}
/**
* 校验token有效性
*/
suspend fun selectTokenExpire(token:String): ApiResponse<Boolean> {
return apiCall {
val map = mutableMapOf<String, Any?>()
map.put("token",token)
service.selectTokenExpire(map)
}
}
}
@@ -18,6 +18,7 @@ import com.xjjk.healthyclients.superfuntion.loadCircle
import com.xjjk.healthyclients.superfuntion.startConsultantManagerActivity
import com.xjjk.healthyclients.superfuntion.startEmergencySeekDoctorActivity
import com.xjjk.healthyclients.superfuntion.startLoginActivity
import com.xjjk.healthyclients.superfuntion.startSimulateUserActivity
import com.xjjk.healthyclients.superfuntion.startUserInfoSettingActivity
import com.xjjk.healthyclients.superfuntion.startUserMyGuidanceActivity
import com.xjjk.healthyclients.superfuntion.startUserSettingActivity
@@ -72,7 +73,7 @@ class UserInfoFragment :
if (mHits[0] >= (SystemClock.uptimeMillis() - time)) {
//数组重新初始化
mHits = LongArray(mCount)
// startSimulateUserActivity(requireContext())
startSimulateUserActivity(requireContext())
}
}
@@ -12,6 +12,7 @@ import com.xjjk.healthyclients.ui.activity.EmergencyContactActivity
import com.xjjk.healthyclients.ui.activity.FullScreenImageActivity
import com.xjjk.healthyclients.ui.activity.LoginActivity
import com.xjjk.healthyclients.ui.activity.RetrievePassWordActivity
import com.xjjk.healthyclients.ui.activity.SimulateUserActivity
import com.xjjk.healthyclients.ui.activity.UserInfoSettingActivity
import com.xjjk.healthyclients.ui.activity.UserSettingActivity
import com.xjjk.healthyclients.ui.activity.UserSoSContactsActivity
@@ -25,7 +26,6 @@ import com.xjjk.healthyclients.ui.activity.guidance.BaseHealthyInfoAddActivity
import com.xjjk.healthyclients.ui.activity.guidance.ConsultArchivesDetailActivity
import com.xjjk.healthyclients.ui.activity.guidance.ConsultantManagerActivity
import com.xjjk.healthyclients.ui.activity.guidance.DoctorAllAppraiseActivity
import com.xjjk.healthyclients.ui.activity.guidance.DoctorHomepageActivity
import com.xjjk.healthyclients.ui.activity.guidance.EditConsultantActivity
import com.xjjk.healthyclients.ui.activity.guidance.GeneralPracticeGuidanceActivity
import com.xjjk.healthyclients.ui.activity.guidance.GuidanceNoticeActivity
@@ -1373,9 +1373,9 @@ fun Context.startAllDoctorActivity(id:String) {
///**
// * 模拟用户
// */
//fun startSimulateUserActivity(context: Context){
// startActivity(context, targetClass = SimulateUserActivity::class.java)
//}
fun startSimulateUserActivity(context: Context){
startActivity(context, targetClass = SimulateUserActivity::class.java)
}
//
///**
// * 自由训练记录列表
@@ -169,7 +169,7 @@ class LoginActivity : BaseVMBActivity<LoginViewModel, ActivityLoginNewBinding>(R
mHits = LongArray(mCount)
isAdminEnable=true
mBinding.loginEtUserName.setText("admin")
mBinding.loginEtUserPassword.setInputContext("&ZzW$3**@VLA")
mBinding.loginEtUserPassword.setInputContext("#fCjW%x2dv@a")
showToast("已开启专业模式")
mCount = 5
@@ -0,0 +1,145 @@
package com.xjjk.healthyclients.ui.activity
import android.os.Bundle
import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemClickListener
import com.google.gson.Gson
import com.sw.healthyclients.data.local.DataStoreManager
import com.xjjk.healthyclients.R
import com.xjjk.healthyclients.adapter.UserListAdapter
import com.xjjk.healthyclients.base.BaseVMBActivity
import com.xjjk.healthyclients.bean.UserListBean
import com.xjjk.healthyclients.databinding.ActivitySumilateBinding
import com.xjjk.healthyclients.event.UserInfoEvent
import com.xjjk.healthyclients.superfuntion.getEmptyView
import com.xjjk.healthyclients.superfuntion.orEmptyDefault
import com.xjjk.healthyclients.ui.viewmodel.SimulateUserViewModel
import com.xjjk.healthyclients.utils.CommonUtils
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
/**
* @author nanfeifei
* @time 2023/7/17 16:20
* @description
*/
class SimulateUserActivity: BaseVMBActivity<SimulateUserViewModel, ActivitySumilateBinding>(R.layout.activity_sumilate),
SwipeRefreshLayout.OnRefreshListener, OnItemClickListener {
private val mAdapter: UserListAdapter = UserListAdapter()
var userName=""
override fun initView(savedInstanceState: Bundle?) {
mBinding.apply {
val linearLayoutManager = LinearLayoutManager(this@SimulateUserActivity
)
rvList.layoutManager = linearLayoutManager
csvSearch.initView("请输入模拟用户账号")
csvSearch.setOnCustomClickListener {
userName= it
onRefresh()
}
btnReset.setOnClickListener {
var bean2= DataStoreManager.getUserInfo2()
CommonUtils.loginSaveData(bean2)
mViewModel.restore()
}
}
}
override fun initData() {
mViewModel.fakeUser(){}
}
override fun createObserve() {
super.createObserve()
mBinding.apply {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.userList.collectLatest { list ->
list?.let {
mAdapter.setNewInstance(list.records)
mAdapter.notifyDataSetChanged()
if (rvList.adapter == null) {
mAdapter.setEmptyView(rvList.getEmptyView())
mAdapter.setOnItemClickListener(this@SimulateUserActivity)
// initLoadMore()
rvList.adapter = mAdapter
}
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.isSimuLateState.collectLatest { state ->
if (state){
mViewModel.fakeUser(){bean->
DataStoreManager.saveUserInfo2(Gson().toJson(DataStoreManager.getUserInfo()))
var bean2= DataStoreManager.getUserInfo()
bean2.id=bean.id
bean2.username=bean.username
bean2.orgCode=bean.orgCode
bean2.birthday=bean.birthday
bean2.phone=bean.phone
bean2.avatar=bean.avatar
bean2.idCard=bean.idCard
bean2.workNo=bean.workNo
bean2.realname=bean.realname
bean2.sex=bean.sex
CommonUtils.loginSaveData(bean2)
EventBus.getDefault().post(UserInfoEvent())
finish()
}
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.isResetState.collectLatest { state ->
if (state){
mBinding.tvUserName.text="当前模拟的用户:--"
EventBus.getDefault().post(UserInfoEvent())
}
}
}
}
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.CREATED) {
mViewModel.userBean.collectLatest { bean ->
if (bean!=null){
// mBinding.llUser.visibility=View.VISIBLE
mBinding.tvUserName.text="当前模拟的用户:"+bean.realname.orEmptyDefault()
}else{
// mBinding.llUser.visibility=View.GONE
mBinding.tvUserName.text="当前模拟的用户:--"
}
}
}
}
}
}
override fun bindEvent() {
}
override fun processClick(v: View?) {
}
override fun onRefresh() {
mViewModel.getMessageList(userName)
}
override fun onItemClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
var bean=mAdapter?.getItem(position) as UserListBean.RecordsDTO
mViewModel.simulateUser(bean.id)
}
}
@@ -0,0 +1,101 @@
package com.xjjk.healthyclients.ui.viewmodel
import com.sw.healthyclients.data.local.DataStoreManager
import com.xjjk.healthyclients.base.viewmodel.BaseViewModel
import com.xjjk.healthyclients.bean.UserListBean
import com.xjjk.healthyclients.data.repository.OtherRepository
import com.xjjk.healthyclients.superfuntion.handleRequest
import com.xjjk.healthyclients.superfuntion.launch
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
/**
* @author nanfeifei
* @time 2023/7/17 16:19
* @description
*/
class SimulateUserViewModel: BaseViewModel() {
var userList = MutableSharedFlow<UserListBean>()
var userBean = MutableSharedFlow<UserListBean.RecordsDTO>()
var pageIndex = MutableStateFlow(1)
var isRefreshing = MutableStateFlow(false)
var isSimuLateState = MutableSharedFlow<Boolean>()
var isResetState = MutableStateFlow(false)
var isLoadMoreEnd = MutableSharedFlow<Boolean>()
var tokenOverdue = MutableSharedFlow<Boolean>()
private val pageSize = 20
override fun init() {
getMessageList("")
}
fun getMessageList(username: String){
launch(tryBlock = {
handleRequest(OtherRepository.getList(username), successBlock = {
if(it.result == null){
}else{
userList.emit(it.result!!)
}
})
}, finallyBlock = {
isRefreshing.emit(false)
})
}
fun simulateUser(userid: String){
launch(tryBlock = {
handleRequest(OtherRepository.simulateUser(userid), successBlock = {
if (it.result == true){
isSimuLateState.emit(true)
}else{
isSimuLateState.emit(false)
}
})
}, finallyBlock = {
isRefreshing.emit(false)
})
}
fun fakeUser(method:(bean: UserListBean.RecordsDTO)->Unit){
launch(tryBlock = {
handleRequest(OtherRepository.fakeUser(), successBlock = {
if (it.result !=null){
method(it.result!!)
userBean.emit(it.result!!)
}else{
userBean.emit(UserListBean.RecordsDTO())
}
})
}, finallyBlock = {
isRefreshing.emit(false)
})
}
fun restore(){
launch(tryBlock = {
handleRequest(OtherRepository.restore(), successBlock = {
if (it.result == true){
isResetState.emit(true)
}else{
isResetState.emit(false)
}
})
}, finallyBlock = {
isRefreshing.emit(false)
})
}
/**
* token有效性
*/
fun selectTokenExpire() {
launch(
{
handleRequest(
OtherRepository.selectTokenExpire(DataStoreManager.getToken()),
successBlock = {
it.result?.let { result ->
tokenOverdue.emit(result)
}
})
}
)
}
}
@@ -0,0 +1,97 @@
package com.xjjk.healthyclients.view
import android.content.Context
import android.text.Editable
import android.text.TextUtils
import android.text.TextWatcher
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import android.widget.RelativeLayout
import androidx.databinding.DataBindingUtil
import com.sw.healthyclients.utils.KeyboardUtil.hideSoftInput
import com.xjjk.healthyclients.R
import com.xjjk.healthyclients.databinding.CustomSearchViewBinding
class CustomSearchView : RelativeLayout {
var mContext:Context?=null
lateinit var mBinding: CustomSearchViewBinding
constructor(context: Context?,attrs : AttributeSet?): super(context, attrs,0){
mContext=context
if(isInEditMode){
LayoutInflater.from(context).inflate(R.layout.custom_search_view, this, true)
}else{
mBinding = DataBindingUtil.inflate(
LayoutInflater.from(context),
R.layout.custom_search_view, this,true)
}
}
fun initView(hint:String){
mBinding.customSearchEt.hint="$hint"
}
fun initEtContext(value:String?){
mBinding.customSearchEt.setText(value)
}
fun setPerformClick(){
mBinding.customSearchTv.performClick()
}
fun setOnCustomClickListener(method: (searchContent: String) -> Unit): String {
mBinding.customSearchTv.setOnClickListener {
hideSoftInput(context, mBinding.customSearchEt)
var value = mBinding.customSearchEt.text.trim().toString()
method(value)
}
//输入内容为空时回调
mBinding.customSearchEt.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(
s: CharSequence?,
start: Int,
count: Int,
after: Int
) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (TextUtils.isEmpty(s)) {
// method("")
mBinding.customSearchTv.performClick()
}
}
override fun afterTextChanged(s: Editable?) {
}
})
mBinding.customSearchEt.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
//点击搜索的时候隐藏软键盘
hideSoftInput(context, v as EditText)
var value = mBinding.customSearchEt.text.trim().toString()
method(value)
}
false
}
return mBinding.customSearchEt.text.trim().toString()
}
fun setFocusListener(method: (hasFocus:Boolean) -> Unit){
mBinding.customSearchEt.setOnFocusChangeListener(object: OnFocusChangeListener{
override fun onFocusChange(v: View?, hasFocus: Boolean) {
method(hasFocus)
}
})
}
fun getInoputText():String{
return mBinding.customSearchEt.text.toString().trim()
}
}
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
</data>
<LinearLayout
android:orientation="vertical"
android:background="#EEEEEE"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/lay_title_bar"
app:title="@{@string/app_name}"/>
<RelativeLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/theme_bg">
<LinearLayout
android:id="@+id/ll_user"
android:orientation="vertical"
android:layout_margin="@dimen/dp_15"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tv_user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前模拟的用户:"
/>
<Button
android:id="@+id/btn_reset"
android:layout_marginTop="@dimen/dp_20"
android:layout_width="wrap_content"
android:layout_height="@dimen/dp_40"
android:text="取消模拟"
/>
</LinearLayout>
<com.xjjk.healthyclients.view.CustomSearchView
android:id="@+id/csv_search"
android:layout_below="@+id/ll_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<androidx.recyclerview.widget.RecyclerView
android:layout_below="@+id/csv_search"
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_5" />
</RelativeLayout>
</LinearLayout>
</layout>
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/dp_50"
android:background="@color/white">
<LinearLayout
android:layout_marginRight="10dp"
android:id="@+id/custom_ll_search"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_35"
android:layout_centerVertical="true"
android:layout_marginLeft="@dimen/dp_18"
android:layout_toLeftOf="@+id/custom_search_tv"
android:background="@drawable/bg_search_shap_radius23">
<ImageView
android:layout_width="@dimen/dp_15"
android:layout_height="@dimen/dp_15"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/dp_17"
android:src="@mipmap/ic_search" />
<EditText
android:id="@+id/custom_search_et"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
android:layout_marginLeft="@dimen/dp_12"
android:background="@null"
android:longClickable="false"
android:gravity="center_vertical"
android:hint="@string/search_hint"
android:maxLines="1"
android:imeOptions="actionSearch"
android:singleLine="true"
android:textColor="@color/text_black_66"
android:textColorHint="@color/text_black_99"
android:textSize="@dimen/txt13" />
</LinearLayout>
<TextView
android:id="@+id/custom_search_tv"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/dp_22"
android:gravity="center_vertical"
android:paddingLeft="@dimen/dp_10"
android:text="@string/search_submit"
android:textColor="@color/text_black_99"
android:textSize="@dimen/txt13" />
</RelativeLayout>
</layout>
+123
View File
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_15"
android:layout_marginTop="@dimen/dp_5"
android:layout_marginRight="@dimen/dp_15"
android:layout_marginBottom="@dimen/dp_5"
android:background="@drawable/bg_white_background_shap"
android:orientation="horizontal"
android:paddingTop="@dimen/dp_10"
android:paddingBottom="@dimen/dp_10">
<ImageView
android:id="@+id/iv_head"
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30"
android:layout_gravity="center"
android:layout_marginLeft="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="用户账号" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="用户名称" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="单位" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="部门" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="@dimen/dp_3"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_account"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="用户账号" />
<TextView
android:id="@+id/tv_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="用户名称" />
<TextView
android:id="@+id/tv_unit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="单位名称" />
<TextView
android:id="@+id/tv_class"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="部门名称" />
</LinearLayout>
<TextView
android:id="@+id/user_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:text="员工编号:" />
<TextView
android:id="@+id/user_id_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="5dp"
android:text="身份证号:" />
</LinearLayout>
</LinearLayout>
</layout>