管灌系统巡查员智能手机App
zuoxiao
2024-12-09 fbb64f0b4151a4fefb90191991aa0fba7b26c52a
1.优化MQ相关设置
2.上报问题界面相关
1 文件已复制
1 文件已重命名
6个文件已添加
10个文件已修改
928 ■■■■ 已修改文件
app/src/main/java/com/dayu/pipirrapp/activity/AddQuestionActivity.java 404 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/activity/MainActivity.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/activity/OrderDetailActivity.java 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/bean/net/AddIssueRequest.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingRequest.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/bean/net/ImageRequest.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/fragment/OrderFragment.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/net/MqttManager.java 155 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/utils/MyLog.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/ic_green_bg.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/ic_green_bg_down.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/drawable/ic_green_bg_up.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_add_question.xml 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/activity_order_detail.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/layout/fragment_map.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/res/values/colors.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/dayu/pipirrapp/activity/AddQuestionActivity.java
New file
@@ -0,0 +1,404 @@
package com.dayu.pipirrapp.activity;
import static com.dayu.pipirrapp.net.Constants.BASE_URL;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import com.dayu.pipirrapp.MyApplication;
import com.dayu.pipirrapp.adapter.AddPictureAdapter;
import com.dayu.pipirrapp.bean.db.LatLonBean;
import com.dayu.pipirrapp.bean.net.AddIssueRequest;
import com.dayu.pipirrapp.bean.net.InsectionResult;
import com.dayu.pipirrapp.bean.net.UplodFileState;
import com.dayu.pipirrapp.databinding.ActivityAddQuestionBinding;
import com.dayu.pipirrapp.fragment.OrderFragment;
import com.dayu.pipirrapp.net.ApiManager;
import com.dayu.pipirrapp.net.BaseResponse;
import com.dayu.pipirrapp.net.subscribers.SubscriberListener;
import com.dayu.pipirrapp.net.upload.UploadFileListener;
import com.dayu.pipirrapp.service.MyLocationService;
import com.dayu.pipirrapp.tool.FullyGridLayoutManager;
import com.dayu.pipirrapp.tool.GlideEngine;
import com.dayu.pipirrapp.utils.CommonKeyName;
import com.dayu.pipirrapp.utils.ToastUtil;
import com.dayu.pipirrapp.view.TitleBar;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.luck.picture.lib.basic.PictureSelectionModel;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.config.PictureMimeType;
import com.luck.picture.lib.config.SelectMimeType;
import com.luck.picture.lib.decoration.GridSpacingItemDecoration;
import com.luck.picture.lib.engine.CompressFileEngine;
import com.luck.picture.lib.engine.ImageEngine;
import com.luck.picture.lib.entity.LocalMedia;
import com.luck.picture.lib.entity.MediaExtraInfo;
import com.luck.picture.lib.interfaces.OnExternalPreviewEventListener;
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener;
import com.luck.picture.lib.utils.DateUtils;
import com.luck.picture.lib.utils.DensityUtil;
import com.luck.picture.lib.utils.MediaUtils;
import com.luck.picture.lib.utils.PictureFileUtils;
import com.tencent.bugly.crashreport.CrashReport;
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import top.zibin.luban.CompressionPredicate;
import top.zibin.luban.Luban;
import top.zibin.luban.OnNewCompressListener;
import top.zibin.luban.OnRenameListener;
/**
 * AddQuestionActivity -问题上报
 *
 * @author zuoxiao
 * @version 1.0
 * @since 2024-12-09
 */
