Browse Source

2024-09-02 新增 / 修改

修改:
1. 邀请 / 公务资料 文件上传
zhaiy 10 months ago
parent
commit
ea7e789a2d

+ 1 - 14
.idea/deploymentTargetDropDown.xml

@@ -6,20 +6,7 @@
         <State />
       </entry>
       <entry key="app">
-        <State>
-          <runningDeviceTargetSelectedWithDropDown>
-            <Target>
-              <type value="RUNNING_DEVICE_TARGET" />
-              <deviceKey>
-                <Key>
-                  <type value="SERIAL_NUMBER" />
-                  <value value="3bb3c424" />
-                </Key>
-              </deviceKey>
-            </Target>
-          </runningDeviceTargetSelectedWithDropDown>
-          <timeTargetWasSelectedWithDropDown value="2024-08-21T09:11:19.338155400Z" />
-        </State>
+        <State />
       </entry>
     </value>
   </component>

+ 8 - 3
app/src/main/AndroidManifest.xml

@@ -15,8 +15,13 @@
     <uses-permission android:name="android.permission.WAKE_LOCK" />
     <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
 
-    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:maxSdkVersion="32" tools:ignore="ScopedStorage"/>
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
+    <uses-permission
+        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
+        android:maxSdkVersion="32"
+        tools:ignore="ScopedStorage" />
+    <uses-permission
+        android:name="android.permission.READ_EXTERNAL_STORAGE"
+        android:maxSdkVersion="32" />
     <uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
     <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
 
@@ -34,7 +39,7 @@
         <activity
             android:name=".ui.group_common.commission_confirm.CommissionConfirmActivity"
             android:exported="false"
-            android:launchMode="singleTop"/>
+            android:launchMode="singleTop" />
         <activity
             android:name=".ui.picture_preview.PicturePreviewActivity"
             android:exported="false"

+ 10 - 0
app/src/main/java/com/pan_american/android/data/model/common/entity/FileListItem.kt

@@ -0,0 +1,10 @@
+package com.pan_american.android.data.model.common.entity
+
+import android.net.Uri
+
+class FileListItem {
+    var fileName = ""
+    var uri: Uri = Uri.EMPTY
+    var url = ""
+    var fromServer = false
+}

+ 1 - 5
app/src/main/java/com/pan_american/android/data/model/group_invite_official/invite_data/entity/InviteDataDetail.kt

@@ -1,7 +1,5 @@
 package com.pan_american.android.data.model.group_invite_official.invite_data.entity
 
