Browse Source

@fun: file and url

bai 3 years ago
parent
commit
1564b1c9af
22 changed files with 310 additions and 73 deletions
  1. 3 14
      app/src/main/java/com/ys/bdtp/adm/app/Constants.kt
  2. 27 0
      app/src/main/java/com/ys/bdtp/adm/app/Url.kt
  3. 0 22
      app/src/main/java/com/ys/bdtp/adm/app/tools/Files.kt
  4. 39 0
      app/src/main/java/com/ys/bdtp/adm/app/tools/file/FileDownload.kt
  5. 51 0
      app/src/main/java/com/ys/bdtp/adm/app/tools/file/FileUpload.kt
  6. 121 0
      app/src/main/java/com/ys/bdtp/adm/app/tools/file/Files.kt
  7. 2 2
      app/src/main/java/com/ys/bdtp/adm/di/Di.kt
  8. 1 0
      app/src/main/java/com/ys/bdtp/adm/mvvm/model/Data.kt
  9. 41 10
      app/src/main/java/com/ys/bdtp/adm/mvvm/model/nt/Api.kt
  10. 1 1
      app/src/main/java/com/ys/bdtp/adm/mvvm/model/Fail.kt
  11. 1 1
      app/src/main/java/com/ys/bdtp/adm/mvvm/model/Http.kt
  12. 1 1
      app/src/main/java/com/ys/bdtp/adm/mvvm/model/Model.kt
  13. 1 1
      app/src/main/java/com/ys/bdtp/adm/mvvm/model/Response.kt
  14. 2 2
      app/src/main/java/com/ys/bdtp/adm/mvvm/ui/screen/project/Project.kt
  15. 2 2
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/flash/FlashRepository.kt
  16. 3 3
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/flash/FlashViewModel.kt
  17. 2 2
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/login/LoginRepository.kt
  18. 3 3
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/login/LoginViewModel.kt
  19. 2 2
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/offline/OfflineRepository.kt
  20. 1 1
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/offline/OfflineViewModel.kt
  21. 2 2
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/project/ProjectRepository.kt
  22. 4 4
      app/src/main/java/com/ys/bdtp/adm/mvvm/vm/project/ProjectViewModel.kt

+ 3 - 14
app/src/main/java/com/ys/bdtp/adm/app/Constants.kt

@@ -1,20 +1,6 @@
 package com.ys.bdtp.adm.app
 
-/**
- * 测试服务器 IP
- */
-
-const val devUrl = "http://develop.ysbdtp.com/adm-server/"
-
-const val baseUrl = "http://www.ysbdtp.com/adm-server/"
-
-const val IP = devUrl
 
-const val devFileServiceUrl = "http://develop.persagy.com/image-service/"
-
-const val fileServiceUrl = devFileServiceUrl
-
-const val pathDownloadMap = "adm/downloadMap?key="
 
 const val DEVICE_ID = "device_id"
 
@@ -24,4 +10,7 @@ const val ADM_TS = "adm_ts"
 
 const val CLIENT_ID = "client_id"
 
+/**
+ * http 请求头
+ */
 const val Token = "token"

+ 27 - 0
app/src/main/java/com/ys/bdtp/adm/app/Url.kt

@@ -0,0 +1,27 @@
+package com.ys.bdtp.adm.app
+
+/**
+ * 获取文件上传信息的Url
+ */
+const val fileUploadInfoUrl = "http://www.ysbdtp.com/dmp-file/file/initSingleUpload"
+
+/**
+ * 获取文件下载信息的Url
+ */
+const val fileDownloadInfoUrl = "http://www.ysbdtp.com/dmp-file/file/initFileDownload"
+
+/**
+ * 正式版本Url
+ */
+const val releaseUrl = "http://www.ysbdtp.com/adm-server/"
+
+/**
+ * 开发版本Url
+ */
+const val devUrl = "http://develop.ysbdtp.com/adm-server/"
+
+
+/**
+ * Retrofit baseUrl
+ */
+const val baseUrl = devUrl