public class AddQuestionActivity extends BaseActivity{
    private String TAG = "AddQuestionActivity";
    ActivityAddQuestionBinding binding;
    RecyclerView mRecyclerView;
    AddPictureAdapter mAdapter;
    int maxSelectNum = 10;//最大照片
    int maxSelectVideoNum = 0;//最大视频
    private final List<LocalMedia> mData = new ArrayList<>();
    private ActivityResultLauncher<Intent> launcherResult;
    private ImageEngine imageEngine;
    List<UplodFileState> uplodFileStates = new ArrayList<>();
    LatLonBean latLonBean;
    /**
     * 定位监听
     */
    private Observer<Object> locationObserver = new Observer<Object>() {
        @Override
        public void onChanged(Object o) {
            latLonBean = (LatLonBean) o;
        }
    };
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding=ActivityAddQuestionBinding.inflate(LayoutInflater.from(this));
        setContentView(binding.getRoot());
    }
    void initView() {
        new TitleBar(this).setTitleText("处理工单").setLeftIco().setLeftIcoListening(v -> AddQuestionActivity.this.finish());
        mRecyclerView = binding.recycler;
        FullyGridLayoutManager manager = new FullyGridLayoutManager(this,
                4, GridLayoutManager.VERTICAL, false);
        mRecyclerView.setLayoutManager(manager);
        RecyclerView.ItemAnimator itemAnimator = mRecyclerView.getItemAnimator();
        if (itemAnimator != null) {
            ((SimpleItemAnimator) itemAnimator).setSupportsChangeAnimations(false);
        }
        mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(4,
                DensityUtil.dip2px(this, 8), false));
        mAdapter = new AddPictureAdapter(this, mData);
        mAdapter.setSelectMax(maxSelectNum + maxSelectVideoNum);
        mRecyclerView.setAdapter(mAdapter);
        imageEngine = GlideEngine.createGlideEngine();
        mAdapter.setOnItemClickListener(new AddPictureAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View v, int position) {
                // 预览图片、视频、音频
                PictureSelector.create(AddQuestionActivity.this)
                        .openPreview()
                        .setImageEngine(imageEngine)
                        .setExternalPreviewEventListener(new AddQuestionActivity.MyExternalPreviewEventListener())
                        .startActivityPreview(position, true, mAdapter.getData());
            }
            @Override
            public void openPicture() {
                //添加图片
                mOpenPicture();
            }
        });
        binding.dealButton.setOnClickListener(v -> {
            boolean isAllPost = true;
            for (UplodFileState imgData : uplodFileStates) {
                if (imgData.getState() == 0) {
                    isAllPost = false;
                }
            }
            if (!TextUtils.isEmpty(binding.contentET.getText().toString())) {
                if (isAllPost) {
                    if (uplodFileStates.size() > 0) {
                        postData();
                    } else {
                        ToastUtil.showToast(AddQuestionActivity.this, "请上传图片");
                    }
                } else {
                    ToastUtil.showToast(AddQuestionActivity.this, "图片正在上传请稍后提交");
                }
            } else {
                ToastUtil.showToast(AddQuestionActivity.this, "请输入反馈内容");
            }
        });
    }
    /**
     * 添加图片
     */
    private void mOpenPicture() {
        // 进入相册
        PictureSelectionModel selectionModel = PictureSelector.create(this)
                .openGallery(SelectMimeType.ofImage())
                .setMaxSelectNum(maxSelectNum)
                .setMaxVideoSelectNum(maxSelectVideoNum)
                .setImageEngine(imageEngine)
                //设置图片压缩
                .setCompressEngine(new AddQuestionActivity.ImageFileCompressEngine())
                .setSelectedData(mAdapter.getData());
        selectionModel.forResult(launcherResult);
    }
    /**
     * 创建一个ActivityResultLauncher
     *
     * @return
     */
    private ActivityResultLauncher<Intent> createActivityResultLauncher() {
        return registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),
                result -> {
                    int resultCode = result.getResultCode();
                    if (resultCode == RESULT_OK) {
                        ArrayList<LocalMedia> selectList = PictureSelector.obtainSelectorList(result.getData());
                        analyticalSelectResults(selectList);
                    } else if (resultCode == RESULT_CANCELED) {
                        Log.i(TAG, "onActivityResult PictureSelector Cancel");
                    }
                });
    }
    /**
     * 外部预览监听事件
     */
    private class MyExternalPreviewEventListener implements OnExternalPreviewEventListener {
        @Override
        public void onPreviewDelete(int position) {
            mAdapter.remove(position);
            mAdapter.notifyItemRemoved(position);
        }
        @Override
        public boolean onLongPressDownload(Context context, LocalMedia media) {
            return false;
        }
    }
    /**
     * 处理选择结果
     *
     * @param result
     */
    private void analyticalSelectResults(ArrayList<LocalMedia> result) {
        Set<String> existingPaths = new HashSet<>();
        for (UplodFileState uplodData : uplodFileStates) {
            existingPaths.add(uplodData.getFilePath());
        }
        for (LocalMedia media : result) {
            if (media.getWidth() == 0 || media.getHeight() == 0) {
                if (PictureMimeType.isHasImage(media.getMimeType())) {
                    MediaExtraInfo imageExtraInfo = MediaUtils.getImageSize(this, media.getPath());
                    media.setWidth(imageExtraInfo.getWidth());
                    media.setHeight(imageExtraInfo.getHeight());
                } else if (PictureMimeType.isHasVideo(media.getMimeType())) {
                    MediaExtraInfo videoExtraInfo = MediaUtils.getVideoSize(this, media.getPath());
                    media.setWidth(videoExtraInfo.getWidth());
                    media.setHeight(videoExtraInfo.getHeight());
                }
            }
            Log.i(TAG, "文件名: " + media.getFileName());
            Log.i(TAG, "是否压缩:" + media.isCompressed());
            Log.i(TAG, "压缩:" + media.getCompressPath());
            Log.i(TAG, "初始路径:" + media.getPath());
            Log.i(TAG, "绝对路径:" + media.getRealPath());
            Log.i(TAG, "是否裁剪:" + media.isCut());
            Log.i(TAG, "裁剪路径:" + media.getCutPath());
            Log.i(TAG, "是否开启原图:" + media.isOriginal());
            Log.i(TAG, "原图路径:" + media.getOriginalPath());
            Log.i(TAG, "沙盒路径:" + media.getSandboxPath());
            Log.i(TAG, "水印路径:" + media.getWatermarkPath());
            Log.i(TAG, "视频缩略图:" + media.getVideoThumbnailPath());
            Log.i(TAG, "原始宽高: " + media.getWidth() + "x" + media.getHeight());
            Log.i(TAG, "裁剪宽高: " + media.getCropImageWidth() + "x" + media.getCropImageHeight());
            Log.i(TAG, "文件大小: " + PictureFileUtils.formatAccurateUnitFileSize(media.getSize()));
            Log.i(TAG, "文件时长: " + media.getDuration());
            String compressPath = media.getCompressPath();
            //判断是否有这个路径,没有的话上传该图片
            if (!existingPaths.contains(compressPath)) {
                UplodFileState uplodFileState = new UplodFileState();
                uplodFileState.setFilePath(media.getRealPath());
                uplodFileStates.add(uplodFileState);
                // 执行上传图片的操作
                uplodeImg(uplodFileState);
            }
        }
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                boolean isMaxSize = result.size() == mAdapter.getSelectMax();
                int oldSize = mAdapter.getData().size();
                mAdapter.notifyItemRangeRemoved(0, isMaxSize ? oldSize + 1 : oldSize);
                mAdapter.getData().clear();
                mAdapter.getData().addAll(result);
                mAdapter.notifyItemRangeInserted(0, result.size());
            }
        });
    }
    /**
     * 自定义图片压缩
     */
    private static class ImageFileCompressEngine implements CompressFileEngine {
        @Override
        public void onStartCompress(Context context, ArrayList<Uri> source, OnKeyValueResultCallbackListener call) {
            Luban.with(context).load(source).ignoreBy(100).setRenameListener(new OnRenameListener() {
                @Override
                public String rename(String filePath) {
                    int indexOf = filePath.lastIndexOf(".");
                    String postfix = indexOf != -1 ? filePath.substring(indexOf) : ".jpg";
                    return DateUtils.getCreateFileName("CMP_") + postfix;
                }
            }).filter(new CompressionPredicate() {
                @Override
                public boolean apply(String path) {
                    if (PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(path)) {
                        return true;
                    }
                    return !PictureMimeType.isUrlHasGif(path);
                }
            }).setCompressListener(new OnNewCompressListener() {
                @Override
                public void onStart() {
                }
                @Override
                public void onSuccess(String source, File compressFile) {
                    if (call != null) {
                        call.onCallback(source, compressFile.getAbsolutePath());
                    }
                }
                @Override
                public void onError(String source, Throwable e) {
                    if (call != null) {
                        call.onCallback(source, null);
                    }
                }
            }).launch();
        }
    }
    //上传图片
    private void uplodeImg(UplodFileState uplodFileState) {
        ApiManager.getInstance().uploadFile(this, uplodFileState, new UploadFileListener() {
            @Override
            public void onBack(UplodFileState state) {
                for (UplodFileState uplodFile : uplodFileStates) {
                    if (uplodFile.getFilePath().equals(state.getFilePath())) {
                        int index = uplodFileStates.indexOf(uplodFile);
                        if (index != -1) {
                            uplodFileStates.set(index, uplodFile); // 更新对应的项
                        }
                    }
                }
            }
        });
    }
    /**
     * 上报处理结果
     */
    private void postData() {
        AddIssueRequest result = new AddIssueRequest();
        result.setImages(uplodFileStates);
        result.setContent(binding.contentET.getText().toString());
        result.setInspectorId(MyApplication.myApplication.userId);
        result.setCompleteTime(com.dayu.pipirrapp.utils.DateUtils.getNowDateToMMStr());
        if (latLonBean != null) {
            result.setLat(String.valueOf(latLonBean.getLatitude()));
            result.setLng(String.valueOf(latLonBean.getLongitude()));
        }
        ApiManager.getInstance().requestPostHideLoading(this, BASE_URL + "/app/issue/addIssueReport", InsectionResult.class, result.toMap(result), new SubscriberListener<BaseResponse<List<InsectionResult>>>() {
            @Override
            public void onNext(BaseResponse<List<InsectionResult>> t) {
                try {
                    if (t.isSuccess()) {
                        ToastUtil.showToastLong(AddQuestionActivity.this, "上报成功");
                        setResult(OrderFragment.RESULT_REFRESH);
                        AddQuestionActivity.this.finish();
                    } else {
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    CrashReport.postCatchedException(e);
                }
            }
        });
    }
    /**
     * 开始定位相关逻辑
     */
    private void startLocation() {
        Intent location = new Intent(this, MyLocationService.class);
        location.putExtra("isSingle", true);
        //开启定位
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(location);
        } else {
            startService(location);
        }
        //获取定位服务传过来的坐标点
        LiveEventBus.get(CommonKeyName.locationData).observeForever(locationObserver);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        LiveEventBus.get(CommonKeyName.locationData).removeObserver(locationObserver);
    }
}
app/src/main/java/com/dayu/pipirrapp/activity/MainActivity.java
@@ -58,7 +58,7 @@
        } catch (Exception e) {
            e.printStackTrace();
        }
        mqttManager = new MqttManager(this);
        mqttManager = new MqttManager(this, this);
        mqttManager.connect();
        LiveEventBus.get(CommonKeyName.NetworkCallback).observeForever(new Observer<Object>() {
            @Override
@@ -190,8 +190,6 @@
    private void unregisterNetworkCallback() {
        NetUtils.unregisterReceiver(this);
    }
}
app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java
@@ -22,10 +22,11 @@
import com.dayu.pipirrapp.MyApplication;
import com.dayu.pipirrapp.adapter.AddPictureAdapter;
import com.dayu.pipirrapp.bean.db.LatLonBean;
import com.dayu.pipirrapp.bean.net.AddProcessingResult;
import com.dayu.pipirrapp.bean.net.AddProcessingRequest;
import com.dayu.pipirrapp.bean.net.InsectionResult;
import com.dayu.pipirrapp.bean.net.UplodFileState;
import com.dayu.pipirrapp.databinding.ActivityOrderDealBinding;
import com.dayu.pipirrapp.fragment.OrderFragment;
import com.dayu.pipirrapp.net.ApiManager;
import com.dayu.pipirrapp.net.BaseResponse;
import com.dayu.pipirrapp.net.subscribers.SubscriberListener;
@@ -352,7 +353,7 @@
     * 上报处理结果
     */
    private void postData() {
        AddProcessingResult result = new AddProcessingResult();
        AddProcessingRequest result = new AddProcessingRequest();
        result.setImages(uplodFileStates);
        result.setContent(binding.contentET.getText().toString());
        result.setInspectorId(MyApplication.myApplication.userId);
@@ -368,6 +369,7 @@
                try {
                    if (t.isSuccess()) {
                        ToastUtil.showToastLong(OrderDealActivity.this, "上报成功");
                        setResult(OrderFragment.RESULT_REFRESH);
                        OrderDealActivity.this.finish();
                    } else {
app/src/main/java/com/dayu/pipirrapp/activity/OrderDetailActivity.java
@@ -6,28 +6,30 @@
import android.view.LayoutInflater;
import android.view.View;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.SimpleItemAnimator;
import com.dayu.pipirrapp.MyApplication;
import com.dayu.pipirrapp.R;
import com.dayu.pipirrapp.adapter.ImageAdapter;
import com.dayu.pipirrapp.bean.net.DealDetailResult;
import com.dayu.pipirrapp.bean.net.ImageResult;
import com.dayu.pipirrapp.bean.net.OrderDetailResult;
import com.dayu.pipirrapp.databinding.ActivityOrderDetailBinding;
import com.dayu.pipirrapp.fragment.OrderFragment;
import com.dayu.pipirrapp.net.ApiManager;
import com.dayu.pipirrapp.net.BaseResponse;
import com.dayu.pipirrapp.net.Constants;
import com.dayu.pipirrapp.net.subscribers.SubscriberListener;
import com.dayu.pipirrapp.tool.FullyGridLayoutManager;
import com.dayu.pipirrapp.tool.GlideEngine;
import com.dayu.pipirrapp.utils.ToastUtil;
import com.dayu.pipirrapp.view.ConfirmDialog;
import com.dayu.pipirrapp.view.TitleBar;
import com.luck.picture.lib.basic.PictureSelector;
import com.luck.picture.lib.decoration.GridSpacingItemDecoration;
import com.luck.picture.lib.engine.ImageEngine;
import com.luck.picture.lib.utils.DensityUtil;
import java.util.ArrayList;
@@ -36,7 +38,6 @@
import java.util.Map;
import cc.shinichi.library.ImagePreview;
import cc.shinichi.library.bean.ImageInfo;
/**
 * OrderDetailActivity -
@@ -54,6 +55,16 @@
    List<ImageResult> images = new ArrayList<>();
    RecyclerView mRecyclerView;
    final List<String> imageInfoList = new ArrayList<>();
    int ProResultStateId;
    private ActivityResultLauncher<Intent> activityResultLauncher =
            registerForActivityResult(
                    new ActivityResultContracts.StartActivityForResult(),
                    result -> {
                        if (result.getResultCode() == OrderFragment.RESULT_REFRESH) {
                            setResult(OrderFragment.RESULT_REFRESH);
                            finish();
                        }
                    });
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -68,8 +79,11 @@
    void initView() {
        workOrderId = this.getIntent().getStringExtra("workOrderId");
        if (this.getIntent().hasExtra("proResultId")) {
            binding.orderDealLL.setVisibility(View.VISIBLE);
            proResultId = this.getIntent().getStringExtra("proResultId");
            getHandleData(proResultId);
        } else {
            binding.orderDealLL.setVisibility(View.GONE);
        }
        if (!TextUtils.isEmpty(workOrderId)) {
            getMarkerData(workOrderId);
@@ -114,15 +128,20 @@
                            if (!TextUtils.isEmpty(t.getContent().getProResultId()) && TextUtils.isEmpty(proResultId)) {
                                getHandleData(orderDetailResult.getProResultId());
                            }
                            switch (orderDetailResult.getProResultStateId()) {
                            ProResultStateId = orderDetailResult.getProResultStateId();
                            switch (ProResultStateId) {
                                case 0://未上报
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.black));
                                    binding.stateText.setBackground(OrderDetailActivity.this.getResources().getDrawable(R.drawable.order_state_no_bg));
                                    binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color));
                                    binding.dealButton.setVisibility(View.VISIBLE);
                                    break;
                                case 1://已上报
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white));
                                    binding.stateText.setBackground(OrderDetailActivity.this.getResources().getDrawable(R.drawable.order_state_wait_bg));
                                    binding.dealButton.setVisibility(View.GONE);
                                    binding.dealButton.setBackgroundColor(getResources().getColor(R.color.delete_color));
                                    binding.dealButton.setVisibility(View.VISIBLE);
                                    binding.dealButton.setText("删除处理结果");
                                    break;
                                case 2://已完成
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white));
@@ -132,6 +151,8 @@
                                case 3://被驳回
                                    binding.stateText.setTextColor(OrderDetailActivity.this.getResources().getColor(R.color.white));
                                    binding.stateText.setBackground(OrderDetailActivity.this.getResources().getDrawable(R.drawable.order_state_reject_bg));
                                    binding.dealButton.setBackgroundColor(getResources().getColor(R.color.title_color));
                                    binding.dealButton.setVisibility(View.VISIBLE);
                                    break;
                            }
@@ -190,11 +211,55 @@
        });
    }
    /**
     * 删除处理详情
     */
    private void deleteDealData() {
        Map<String, Object> params = new HashMap<>();
        params.put("proResultId", proResultId);
        params.put("inspectorId", MyApplication.myApplication.userId);
        ApiManager.getInstance().requestPost(this, Constants.BASE_URL + "/app/workOrder/deleteProResult", DealDetailResult.class, params, new SubscriberListener<BaseResponse<DealDetailResult>>() {
            @Override
            public void onNext(BaseResponse<DealDetailResult> t) {
                if (t.isSuccess()) {
                    if (t.isSuccess()) {
                        ToastUtil.showToastLong(OrderDetailActivity.this, "删除成功!");
                        setResult(OrderFragment.RESULT_REFRESH);
                        OrderDetailActivity.this.finish();
                    }
                } else {
                    ToastUtil.showToast(OrderDetailActivity.this, t.getMsg());
                }
            }
            @Override
            public void onCloose() {
                super.onCloose();
            }
        });
    }
    public void startDealActivity() {
        Intent intent = new Intent(this, OrderDealActivity.class);
        intent.putExtra("workOrderId", workOrderId);
        startActivityForResult(intent, 1);
        switch (ProResultStateId) {
            case 0:
            case 3:
                Intent intent = new Intent(this, OrderDealActivity.class);
                intent.putExtra("workOrderId", workOrderId);
                activityResultLauncher.launch(intent);
                break;
            case 1:
                ConfirmDialog confirmDialog = new ConfirmDialog(this, "确认删除该处理结果吗?", (confirmDialog1, v) -> {
                    confirmDialog1.dismiss();
                    deleteDealData();
                });
                confirmDialog.show();
                break;
        }
    }
}
app/src/main/java/com/dayu/pipirrapp/bean/net/AddIssueRequest.java
copy from app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingResult.java copy to app/src/main/java/com/dayu/pipirrapp/bean/net/AddIssueRequest.java
File was copied from app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingResult.java
@@ -4,45 +4,20 @@
import java.util.List;
/**
 * AddProcessingResult -上报处理结果
 * AddIssueRequest -
 *
 * @author zuoxiao
 * @version 1.0
 * @since 2024-12-05
 * @since 2024-12-09
 */
public class AddProcessingResult extends BaseRequest {
public class AddIssueRequest extends BaseRequest{
    String workOrderId;//工单ID
    String inspectorId;//巡检员ID
    String content;//结果内容
    List<Image> images = new ArrayList<>();
    List<ImageRequest> images = new ArrayList<>();
    String completeTime;//任务完成时间
    String lng;
    String lat;
    public String getLng() {
        return lng;
    }
    public void setLng(String lng) {
        this.lng = lng;
    }
    public String getLat() {
        return lat;
    }
    public void setLat(String lat) {
        this.lat = lat;
    }
    public String getCompleteTime() {
        return completeTime;
    }
    public void setCompleteTime(String completeTime) {
        this.completeTime = completeTime;
    }
    public String getWorkOrderId() {
        return workOrderId;
@@ -68,38 +43,41 @@
        this.content = content;
    }
    public List<Image> getImages() {
    public List<ImageRequest> getImages() {
        return images;
    }
    public void setImages(List<UplodFileState> states) {
        images.clear();
        for (UplodFileState data : states) {
            Image image = new Image();
            ImageRequest image = new ImageRequest();
            image.setWebPath(data.getWebPath());
            image.setId(data.getId());
            images.add(image);
        }
    }
    public class Image {
        String id;
        String webPath;
    public String getCompleteTime() {
        return completeTime;
    }
        public String getId() {
            return id;
        }
    public void setCompleteTime(String completeTime) {
        this.completeTime = completeTime;
    }
        public void setId(String id) {
            this.id = id;
        }
    public String getLng() {
        return lng;
    }
        public String getWebPath() {
            return webPath;
        }
    public void setLng(String lng) {
        this.lng = lng;
    }
        public void setWebPath(String webPath) {
            this.webPath = webPath;
        }
    public String getLat() {
        return lat;
    }
    public void setLat(String lat) {
        this.lat = lat;
    }
}
app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingRequest.java
File was renamed from app/src/main/java/com/dayu/pipirrapp/bean/net/AddProcessingResult.java
@@ -10,11 +10,11 @@
 * @version 1.0
 * @since 2024-12-05
 */
public class AddProcessingResult extends BaseRequest {
public class AddProcessingRequest extends BaseRequest {
    String workOrderId;//工单ID
    String inspectorId;//巡检员ID
    String content;//结果内容
    List<Image> images = new ArrayList<>();
    List<ImageRequest> images = new ArrayList<>();
    String completeTime;//任务完成时间
    String lng;
    String lat;
@@ -68,38 +68,19 @@
        this.content = content;
    }
    public List<Image> getImages() {
    public List<ImageRequest> getImages() {
        return images;
    }
    public void setImages(List<UplodFileState> states) {
        images.clear();
        for (UplodFileState data : states) {
            Image image = new Image();
            ImageRequest image = new ImageRequest();
            image.setWebPath(data.getWebPath());
            image.setId(data.getId());
            images.add(image);
        }
    }
    public class Image {
        String id;
        String webPath;
        public String getId() {
            return id;
        }
        public void setId(String id) {
            this.id = id;
        }
        public String getWebPath() {
            return webPath;
        }
        public void setWebPath(String webPath) {
            this.webPath = webPath;
        }
    }
}
app/src/main/java/com/dayu/pipirrapp/bean/net/ImageRequest.java
New file
@@ -0,0 +1,29 @@
package com.dayu.pipirrapp.bean.net;
/**
 * ImageRequest -
 *
 * @author zuoxiao
 * @version 1.0
 * @since 2024-12-09
 */
public class ImageRequest {
    String id;
    String webPath;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getWebPath() {
        return webPath;
    }
    public void setWebPath(String webPath) {
        this.webPath = webPath;
    }
}
app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java
@@ -371,6 +371,10 @@
        binding.inspectClose.setOnClickListener(v -> {
            chageInspecState(InspectionUtils.STOP_INSPECTION);
        });
        //上报问题
        binding.putButton.setOnClickListener(v->{
        });
    }
app/src/main/java/com/dayu/pipirrapp/fragment/OrderFragment.java
@@ -8,6 +8,8 @@
import android.view.View;
import android.view.ViewGroup;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
@@ -41,7 +43,7 @@
 * 备注:首页
 */
public class OrderFragment extends BaseFragment {
    public static final int RESULT_REFRESH = 1001;
    private final int STATE_DONE = 2;
    private final int STATE_UNDONE = 1;
@@ -54,6 +56,16 @@
    int state = 1;
    List<OrderListResult.Data> recordsListDone = new ArrayList<>();
    List<OrderListResult.Data> recordsList = new ArrayList<>();
    RefreshLayout myRefreshLayout;
    private ActivityResultLauncher<Intent> activityResultLauncher =
            registerForActivityResult(
                    new ActivityResultContracts.StartActivityForResult(),
                    result -> {
                        if (result.getResultCode() == RESULT_REFRESH) {
                            myRefreshLayout.autoRefresh();
                        }
                    });
    /**
     * 设置天气相关信息
@@ -83,9 +95,7 @@
        initView();
        //获取定位服务传过来的坐标点
        LiveEventBus.get(CommonKeyName.MQTTData).observeForever(o -> {
        });
        return binding.getRoot();
    }
@@ -104,7 +114,7 @@
            state = STATE_DONE;//1 未开始 2 已完成
        });
        //未完成
        RefreshLayout myRefreshLayout = (RefreshLayout) binding.refreshLayout;
        myRefreshLayout = (RefreshLayout) binding.refreshLayout;
        myRefreshLayout.setRefreshHeader(new ClassicsHeader(this.getContext()));
        myRefreshLayout.setRefreshFooter(new ClassicsFooter(this.getContext()));
@@ -181,7 +191,7 @@
                            } else {
                                recordsListDone.addAll(t.getContent().getObj());
                            }
                            if (t.getContent().getObj().size() < pageSize) {
                            if (t.getContent().getPageTotal() == page) {
                                refreshlayout.finishLoadMoreWithNoMoreData();
                            }
                        } else {
@@ -202,8 +212,6 @@
                } else {
                    mDoneAdapter.notifyDataSetChanged();
                }
            }
        });
@@ -215,7 +223,7 @@
        if (!TextUtils.isEmpty(proResultId)) {
            intent.putExtra("proResultId", proResultId);
        }
        startActivity(intent);
        activityResultLauncher.launch(intent);
    }
app/src/main/java/com/dayu/pipirrapp/net/MqttManager.java
@@ -4,7 +4,12 @@
import android.net.ConnectivityManager;
import android.util.Log;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;
import com.dayu.pipirrapp.utils.CommonKeyName;
import com.dayu.pipirrapp.utils.MyLog;
import com.dayu.pipirrapp.utils.NetUtils;
import com.jeremyliao.liveeventbus.LiveEventBus;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
@@ -28,15 +33,15 @@
public class MqttManager {
    private static final String MQTT_BROKER_URL = "tcp://115.236.153.170:30764"; // 修改为你的 broker 地址
    private static final String CLIENT_ID = "mqttx_54052fa0";
    private static final String CLIENT_ID = "mqttx_f62ef124";
    private static final String TOPIC = "workOrder"; // 订阅的主题
    private ConnectivityManager connectivityManager;
    private MqttClient mqttClient;
    private MqttConnectOptions connectOptions;
    boolean isHasNet = false;
    boolean isHasNet = true;
    private ExecutorService executorService = Executors.newSingleThreadExecutor();
    public MqttManager(Context context) {
    public MqttManager(Context context, LifecycleOwner lifecycleOwner) {
        try {
            mqttClient = new MqttClient(MQTT_BROKER_URL, CLIENT_ID, new MemoryPersistence());
            connectOptions = new MqttConnectOptions();
@@ -45,28 +50,25 @@
            connectOptions.setCleanSession(false);
            connectOptions.setKeepAliveInterval(60); // 设置保持连接的时间
            connectOptions.setAutomaticReconnect(true);  // 启用自动重连
            connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
//            LiveEventBus.get(CommonKeyName.NetworkCallback).observeForever(new Observer<Object>() {
//                @Override
//                public void onChanged(Object o) {
//                    switch ((int) o) {
//                        case NetUtils.Available:
//                            MyLog.i("MqttManager>>>Available");
//                            isHasNet = true;
//                            reconnect();
//                            break;
//                        case NetUtils.Lost:
//                            MyLog.i("MqttManager>>>Lost");
//                            isHasNet = false;
//                            try {
//                                mqttClient.disconnect();
//                            } catch (MqttException e) {
//                                e.printStackTrace();
//                            }
//                            break;
//                    }
//                }
//            });
            LiveEventBus.get(CommonKeyName.NetworkCallback).observe(lifecycleOwner, new Observer<Object>() {
                @Override
                public void onChanged(Object o) {
                    if (o instanceof Integer) {
                        switch ((int) o) {
                            case NetUtils.Available:
                                MyLog.i("MqttManager>>>Available");
                                isHasNet = true;
                                reconnect();
                                break;
                            case NetUtils.Lost:
                                MyLog.i("MqttManager>>>Lost");
                                isHasNet = false;
                                disconnect();
                                break;
                        }
                    }
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }
@@ -74,16 +76,43 @@
    // 连接到 MQTT broker
    public void connect() {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    Log.d("MqttManager", "connect开始连接isHasNet:" + isHasNet);
                    if (isHasNet) {
                        Log.d("MqttManager", "connect开始连接");
                        mqttClient.setCallback(new MqttCallback() {
                            @Override
                            public void connectionLost(Throwable cause) {
                                Log.d("MqttManager", "连接丢失:" + cause.getMessage());
                                // 处理连接丢失,可以尝试重新连接
                                reconnect();
                            }
                            @Override
                            public void messageArrived(String topic, MqttMessage message) throws Exception {
                                Log.d("MqttManager", "收到的消:" + new String(message.getPayload()));
                                // 处理收到的消息
                            }
                            @Override
                            public void deliveryComplete(IMqttDeliveryToken token) {
                                // 处理消息发送完成
                                try {
                                    Log.d("MqttManager", "发送完成:" + new String(token.getMessage().toString()));
                                } catch (MqttException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                        mqttClient.connect(connectOptions);
                        if (mqttClient.isConnected()) {
                            Log.d("MqttManager", "Connected to MQTT broker");
                            Log.d("MqttManager", "connect连接成功");
                            subscribeToTopic();
                        } else {
                            Log.d("MqttManager", "connect连接失败");
                        }
                    } else {
                        reconnect();
@@ -102,34 +131,11 @@
        try {
            mqttClient.subscribe(TOPIC, (topic, message) -> {
                // 收到消息时的处理逻辑
                Log.d("MqttManager", "Received message:" + new String(message.getPayload()));
                Log.d("MqttManager", "收到消息:" + new String(message.getPayload()));
                //传递MQ收到的信息
                LiveEventBus.get(CommonKeyName.locationData).post(message.getPayload());
            });
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {
                    Log.d("MqttManager", "connectionLost" + cause.getMessage());
                    reconnect();
                    // 处理连接丢失,可以尝试重新连接
                }
                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
                    Log.d("MqttManager", "Received messageArrived:" + new String(message.getPayload()));
                    // 处理收到的消息
                }
                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {
                    // 处理消息发送完成
                    try {
                        Log.d("MqttManager", "deliveryComplete:" + new String(token.getMessage().toString()));
                    } catch (MqttException e) {
                        e.printStackTrace();
                    }
                }
            });
        } catch (MqttException e) {
            e.printStackTrace();
        }
@@ -147,10 +153,11 @@
    // 断开连接
    public void disconnect() {
        MyLog.d("MqttManager>>>>关闭连接");
        try {
            if (mqttClient != null && mqttClient.isConnected()) {
                mqttClient.disconnect();
                System.out.println("Disconnected from MQTT broker");
                MyLog.d("MqttManager>>>>关闭连接成功");
            }
        } catch (MqttException e) {
            e.printStackTrace();
@@ -159,32 +166,22 @@
    // 自动重连方法
    private void reconnect() {
        try {
            if (isHasNet) {
                while (!mqttClient.isConnected() && isHasNet) {
                    Log.d("MqttManager", "Attempting to reconnect...");
                    mqttClient.connect(connectOptions);  // 重试连接
                    if (mqttClient.isConnected()) {
                        Log.d("MqttManager", "Connected to MQTT broker");
                        subscribeToTopic();
                    }
                    Thread.sleep(5000);     // 每 5 秒重试一次
                }
                Log.d("MqttManager", "Reconnected to MQTT broker! isHasNet=true");
            } else {
                Log.d("MqttManager", "isHasNet is false");
//                Thread.sleep(5000);
//                reconnect();
            }
        } catch (MqttException | InterruptedException e) {
//        executorService.execute(() -> {
//            try {
//                Thread.sleep(5000);
//            } catch (InterruptedException ex) {
//                e.printStackTrace();
//            }// 每 5 秒重试一次
//            reconnect();
        }
//                MyLog.d("MqttManager>>>>开始重连+isHasNet:" + isHasNet + ">>>mqttClient.isConnected():" + mqttClient.isConnected());
//                while (!mqttClient.isConnected() && isHasNet) {
//                    MyLog.d("MqttManager>>>>开始连接");
//                    mqttClient.connect(connectOptions);
//                    if (mqttClient.isConnected()) {
//                        MyLog.d("MqttManager>>>连接成功");
//                        subscribeToTopic();
//                        break;
//                    }
//                    Thread.sleep(5000);  // 每5秒重试一次
//                }
//            } catch (MqttException | InterruptedException e) {
//                MyLog.e("MqttManager>>>Reconnection failed" + e.toString());
//            }
//        });
    }
}
app/src/main/java/com/dayu/pipirrapp/utils/MyLog.java
@@ -19,5 +19,7 @@
        Log.d(TAG, data);
    }
    public static void e(String data) {
        Log.e(TAG, data);
    }
}
app/src/main/res/drawable/ic_green_bg.xml
New file
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_green_bg_up" />
    <item android:drawable="@drawable/ic_green_bg_down" android:state_pressed="true" />
</selector>
app/src/main/res/drawable/ic_green_bg_down.xml
New file
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/down_green_down" />
    <corners android:radius="10dp" />
    <stroke
        android:width="1dp"
        android:color="@color/down_green_down" />
</shape>
app/src/main/res/drawable/ic_green_bg_up.xml
New file
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="@color/down_green_up" />
    <corners android:radius="10dp" />
    <stroke
        android:width="1dp"
        android:color="@color/down_green_up" />
</shape>
app/src/main/res/layout/activity_add_question.xml
New file
@@ -0,0 +1,64 @@
<?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">
    <include
        android:id="@+id/title"
        layout="@layout/top_title" />
    <LinearLayout
        android:id="@+id/center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/deal_button"
        android:layout_below="@+id/title"
        android:orientation="vertical"
        android:padding="20dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="反馈内容:"
            android:textColor="@color/black"
            android:textSize="@dimen/order_detail_button_size" />
        <EditText
            android:id="@+id/contentET"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text=""
            android:gravity="start"
            android:background="@drawable/edittext_backgroud"
            android:minHeight="100dp"
            android:maxHeight="200dp"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="提交图片:"
            android:layout_marginTop="10dp"
            android:textColor="@color/black"
            android:textSize="@dimen/order_detail_button_size" />
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:background="@color/white"
            android:layout_marginTop="10dp"
            android:overScrollMode="never" />
    </LinearLayout>
    <TextView
        android:id="@+id/deal_button"
        android:layout_width="match_parent"
        android:layout_height="@dimen/order_detail_button_height"
        android:layout_alignParentBottom="true"
        android:background="@color/title_color"
        android:gravity="center"
        android:text="上报问题"
        android:textColor="@color/white"
        android:textSize="@dimen/order_detail_button_size" />
</RelativeLayout>
app/src/main/res/layout/activity_order_detail.xml
@@ -285,7 +285,7 @@
                    android:layout_height="wrap_content"
                    android:layout_marginTop="15dp"
                    android:orientation="vertical"
                    android:visibility="visible">
                    android:visibility="gone">
                    <View
                        android:layout_width="match_parent"
@@ -305,7 +305,7 @@
                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginTop="5dp"
                        android:layout_marginTop="10dp"
                        android:gravity="center_vertical"
                        android:orientation="horizontal">
@@ -394,7 +394,8 @@
            android:onClick="@{()->itemclidk.startDealActivity()}"
            android:text="处理工单"
            android:textColor="@color/white"
            android:textSize="@dimen/order_detail_button_size" />
            android:textSize="@dimen/order_detail_button_size"
            android:visibility="gone" />
    </RelativeLayout>
app/src/main/res/layout/fragment_map.xml
@@ -67,7 +67,6 @@
        android:layout_alignParentRight="true"
        android:layout_marginTop="60dp"
        android:layout_marginRight="15dp"
        android:background="@drawable/ic_blue_background"
        android:padding="10dp"
        android:text="巡"
@@ -75,6 +74,20 @@
        android:textSize="18sp" />
    <TextView
        android:id="@+id/putButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginTop="120dp"
        android:layout_marginRight="15dp"
        android:background="@drawable/ic_green_bg"
        android:padding="10dp"
        android:text="报"
        android:textColor="@color/white"
        android:textSize="18sp" />
    <LinearLayout
        android:id="@+id/bottomLL"
        android:layout_width="match_parent"
app/src/main/res/values/colors.xml
@@ -2,15 +2,17 @@
<resources>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>
    <color name="base_blue">#1890FF</color>
    <color name="base_blue">#3D8BFF</color>
    <color name="down_blue">#3a68fc</color>
    <color name="down_green_up">#00cc00</color>
    <color name="down_green_down">#006600</color>
    <color name="ws_pay_alpha">#00000000</color>
    <color name="title_color">#1890FF</color>
    <color name="title_color">#3D8BFF</color>
    <color name="bg_color">#F5F5F5</color>
    <color name="grey">#757575</color>
    <color name="colorSelected">#ffffff</color>
    <color name="colorUnselected">#000000</color>
    <color name="bottom_color">#1890FF</color>
    <color name="bottom_color">#3D8BFF</color>
    <color name="dialog_btn">#1FA9EC</color>
    <color name="line_bg">#DADADA</color>
    <color name="text_on">#BEBEBE</color>
@@ -24,4 +26,5 @@
    <color name="inspect_text_color_close">#ff0000</color>
    <color name="inspect_text_color_pause">#7fff00</color>
    <color name="inspect_rl_bg_color">#ff6347</color>
    <color name="delete_color">#ff0000</color>
</resources>