-import com.pan_american.android.OASystem
-
 open class InviteDataDetail {
     var id = 0
     var country = ""
@@ -19,9 +17,7 @@ open class InviteDataDetail {
     var faceBook = ""
     var ins = ""
     var delegation = ""
-    var filePath = ""
-    var sndFilePath = ""
+    var sndFilePathItem = ArrayList<String>()
     var fax = ""
-    var createUserId = OASystem.userInfo.userId
     var remark = ""
 }

+ 0 - 3
app/src/main/java/com/pan_american/android/data/model/group_invite_official/invite_data/network/InviteDataDetailRequest.kt

@@ -1,3 +0,0 @@
-package com.pan_american.android.data.model.group_invite_official.invite_data.network
-
-class InviteDataDetailRequest(val id: Int)

+ 2 - 0
app/src/main/java/com/pan_american/android/data/model/group_invite_official/invite_data/network/UpdateInviteDetailRequest.kt

@@ -1,7 +1,9 @@
 package com.pan_american.android.data.model.group_invite_official.invite_data.network
 
+import com.pan_american.android.OASystem
 import com.pan_american.android.data.model.group_invite_official.invite_data.entity.InviteDataDetail
 
 class UpdateInviteDetailRequest: InviteDataDetail() {
     var status = 0
+    var createUserId = OASystem.userInfo.userId
 }

+ 0 - 10
app/src/main/java/com/pan_american/android/data/model/group_invite_official/official_visits/entity/PictureListItem.kt

@@ -1,10 +0,0 @@
-package com.pan_american.android.data.model.group_invite_official.official_visits.entity
-
-import android.net.Uri
-
-class PictureListItem {
-    var picName = ""
-    var uri: Uri = Uri.EMPTY
-    var url = ""
-    var fromServer = false
-}

+ 12 - 5
app/src/main/java/com/pan_american/android/data/network/APIService.kt

@@ -97,13 +97,11 @@ import com.pan_american.android.data.model.group_hotel.hotel_payment_insert.netw
 import com.pan_american.android.data.model.group_hotel.hotel_payment_insert.network.HotelPredetermineListResponse
 import com.pan_american.android.data.model.group_hotel.hotel_payment_insert.network.HotelPredetermineResourceRequest
 import com.pan_american.android.data.model.group_hotel.hotel_payment_insert.network.HotelPredetermineResourceResponse
-import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataDetailRequest
 import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataDetailResponse
 import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataListRequest
 import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataListResponse
 import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataResourceRequest
 import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataResourceResponse
-import com.pan_american.android.data.model.group_invite_official.invite_data.network.UpdateInviteDetailRequest
 import com.pan_american.android.data.model.group_invite_official.invite_official_payment_insert.network.InviteOfficialBaseDataResponse
 import com.pan_american.android.data.model.group_invite_official.invite_official_payment_insert.network.InviteOfficialCostDataRequest
 import com.pan_american.android.data.model.group_invite_official.invite_official_payment_insert.network.InviteOfficialCostDataResponse
@@ -186,8 +184,11 @@ import com.pan_american.android.data.model.resource_management.hotel_resource.ne
 import okhttp3.RequestBody
 import retrofit2.Call
 import retrofit2.http.Body
+import retrofit2.http.DELETE
 import retrofit2.http.GET
 import retrofit2.http.POST
+import retrofit2.http.Path
+import retrofit2.http.Query
 
 interface APIService {
 
@@ -789,15 +790,21 @@ interface APIService {
     /**
      * 邀请资料,根据ID获取团组详情
      */
-    @POST("/api/Resource/QueryInvitationOfficialActivityById")
-    fun getInviteDataDetailById(@Body inviteDataDetailRequest: InviteDataDetailRequest): Call<InviteDataDetailResponse>
+    @GET("/api/Resource/QueryInvitationOfficialActivityById/{id}")
+    fun getInviteDataDetailById(@Path("id") id: Int): Call<InviteDataDetailResponse>
 
     /**
      * 邀请资料,新增/修改邀请资料
      * status:  1.新增    2.修改
      */
     @POST("/api/Resource/OpInvitationOfficialActivity")
-    fun updateInviteData(@Body updateInviteDetailRequest: UpdateInviteDetailRequest): Call<BaseResponse>
+    fun updateInviteData(@Body requestBody: RequestBody): Call<BaseResponse>
+
+    /**
+     * 邀请资料,删除文件
+     */
+    @DELETE("api/Resource/InvitationOfficialActivityDelFile/{id}")
+    fun deleteInviteDataFile(@Path("id") id: Int, @Query("fileName") fileName: String): Call<BaseResponse>
 
     /**
      * 文档下载 团组list

+ 203 - 13
app/src/main/java/com/pan_american/android/ui/group_invite_official/invite_data/AddInviteDataActivity.kt

@@ -9,6 +9,7 @@ import android.graphics.BitmapFactory
 import android.net.Uri
 import android.os.Bundle
 import android.provider.MediaStore
+import android.provider.OpenableColumns
 import android.text.Editable
 import android.text.TextWatcher
 import android.util.Base64
@@ -18,6 +19,7 @@ import android.widget.EditText
 import android.widget.LinearLayout
 import android.widget.PopupWindow
 import android.widget.TextView
+import androidx.activity.result.ActivityResultCallback
 import androidx.activity.result.ActivityResultLauncher
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.core.app.ActivityCompat
@@ -34,23 +36,27 @@ import com.pan_american.android.base.BaseResponse
 import com.pan_american.android.base.CardAdapter
 import com.pan_american.android.base.CustomAlertDialog
 import com.pan_american.android.base.ListAdapter
+import com.pan_american.android.data.model.common.entity.FileListItem
 import com.pan_american.android.data.model.common.entity.Selector
 import com.pan_american.android.data.model.common.network.SelectorResponse
-import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataDetailRequest
-import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataDetailResponse
-import com.pan_american.android.data.model.group_invite_official.invite_data.network.UpdateInviteDetailRequest
 import com.pan_american.android.data.model.customer_resource.company_customer.network.BusinessCardInfoRequest
 import com.pan_american.android.data.model.customer_resource.company_customer.network.BusinessCardInfoResponse
+import com.pan_american.android.data.model.group_invite_official.invite_data.network.InviteDataDetailResponse
+import com.pan_american.android.data.model.group_invite_official.invite_data.network.UpdateInviteDetailRequest
 import com.pan_american.android.data.network.APIService
 import com.pan_american.android.data.network.ServiceCreator
 import com.pan_american.android.databinding.ActivityAddInviteDataBinding
 import com.pan_american.android.databinding.LayoutTitleBinding
+import okhttp3.MediaType
+import okhttp3.MultipartBody
+import okhttp3.RequestBody
 import retrofit2.Call
 import retrofit2.Callback
 import retrofit2.Response
 import java.io.ByteArrayOutputStream
 import java.io.File
 
+
 class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
 
     private var fromList = false
@@ -65,12 +71,12 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
 
     private val groupSelected = ArrayList<Selector>()
 
-    private lateinit var adapter: CardAdapter<Selector>
+    private lateinit var groupNameAdapter: CardAdapter<Selector>
 
     private var updateInviteDataDetailRequest = UpdateInviteDetailRequest()
 
     //监听拍照事件回调
-    private lateinit var result: ActivityResultLauncher<Intent>
+    private lateinit var getPhotoResult: ActivityResultLauncher<Intent>
 
     //名片识别,图片Uri
     private lateinit var imageUri: Uri
@@ -87,6 +93,12 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
     //识别后地址可能存在多行
     private var locationOCR = ""
 
+    private var fileListItem = ArrayList<FileListItem>()
+
+    private lateinit var fileListAdapter: CardAdapter<FileListItem>
+
+    private lateinit var fileSelectResult: ActivityResultLauncher<Intent>
+
     override fun getViewBinding() = ActivityAddInviteDataBinding.inflate(layoutInflater)
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -97,7 +109,7 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
             dataId = getIntExtra("data_id", 0)
         }
 
-        result = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+        getPhotoResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
             if (it.resultCode == Activity.RESULT_OK) {
 
                 telephoneOCR = ""
@@ -109,6 +121,32 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
             }
         }
 
+        fileSelectResult = registerForActivityResult(
+            ActivityResultContracts.StartActivityForResult(),
+            ActivityResultCallback { result ->
+                if (result.resultCode == RESULT_OK) {
+                    val data: Intent? = result.data
+                    if (data != null) {
+                        val selectedImageUri = data.data
+                        if (selectedImageUri != null) {
+
+                            fileListItem.add(FileListItem().apply {
+                                fileName = File(uri2Path(selectedImageUri)).name
+
+                                if (fileName.isBlank()) {
+                                    showMessage(resources.getString(R.string.file_select_error_hint))
+                                    return@ActivityResultCallback
+                                }
+
+                                uri = selectedImageUri
+                            })
+
+                            initFileNameList()
+                        }
+                    }
+                }
+            })
+
         initTitle()
 
         getGroupNameList()
@@ -184,6 +222,7 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
     }
 
     override fun initEvents() {
+
         binding.add.setOnClickListener {
             val selectorList = ArrayList<Selector>()
 
@@ -291,6 +330,10 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
             }
         }
 
+        binding.upload.setOnClickListener {
+            openFileManager()
+        }
+
         binding.commit.setOnClickListener {
             if (!OASystem.authorization(OASystem.INVITE_DATA, OASystem.EDIT)) {
                 back()
@@ -440,7 +483,8 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
     }
 
     private fun getInviteDataDetail() {
-        apiService.getInviteDataDetailById(InviteDataDetailRequest(dataId)).enqueue(object : Callback<InviteDataDetailResponse> {
+
+        apiService.getInviteDataDetailById(dataId).enqueue(object : Callback<InviteDataDetailResponse> {
             override fun onResponse(
                 call: Call<InviteDataDetailResponse>,
                 response: Response<InviteDataDetailResponse>
@@ -453,7 +497,7 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
                         detailResponse.data.apply {
 
                             updateInviteDataDetailRequest.id = id
-                            updateInviteDataDetailRequest.createUserId = createUserId
+                            updateInviteDataDetailRequest.createUserId = OASystem.userInfo.userId
 
                             binding.country.setText(country)
                             binding.city.setText(city)
@@ -484,6 +528,20 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
                                 initGroupNameList()
                             }
 
+                            if (sndFilePathItem.size > 0) {
+
+                                for (item in sndFilePathItem) {
+                                    fileListItem.add(FileListItem().apply {
+                                        fileName = item.substringAfterLast("/")
+                                        url = item
+                                        fromServer = true
+                                    })
+                                }
+
+                                initFileNameList()
+
+                            }
+
                             binding.contactsFax.setText(fax)
                             binding.otherInfo.setText(remark)
                         }
@@ -504,7 +562,7 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
         val layoutManager = LinearLayoutManager(OASystem.context)
         binding.groupList.layoutManager = layoutManager
 
-        adapter = CardAdapter.Builder<Selector>().apply {
+        groupNameAdapter = CardAdapter.Builder<Selector>().apply {
             setData(groupSelected)
             setLayoutId(R.layout.item_delete_button_selector)
             setCanDelete(OASystem.authorization(OASystem.INVITE_DATA, OASystem.EDIT))
@@ -513,9 +571,9 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
             }
         }.create()
 
-        binding.groupList.adapter = adapter
+        binding.groupList.adapter = groupNameAdapter
 
-        adapter.onRecyclerViewItemClick = object : CardAdapter.OnRecyclerViewItemClick<Selector> {
+        groupNameAdapter.onRecyclerViewItemClick = object : CardAdapter.OnRecyclerViewItemClick<Selector> {
             override fun onItemClick(position: Int) {
 
             }
@@ -537,11 +595,121 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
         }
     }
 
+    private fun initFileNameList() {
+        val layoutManager = LinearLayoutManager(OASystem.context)
+        binding.inviteDataFileList.layoutManager = layoutManager
+
+        fileListAdapter = CardAdapter.Builder<FileListItem>().apply {
+            setData(fileListItem)
+            setLayoutId(R.layout.item_delete_button_selector)
+            setCanDelete(OASystem.authorization(OASystem.INVITE_DATA, OASystem.EDIT))
+            addBindView { itemView, data ->
+                itemView.findViewById<TextView>(R.id.left_text).text = data.fileName
+            }
+        }.create()
+
+        binding.inviteDataFileList.adapter = fileListAdapter
+
+        fileListAdapter.onRecyclerViewItemClick = object : CardAdapter.OnRecyclerViewItemClick<FileListItem> {
+            override fun onItemClick(position: Int) {
+
+            }
+
+            override fun onItemDelete(position: Int) {
+                CustomAlertDialog.Builder(OASystem.context).apply {
+                    setTitle(resources.getString(R.string.alert))
+                    if (fileListItem[position].fromServer) {
+                        setMessage(String.format(resources.getString(R.string.file_uploaded_delete_hint), fileListItem[position].fileName))
+                    } else {
+                        setMessage(String.format(resources.getString(R.string.delete_alert_text), fileListItem[position].fileName))
+                    }
+                    setNegativeButtonAndListener(resources.getString(R.string.cancel)) { dialog, _ ->
+                        dialog.dismiss()
+                    }
+                    setPositiveButtonAndListener(resources.getString(R.string.confirm)) { _, _ ->
+
+                        if (fileListItem[position].fromServer) {
+
+                            deleteFileFromServer(position)
+
+                        } else {
+                            fileListItem.removeAt(position)
+                            binding.inviteDataFileList.adapter!!.notifyItemRemoved(position)
+                            binding.inviteDataFileList.adapter!!.notifyItemRangeChanged(position, fileListItem.size - position)
+
+                            showMessage(resources.getString(R.string.delete_success))
+                        }
+
+                    }
+                }.show()
+            }
+        }
+    }
+
+    private fun deleteFileFromServer(position: Int) {
+
+        apiService.deleteInviteDataFile(updateInviteDataDetailRequest.id, fileListItem[position].fileName).enqueue(object : Callback<BaseResponse> {
+            override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {
+
+                val deleteResponse = response.body()
+
+                if (deleteResponse != null) {
+                    if (deleteResponse.code == 200) {
+
+                        fileListItem.removeAt(position)
+                        binding.inviteDataFileList.adapter!!.notifyItemRemoved(position)
+                        binding.inviteDataFileList.adapter!!.notifyItemRangeChanged(position, fileListItem.size - position)
+
+                        showMessage(resources.getString(R.string.delete_success))
+
+                    } else {
+                        showMessage(deleteResponse.msg)
+                    }
+                }
+            }
+
+            override fun onFailure(p0: Call<BaseResponse>, p1: Throwable) {
+                showErrorInfo(R.string.delete_error)
+            }
+        })
+    }
+
     private fun updateInviteData() {
 
         binding.commit.setButtonStatus(1)
 
-        apiService.updateInviteData(updateInviteDataDetailRequest).enqueue(object : Callback<BaseResponse> {
+        val requestBody = MultipartBody.Builder().setType(MultipartBody.FORM).apply {
+            addFormDataPart("Id", updateInviteDataDetailRequest.id.toString())
+            addFormDataPart("Country", updateInviteDataDetailRequest.country)
+            addFormDataPart("City", updateInviteDataDetailRequest.city)
+            addFormDataPart("UnitName", updateInviteDataDetailRequest.unitName)
+            addFormDataPart("UnitWeb", updateInviteDataDetailRequest.unitWeb)
+            addFormDataPart("Field", updateInviteDataDetailRequest.field)
+            addFormDataPart("Address", updateInviteDataDetailRequest.address)
+            addFormDataPart("UnitInfo", updateInviteDataDetailRequest.unitInfo)
+            addFormDataPart("Contact", updateInviteDataDetailRequest.contact)
+            addFormDataPart("Job", updateInviteDataDetailRequest.job)
+            addFormDataPart("Tel", updateInviteDataDetailRequest.tel)
+            addFormDataPart("Email", updateInviteDataDetailRequest.email)
+            addFormDataPart("WeChat", updateInviteDataDetailRequest.weChat)
+            addFormDataPart("FaceBook", updateInviteDataDetailRequest.faceBook)
+            addFormDataPart("Ins", updateInviteDataDetailRequest.ins)
+            addFormDataPart("Delegation", updateInviteDataDetailRequest.delegation)
+            addFormDataPart("Fax", updateInviteDataDetailRequest.fax)
+            addFormDataPart("Remark", updateInviteDataDetailRequest.remark)
+            addFormDataPart("Status", updateInviteDataDetailRequest.status.toString())
+            addFormDataPart("CreateUserId", updateInviteDataDetailRequest.createUserId.toString())
+            for (item in fileListItem) {
+                if (!item.fromServer) {
+                    val file = contentResolver.openInputStream(item.uri)!!
+                    val fileRequestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file.readBytes())
+                    addFormDataPart("Files", item.fileName, fileRequestBody)
+                    file.close()
+                }
+            }
+        }.build()
+
+        apiService.updateInviteData(requestBody).enqueue(object : Callback<BaseResponse> {
             override fun onResponse(call: Call<BaseResponse>, response: Response<BaseResponse>) {
 
                 val updateResponse = response.body()
@@ -593,7 +761,7 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
         //启动相机程序
         val intent = Intent("android.media.action.IMAGE_CAPTURE")
         intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri)
-        result.launch(intent)
+        getPhotoResult.launch(intent)
     }
 
     private fun getBusinessCardInfo() {
@@ -708,4 +876,26 @@ class AddInviteDataActivity : BaseActivity<ActivityAddInviteDataBinding>() {
                 }
             })
     }
+
+    private fun uri2Path(uri: Uri): String {
+        var filePath = ""
+        val projection = arrayOf(OpenableColumns.DISPLAY_NAME)
+        contentResolver.query(uri, projection, null, null, null)?.use { cursor ->
+            if (cursor.moveToFirst()) {
+                val columnIndex =
+                    cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME)
+                filePath = cursor.getString(columnIndex)
+            }
+        }
+
+        return filePath
+    }
+
+    private fun openFileManager() {
+        val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
+        intent.addCategory(Intent.CATEGORY_OPENABLE)
+        intent.setType("*/*") // Use specific MIME type if you know the file type (e.g., "text/plain" for .txt files)
+
+        fileSelectResult.launch(intent)
+    }
 }

+ 14 - 4
app/src/main/java/com/pan_american/android/ui/group_invite_official/invite_data/InviteDataSearchFragment.kt

@@ -77,7 +77,12 @@ class InviteDataSearchFragment : BaseFragment<FragmentInviteDataSearchBinding>()
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
-        getInviteDataResource()
+        if (dataInit) {
+            initEvents()
+        } else {
+            getInviteDataResource()
+        }
+
     }
 
     override fun onStart() {
@@ -101,6 +106,7 @@ class InviteDataSearchFragment : BaseFragment<FragmentInviteDataSearchBinding>()
     }
 
     override fun initViews() {
+
         if (inStuck) {
             binding.inviteCountry.text = selectedCountry
             binding.inviteeName.text = selectedInvitee
@@ -685,10 +691,10 @@ class InviteDataSearchFragment : BaseFragment<FragmentInviteDataSearchBinding>()
                 } else {
                     binding.contractName.text.toString()
                 })