+ 0 - 22
app/src/main/java/com/ys/bdtp/adm/app/tools/Files.kt

@@ -1,22 +0,0 @@
-package com.ys.bdtp.adm.app.tools
-
-import okhttp3.MediaType.Companion.toMediaType
-import okhttp3.RequestBody
-import okhttp3.RequestBody.Companion.toRequestBody
-import java.io.File
-import java.io.FileInputStream
-
-/**
- * 读取文件,返回字节数组
- */
-fun File.toBytes(): ByteArray {
-    val fis = FileInputStream(this)
-    return fis.readBytes()
-}
-
-fun File.toRequestBody(
-    mediaType: String = "application/json;charset=utf-8"
-): RequestBody {
-    val bytes = this.toBytes()
-    return bytes.toRequestBody(mediaType.toMediaType())
-}

+ 39 - 0
app/src/main/java/com/ys/bdtp/adm/app/tools/file/FileDownload.kt

@@ -0,0 +1,39 @@
+package com.ys.bdtp.adm.app.tools.file
+
+/**
+ * 文件下载信息
+ *
+ * @author bai
+ *
+ * @param id
+ * @param fileName 文件名
+ * @param fileType 文件类型: 0 文件,1 文件夹
+ * @param fileMd5 文件摘要
+ * @param fileSize 文件大小
+ * @param fileDownloadUrl 文件下载Url
+ * @param groupCode 集团编码
+ * @param businessId
+ *
+ */
+data class FileDownloadInfo(
+    val id: String,
+    val fileName: String,
+    val fileType: String?,
+    val fileMd5: String,
+    val fileSize: Int,
+    val fileBucket: String,
+    val fileDownloadUrl: String?,
+    val groupCode: String? = "",
+    val businessId: String? = ""
+)
+
+/**
+ * 文件 Id 包装类
+ *
+ * @author bai
+ *
+ * @param fileId
+ */
+data class FileId(
+    val fileId: String
+)

+ 51 - 0
app/src/main/java/com/ys/bdtp/adm/app/tools/file/FileUpload.kt

@@ -0,0 +1,51 @@
+package com.ys.bdtp.adm.app.tools.file
+
+/**
+ * 文件基本信息
+ *
+ * @author bai
+ *
+ * @param fileId 自定义文件id,
+ * @param fileMd5 文件摘要
+ * @param fileName 文件名
+ * @param fileName 文件名
+ * @param fileBucket 文件桶
+ * @param fileSize 文件大小
+ *
+ */
+data class FileInfo(
+    val fileId: String,
+    val fileMd5: String,
+    val fileName: String,
+    val fileBucket: String = "adm",
+    val fileSize: Int = 0
+)
+
+/**
+ * 文件上传信息
+ *
+ * @author bai
+ *
+ * @param id
+ * @param uploadCode 上传Code
+ * @param content 上传内容
+ *
+ */
+data class FileUploadInfo(
+    val id: String,
+    val uploadCode: Int,
+    val content: List<FilePartInfo>? = null
+)
+
+/**
+ * 文件上传分段信息和上传Url
+ *
+ * @author bai
+ *
+ * @param partNumber 文件分几段
+ * @param uploadUrl 每段上传的Url
+ */
+data class FilePartInfo(
+    val partNumber: Int,
+    val uploadUrl: String
+)

+ 121 - 0
app/src/main/java/com/ys/bdtp/adm/app/tools/file/Files.kt

