ProvinceDataFetcher.java 11.3 KB
package com.wd.model;


import android.text.TextUtils;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wd.capability.network.BaseObserver;
import com.wd.capability.network.bean.MetaBean;
import com.wd.capability.network.fetcher.BaseDataFetcher;
import com.wd.capability.network.response.BaseResponse;
import com.wd.common.api.RequestApi;
import com.wd.foundation.bean.launch.LaunchPageBean;
import com.wd.foundation.bean.response.AreaTreeselectBean;
import com.wd.foundation.wdkit.file.MyFileUtils;
import com.wd.foundation.wdkit.json.GsonUtils;
import com.wd.foundation.wdkit.mvvm.vm.IVMCallback;
import com.wd.foundation.wdkit.utils.SpUtils;
import com.wd.foundation.wdkitcore.tools.AppContext;
import com.wd.foundation.wdkitcore.tools.StringUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import io.reactivex.Observable;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 省份信息
 *
 * @author libo
 * @version [V1.0.0, 2022/08/27]
 * @since V1.0.0
 */
public class ProvinceDataFetcher extends BaseDataFetcher<RequestApi> {
    private static final String TAG = "ProvinceDataFetcher";
    private final String AREAS_FILE_NAME =  "areas_file_name.txt";
    private IGetAreaRevealListener iGetAreaRevealListener;

    private IGetAreaRevealListener iGetTwoAreaRevealListener;

    public void setAreaRevealListener(IGetAreaRevealListener iGetAreaRevealListener) {
        this.iGetAreaRevealListener = iGetAreaRevealListener;
    }

    public void setTwoAreaRevealListener(IGetAreaRevealListener iGetTwoAreaRevealListener) {
        this.iGetTwoAreaRevealListener = iGetTwoAreaRevealListener;
    }
    /**
     * 获取 地区展示
     */
    public void getAreaReveal() {
        String areaTreeMd5 = SpUtils.getAreaTreeMd5();
        Observable<BaseResponse<List<AreaTreeselectBean>>> phoneCode = getRetrofit().getAreaReveal(areaTreeMd5);
        request(phoneCode, new BaseObserver<List<AreaTreeselectBean>>() {
            @Override
            protected void dealSpecialCode(int code, String message) {
                if (iGetAreaRevealListener != null) {
                    iGetAreaRevealListener.onFailed(message);
                }
            }

            @Override
            protected void onSuccess(List<AreaTreeselectBean> areaTreeselectBeans) {

            }

            @Override
            protected void onSuccess(List<AreaTreeselectBean> areaDatas, MetaBean metaBean, String msg, int code) {
                getAreaDataSuccess(areaDatas,metaBean,areaTreeMd5);
            }

            @Override
            public void _onError(String e) {
                List<AreaTreeselectBean> areaDataList = new ArrayList<>();
                areaDataList.addAll(getLocalAreaData());
                if (iGetAreaRevealListener != null) {
                    iGetAreaRevealListener.onSuccess(areaDataList);
                }
            }
        });
    }

    private List<AreaTreeselectBean> getLocalAreaData(){
        List<AreaTreeselectBean> areaDataList = new ArrayList<>();
        String areaTreeData = SpUtils.getAreaTreeData();
        if (StringUtils.isNotBlank(areaTreeData)){
            areaDataList = GsonUtils.jsonToArrayList(areaTreeData, AreaTreeselectBean.class);
        }
        return areaDataList;
    }

    /**
     * 请求区域成功
     */
    private void getAreaDataSuccess(List<AreaTreeselectBean> areaData, MetaBean metaBean, String areaTreeMd5){
        List<AreaTreeselectBean> areaDataList = new ArrayList<>();
        if (metaBean != null){
            String md5 = metaBean.getMd5();
            if (areaTreeMd5.equals(md5)){
                //md5 没变使用缓存
                areaDataList.addAll(getLocalAreaData());
            }else {
                //md5 发生变化重新存下md5
                areaDataList.addAll(areaData);
                SpUtils.saveAreaTreeMd5(md5);
                //数据保存到本地
                String retData = GsonUtils.objectToJson(areaData);
                SpUtils.saveAreaTreeData(retData);
            }

        }else {
            areaDataList.addAll(areaData);
            //数据保存到本地
            String retData = GsonUtils.objectToJson(areaData);
            SpUtils.saveAreaTreeData(retData);
        }
        if (iGetAreaRevealListener != null) {
            iGetAreaRevealListener.onSuccess(areaDataList);
        }
    }

    /**
     * 保存地区
     */
    public void saveAreaData(LaunchPageBean.AreasBean bean){
        if (bean != null){
            String md5 = bean.getMd5();
            String areaTreeMd5 = SpUtils.getAreaTreeMd5();
            //md5 不同或者文件不存在,更新
            if (!areaTreeMd5.equals(md5)||isAreasFileNoExists()){
                String areasUrl = bean.getAreasUrl();
                if (StringUtils.isBlank(areasUrl)){
                    userLocalAreaData();
                }else {
                    //下载文件
                    if (StringUtils.isNotBlank(areasUrl)){
                        //异步下载
                        downloadAreasUrl(areasUrl,md5);
                    }
                }
            }else {
                userLocalAreaData();
            }
        }else {
            userLocalAreaData();
        }
    }

