Quellcode durchsuchen

1、违建点的移入移除功能与案件面的关联BUG解决
2、开始开发案件上传功能,搭建展示页面

不会爬树的猴 vor 1 Jahr
Ursprung
Commit
8a9c524942

+ 45 - 0
app/src/main/java/com/cr/adapter/CrPageAdapter.kt

@@ -0,0 +1,45 @@
+package com.cr.adapter
+
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentActivity
+import androidx.viewpager2.adapter.FragmentStateAdapter
+import com.cr.pages.CrNavigationFragment
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/6/15 16:00
+ * 描述:页面适配器
+ */
+class CrPageAdapter@JvmOverloads constructor(
+    activity: FragmentActivity
+): FragmentStateAdapter(activity){
+    private val mFragmentList: MutableList<CrNavigationFragment> = ArrayList()
+
+    /**
+     * 添加页面
+     * @param fragment CrFragment
+     */
+    fun addFragment(fragment: CrNavigationFragment){
+        mFragmentList.add(fragment)
+    }
+
+    /**
+     * 获取加载的页面
+     * @return MutableList<Fragment>
+     */
+    fun getFragments(): MutableList<CrNavigationFragment> {
+        return mFragmentList
+    }
+
+    // todo: 2023/4/11 页面数量
+    override fun getItemCount(): Int {
+        return mFragmentList.size
+    }
+
+    // todo: 2023/4/11 当前页面
+    override fun createFragment(position: Int): Fragment {
+        return mFragmentList[position]
+    }
+
+}

+ 1 - 1
app/src/main/java/com/cr/cruav/AvLogin.kt