@@ -0,0 +1,121 @@
+package com.ys.bdtp.adm.app.tools
+
+import android.util.Log
+import com.ys.bdtp.adm.app.tools.file.FileId
+import com.ys.bdtp.adm.app.tools.file.FileInfo
+import com.ys.bdtp.adm.mvvm.model.nt.Api
+import com.ys.bdtp.adm.mvvm.model.nt.FailureResponse
+import com.ys.bdtp.adm.mvvm.model.nt.SuccessResponse
+import com.ys.bdtp.adm.mvvm.model.nt.request
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import okhttp3.MediaType.Companion.toMediaType
+import okhttp3.RequestBody
+import okhttp3.RequestBody.Companion.toRequestBody
+import java.io.File
+import java.io.FileInputStream
+import java.io.FileOutputStream
+
+/**
+ * 读取文件,返回字节数组
+ */
+fun File.toBytes(): ByteArray {
+    val fis = FileInputStream(this)
+    return fis.readBytes()
+}
+
+/**
+ * 文件转换程 RequestBody
+ */
+fun File.toRequestBody(
+    mediaType: String = "application/json;charset=utf-8"
+): RequestBody {
+    val bytes = this.toBytes()
+    return bytes.toRequestBody(mediaType.toMediaType())
+}
+
+/**
+ * 文件上传
+ *
+ * @author bai
+ *
+ * @param param
+ *        mapOf(
+ *            "appId" to "adm",
+ *            "userId" to "",
+ *            "groupCode" to "",
+ *            "projectId" to ""
+ *        )
+ * @param file 要上传的文件, 确保文件存在
+ *
+ */
+suspend fun fileUpload(api: Api, param: Map<String, String>, file: File) {
+    val bytes = file.toBytes()
+    val md5 = md5(bytes)
+    val size = bytes.size
+    val fileInfo = FileInfo(
+        fileId = file.name, fileName = file.name, fileSize = size, fileMd5 = md5
+    )
+    when (val response = request { api.getFileUploadInfo(param, fileInfo) }) {
+        is SuccessResponse -> {
+            val data = response.data
+            val url = data.content?.get(0)?.uploadUrl ?: ""
+            if (url.isNotEmpty()) {
+                val body = bytes.toRequestBody()
+                val result = api.uploadFile(url, body)
+                Log.d("fileUpload", "success: $result")
+            } else {
+                Log.d("fileUpload", "failure: no url to upload file")
+            }
+        }
+        is FailureResponse -> {
+            Log.d("fileUpload", "upload file has something error:${response.fail}")
+        }
+    }
+}
+
+/**
+ * 下载文件
+ *
+ * @author bai
+ *
+ * @param param
+ *        mapOf(
+ *            "appId" to "adm",
+ *            "userId" to "",
+ *            "groupCode" to "",
+ *            "projectId" to ""
+ *        )
+ * @param file 创建的空file, 存储下载的文件字节数组
+ *        例:
+ *        val path: File? = getExternalFilesDir("/img/png")
+ *        if (path == null || !path.exists()) {
+ *            path?.mkdirs()
+ *        }
+ *        val file = File(path, "download.png")
+ * @param fileId 文件存储平台的 fileId
+ *
+ */
+suspend fun fileDownload(api: Api, param: Map<String, String>, file: File, fileId: FileId) {
+    when (val response = request { api.getFileDownloadInfo(param, fileId) }) {
+        is SuccessResponse -> {
+            val data = response.data
+            val url = data.fileDownloadUrl ?: ""
+            if (url.isNotEmpty()) {
+                val bytes = api.downloadFile(url)
+                val fos = withContext(Dispatchers.IO) {
+                    FileOutputStream(file)
+                }
+                fos.use { out ->
+                    out.write(bytes)
+                }
+                Log.d("fileDownload", "success")
+            } else {
+                Log.d("fileDownload", "failure: no url to download file")
+            }
+        }
+        is FailureResponse -> {
+            Log.d("fileDownload", "download file has something error:${response.fail}")
+        }
+    }
+}

+ 2 - 2
app/src/main/java/com/ys/bdtp/adm/di/Di.kt

@@ -2,7 +2,7 @@ package com.ys.bdtp.adm.di
 
 import android.content.Context
 import android.util.Log
-import com.ys.bdtp.adm.app.IP
+import com.ys.bdtp.adm.app.baseUrl
 import com.ys.bdtp.adm.app.converter.NullOrEmptyConverter
 import com.ys.bdtp.adm.app.interceptor.GzipInterceptor
 import com.ys.bdtp.adm.app.interceptor.TokenInterceptor