-                putString("delegation", if (binding.groupName.text.equals(resources.getString(R.string.all))) {
-                    ""
+                putString("delegation", if (groupId == 0) {
+                    "0"
                 } else {
-                    binding.groupName.text.toString()
+                    groupId.toString()
                 })
                 putString("field", if (binding.industry.text.equals(resources.getString(R.string.all))) {
                     ""
@@ -723,6 +729,10 @@ class InviteDataSearchFragment : BaseFragment<FragmentInviteDataSearchBinding>()
 
     private fun getInviteDataResource() {
 
+        if (!isAdded) {
+            return
+        }
+
         if (!dataInit) {
             apiService.getInviteDataResource(InviteDataResourceRequest()).enqueue(object : Callback<InviteDataResourceResponse> {
                 override fun onResponse(

+ 15 - 16
app/src/main/java/com/pan_american/android/ui/group_invite_official/official_visits/AddOfficialVisitsActivity.kt

@@ -32,13 +32,13 @@ import com.pan_american.android.base.BaseResponse
 import com.pan_american.android.base.CardAdapter
 import com.pan_american.android.base.CustomAlertDialog
 import com.pan_american.android.base.ListAdapter
+import com.pan_american.android.data.model.common.entity.FileListItem
 import com.pan_american.android.data.model.common.entity.Selector
 import com.pan_american.android.data.model.common.entity.SimpleGroupInfo
 import com.pan_american.android.data.model.common.network.QueryDataSetRequest
 import com.pan_american.android.data.model.common.network.QueryDataSetResponse
 import com.pan_american.android.data.model.common.network.SimpleGroupInfoRequest
 import com.pan_american.android.data.model.common.network.SimpleGroupInfoResponse
-import com.pan_american.android.data.model.group_invite_official.official_visits.entity.PictureListItem
 import com.pan_american.android.data.model.group_invite_official.official_visits.network.DeleteOfficialVisitPic
 import com.pan_american.android.data.model.group_invite_official.official_visits.network.GetOfficialVisitDetailRequest
 import com.pan_american.android.data.model.group_invite_official.official_visits.network.GetOfficialVisitDetailResponse
@@ -60,7 +60,6 @@ import retrofit2.Callback
 import retrofit2.Response
 import java.io.File
 
-
 class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>() {
 
     private var fromList = false
@@ -83,7 +82,7 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
 
 //    private val officialAttributeList = ArrayList<Selector>()
 
-    private val photoList = ArrayList<PictureListItem>()
+    private val photoList = ArrayList<FileListItem>()
 
     private var invitorId = 0
 
@@ -127,10 +126,10 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
                     if (data != null) {
                         val selectedImageUri = data.data
                         if (selectedImageUri != null) {
-                            photoList.add(PictureListItem().apply {
-                                picName = File(uri2Path(selectedImageUri)).name
+                            photoList.add(FileListItem().apply {
+                                fileName = File(uri2Path(selectedImageUri)).name
 
-                                if (picName.isBlank()) {
+                                if (fileName.isBlank()) {
                                     showMessage(resources.getString(R.string.picture_select_error_hint))
                                     return@ActivityResultCallback
                                 }
@@ -709,8 +708,8 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
                             binding.participationMember.setText(attendees)
 
                             for (item in screenshotOfMailUrls) {
-                                val photo = PictureListItem().apply {
-                                    picName = item.substringAfterLast("/")
+                                val photo = FileListItem().apply {
+                                    fileName = item.substringAfterLast("/")
                                     url = item
                                     fromServer = true
                                 }
@@ -896,18 +895,18 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
         val layoutManager = LinearLayoutManager(OASystem.context)
         binding.emailScreenshotList.layoutManager = layoutManager
 
-        val adapter = CardAdapter.Builder<PictureListItem>().apply {
+        val adapter = CardAdapter.Builder<FileListItem>().apply {
             setData(photoList)
             setLayoutId(R.layout.item_delete_button_selector)
             setCanDelete(OASystem.authorization(OASystem.OFFICIAL_VISITS, OASystem.EDIT))
             addBindView { itemView, data ->
-                itemView.findViewById<TextView>(R.id.left_text).text = data.picName
+                itemView.findViewById<TextView>(R.id.left_text).text = data.fileName
             }
         }.create()
 
         binding.emailScreenshotList.adapter = adapter
 
-        adapter.onRecyclerViewItemClick = object : CardAdapter.OnRecyclerViewItemClick<PictureListItem> {
+        adapter.onRecyclerViewItemClick = object : CardAdapter.OnRecyclerViewItemClick<FileListItem> {
             override fun onItemClick(position: Int) {
 //                val intent = Intent(OASystem.context, PicturePreviewActivity::class.java).apply {
 //                    putExtra("name", photoList[position].picName)
@@ -933,7 +932,7 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
 
                     recyclerView.layoutManager = LinearLayoutManager(OASystem.context)
 
-                    val picturePreviewAdapter = ListAdapter.Builder<PictureListItem>().apply {
+                    val picturePreviewAdapter = ListAdapter.Builder<FileListItem>().apply {
                         setData(photoList)
                         setLayoutId(R.layout.item_image_preview)
                         addBindView { itemView, data ->
@@ -943,7 +942,7 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
                                 Picasso.get().load(data.uri).into(itemView.findViewById<AppCompatImageView>(R.id.image_view))
                             }
 
-                            itemView.findViewById<TextView>(R.id.image_name).text = data.picName
+                            itemView.findViewById<TextView>(R.id.image_name).text = data.fileName
                         }
                     }.create()
 
@@ -959,9 +958,9 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
                     setTitle(resources.getString(R.string.alert))
 
                     if (photoList[position].fromServer) {
-                        setMessage(String.format(resources.getString(R.string.picture_uploaded_delete_hint), photoList[position].picName))
+                        setMessage(String.format(resources.getString(R.string.picture_uploaded_delete_hint), photoList[position].fileName))
                     } else {
-                        setMessage(String.format(resources.getString(R.string.delete_alert_text), photoList[position].picName))
+                        setMessage(String.format(resources.getString(R.string.delete_alert_text), photoList[position].fileName))
 
                     }
 
@@ -1170,7 +1169,7 @@ class AddOfficialVisitsActivity : BaseActivity<ActivityAddOfficialVisitsBinding>
 
             val deleteOfficialVisitPic = DeleteOfficialVisitPic().apply {
                 id = officialVisitId
-                fileName = photoList[position].picName
+                fileName = photoList[position].fileName
             }
 
             apiService.deleteOfficialPic(deleteOfficialVisitPic).enqueue(object : Callback<BaseResponse> {

+ 3 - 23
app/src/main/res/layout/activity_add_invite_data.xml

@@ -604,29 +604,16 @@
 
             </LinearLayout>
 
-            <View
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/line"
-                android:layout_marginTop="@dimen/common_padding"
-                android:layout_marginBottom="@dimen/common_padding"
-                android:background="@color/line_color" />
-
             <androidx.recyclerview.widget.RecyclerView
                 android:id="@+id/group_list"
                 android:layout_width="match_parent"
-                android:layout_height="wrap_content" />
-
-            <View
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/line"
-                android:layout_marginTop="@dimen/common_padding"
-                android:layout_marginBottom="@dimen/common_padding"
-                android:background="@color/line_color" />
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/common_padding_small" />
 
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/common_padding"
+                android:layout_marginTop="@dimen/common_padding_huge"
                 android:layout_marginBottom="@dimen/common_padding"
                 android:orientation="horizontal">
 
@@ -657,13 +644,6 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" />
 
-            <View
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/line"
-                android:layout_marginTop="@dimen/common_padding"
-                android:layout_marginBottom="@dimen/common_padding"
-                android:background="@color/line_color" />
-
             <LinearLayout
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"

+ 6 - 1
app/src/main/res/values/strings.xml

@@ -131,7 +131,8 @@
     <string name="document_generated">文档已生成, 点击确认跳转至浏览器下载\n\n团组名称: %s\n\n文档类型: %s</string>
 
     <string name="camera_permission_hint">请在设置中打开相机权限</string>
-    <string name="permission_denied">未拥有该权限</string>
+    <string name="file_manager_permission_hint">检测到未赋予文件管理权限,请在设置中打开文件管理权限,点击确定跳转到设置界面</string>
+    <string name="permission_denied">未拥有该权限, 请前往设置界面打开权限</string>
 
     <!-- 网络错误 -->
     <string name="network_error">%s,请检查网络设置</string>
@@ -912,6 +913,10 @@
     <string name="invitee_city_input_hint">请输入邀请方城市</string>
     <string name="invitee_industry_input_hint">请输入邀请方涉及领域</string>
 
+    <string name="file_uploaded_delete_hint">是否删除: %s ? \n\n此文件已上传至服务器此操作将永久删除该文件, 该操作不可逆, 是否继续?</string>
+
+    <string name="file_select_error_hint">文件路径获取失败,请从系统文件选择器选择文件</string>
+
     <!-- 邀请/公务活动资料详情,错误信息 -->
     <string name="group_name_list_get_failed">团组名称列表获取失败</string>
     <string name="invite_data_info_get_failed">商邀资料详情获取失败</string>