@@ -78,7 +78,7 @@ class AvLogin : CrActivity(), OnClickListener {
         // todo: 2023/3/30 初始化页面
         fragIpAndCom = FragmentSetIpAndCom()
         fragIpAndCom?.let {
-            addFragment(it, R.id.av_frm_left_panel)
+            addFragment(it, R.id.av_frm_left_big_panel)
             hideFragment(it)
         }
         // todo: 2023/4/6 初始化控件

+ 38 - 14
app/src/main/java/com/cr/cruav/AvMain.kt

@@ -9,6 +9,7 @@ import androidx.fragment.app.commit
 import com.cr.data.CrConfig
 import com.cr.data.CrUtil
 import com.cr.event.EventFragmentBarAction
+import com.cr.map.CaseModel
 import com.cr.map.EventMap
 import com.cr.map.MapAction
 import com.cr.pages.*
@@ -62,10 +63,13 @@ class AvMain : CrActivity(), View.OnClickListener {
     private var fragmentMark: FragmentMark? = null
 
     // define: 2023/4/21 工具页面
-    private var fragmentTools:FragmentTools? = null
+    private var fragmentTools: FragmentTools? = null
 
     // define: 2023/6/9 案件图斑编辑页面
-    private var fragmentCaseTools:FragmentCaseTools?= null
+    private var fragmentCaseTools: FragmentCaseTools? = null
+
+    // define: 2023/6/15 案件上传页面
+    private var fragmentUploadCase: FragmentUploadCase? = null
 
 
     /**
@@ -131,28 +135,34 @@ class AvMain : CrActivity(), View.OnClickListener {
         fragmentDoodle = FragmentDoodle()
         fragmentDoodle?.setListener(doodleListener)
         fragmentDoodle?.let {
-            addFragment(it, R.id.av_frm_left_panel)
+            addFragment(it, R.id.av_frm_left_smart_panel)
             hideFragment(it)
         }
         // todo: 2023/4/18 初始化标志页面
         fragmentMark = FragmentMark()
         fragmentMark?.setListener(markListener)
         fragmentMark?.let {
-            addFragment(it, R.id.av_frm_left_panel)
+            addFragment(it, R.id.av_frm_left_big_panel)
             hideFragment(it)
         }
         // todo: 2023/4/21 初始化工具页面
         fragmentTools = FragmentTools()
         fragmentTools?.let {
             it.setListener(toolsListener)
-            addFragment(it,R.id.av_frm_left_panel)
+            addFragment(it, R.id.av_frm_left_smart_panel)
             hideFragment(it)
         }
         // todo: 2023/6/9 初始化案件图斑编辑页面
         fragmentCaseTools = FragmentCaseTools()
         fragmentCaseTools?.let {
             it.setListener(caseToolsListener)
-            addFragment(it,R.id.av_frm_left_panel)
+            addFragment(it, R.id.av_frm_left_smart_panel)
+            hideFragment(it)
+        }
+        // todo: 2023/6/15 初始化案件上传页面
+        fragmentUploadCase = FragmentUploadCase()
+        fragmentUploadCase?.let {
+            addFragment(it, R.id.av_frm_center_panel)
             hideFragment(it)
         }
     }
@@ -192,6 +202,7 @@ class AvMain : CrActivity(), View.OnClickListener {
         }
         // todo: 2023/3/14 加入地图视图
         fragmentMap = FragmentMap()
+        fragmentMap?.crSetEventListener(mapEventListener)
         supportFragmentManager.commit {
             replace(R.id.av_fragment_map, fragmentMap!!)
         }
@@ -259,18 +270,21 @@ class AvMain : CrActivity(), View.OnClickListener {
             R.id.tools_doodle -> {
                 showFragment(fragmentDoodle!!)
             }
-            R.id.tools_mark->{
+            R.id.tools_mark -> {
                 showFragment(fragmentMark!!)
             }
-            R.id.tools_tools->{
+            R.id.tools_tools -> {
                 showFragment(fragmentTools!!)
             }
-            R.id.tools_case_tools->{
+            R.id.tools_case_tools -> {
                 showFragment(fragmentCaseTools!!)
             }
-            R.id.tools_append_point_from_map->{
+            R.id.tools_append_point_from_map -> {
                 CrApplication.getEventBus().post(EventMap(MapAction.MapTapAddWaypoint))
             }
+            R.id.tools_wx -> {
+                CrApplication.getEventBus().post(EventMap(MapAction.MapTapCaseWxAndUpload))
+            }
         }
     }
 
@@ -325,7 +339,7 @@ class AvMain : CrActivity(), View.OnClickListener {
     private val markListener = object : FragmentMark.OnOperationListener {
         // todo: 2023/4/17 开启绘制
         override fun onStartDraw() {
-            CrApplication.getEventBus().post(EventMap(MapAction.MapTapAppendMark,fragmentMark))
+            CrApplication.getEventBus().post(EventMap(MapAction.MapTapAppendMark, fragmentMark))
         }
 
         // todo: 2023/4/17 停止绘制
@@ -367,7 +381,7 @@ class AvMain : CrActivity(), View.OnClickListener {
     /**
      * 工具监听
      */
-    private var toolsListener = object:FragmentTools.OnOperationListener{
+    private var toolsListener = object : FragmentTools.OnOperationListener {
         // todo: 2023/4/21 长度测量
         override fun onMeasureLength() {
             CrApplication.getEventBus().post(EventMap(MapAction.EventSurveyLength))
@@ -398,7 +412,7 @@ class AvMain : CrActivity(), View.OnClickListener {
     /**
      * 案件图斑编辑工具页面监听
      */
-    private val caseToolsListener = object:FragmentCaseTools.OnOperationListener{
+    private val caseToolsListener = object : FragmentCaseTools.OnOperationListener {
         // todo: 2023/6/9 开启绘制案件图斑
         override fun onStartDraw() {
             CrApplication.getEventBus().post(EventMap(MapAction.EventCaseDrawPolygon))
@@ -431,14 +445,24 @@ class AvMain : CrActivity(), View.OnClickListener {
 
         // todo: 2023/6/9 移动违建点
         override fun onMoveCasePoint() {
-            CrApplication.getEventBus().post(EventMap(MapAction.MapTapMoveWaypoing))
+            CrApplication.getEventBus().post(EventMap(MapAction.MapTapStartMoveWaypoing))
         }
 
         // todo: 2023/6/13 删除违建点
         override fun onRemoveCasePoint() {
             CrApplication.getEventBus().post(EventMap(MapAction.MapTapDeleteWaypoint))
         }
+    }
 
+    /**
+     * 地图事件监听
+     */
+    private val mapEventListener = object :FragmentMap.EventListener{
+        // todo: 2023/6/15 案件上传
+        override fun onCaseUpdate(selCase: CaseModel) {
+            fragmentUploadCase?.crSetJoinCase(selCase)
+            showFragment(fragmentUploadCase!!)
+        }
     }
 
     /**

+ 11 - 11
app/src/main/java/com/cr/map/CaseModel.kt

@@ -62,19 +62,19 @@ class CaseModel {
 
     /**
      * 通过属性初始化
-     * @param attribute Map<String, String>
+     * @param attribute MutableMap<String,Any>
      * @constructor
      */
-    constructor(attribute:Map<String,String>):this(){
-        this.name = attribute[FragmentMap.FIELD_CASE_NAME]
-        this.imgName = attribute[FragmentMap.FIELD_CASE_IMAGES]
-        this.date = attribute[FragmentMap.FIELD_CASE_RQ]
-        this.isDown = attribute[FragmentMap.FIELD_CASE_ISDOWN].equals("1")
-        this.longitude = attribute[FragmentMap.FIELD_CASE_LNG]?.toDouble()
-        this.latitude = attribute[FragmentMap.FIELD_CASE_LAT]?.toDouble()
-        this.altitude = attribute[FragmentMap.FIELD_CASE_ALT]?.toDouble()
-        this.angle = attribute[FragmentMap.FIELD_CASE_ANG]?.toDouble()
-        var mediaType = attribute[FragmentMap.FIELD_CASE_TYPE]
+    constructor(attribute:MutableMap<String,Any>):this(){
+        this.name = attribute[FragmentMap.FIELD_CASE_NAME].toString()
+        this.imgName = attribute[FragmentMap.FIELD_CASE_IMAGES].toString()
+        this.date = attribute[FragmentMap.FIELD_CASE_RQ].toString()
+        this.isDown = attribute[FragmentMap.FIELD_CASE_ISDOWN].toString() == "1"
+        this.longitude = attribute[FragmentMap.FIELD_CASE_LNG].toString().toDouble()
+        this.latitude = attribute[FragmentMap.FIELD_CASE_LAT].toString().toDouble()
+        this.altitude = attribute[FragmentMap.FIELD_CASE_ALT].toString().toDouble()
+        this.angle = attribute[FragmentMap.FIELD_CASE_ANG].toString().toDouble()
+        var mediaType = attribute[FragmentMap.FIELD_CASE_TYPE].toString()
         mediaType?.let {
             when (it) {
                 FragmentMap.MEDIA_TYPE_WJ_NO -> {

+ 3 - 3
app/src/main/java/com/cr/map/MapAction.kt

@@ -73,14 +73,14 @@ enum class MapAction {
     MapTapDeleteAllWaypoing,
 
     /**
-     * 移动违建点动作
+     * 开始移动案件点
      */
-    MapTapMoveWaypoing,
+    MapTapStartMoveWaypoing,
 
     /**
      * 移动中动作
      */
-    MapTapMovingWaypoint,
+    MapTapStopMoveWaypoint,
 
     /**
      * 创建案件面动作

+ 16 - 10
app/src/main/java/com/cr/map/MapTouch.kt

@@ -44,8 +44,8 @@ class MapTouch constructor(context: Context, mapView: MapView) :
         // todo: 2023/6/14 移动案件点
         fun onMoveWaypointBySelect(location: Point)
 
-        // todo: 2023/6/14 移动结束
-        fun onMoveWaypointToEnd(location: Point)
+        // todo: 2023/6/15 案件上传选择
+        fun onCaseUploadBySelect(screenPoint:android.graphics.Point)
     }
 
 
@@ -114,18 +114,16 @@ class MapTouch constructor(context: Context, mapView: MapView) :
                 this.action = MapAction.MapTapNon
             }
             // todo: 2023/6/14 移动案件点
-            MapAction.MapTapMoveWaypoing->{
+            MapAction.MapTapStartMoveWaypoing->{
                 var mapPoint = mapView?.screenToLocation(android.graphics.Point(e!!.x.toInt(),e.y.toInt()))
                 if(listener != null) listener?.onMoveWaypointBySelect(mapPoint!!)
             }
-            // todo: 2023/6/14 移动案件点结束
-            MapAction.MapTapMovingWaypoint->{
-                var mapPoint = mapView?.screenToLocation(android.graphics.Point(e!!.x.toInt(),e.y.toInt()))
-                if(listener != null) listener?.onMoveWaypointToEnd(mapPoint!!)
-                this.action = MapAction.MapTapNon
+            // todo: 2023/6/15 案件分享及上传选择
+            MapAction.MapTapCaseWxAndUpload->{
+                var screenPoint = android.graphics.Point(e!!.x.toInt(),e.y.toInt())
+                var mapPoint = mapView?.screenToLocation(screenPoint)
+                if (listener != null) listener?.onCaseUploadBySelect(screenPoint)
             }
-
-
         }
         return true
     }
@@ -196,6 +194,14 @@ class MapTouch constructor(context: Context, mapView: MapView) :
     }
 
     /**
+     * 获取当前地图操作动作
+     * @return MapAction? 地图操作动作
+     */
+    fun getAction():MapAction?{
+        return this.action
+    }
+
+    /**
      * 设置监听
      * @param listener TouchListener 监听
      */

+ 2 - 0
app/src/main/java/com/cr/pages/FragmentCaseTools.kt

@@ -138,10 +138,12 @@ class FragmentCaseTools : CrNavigationFragment(), CrButton.OnClickListener,
             R.id.case_move_point->{
                 if(listener != null) listener?.onMoveCasePoint()
                 switchDraw?.isChecked = false
+                onDismiss()
             }
             R.id.case_remove_point->{
                 if(listener != null) listener?.onRemoveCasePoint()
                 switchDraw?.isChecked = false
+                onDismiss()
             }
         }
     }

+ 245 - 106
app/src/main/java/com/cr/pages/FragmentMap.kt

@@ -35,6 +35,7 @@ import com.google.gson.JsonObject
 import com.google.gson.JsonParser
 import com.google.gson.JsonPrimitive
 import com.squareup.otto.Subscribe
+import kotlinx.android.synthetic.main.frag_map.*
 import java.util.concurrent.ExecutionException
 import kotlin.math.abs
 
@@ -45,6 +46,14 @@ import kotlin.math.abs
  * 描述:地图界面
  */
 class FragmentMap : CrAnimationFragment() {
+    /**
+     * 事件监听接口
+     */
+    interface EventListener {
+        // todo: 2023/6/15 案件上传监听
+        fun onCaseUpdate(selCase: CaseModel)
+    }
+
     // define: 2023/3/14 地图容器
     private var mapView: MapView? = null
 
@@ -89,7 +98,7 @@ class FragmentMap : CrAnimationFragment() {
     val MEDIA_TYPE_REPEAT_YES = "5";   //  define: 2023/4/13 已上传的复飞案件
 
     // todo: 2023/4/14 字段相关常量
-    companion object{
+    companion object {
         val FIELD_NET_CASE_POLYGON_AJH = "AJH";   //  define: 2023/4/13 网络案件的案件编号
         val FIELD_CASE_POLYGON_ANJID = "ANJID";   //  define: 2023/4/13 案件ID
         val FIELD_CASE_POLYGON_MJ = "MJ";   //  define: 2023/4/13 面积
@@ -159,6 +168,9 @@ class FragmentMap : CrAnimationFragment() {
     // todo: 2023/4/18 地图Touch事件
     private var mapTouch: MapTouch? = null
 
+    // todo: 2023/6/15 内部监听 自行设置
+    private var eventListener: EventListener? = null
+
 
     /**
      * 重写创建View方法
@@ -254,6 +266,8 @@ class FragmentMap : CrAnimationFragment() {
                         )
                     }
                 }
+            } else if (p0!!.geometry.geometryType == GeometryType.POINT && mapTouch!!.getAction() == MapAction.MapTapStopMoveWaypoint) {
+                caseMoveWaypointToEnd(p0!!.geometry as Point)
             }
         }
 
@@ -323,7 +337,7 @@ class FragmentMap : CrAnimationFragment() {
 
         // todo: 2023/6/12 添加案件点
         override fun onAppendWaypoint(location: Point, longitude: String, latitude: String) {
-            caseAppendWaypointToMap(location,longitude,latitude)
+            caseAppendWaypointToMap(location, longitude, latitude)
         }
 
         // todo: 2023/6/14 删除案件点
@@ -336,10 +350,11 @@ class FragmentMap : CrAnimationFragment() {
             caseMoveWaypointBySelect(location)
         }
 
-        // todo: 2023/6/14 移动完成
-        override fun onMoveWaypointToEnd(location: Point) {
-            caseMoveWaypointToEnd(location)
+        // todo: 2023/6/15 案件分享及上传选择回调
+        override fun onCaseUploadBySelect(screenPoint: android.graphics.Point) {
+            caseUpload(screenPoint)
         }
+
     }
 
     /**
@@ -1030,41 +1045,49 @@ class FragmentMap : CrAnimationFragment() {
                 var queryParams = QueryParameters()
                 queryParams.geometry = polygon
                 queryParams.spatialRelationship = QueryParameters.SpatialRelationship.CONTAINS
-                queryParams.whereClause = String.format("%s='%s' or %s='%s'",FIELD_CASE_ISUP,MEDIA_TYPE_WJ_NO,FIELD_CASE_ISUP,MEDIA_TYPE_WJ_YES)
+                queryParams.whereClause = String.format(
+                    "%s='%s' or %s='%s'",
+                    FIELD_CASE_ISUP,
+                    MEDIA_TYPE_WJ_NO,
+                    FIELD_CASE_ISUP,
+                    MEDIA_TYPE_WJ_YES
+                )
                 var queryAsync = fTableMedia?.queryFeaturesAsync(queryParams)
                 queryAsync?.addDoneListener(Runnable {
-                    if(queryAsync.isDone){
+                    if (queryAsync.isDone) {
                         // todo: 2023/6/12 获取查询结果
                         var featureResult = queryAsync.get().iterator()
                         var features = ArrayList<Feature>()
-                        while (featureResult.hasNext()){
+                        while (featureResult.hasNext()) {
                             features.add(featureResult.next())
                         }
                         // todo: 2023/6/12 如果存在违建点 则赋值 否则为 空
                         var caseId = ""
-                        if(features.size > 0){
+                        if (features.size > 0) {
                             caseId = features[0].attributes[FIELD_CASE_NAME].toString()
                         }
                         // todo: 2023/6/12 计算面积 并添加要素到图层
-                        var area = abs(GeometryEngine.area(polygon))*0.0015
+                        var area = abs(GeometryEngine.area(polygon)) * 0.0015
                         var wjFeature = fTableCasePolygon?.createFeature()
                         wjFeature!!.let {
                             it.attributes[FIELD_CASE_POLYGON_ANJID] = caseId
-                            it.attributes[FIELD_CASE_POLYGON_MJ]= area
-                            if(caseId == ""){
-                                it.attributes[FIELD_CASE_POLYGON_BZ] = FIELD_CASE_POLYGON_BZ_VALUE_NO
-                            }else{
-                                it.attributes[FIELD_CASE_POLYGON_BZ] = FIELD_CASE_POLYGON_BZ_VALUE_YES
+                            it.attributes[FIELD_CASE_POLYGON_MJ] = area
+                            if (caseId == "") {
+                                it.attributes[FIELD_CASE_POLYGON_BZ] =
+                                    FIELD_CASE_POLYGON_BZ_VALUE_NO
+                            } else {
+                                it.attributes[FIELD_CASE_POLYGON_BZ] =
+                                    FIELD_CASE_POLYGON_BZ_VALUE_YES
                             }
                             it.geometry = polygon
                             var appendAsync = fTableCasePolygon?.addFeatureAsync(it)
-                            appendAsync?.addDoneListener(Runnable{
-                                try{
-                                    if(appendAsync.isDone){
+                            appendAsync?.addDoneListener(Runnable {
+                                try {
+                                    if (appendAsync.isDone) {
                                         showInformation("案件保存成功!")
                                         sketchEditor?.stop()
                                     }
-                                }catch (ex:java.lang.IllegalArgumentException){
+                                } catch (ex: java.lang.IllegalArgumentException) {
                                     showError("案件保存失败!")
                                 }
                             })
@@ -1080,25 +1103,25 @@ class FragmentMap : CrAnimationFragment() {
     /**
      * 删除保存的案件图斑
      */
-    private fun caseDelete(){
+    private fun caseDelete() {
         var queryParameters = QueryParameters()
         queryParameters.whereClause = "1=1"
         var queryAsync = fTableCasePolygon?.queryFeaturesAsync(queryParameters)
         queryAsync?.addDoneListener(Runnable {
-            try{
-                if(queryAsync.isDone){
+            try {
+                if (queryAsync.isDone) {
                     var deleteAsync = fTableCasePolygon?.deleteFeaturesAsync(queryAsync.get())
-                    deleteAsync?.addDoneListener(Runnable{
+                    deleteAsync?.addDoneListener(Runnable {
                         try {
-                            if(deleteAsync.isDone){
+                            if (deleteAsync.isDone) {
                                 showInformation("删除成功!")
                             }
-                        }catch (ex:java.lang.IllegalArgumentException){
+                        } catch (ex: java.lang.IllegalArgumentException) {
                             showError("删除失败!")
                         }
                     })
                 }
-            }catch (ex:java.lang.IllegalArgumentException){
+            } catch (ex: java.lang.IllegalArgumentException) {
                 showError("删除失败!")
             }
         })
@@ -1110,9 +1133,10 @@ class FragmentMap : CrAnimationFragment() {
      * @param longitude String 经度
      * @param latitude String 纬度
      */
-    private fun caseAppendWaypointToMap(location: Point,longitude: String,latitude: String){
+    private fun caseAppendWaypointToMap(location: Point, longitude: String, latitude: String) {
         // todo: 2023/6/13 创建案件点模型
-        var caseModel = CaseModel(longitude.toDouble(),latitude.toDouble(),0.0,0.0,CaseType.MediaTypeWjNo)
+        var caseModel =
+            CaseModel(longitude.toDouble(), latitude.toDouble(), 0.0, 0.0, CaseType.MediaTypeWjNo)
         // todo: 2023/6/13 创建案件点图元
         var caseFeature = fTableMedia?.createFeature()
         // todo: 2023/6/13 添加属性
@@ -1122,69 +1146,139 @@ class FragmentMap : CrAnimationFragment() {
         // todo: 2023/6/13 添加到地图中
         var appendAsync = fTableMedia?.addFeatureAsync(caseFeature)
         appendAsync?.addDoneListener(Runnable {
-            try{
-                if(appendAsync.isDone){
+            try {
+                if (appendAsync.isDone) {
                     fLayerMedia?.clearSelection()
                     fLayerMedia?.selectFeature(caseFeature)
-                    caseUpdatePolygonByFeature(caseFeature,true,object:iCompletion{
+                    caseUpdatePolygonByFeature(caseFeature, object : iCompletion {
                         override fun onCompletion(result: ResultModel) {
-                            if (result.isSuccess == true){
-                                CrUtil.showMessage(String.format("案件点追加成功 %s",caseFeature.attributes[FIELD_CASE_NAME]))
-                            }else{
+                            if (result.isSuccess == true) {
+                                CrUtil.showMessage(
+                                    String.format(
+                                        "案件点追加成功 %s",
+                                        caseFeature.attributes[FIELD_CASE_NAME]
+                                    )
+                                )
+                            } else {
                                 showError(result.message!!)
                             }
                         }
                     })
                 }
-            }catch (ex:java.lang.IllegalArgumentException){
+            } catch (ex: java.lang.IllegalArgumentException) {
                 showError("案件点添加错误!")
             }
         })
     }
 
     /**
-     * 更新案件点对应的案件对象
-     * @param geom Feature 案件点
-     * @param isAppend Boolean ture表示为追加案件点 false表示删除案件点
-     * @param callback iCompletion 回调
+     * 根据案件点要素图元的案件编号查询到与之关联的案件面,并进行初始化
+     * @param geom Feature 案件点要素
+     * @param callback iCompletion 完成回调
      */
-    private fun caseUpdatePolygonByFeature(geom:Feature,isAppend:Boolean,callback:iCompletion){
+    private fun caseClearPolygonByFeature(geom: Feature, callback: iCompletion) {
         // todo: 2023/6/13 获取案件ID
         val caseId = geom.attributes[FIELD_CASE_NAME]
-        // todo: 2023/6/13 先进行空间查询 查询案件点对应的案件面
+        // todo: 2023/6/15 先判断是否存在与该案件点名称相同的案件图斑 将其标志清除
         var queryParameters = QueryParameters()
-        queryParameters.geometry = geom.geometry
-        queryParameters.spatialRelationship = QueryParameters.SpatialRelationship.INTERSECTS
-        queryParameters.whereClause = "1=1"
-        var queryAsync = fTableCasePolygon!!.queryFeaturesAsync(queryParameters)
-        queryAsync?.addDoneListener(Runnable{
+        queryParameters.whereClause = String.format("%s = '%s'", FIELD_CASE_POLYGON_ANJID, caseId)
+        var asyncQuery = fTableCasePolygon?.queryFeaturesAsync(queryParameters)
+        asyncQuery?.addDoneListener(Runnable {
             try {
-                if(queryAsync.isDone){
-                    var features = queryAsync.get()
-                    for(fea in features){
-                        if(isAppend){
-                            fea.attributes[FIELD_CASE_POLYGON_ANJID] = caseId
-                            fea.attributes[FIELD_CASE_POLYGON_BZ] = FIELD_CASE_POLYGON_BZ_VALUE_YES
-                        }else{
-                            fea.attributes[FIELD_CASE_POLYGON_ANJID] = ""
-                            fea.attributes[FIELD_CASE_POLYGON_BZ] = FIELD_CASE_POLYGON_BZ_VALUE_NO
-                        }
+                if (asyncQuery.isDone) {
+                    var features = mutableListOf<Feature>()
+                    for (fea in asyncQuery.get()) {
+                        fea.attributes[FIELD_CASE_POLYGON_ANJID] = ""
+                        fea.attributes[FIELD_CASE_POLYGON_BZ] = FIELD_CASE_POLYGON_BZ_VALUE_NO
+                        features.add(fea)
                     }
-                    // todo: 2023/6/13 更新
-                    var updateAsync = fTableCasePolygon!!.updateFeaturesAsync(features)
-                    updateAsync?.addDoneListener(Runnable {
+                    var asyncUpdate = fTableCasePolygon?.updateFeaturesAsync(features)
+                    asyncUpdate?.addDoneListener(Runnable {
                         try {
-                            if(updateAsync.isDone){
-                                // todo: 2023/6/13 更新完成
-                                if(callback != null) callback.onCompletion(ResultModel(true,"成功!"))
+                            if (asyncUpdate.isDone) {
+                                if (callback != null) callback.onCompletion(ResultModel(true, ""))
                             }
-                        }catch (ex:java.lang.IllegalArgumentException){
-                            if(callback != null) callback.onCompletion(ResultModel(false,"案件对象更新失败!"))
+                        } catch (ex: java.lang.IllegalArgumentException) {
+                            if (callback != null) callback.onCompletion(
+                                ResultModel(
+                                    false,
+                                    "案件面初始化错误!"
+                                )
+                            )
+                        }
+                    })
+                }
+            } catch (ex: java.lang.IllegalArgumentException) {
+                if (callback != null) callback.onCompletion(ResultModel(false, "案件面初始化错误!"))
+            }
+        })
+    }
+
+    /**
+     * 更新案件点对应的案件对象
+     * @param geom Feature 案件点
+     * @param callback iCompletion 回调
+     */
+    private fun caseUpdatePolygonByFeature(geom: Feature, callback: iCompletion) {
+        // todo: 2023/6/15 先进行初始化
+        caseClearPolygonByFeature(geom, object : iCompletion {
+            override fun onCompletion(result: ResultModel) {
+                if (result.isSuccess == false) {
+                    if (callback != null) callback.onCompletion(result)
+                } else {
+                    // todo: 2023/6/13 获取案件ID
+                    val caseId = geom.attributes[FIELD_CASE_NAME]
+                    // todo: 2023/6/15 先判断是否存在与该案件点名称相同的案件图斑 将其标志清除
+                    var queryParameters = QueryParameters()
+                    // todo: 2023/6/13 先进行空间查询 查询案件点对应的案件面
+                    queryParameters.geometry = geom.geometry
+                    queryParameters.spatialRelationship =
+                        QueryParameters.SpatialRelationship.INTERSECTS
+                    queryParameters.whereClause = "1=1"
+                    var queryAsync = fTableCasePolygon!!.queryFeaturesAsync(queryParameters)
+                    queryAsync?.addDoneListener(Runnable {
+                        try {
+                            if (queryAsync.isDone) {
+                                var features = mutableListOf<Feature>()
+                                for (fea in queryAsync.get()) {
+                                    fea.attributes[FIELD_CASE_POLYGON_ANJID] = caseId
+                                    fea.attributes[FIELD_CASE_POLYGON_BZ] =
+                                        FIELD_CASE_POLYGON_BZ_VALUE_YES
+                                    features.add(fea)
+                                }
+                                // todo: 2023/6/13 更新
+                                var updateAsync = fTableCasePolygon!!.updateFeaturesAsync(features)
+                                updateAsync?.addDoneListener(Runnable {
+                                    try {
+                                        if (updateAsync.isDone) {
+                                            // todo: 2023/6/13 更新完成
+                                            if (callback != null) callback.onCompletion(
+                                                ResultModel(
+                                                    true,
+                                                    "成功!"
+                                                )
+                                            )
+                                        }
+                                    } catch (ex: java.lang.IllegalArgumentException) {
+                                        if (callback != null) callback.onCompletion(
+                                            ResultModel(
+                                                false,
+                                                "案件对象更新失败!"
+                                            )
+                                        )
+                                    }
+                                })
+                            }
+                        } catch (ex: java.lang.IllegalArgumentException) {
+                            if (callback != null) callback.onCompletion(
+                                ResultModel(
+                                    false,
+                                    "案件对象查询失败!"
+                                )
+                            )
                         }
                     })
                 }
-            }catch (ex:java.lang.IllegalArgumentException){
-                if(callback != null) callback.onCompletion(ResultModel(false,"案件对象查询失败!"))
             }
         })
     }
@@ -1193,9 +1287,9 @@ class FragmentMap : CrAnimationFragment() {
      * 删除案件点
      * @param queryPoint Point 查询产靠位置
      */
-    private fun caseRemoveCaseWaypoing(queryPoint:Point){
+    private fun caseRemoveCaseWaypoing(queryPoint: Point) {
         // todo: 2023/6/14 创建缓冲区
-        var queryGeometry = GeometryEngine.buffer(queryPoint,10.0)
+        var queryGeometry = GeometryEngine.buffer(queryPoint, 10.0)
         // todo: 2023/6/14 设置查询参数
         var queryParameters = QueryParameters()
         queryParameters.spatialRelationship = QueryParameters.SpatialRelationship.CONTAINS
@@ -1203,29 +1297,29 @@ class FragmentMap : CrAnimationFragment() {
         queryParameters.whereClause = "1=1"
         // todo: 2023/6/14 开始查询
         var identifyAsync = fTableMedia?.queryFeaturesAsync(queryParameters)
-        identifyAsync?.addDoneListener(Runnable{
+        identifyAsync?.addDoneListener(Runnable {
             try {
-                if (identifyAsync.isDone){
+                if (identifyAsync.isDone) {
                     var queryFeatures = identifyAsync.get()
                     var features = mutableListOf<Feature>()
-                    for (fea in queryFeatures){
+                    for (fea in queryFeatures) {
                         features.add(fea)
                     }
-                    if(features.size >0){
+                    if (features.size > 0) {
                         var dig = DialogNormal(context!!)
                         dig.setTitle("提示")
                         dig.setMessage("删除后将无法恢复,确定删除吗?")
-                        dig.setButtonsText("删除","取消")
-                        dig.setListener(object :DialogNormal.DialogNormalListener{
+                        dig.setButtonsText("删除", "取消")
+                        dig.setListener(object : DialogNormal.DialogNormalListener {
                             // todo: 2023/6/14 确认删除
                             override fun completion() {
                                 var deleteAsync = fTableMedia?.deleteFeaturesAsync(features)
                                 deleteAsync?.addDoneListener(Runnable {
                                     try {
-                                        if(deleteAsync.isDone){
+                                        if (deleteAsync.isDone) {
                                             showInformation("案件点删除成功!")
                                         }
-                                    }catch (ex:java.lang.IllegalArgumentException){
+                                    } catch (ex: java.lang.IllegalArgumentException) {
                                         showError("案件点删除失败!")
                                     }
                                 })
@@ -1237,11 +1331,11 @@ class FragmentMap : CrAnimationFragment() {
 
                         })
                         dig.show()
-                    }else{
+                    } else {
                         showWarning("未查询到任何案件点!")
                     }
                 }
-            }catch (ex:java.lang.IllegalArgumentException){
+            } catch (ex: java.lang.IllegalArgumentException) {
                 showError("查询错误,无法删除!")
             }
         })
@@ -1250,18 +1344,18 @@ class FragmentMap : CrAnimationFragment() {
     /**
      * 移动案件点
      */
-    private fun caseMoveWaypoint(){
+    private fun caseMoveWaypoint() {
         CrUtil.showMessage("选择需要移动的案件点!")
-        mapTouch?.setAction(MapAction.MapTapMoveWaypoing)
+        mapTouch?.setAction(MapAction.MapTapStartMoveWaypoing)
     }
 
     /**
      * 选择移动的案件点
      * @param location Point 点击位置
      */
-    private fun caseMoveWaypointBySelect(location: Point){
+    private fun caseMoveWaypointBySelect(location: Point) {
         // todo: 2023/6/14 设置查询区域
-        var queryGeometry = GeometryEngine.buffer(location,10.0)
+        var queryGeometry = GeometryEngine.buffer(location, 10.0)
         // todo: 2023/6/14 设置查询条件
         var queryParameters = QueryParameters()
         queryParameters.geometry = queryGeometry
@@ -1269,23 +1363,26 @@ class FragmentMap : CrAnimationFragment() {
         queryParameters.whereClause = "1=1"
         // todo: 2023/6/14 开始查询
         var queryAsync = fTableMedia?.queryFeaturesAsync(queryParameters)
-        queryAsync?.addDoneListener(Runnable{
+        queryAsync?.addDoneListener(Runnable {
             try {
-                if(queryAsync.isDone){
+                if (queryAsync.isDone) {
                     var features = mutableListOf<Feature>()
-                    for(fea in queryAsync.get()){
+                    for (fea in queryAsync.get()) {
                         features.add(fea)
                     }
-                    if(features.size == 0){
+                    if (features.size == 0) {
                         CrUtil.showMessage("未查询到任何违建点!")
-                    }else{
+                    } else {
                         fLayerMedia?.clearSelection()
                         fLayerMedia?.selectFeature(features[0])
                         CrUtil.showMessage("地图点击确定移动位置!")
-                        mapTouch?.setAction(MapAction.MapTapMovingWaypoint)
+                        mapTouch?.setAction(MapAction.MapTapStopMoveWaypoint)
+                        // todo: 2023/6/15 利用编辑工具
+                        sketchEditor?.start(location)
+                        sketchEditor?.addGeometryChangedListener(sketchGeometryChangeListener)
                     }
                 }
-            }catch (ex:java.lang.IllegalArgumentException){
+            } catch (ex: java.lang.IllegalArgumentException) {
                 showError("案件点查询错误!")
             }
         })
@@ -1295,46 +1392,75 @@ class FragmentMap : CrAnimationFragment() {
      * 案件点移动结束
      * @param location Point 移动后位置
      */
-    private fun caseMoveWaypointToEnd(location: Point){
+    private fun caseMoveWaypointToEnd(location: Point) {
         var asyncSelected = fLayerMedia?.selectedFeaturesAsync
         asyncSelected?.addDoneListener(Runnable {
             try {
-                if(asyncSelected.isDone){
-                    var features =  mutableListOf<Feature>()
-                    for(fea in asyncSelected.get()){
+                if (asyncSelected.isDone) {
+                    var features = mutableListOf<Feature>()
+                    for (fea in asyncSelected.get()) {
                         features.add(fea)
                     }
-                    if(features.size == 0){
+                    if (features.size == 0) {
                         showError("未获取到可移动违建点,无法完成移动操作!")
-                    }else{
+                    } else {
                         features[0].geometry = location
                         var asyncUpdate = fTableMedia?.updateFeatureAsync(features[0])
-                        asyncUpdate?.addDoneListener(Runnable{
+                        asyncUpdate?.addDoneListener(Runnable {
                             try {
-                                if (asyncUpdate.isDone){
-                                    caseUpdatePolygonByFeature(features[0],true,object:iCompletion{
+                                if (asyncUpdate.isDone) {
+                                    caseUpdatePolygonByFeature(features[0], object : iCompletion {
                                         override fun onCompletion(result: ResultModel) {
-                                            if(result.isSuccess == true){
+                                            if (result.isSuccess == true) {
                                                 CrUtil.showMessage("移动完成!")
-                                            }else{
+                                                sketchEditor?.removeGeometryChangedListener(
+                                                    sketchGeometryChangeListener
+                                                )
+                                                sketchEditor?.stop()
+                                                fLayerMedia?.clearSelection()
+                                            } else {
                                                 showError(result.message!!)
                                             }
                                         }
                                     })
                                 }
-                            }catch (ex:java.lang.IllegalArgumentException){
+                            } catch (ex: java.lang.IllegalArgumentException) {
                                 showError("移动错误,无法完成移动操作!")
                             }
                         })
                     }
                 }
-            }catch (ex:java.lang.IllegalArgumentException){
+            } catch (ex: java.lang.IllegalArgumentException) {
                 showError("获取可移动违建点错误,无法完成移动操作!")
             }
         })
     }
 
     /**
+     * 案件分享及上传选择执行
+     * @param screenPoint Point 屏幕点
+     */
+    private fun caseUpload(screenPoint: android.graphics.Point) {
+        // todo: 2023/6/15 查询
+        var asyncQuery = map_mapView?.identifyLayerAsync(fLayerMedia, screenPoint, 6.0, false)
+        asyncQuery?.addDoneListener(Runnable {
+            try {
+                if (asyncQuery.isDone) {
+                    var elements = asyncQuery.get().elements
+                    if (elements.size <= 0) {
+                        CrUtil.showMessage("未选择上传案件!")
+                    } else {
+                        fLayerMedia?.selectFeature(elements.last() as Feature)
+                        if(eventListener != null) eventListener?.onCaseUpdate(CaseModel(elements.last().attributes))
+                    }
+                }
+            } catch (ex: java.lang.IllegalArgumentException) {
+                showError("案件查询错误!")
+            }
+        })
+    }
+
+    /**
      * 显示警告信息
      * @param warning String 警告消息
      */
@@ -1484,26 +1610,39 @@ class FragmentMap : CrAnimationFragment() {
                 caseSave()
             }
             // todo: 2023/6/12 删除保存的图斑
-            MapAction.EventCaseRemovePolygon->{
+            MapAction.EventCaseRemovePolygon -> {
                 caseDelete()
             }
             // todo: 2023/6/12 地图点击添加违建点
-            MapAction.MapTapAddWaypoint->{
+            MapAction.MapTapAddWaypoint -> {
                 CrUtil.showMessage("地图上点击添加案件点!")
                 mapTouch?.setAction(MapAction.MapTapAddWaypoint)
             }
             // todo: 2023/6/13 删除案件点
-            MapAction.MapTapDeleteWaypoint->{
+            MapAction.MapTapDeleteWaypoint -> {
                 CrUtil.showMessage("地图上选择需要删除的违建点后删除!")
                 mapTouch?.setAction(MapAction.MapTapDeleteWaypoint)
             }
             // todo: 2023/6/14 移动案件点
-            MapAction.MapTapMoveWaypoing->{
+            MapAction.MapTapStartMoveWaypoing -> {
                 caseMoveWaypoint()
             }
+            // todo: 2023/6/15 案件分享及上传
+            MapAction.MapTapCaseWxAndUpload -> {
+                CrUtil.showMessage("地图上选择需要上传或分享的案件!")
+                mapTouch?.setAction(MapAction.MapTapCaseWxAndUpload)
+            }
         }
     }
 
+    /**
+     * 设置事件监听
+     * @param listener EventListener 事件监听
+     */
+    fun crSetEventListener(listener: EventListener) {
+        this.eventListener = listener
+    }
+
     // todo: 2023/4/17 生命周期
     override fun onDestroy() {
         // todo: 2023/4/17 移除订阅监听

+ 1 - 38
app/src/main/java/com/cr/pages/FragmentSet.kt

@@ -8,6 +8,7 @@ import androidx.fragment.app.Fragment
 import androidx.fragment.app.FragmentActivity
 import androidx.viewpager2.adapter.FragmentStateAdapter
 import androidx.viewpager2.widget.ViewPager2
+import com.cr.adapter.CrPageAdapter
 import com.cr.adapter.SettingAdapter
 import com.cr.cruav.CrApplication
 import com.cr.cruav.R
@@ -106,7 +107,6 @@ class FragmentSet : CrNavigationFragment() {
                 break
             }
         }
-
     }
 
     /**
@@ -137,43 +137,6 @@ class FragmentSet : CrNavigationFragment() {
     }
 
     /**
-     * 页面适配器
-     * @constructor
-     */
-    private class CrPageAdapter@JvmOverloads constructor(
-        activity:FragmentActivity
-    ): FragmentStateAdapter(activity){
-        private val mFragmentList: MutableList<CrNavigationFragment> = ArrayList()
-
-        /**
-         * 添加页面
-         * @param fragment CrFragment
-         */
-        fun addFragment(fragment:CrNavigationFragment){
-            mFragmentList.add(fragment)
-        }
-
-        /**
-         * 获取加载的页面
-         * @return MutableList<Fragment>
-         */
-        fun getFragments(): MutableList<CrNavigationFragment> {
-            return mFragmentList
-        }
-
-        // todo: 2023/4/11 页面数量
-        override fun getItemCount(): Int {
-            return mFragmentList.size
-        }
-
-        // todo: 2023/4/11 当前页面
-        override fun createFragment(position: Int): Fragment {
-            return mFragmentList[position]
-        }
-
-    }
-
-    /**
      * 挂载控件
      */
     override fun joinControls() {

+ 119 - 0
app/src/main/java/com/cr/pages/FragmentUploadCase.kt

@@ -0,0 +1,119 @@
+package com.cr.pages
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.viewpager2.widget.ViewPager2
+import com.cr.adapter.CrPageAdapter
+import com.cr.cruav.CrApplication
+import com.cr.cruav.R
+import com.cr.data.CrUtil
+import com.cr.event.BarAction
+import com.cr.event.EventFragmentBarAction
+import com.cr.map.CaseModel
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/6/15 11:18
+ * 描述:案件上传页面框架
+ */
+class FragmentUploadCase : CrNavigationFragment() {
+    private var joinCase: CaseModel? = null // define: 2023/6/15 关联的案件模型
+    private var adapter: CrPageAdapter? = null // define: 2023/6/15 页面适配器
+    private var viewPager: ViewPager2? = null // define: 2023/6/15 页面容器
+
+    // todo: 2023/6/15 主页面
+    private var fragmentUploadCaseMain: FragmentUploadCaseMain? = null
+
+    /**
+     * 初始化
+     * @param inflater LayoutInflater
+     * @param container ViewGroup?
+     * @param savedInstanceState Bundle?
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        // todo: 2023/6/15 设置动画方向
+        setAnimationDirection(AnimationDirection.RIGHT)
+        self = this
+        mainView = inflater.inflate(R.layout.frag_case_upload, null)
+        // todo: 2023/6/15 挂接控件
+        joinControls()
+        // todo: 2023/6/15 初始化月面
+        initPage()
+        // todo: 2023/6/15 设置导航栏
+        setBar(R.id.nv)
+        // todo: 2023/6/15 初始化导航栏
+        initBar()
+        return mainView
+    }
+
+    /**
+     * 覆写控件挂接
+     */
+    override fun initControls() {
+        // todo: 2023/6/15 挂接页面
+        viewPager = mainView?.findViewById(R.id.frag_pages)
+        viewPager?.isUserInputEnabled = false  // todo: 2023/6/15 禁止滑动
+    }
+
+    /**
+     * 初始化页面
+     */
+    override fun initPage() {
+        // todo: 2023/6/15 初始化页面适配器
+        adapter = CrPageAdapter(this.activity!!)
+        // todo: 2023/6/15 初始化主页面
+        fragmentUploadCaseMain = FragmentUploadCaseMain()
+        adapter?.addFragment(fragmentUploadCaseMain!!)
+
+        // todo: 2023/6/15 设置监听
+        viewPager?.adapter = adapter
+    }
+
+    /**
+     * 显示页面
+     * @param fragment CrNavigationFragment
+     */
+    private fun showPage(fragment: CrNavigationFragment){
+        var fragments = adapter?.getFragments()
+        for(i in 0 until fragments!!.size){
+            if(fragments?.get(i) == fragment){
+                fragment.nvBar?.visibility = View.GONE
+                viewPager?.currentItem = i
+                break
+            }
+        }
+    }
+
+    /**
+     * 初始化导航栏
+     */
+    private fun initBar() {
+        nvBar?.crSetTitle(R.string.upload_case_title_main)
+        nvBar?.crSetVisible(backIsVisible = false, dismissIsVisible = true)
+        showPage(fragmentUploadCaseMain!!)
+    }
+
+    /**
+     * 设置关联的案件
+     * @param joinCase CaseModel 关联案件
+     */
+    fun crSetJoinCase(joinCase: CaseModel) {
+        this.joinCase = joinCase
+        fragmentUploadCaseMain!!.crSetJoinCase(this.joinCase!!)
+    }
+
+    /**
+     * 重写关闭事件
+     */
+    override fun onDismiss() {
+        CrApplication.getEventBus().post(EventFragmentBarAction(self!!, BarAction.ACTION_DISMISS))
+    }
+}

+ 109 - 0
app/src/main/java/com/cr/pages/FragmentUploadCaseMain.kt

@@ -0,0 +1,109 @@
+package com.cr.pages
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.LinearLayout
+import android.widget.TextView
+import com.cr.cruav.R
+import com.cr.map.CaseModel
+
+/**
+ * 操作系统:MAC系统
+ * 创建者:王成
+ * 创建日期:2023/6/15 16:06
+ * 描述:案件上传主页面
+ */
+class FragmentUploadCaseMain : CrNavigationFragment(), View.OnClickListener {
+    private var lblCaseName: TextView? = null // define: 2023/6/15 案件名称
+    private var lblCaseImageCount: TextView? = null // define: 2023/6/15 案件照片数量
+    private var lblCaseCreateDate: TextView? = null // define: 2023/6/15 案件创建日期
+    private var lblCaseMediaName: TextView? = null // define: 2023/6/15 案件媒体点名称
+    private var lblCaseMediaSize: TextView? = null // define: 2023/6/15 案件媒体大小
+    private var btnEdit: LinearLayout? = null // define: 2023/6/15 编辑按钮
+    private var btnPhoto: LinearLayout? = null // define: 2023/6/15 相册按钮
+    private var btnUpload: LinearLayout? = null // define: 2023/6/15 上传按钮
+
+    private var joinCase: CaseModel? = null // define: 2023/6/15 关联的案件点
+
+    /**
+     * 初始化
+     * @param inflater LayoutInflater
+     * @param container ViewGroup?
+     * @param savedInstanceState Bundle?
+     * @return View?
+     */
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View? {
+        mainView = inflater.inflate(R.layout.frag_case_upload_main, null)
+        self = this
+        // todo: 2023/6/15 挂载控件
+        joinControls()
+        // todo: 2023/6/15 显示
+        if (this.joinCase != null) {
+            crSetJoinCase(this.joinCase!!)
+        }
+        return mainView
+    }
+
+    /**
+     * 覆写挂载控件
+     */
+    override fun joinControls() {
+        mainView?.let {
+            lblCaseName = it.findViewById(R.id.case_name)
+            lblCaseImageCount = it.findViewById(R.id.case_image_count)
+            lblCaseCreateDate = it.findViewById(R.id.case_create_date)
+            lblCaseMediaName = it.findViewById(R.id.case_media_name)
+            lblCaseMediaSize = it.findViewById(R.id.case_media_size)
+
+            btnEdit = it.findViewById(R.id.case_btn_edit)
+            btnEdit?.setOnClickListener(this)
+
+            btnPhoto = it.findViewById(R.id.case_btn_photo)
+            btnPhoto?.setOnClickListener(this)
+
+            btnUpload = it.findViewById(R.id.case_btn_upload)
+            btnUpload?.setOnClickListener(this)
+        }
+    }
+
+    /**
+     * 覆写点击事件
+     * @param view View
+     */
+    override fun onClick(view: View?) {
+        when (view?.id) {
+            // todo: 2023/6/15 编辑照片
+            R.id.case_btn_edit -> {
+
+            }
+            // todo: 2023/6/15 打开相册
+            R.id.case_btn_photo -> {
+
+            }
+            // todo: 2023/6/15 上传
+            R.id.case_btn_upload -> {
+
+            }
+        }
+    }
+
+    /**
+     * 设置关联的案件点
+     * @param joinCase CaseModel 案件点
+     */
+    fun crSetJoinCase(joinCase: CaseModel) {
+        this.joinCase = joinCase
+        // todo: 2023/6/15 设置显示内容
+        lblCaseName?.text = this.joinCase?.name
+        lblCaseImageCount?.text = String.format("取证照片[%s]张", this.joinCase?.imgArray?.size)
+        lblCaseCreateDate?.text = this.joinCase?.date
+        lblCaseMediaName?.text = ""
+        lblCaseMediaSize?.text = ""
+    }
+}

+ 17 - 0
app/src/main/res/drawable/shape_image_circle.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <!--填充色-->
+    <solid android:color="#000000" />
+    <!--描边-->
+    <stroke
+        android:width="0dp"
+        android:color="#736864" />
+    <!-- 圆角 -->
+    <corners
+        android:radius="@dimen/cr_100_dp"/>
+    <padding
+        android:left="0dp"
+        android:right="0dp"
+        android:top="0dp"
+        android:bottom="0dp"/>
+</shape>

+ 1 - 1
app/src/main/res/layout/av_login.xml

@@ -125,7 +125,7 @@
     </LinearLayout>
     <!--左侧弹窗容器-->
     <FrameLayout
-        android:id="@+id/av_frm_left_panel"
+        android:id="@+id/av_frm_left_big_panel"
         android:layout_width="@dimen/cr_200_dp"
         android:layout_height="match_parent"
         android:orientation="vertical"/>

+ 18 - 2
app/src/main/res/layout/av_main.xml

@@ -101,12 +101,28 @@
         android:orientation="vertical"
         app:layout_constraintRight_toRightOf="parent"
         app:layout_constraintTop_toBottomOf="@id/av_fragment_top"/>
-    <!--左侧弹窗容器-->
+    <!--左侧弹窗容器-->
     <FrameLayout
-        android:id="@+id/av_frm_left_panel"
+        android:id="@+id/av_frm_left_big_panel"
         android:layout_width="@dimen/cr_200_dp"
         android:layout_height="match_parent"
         android:orientation="vertical"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintTop_toBottomOf="@id/av_fragment_top"/>
+    <!--左侧弹窗容器 小-->
+    <FrameLayout
+        android:id="@+id/av_frm_left_smart_panel"
+        android:layout_width="@dimen/cr_120_dp"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/av_fragment_top"/>
+    <FrameLayout
+        android:id="@+id/av_frm_center_panel"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/av_fragment_top"
+        android:layout_margin="@dimen/cr_20_dp"/>
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 25 - 0
app/src/main/res/layout/frag_case_upload.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:clickable="true">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@drawable/shape_back_fragment"
+        android:orientation="vertical">
+        <com.cr.widget.CrNavigationBarWidget
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            app:crTitle="@string/nv_title_set"
+            app:isGotoBack="false"
+            app:isDismiss="true"
+            android:id="@+id/nv"
+            android:layout_weight="0"/>
+        <androidx.viewpager2.widget.ViewPager2
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:id="@+id/frag_pages"/>
+    </LinearLayout>
+</RelativeLayout>

+ 105 - 0
app/src/main/res/layout/frag_case_upload_main.xml

@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@drawable/shape_back_fragment">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/cr_40_dp"
+        android:orientation="horizontal">
+        <!--案件相关信息视图-->
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:orientation="vertical"
+            android:layout_weight="1">
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1">
+                <ImageView
+                    android:layout_width="@dimen/cr_18_dp"
+                    android:layout_height="@dimen/cr_18_dp"
+                    android:src="@drawable/ico_media_cur"
+                    android:layout_marginLeft="@dimen/common_margin"/>
+                <TextView
+                    style="@style/text_case_upload"
+                    android:textColor="@color/white"
+                    android:text="@string/ucm_lbl_name"
+                    android:layout_weight="1"
+                    android:textStyle="bold"
+                    android:id="@+id/case_name"/>
+                <TextView
+                    style="@style/text_case_upload"
+                    android:textColor="@color/green"
+                    android:text="@string/ucm_lbl_description"
+                    android:id="@+id/case_image_count"/>
+                <TextView
+                    style="@style/text_case_upload"
+                    android:textColor="@color/yellow"
+                    android:text="@string/ucm_lbl_date"
+                    android:id="@+id/case_create_date"/>
+            </LinearLayout>
+            <View style="@style/view_split_h1"/>
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_weight="1">
+                <TextView
+                    style="@style/text_case_upload"
+                    android:text="@string/ucm_lbl_media_name"
+                    android:textStyle="bold"/>
+                <TextView
+                    style="@style/text_case_upload"
+                    android:textColor="@color/white"
+                    android:text="@string/ucm_lbl_media_name_value"
+                    android:layout_weight="1"
+                    android:id="@+id/case_media_name"/>
+                <TextView
+                    style="@style/text_case_upload"
+                    android:text="@string/ucm_lbl_media_size"
+                    android:textStyle="bold"/>
+                <TextView
+                    style="@style/text_case_upload"
+                    android:textColor="@color/white"
+                    android:text="@string/ucm_lbl_media_size_value"
+                    android:id="@+id/case_media_size"/>
+            </LinearLayout>
+        </LinearLayout>
+        <View style="@style/view_split_v1"/>
+        <LinearLayout
+            style="@style/button_panel"
+            android:id="@+id/case_btn_edit">
+            <ImageView
+                style="@style/button_image"
+                android:src="@drawable/ty_save"/>
+            <TextView
+                style="@style/button_title"
+                android:text="@string/ucm_btn_edit"/>
+        </LinearLayout>
+        <View style="@style/view_split_v1"/>
+        <LinearLayout
+            style="@style/button_panel"
+            android:id="@+id/case_btn_photo">
+            <ImageView
+                style="@style/button_image"
+                android:src="@drawable/ico_multimage"/>
+            <TextView
+                style="@style/button_title"
+                android:text="@string/ucm_btn_photo"/>
+        </LinearLayout>
+        <View style="@style/view_split_v1"/>
+        <LinearLayout
+            style="@style/button_panel"
+            android:id="@+id/case_btn_upload">
+            <ImageView
+                style="@style/button_image"
+                android:src="@drawable/ico_upload_wj"/>
+            <TextView
+                style="@style/button_title"
+                android:text="@string/ucm_btn_upload"/>
+        </LinearLayout>
+    </LinearLayout>
+    <View style="@style/view_split_h1"/>
+</LinearLayout>

+ 1 - 0
app/src/main/res/values/colors.xml

@@ -19,6 +19,7 @@
     <color name="switch_off">#9e9e9e</color>
     <color name="switch_on">#34db35</color>
 
+
     <!--常用颜色-->
     <color name="white">#FFFFFF</color>
     <!-- 白色 -->

+ 13 - 0
app/src/main/res/values/strings.xml

@@ -134,6 +134,19 @@
     <string name="bar_lbl_right">右</string>
     <string name="bar_lbl_title">标题</string>
 
+    <!--案件上传相关-->
+    <string name="upload_case_title_main">案件上传</string>
+    <string name="ucm_lbl_name">20230615124325</string>
+    <string name="ucm_lbl_description">取证照片[10]张</string>
+    <string name="ucm_lbl_date">2023-06-15 12:00:00</string>
+    <string name="ucm_lbl_media_name">媒体名称</string>
+    <string name="ucm_lbl_media_name_value">2023******.JPG</string>
+    <string name="ucm_lbl_media_size">媒体大小</string>
+    <string name="ucm_lbl_media_size_value">900.1M</string>
+    <string name="ucm_btn_edit">编辑</string>
+    <string name="ucm_btn_photo">相册</string>
+    <string name="ucm_btn_upload">上传</string>
+
     <!--字体-->
     <string name="ico_nv_left" translatable="false">&#xe60b;</string>
     <string name="ico_nv_right" translatable="false">&#xe81a;</string>

+ 35 - 0
app/src/main/res/values/themes.xml

@@ -109,6 +109,15 @@
         <item name="android:layout_marginRight">@dimen/cr_3_dp</item>
     </style>
 
+    <!--案件上传文字样式-->
+    <style name="text_case_upload" parent="text_default">
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:textSize">@dimen/sp_10</item>
+        <item name="android:textColor">@color/yellow</item>
+        <item name="android:layout_marginLeft">@dimen/cr_5_dp</item>
+        <item name="android:layout_marginRight">@dimen/cr_5_dp</item>
+    </style>
+
     <!--登录界面相关样式集合-->
     <!--密码和用户名输入框文字样式-->
     <style name="login_txt_style" parent="text_default">
@@ -236,6 +245,32 @@
         <item name="android:scaleType">fitCenter</item>
     </style>
 
+    <!--上部图片 下部文字 按钮样式-->
+    <style name="button_panel">
+        <item name="android:layout_width">@dimen/cr_30_dp</item>
+        <item name="android:layout_height">match_parent</item>
+        <item name="android:padding">@dimen/common_padding</item>
+        <item name="android:background">@drawable/btn_imgbtn_selector</item>
+        <item name="android:layout_marginLeft">@dimen/common_padding</item>
+        <item name="android:layout_marginRight">@dimen/common_padding</item>
+        <item name="android:gravity">center</item>
+        <item name="android:orientation">vertical</item>
+    </style>
+    <style name="button_image">
+        <item name="android:layout_width">@dimen/cr_20_dp</item>
+        <item name="android:layout_height">@dimen/cr_20_dp</item>
+        <item name="android:scaleType">fitCenter</item>
+        <item name="background">@drawable/shape_image_circle</item>
+    </style>
+    <style name="button_title">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:textSize">@dimen/sp_10</item>
+        <item name="android:textColor">@color/yellow</item>
+        <item name="android:layout_marginTop">@dimen/common_margin</item>
+        <item name="android:gravity">center</item>
+    </style>
+
     <!--图层控制页面基础组件-->
     <style name="item_layer_base">
         <item name="android:layout_weight">0</item>