@@ -34,7 +34,7 @@ val httpModule = DI.Module("httpModule") {
     bind {
         singleton {
             Retrofit.Builder()
-                .baseUrl(IP)
+                .baseUrl(baseUrl)
                 .client(instance())
                 .addConverterFactory(NullOrEmptyConverter())
                 .addConverterFactory(GsonConverterFactory.create())

+ 1 - 0
app/src/main/java/com/ys/bdtp/adm/mvvm/model/Data.kt

@@ -1,5 +1,6 @@
 package com.ys.bdtp.adm.mvvm.model
 
+import com.ys.bdtp.adm.mvvm.model.nt.*
 import kotlinx.coroutines.flow.*
 
 /**

+ 41 - 10
app/src/main/java/com/ys/bdtp/adm/mvvm/model/nt/Api.kt

@@ -1,12 +1,16 @@
 package com.ys.bdtp.adm.mvvm.model.nt
 
-import com.ys.bdtp.adm.mvvm.model.Model
+import com.ys.bdtp.adm.app.fileDownloadInfoUrl
+import com.ys.bdtp.adm.app.fileUploadInfoUrl
+import com.ys.bdtp.adm.app.tools.file.FileDownloadInfo
+import com.ys.bdtp.adm.app.tools.file.FileId
+import com.ys.bdtp.adm.app.tools.file.FileInfo
+import com.ys.bdtp.adm.app.tools.file.FileUploadInfo
 import com.ys.bdtp.adm.mvvm.model.vo.*
 import com.ys.bdtp.adm.mvvm.model.vo.request.Account
 import com.ys.bdtp.adm.mvvm.model.vo.request.Login
-import retrofit2.http.Body
-import retrofit2.http.Headers
-import retrofit2.http.POST
+import okhttp3.RequestBody
+import retrofit2.http.*
 
 /**
  * 后端API
@@ -73,16 +77,43 @@ interface Api {
     suspend fun hasUpdate(): Model<Boolean>
 
     /**
-     * 文件上传
-     */
-    @POST("adm/uploadFile")
-    suspend fun uploadFile()
-
-    /**
      * 下载地图
      */
     @POST("adm/downloadMap")
     suspend fun downloadFile()
 
+    /**
+     * 获取文件上传接口
+     *
+     * @param param 查询参数, appId userId groupCode projectId
+     * @param fileInfo 文件信息
+     */
+    @POST(fileUploadInfoUrl)
+    suspend fun getFileUploadInfo(
+        @QueryMap param: Map<String, String>,
+        @Body fileInfo: FileInfo
+    ): Model<FileUploadInfo>
+
+    /**
+     * 上传文件
+     */
+    @PUT
+    suspend fun uploadFile(@Url url: String, @Body file: RequestBody): String
+
+    /**
+     * 文件下载
+     */
+    @POST(fileDownloadInfoUrl)
+    suspend fun getFileDownloadInfo(
+        @QueryMap param: Map<String, String>,
+        @Body fileId: FileId
+    ): Model<FileDownloadInfo>
+
+    /**
+     * 返回地图
+     */
+    @Streaming
+    @GET
+    suspend fun downloadFile(@Url url: String): ByteArray?
 
 }

+ 1 - 1
app/src/main/java/com/ys/bdtp/adm/mvvm/model/Fail.kt

@@ -1,4 +1,4 @@
-package com.ys.bdtp.adm.mvvm.model
+package com.ys.bdtp.adm.mvvm.model.nt
 
 /**
  * 网络请求失败类型

+ 1 - 1
app/src/main/java/com/ys/bdtp/adm/mvvm/model/Http.kt

@@ -1,4 +1,4 @@
-package com.ys.bdtp.adm.mvvm.model
+package com.ys.bdtp.adm.mvvm.model.nt
 
 
 /**

+ 1 - 1
app/src/main/java/com/ys/bdtp/adm/mvvm/model/Model.kt

@@ -1,4 +1,4 @@
-package com.ys.bdtp.adm.mvvm.model
+package com.ys.bdtp.adm.mvvm.model.nt
 
 /**
  * Api 请求数据容器

+ 1 - 1
app/src/main/java/com/ys/bdtp/adm/mvvm/model/Response.kt

@@ -1,4 +1,4 @@
-package com.ys.bdtp.adm.mvvm.model
+package com.ys.bdtp.adm.mvvm.model.nt
 
 /**
  * 网络请求状态

+ 2 - 2
app/src/main/java/com/ys/bdtp/adm/mvvm/ui/screen/project/Project.kt

@@ -10,8 +10,8 @@ import androidx.compose.ui.tooling.preview.Preview
 import androidx.compose.ui.unit.dp
 import com.ys.bdtp.adm.app.tools.isNet
 import com.ys.bdtp.adm.app.theme.underColor
-import com.ys.bdtp.adm.mvvm.model.FailureResponse
-import com.ys.bdtp.adm.mvvm.model.SuccessResponse
+import com.ys.bdtp.adm.mvvm.model.nt.FailureResponse
+import com.ys.bdtp.adm.mvvm.model.nt.SuccessResponse
 import com.ys.bdtp.adm.mvvm.model.db.entity.task.ProjectEntity
 import com.ys.bdtp.adm.mvvm.model.db.entity.UserEntity
 import com.ys.bdtp.adm.mvvm.ui.compose.*

+ 2 - 2
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/flash/FlashRepository.kt

@@ -1,10 +1,10 @@
 package com.ys.bdtp.adm.mvvm.vm.flash
 
-import com.ys.bdtp.adm.mvvm.model.Response
+import com.ys.bdtp.adm.mvvm.model.nt.Response
 import com.ys.bdtp.adm.mvvm.model.db.AdmDatabase
 import com.ys.bdtp.adm.mvvm.model.db.entity.UserEntity
 import com.ys.bdtp.adm.mvvm.model.nt.Api
-import com.ys.bdtp.adm.mvvm.model.request
+import com.ys.bdtp.adm.mvvm.model.nt.request
 import com.ys.bdtp.adm.mvvm.model.vo.request.Account
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext

+ 3 - 3
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/flash/FlashViewModel.kt

@@ -2,9 +2,9 @@ package com.ys.bdtp.adm.mvvm.vm.flash
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import com.ys.bdtp.adm.mvvm.model.Fail
-import com.ys.bdtp.adm.mvvm.model.FailureResponse
-import com.ys.bdtp.adm.mvvm.model.SuccessResponse
+import com.ys.bdtp.adm.mvvm.model.nt.Fail
+import com.ys.bdtp.adm.mvvm.model.nt.FailureResponse
+import com.ys.bdtp.adm.mvvm.model.nt.SuccessResponse
 import com.ys.bdtp.adm.mvvm.model.db.entity.UserEntity
 import com.ys.bdtp.adm.mvvm.model.vo.request.Account
 import kotlinx.coroutines.launch

+ 2 - 2
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/login/LoginRepository.kt

@@ -1,9 +1,9 @@
 package com.ys.bdtp.adm.mvvm.vm.login
 
-import com.ys.bdtp.adm.mvvm.model.Response
+import com.ys.bdtp.adm.mvvm.model.nt.Response
 import com.ys.bdtp.adm.mvvm.model.db.AdmDatabase
 import com.ys.bdtp.adm.mvvm.model.nt.Api
-import com.ys.bdtp.adm.mvvm.model.request
+import com.ys.bdtp.adm.mvvm.model.nt.request
 import com.ys.bdtp.adm.mvvm.model.vo.request.Login
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext

+ 3 - 3
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/login/LoginViewModel.kt

@@ -2,9 +2,9 @@ package com.ys.bdtp.adm.mvvm.vm.login
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import com.ys.bdtp.adm.mvvm.model.Fail
-import com.ys.bdtp.adm.mvvm.model.FailureResponse
-import com.ys.bdtp.adm.mvvm.model.SuccessResponse
+import com.ys.bdtp.adm.mvvm.model.nt.Fail
+import com.ys.bdtp.adm.mvvm.model.nt.FailureResponse
+import com.ys.bdtp.adm.mvvm.model.nt.SuccessResponse
 import com.ys.bdtp.adm.mvvm.model.vo.request.Login
 import kotlinx.coroutines.launch
 

+ 2 - 2
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/offline/OfflineRepository.kt

@@ -1,7 +1,7 @@
 package com.ys.bdtp.adm.mvvm.vm.offline
 
-import com.ys.bdtp.adm.mvvm.model.Fail
-import com.ys.bdtp.adm.mvvm.model.request
+import com.ys.bdtp.adm.mvvm.model.nt.Fail
+import com.ys.bdtp.adm.mvvm.model.nt.request
 import com.ys.bdtp.adm.mvvm.model.db.AdmDatabase
 import com.ys.bdtp.adm.mvvm.model.db.entity.task.BuildingEntity
 import com.ys.bdtp.adm.mvvm.model.db.entity.task.EquipmentEntity

+ 1 - 1
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/offline/OfflineViewModel.kt

@@ -2,7 +2,7 @@ package com.ys.bdtp.adm.mvvm.vm.offline
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import com.ys.bdtp.adm.mvvm.model.Fail
+import com.ys.bdtp.adm.mvvm.model.nt.Fail
 import com.ys.bdtp.adm.mvvm.model.vo.Config
 import com.ys.bdtp.adm.mvvm.model.vo.Dict
 import com.ys.bdtp.adm.mvvm.model.vo.BuildingsAndFloors

+ 2 - 2
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/project/ProjectRepository.kt

@@ -1,12 +1,12 @@
 package com.ys.bdtp.adm.mvvm.vm.project
 
-import com.ys.bdtp.adm.mvvm.model.Response
+import com.ys.bdtp.adm.mvvm.model.nt.Response
 import com.ys.bdtp.adm.mvvm.model.db.AdmDatabase
 import com.ys.bdtp.adm.mvvm.model.db.entity.task.ProjectEntity
 import com.ys.bdtp.adm.mvvm.model.db.entity.UserEntity
 import com.ys.bdtp.adm.mvvm.model.db.entity.relation.UserWithProjects
 import com.ys.bdtp.adm.mvvm.model.nt.Api
-import com.ys.bdtp.adm.mvvm.model.request
+import com.ys.bdtp.adm.mvvm.model.nt.request
 import com.ys.bdtp.adm.mvvm.model.vo.request.Account
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.withContext

+ 4 - 4
app/src/main/java/com/ys/bdtp/adm/mvvm/vm/project/ProjectViewModel.kt

@@ -2,10 +2,10 @@ package com.ys.bdtp.adm.mvvm.vm.project
 
 import androidx.lifecycle.ViewModel
 import androidx.lifecycle.viewModelScope
-import com.ys.bdtp.adm.mvvm.model.Fail
-import com.ys.bdtp.adm.mvvm.model.FailureResponse
-import com.ys.bdtp.adm.mvvm.model.Response
-import com.ys.bdtp.adm.mvvm.model.SuccessResponse
+import com.ys.bdtp.adm.mvvm.model.nt.Fail
+import com.ys.bdtp.adm.mvvm.model.nt.FailureResponse
+import com.ys.bdtp.adm.mvvm.model.nt.Response
+import com.ys.bdtp.adm.mvvm.model.nt.SuccessResponse
 import com.ys.bdtp.adm.mvvm.model.db.entity.task.ProjectEntity
 import com.ys.bdtp.adm.mvvm.model.db.entity.UserEntity
 import com.ys.bdtp.adm.mvvm.model.db.entity.relation.UserWithProjects