    /**
     * 保存区域文件,enqueue异步,execute同步
     * @param areasUrl
     */
    public void downloadAreasUrl(String areasUrl, String md5){
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(areasUrl).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                //失败读取缓存
                userLocalAreaData();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                try {
                    is = response.body().byteStream();
                    String fileName = getCachePath(AREAS_FILE_NAME);
                    String tempFileName = "";
                    if(fileName.contains(".")){
                        tempFileName = fileName.substring(0,fileName.lastIndexOf("."))+".temp";
                    }
                    File file = new File(TextUtils.isEmpty(tempFileName) ? fileName : tempFileName);
                    fos = new FileOutputStream(file);
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                    }
                    fos.flush();
                    if(!TextUtils.isEmpty(tempFileName)){
                        file.renameTo(new File(fileName));
                    }
                    //然后读取文件内容添加到
                    readAreasFile(md5);
                } catch (Exception e) {
                    e.printStackTrace();
                    //失败读取缓存
                    userLocalAreaData();
                } finally {
                    try {
                        if (is != null) {
                            is.close();
                        }
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null) {
                            fos.close();
                        }
                    } catch (IOException e) {
                    }
                }
            }
        });
    }

    private void readAreasFile(String md5){
        File areasFile = getAreasFile();
        if (areasFile != null && areasFile.exists()){
            String readJsonData = MyFileUtils.readJsonFile(areasFile);
            if (StringUtils.isNotBlank(readJsonData)){
                try {
                    byte[] bytes = readJsonData.getBytes("iso-8859-1");
                    String result = new String(bytes, "utf-8");
                    JSONObject jsonObject = JSONObject.parseObject(result);
                    if (jsonObject != null) {
                        JSONArray jsonArray = jsonObject.getJSONArray("data");
                        //解析成功之后
                        List<AreaTreeselectBean> areaDataList = GsonUtils.jsonToArrayList(jsonArray.toString(), AreaTreeselectBean.class);
                        SpUtils.saveAreaTreeMd5(md5);
                        //数据保存到本地
                        String retData = GsonUtils.objectToJson(areaDataList);
                        SpUtils.saveAreaTreeData(retData);

                        if (iGetAreaRevealListener != null) {
                            iGetAreaRevealListener.onSuccess(areaDataList);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    userLocalAreaData();
                }
            }
        }

    }


    /**
     * 文件是否不存在
     * @return true 不存在, false存在
     */
    public boolean isAreasFileNoExists(){
        try {
            File tempFile = getAreasFile();
            return !tempFile.exists();
        }catch (Exception e){
            e.printStackTrace();
        }
        return true;
    }

    private File getAreasFile(){
        String appCachePath = AppContext.getContext().getCacheDir().getAbsolutePath();
        File tempFile = new File(appCachePath, AREAS_FILE_NAME);
        return tempFile;
    }

    private static String getCachePath(String fileName) {
        return new File(AppContext.getContext().getCacheDir(), fileName).getAbsolutePath();
    }

    /**
     * 使用缓存
     */
    private void userLocalAreaData(){
        List<AreaTreeselectBean> areaDataList = new ArrayList<>();
        areaDataList.addAll(getLocalAreaData());
        if (iGetAreaRevealListener != null) {
            iGetAreaRevealListener.onSuccess(areaDataList);
        }
    }


    /**
     *  获取二级地理数据, 省 -->市;直辖市 --->区
     */
    public void getTreeList(){

        Observable<BaseResponse<List<AreaTreeselectBean>>> phoneCode = getRetrofit().getTreeList();
        request(phoneCode, new BaseObserver<List<AreaTreeselectBean>>() {
            @Override
            protected void dealSpecialCode(int code, String message) {
                if (iGetTwoAreaRevealListener != null) {
                    iGetTwoAreaRevealListener.onFailed(message);
                }
            }

            @Override
            protected void onSuccess(List<AreaTreeselectBean>areaDatas) {
                if (iGetTwoAreaRevealListener != null) {
                    iGetTwoAreaRevealListener.onSuccess(areaDatas);
                }
            }

            @Override
            public void _onError(String e) {
                if (iGetTwoAreaRevealListener != null) {
                    iGetTwoAreaRevealListener.onFailed(e);
                }
            }
        });
    }


    public interface IGetAreaRevealListener extends IVMCallback {
        /**
         * 成功
         *
         */
        void onSuccess(List<AreaTreeselectBean> datas);


        /**
         * 失败
         *
         * @param error 错误信息
         */
        void onFailed(String error);
    }

}