diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + + + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt new file mode 100644 index 0000000..379b932 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -0,0 +1,43 @@ +package com.casic.smarttube.widgets + +import android.content.Context +import android.widget.TextView +import com.casic.smarttube.R +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.utils.MPPointF +import java.text.DecimalFormat +import java.util.* + +class LineChartMarkerView(context: Context?) : + MarkerView(context, R.layout.popu_line_chart_marker) { + + private val decimalFormat = DecimalFormat("##0.0") + private val dayView: TextView = findViewById(R.id.dayView) + private val factoryView: TextView = findViewById(R.id.factoryView) + private val dataView: TextView = findViewById(R.id.dataView) + private var xAxisDate: MutableList = ArrayList() + + fun setXAxisDate(date: MutableList) { + this.xAxisDate = date + } + + //每次重绘,会调用此方法刷新数据 + override fun refreshContent(e: Entry, highlight: Highlight) { + super.refreshContent(e, highlight) + val data = e.data as String + try { + factoryView.text = data + dataView.text = String.format("数据:${decimalFormat.format(e.y.toString().toDouble())}t") + dayView.text = xAxisDate[(e.x).toInt()] + } catch (e1: Exception) { + e1.printStackTrace() + } + super.refreshContent(e, highlight) + } + + override fun getOffset(): MPPointF { + return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt new file mode 100644 index 0000000..379b932 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -0,0 +1,43 @@ +package com.casic.smarttube.widgets + +import android.content.Context +import android.widget.TextView +import com.casic.smarttube.R +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.utils.MPPointF +import java.text.DecimalFormat +import java.util.* + +class LineChartMarkerView(context: Context?) : + MarkerView(context, R.layout.popu_line_chart_marker) { + + private val decimalFormat = DecimalFormat("##0.0") + private val dayView: TextView = findViewById(R.id.dayView) + private val factoryView: TextView = findViewById(R.id.factoryView) + private val dataView: TextView = findViewById(R.id.dataView) + private var xAxisDate: MutableList = ArrayList() + + fun setXAxisDate(date: MutableList) { + this.xAxisDate = date + } + + //每次重绘,会调用此方法刷新数据 + override fun refreshContent(e: Entry, highlight: Highlight) { + super.refreshContent(e, highlight) + val data = e.data as String + try { + factoryView.text = data + dataView.text = String.format("数据:${decimalFormat.format(e.y.toString().toDouble())}t") + dayView.text = xAxisDate[(e.x).toInt()] + } catch (e1: Exception) { + e1.printStackTrace() + } + super.refreshContent(e, highlight) + } + + override fun getOffset(): MPPointF { + return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt new file mode 100644 index 0000000..379b932 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -0,0 +1,43 @@ +package com.casic.smarttube.widgets + +import android.content.Context +import android.widget.TextView +import com.casic.smarttube.R +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.utils.MPPointF +import java.text.DecimalFormat +import java.util.* + +class LineChartMarkerView(context: Context?) : + MarkerView(context, R.layout.popu_line_chart_marker) { + + private val decimalFormat = DecimalFormat("##0.0") + private val dayView: TextView = findViewById(R.id.dayView) + private val factoryView: TextView = findViewById(R.id.factoryView) + private val dataView: TextView = findViewById(R.id.dataView) + private var xAxisDate: MutableList = ArrayList() + + fun setXAxisDate(date: MutableList) { + this.xAxisDate = date + } + + //每次重绘,会调用此方法刷新数据 + override fun refreshContent(e: Entry, highlight: Highlight) { + super.refreshContent(e, highlight) + val data = e.data as String + try { + factoryView.text = data + dataView.text = String.format("数据:${decimalFormat.format(e.y.toString().toDouble())}t") + dayView.text = xAxisDate[(e.x).toInt()] + } catch (e1: Exception) { + e1.printStackTrace() + } + super.refreshContent(e, highlight) + } + + override fun getOffset(): MPPointF { + return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_blue.xml b/app/src/main/res/drawable/bg_stroke_layout_blue.xml new file mode 100644 index 0000000..26ddc25 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt new file mode 100644 index 0000000..379b932 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -0,0 +1,43 @@ +package com.casic.smarttube.widgets + +import android.content.Context +import android.widget.TextView +import com.casic.smarttube.R +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.utils.MPPointF +import java.text.DecimalFormat +import java.util.* + +class LineChartMarkerView(context: Context?) : + MarkerView(context, R.layout.popu_line_chart_marker) { + + private val decimalFormat = DecimalFormat("##0.0") + private val dayView: TextView = findViewById(R.id.dayView) + private val factoryView: TextView = findViewById(R.id.factoryView) + private val dataView: TextView = findViewById(R.id.dataView) + private var xAxisDate: MutableList = ArrayList() + + fun setXAxisDate(date: MutableList) { + this.xAxisDate = date + } + + //每次重绘,会调用此方法刷新数据 + override fun refreshContent(e: Entry, highlight: Highlight) { + super.refreshContent(e, highlight) + val data = e.data as String + try { + factoryView.text = data + dataView.text = String.format("数据:${decimalFormat.format(e.y.toString().toDouble())}t") + dayView.text = xAxisDate[(e.x).toInt()] + } catch (e1: Exception) { + e1.printStackTrace() + } + super.refreshContent(e, highlight) + } + + override fun getOffset(): MPPointF { + return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_blue.xml b/app/src/main/res/drawable/bg_stroke_layout_blue.xml new file mode 100644 index 0000000..26ddc25 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_left_right.xml b/app/src/main/res/drawable/ic_left_right.xml new file mode 100644 index 0000000..e80b0f5 --- /dev/null +++ b/app/src/main/res/drawable/ic_left_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt new file mode 100644 index 0000000..379b932 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -0,0 +1,43 @@ +package com.casic.smarttube.widgets + +import android.content.Context +import android.widget.TextView +import com.casic.smarttube.R +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.utils.MPPointF +import java.text.DecimalFormat +import java.util.* + +class LineChartMarkerView(context: Context?) : + MarkerView(context, R.layout.popu_line_chart_marker) { + + private val decimalFormat = DecimalFormat("##0.0") + private val dayView: TextView = findViewById(R.id.dayView) + private val factoryView: TextView = findViewById(R.id.factoryView) + private val dataView: TextView = findViewById(R.id.dataView) + private var xAxisDate: MutableList = ArrayList() + + fun setXAxisDate(date: MutableList) { + this.xAxisDate = date + } + + //每次重绘,会调用此方法刷新数据 + override fun refreshContent(e: Entry, highlight: Highlight) { + super.refreshContent(e, highlight) + val data = e.data as String + try { + factoryView.text = data + dataView.text = String.format("数据:${decimalFormat.format(e.y.toString().toDouble())}t") + dayView.text = xAxisDate[(e.x).toInt()] + } catch (e1: Exception) { + e1.printStackTrace() + } + super.refreshContent(e, highlight) + } + + override fun getOffset(): MPPointF { + return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_blue.xml b/app/src/main/res/drawable/bg_stroke_layout_blue.xml new file mode 100644 index 0000000..26ddc25 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_left_right.xml b/app/src/main/res/drawable/ic_left_right.xml new file mode 100644 index 0000000..e80b0f5 --- /dev/null +++ b/app/src/main/res/drawable/ic_left_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_left_text_color.xml b/app/src/main/res/drawable/ic_left_text_color.xml new file mode 100644 index 0000000..e3af6b5 --- /dev/null +++ b/app/src/main/res/drawable/ic_left_text_color.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt new file mode 100644 index 0000000..379b932 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -0,0 +1,43 @@ +package com.casic.smarttube.widgets + +import android.content.Context +import android.widget.TextView +import com.casic.smarttube.R +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.utils.MPPointF +import java.text.DecimalFormat +import java.util.* + +class LineChartMarkerView(context: Context?) : + MarkerView(context, R.layout.popu_line_chart_marker) { + + private val decimalFormat = DecimalFormat("##0.0") + private val dayView: TextView = findViewById(R.id.dayView) + private val factoryView: TextView = findViewById(R.id.factoryView) + private val dataView: TextView = findViewById(R.id.dataView) + private var xAxisDate: MutableList = ArrayList() + + fun setXAxisDate(date: MutableList) { + this.xAxisDate = date + } + + //每次重绘,会调用此方法刷新数据 + override fun refreshContent(e: Entry, highlight: Highlight) { + super.refreshContent(e, highlight) + val data = e.data as String + try { + factoryView.text = data + dataView.text = String.format("数据:${decimalFormat.format(e.y.toString().toDouble())}t") + dayView.text = xAxisDate[(e.x).toInt()] + } catch (e1: Exception) { + e1.printStackTrace() + } + super.refreshContent(e, highlight) + } + + override fun getOffset(): MPPointF { + return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_blue.xml b/app/src/main/res/drawable/bg_stroke_layout_blue.xml new file mode 100644 index 0000000..26ddc25 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_left_right.xml b/app/src/main/res/drawable/ic_left_right.xml new file mode 100644 index 0000000..e80b0f5 --- /dev/null +++ b/app/src/main/res/drawable/ic_left_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_left_text_color.xml b/app/src/main/res/drawable/ic_left_text_color.xml new file mode 100644 index 0000000..e3af6b5 --- /dev/null +++ b/app/src/main/res/drawable/ic_left_text_color.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml new file mode 100644 index 0000000..d65443d --- /dev/null +++ b/app/src/main/res/layout/activity_history_data.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a9b50c5..e7a86a8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -43,6 +43,9 @@ + (dataBeans[position].devcode) } override fun onEditClicked(position: Int) { diff --git a/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java new file mode 100644 index 0000000..f4096ea --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/DeviceHistoryDataModel.java @@ -0,0 +1,166 @@ +package com.casic.smarttube.model; + +import java.util.List; + +public class DeviceHistoryDataModel { + + private int code; + private DataBean data; + private String message; + private boolean success; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public DataBean getData() { + return data; + } + + public void setData(DataBean data) { + this.data = data; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public boolean isSuccess() { + return success; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public static class DataBean { + private List rows; + private int total; + + public List getRows() { + return rows; + } + + public void setRows(List rows) { + this.rows = rows; + } + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + this.total = total; + } + + public static class RowsBean { + private String deviceType; + private String deptName; + private String devcode; + private String strength; + private String wellCode; + private String deptid; + private String deviceTypeName; + private String cell; + private String descn; + private String logtime; + private String uptime; + + public String getDeviceType() { + return deviceType; + } + + public void setDeviceType(String deviceType) { + this.deviceType = deviceType; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + public String getDevcode() { + return devcode; + } + + public void setDevcode(String devcode) { + this.devcode = devcode; + } + + public String getStrength() { + return strength; + } + + public void setStrength(String strength) { + this.strength = strength; + } + + public String getWellCode() { + return wellCode; + } + + public void setWellCode(String wellCode) { + this.wellCode = wellCode; + } + + public String getDeptid() { + return deptid; + } + + public void setDeptid(String deptid) { + this.deptid = deptid; + } + + public String getDeviceTypeName() { + return deviceTypeName; + } + + public void setDeviceTypeName(String deviceTypeName) { + this.deviceTypeName = deviceTypeName; + } + + public String getCell() { + return cell; + } + + public void setCell(String cell) { + this.cell = cell; + } + + public String getDescn() { + return descn; + } + + public void setDescn(String descn) { + this.descn = descn; + } + + public String getLogtime() { + return logtime; + } + + public void setLogtime(String logtime) { + this.logtime = logtime; + } + + public String getUptime() { + return uptime; + } + + public void setUptime(String uptime) { + this.uptime = uptime; + } + } + } +} diff --git a/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java new file mode 100644 index 0000000..5fe5c55 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/model/LineChartEntryModel.java @@ -0,0 +1,28 @@ +package com.casic.smarttube.model; + +import com.github.mikephil.charting.data.Entry; + +import java.util.List; + +public class LineChartEntryModel { + //折线数据 + private List entryList; + //折线颜色 + private List lineColors; + + public List getEntryList() { + return entryList; + } + + public void setEntryList(List entryList) { + this.entryList = entryList; + } + + public List getLineColors() { + return lineColors; + } + + public void setLineColors(List lineColors) { + this.lineColors = lineColors; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt new file mode 100644 index 0000000..2b32974 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/utils/ChartViewHelper.kt @@ -0,0 +1,79 @@ +package com.casic.smarttube.utils + +import com.casic.smarttube.base.BaseApplication +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.widgets.LineChartMarkerView +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.ValueFormatter +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet +import com.pengxh.kt.lite.extensions.init + + +/** + * @author a203 + * @description 各种图初始化配置类 + * @date 2022/2/15 16:24 + * @email 290677893@qq.com + */ +object ChartViewHelper { + /** + * 折线图 + * */ + fun setLineChartData( + chart: LineChart, xAxisDate: MutableList, entryModels: List + ) { + //每次加载数据都初始化折线图 + chart.init(BaseApplication.obtainInstance()) + //[{"entryList":[],"lineColor":-13118290}] + if (entryModels[0].entryList?.isEmpty() == true) { + chart.clearValues() + return + } + //绑定数据 + val lineDataSets: MutableList = ArrayList() + val entrySize = entryModels[0].entryList!!.size + entryModels.forEachIndexed { index, it -> + //设置数据 + val dataSet = if (entrySize == 1) { + LineDataSet(it.entryList, it.entryList?.get(0)?.data.toString()) + } else { + LineDataSet(it.entryList, it.entryList?.get(index)?.data.toString()) + } + dataSet.setDrawCircles(true) + //线条颜色 + dataSet.color = it.lineColors[index] + //圆点颜色 + dataSet.setCircleColor(it.lineColors[index]) + dataSet.setDrawFilled(true) + dataSet.fillColor = it.lineColors[index] + dataSet.mode = LineDataSet.Mode.CUBIC_BEZIER + lineDataSets.add(dataSet) + } + val lineData = LineData(lineDataSets) + lineData.setDrawValues(false) + //添加自定义Marker + val markerView = LineChartMarkerView(BaseApplication.obtainInstance()) + markerView.chartView = chart + markerView.setXAxisDate(xAxisDate) + chart.marker = markerView + //设置X轴坐标 + val xAxis = chart.xAxis + xAxis.valueFormatter = if (entrySize == 1) { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[0] + } + } + } else { + object : ValueFormatter() { + override fun getFormattedValue(value: Float): String { + return xAxisDate[value.toInt()] + } + } + } + chart.data = lineData + chart.invalidate() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt index 608dd91..4717635 100644 --- a/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt +++ b/app/src/main/java/com/casic/smarttube/utils/LocalConstant.kt @@ -29,7 +29,7 @@ * Long * ============================================================================================= * */ - + const val FIVE_YEARS = 5L * 365 * 60 * 60 * 24 * 1000L /** * ============================================================================================= diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt index f715247..713a640 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitService.kt @@ -129,4 +129,20 @@ @Header("token") token: String, @Query("pid") pid: String ): String + + /** + * 获取管盯分页列表 + * */ + @GET("/tubedata/list") + suspend fun obtainDeviceHistoryData( + @Header("token") token: String, + @Query("deptid") deptid: String?, + @Query("keywords") keywords: String?, + @Query("beginTime") beginTime: String?, + @Query("endTime") endTime: String?, + @Query("sort") sort: String?, + @Query("order") order: String?, + @Query("offset") offset: Int, + @Query("limit") limit: Int + ): String } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt index d888e59..8e82f07 100644 --- a/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt +++ b/app/src/main/java/com/casic/smarttube/utils/retrofit/RetrofitServiceManager.kt @@ -95,6 +95,18 @@ } /** + * 根据设备编号获取历史数据 + */ + suspend fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ): String { + return api.obtainDeviceHistoryData( + AuthenticationHelper.token!!, deptid, keywords, beginTime, endTime, + "", "", 1, 1000 + ) + } + + /** * 上传图片 */ suspend fun uploadImage(image: File): String { diff --git a/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt new file mode 100644 index 0000000..c3da55d --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/view/HistoryDataActivity.kt @@ -0,0 +1,172 @@ +package com.casic.smarttube.view + +import android.view.View +import android.widget.AdapterView +import androidx.lifecycle.ViewModelProvider +import com.casic.smarttube.R +import com.casic.smarttube.extensions.getQuarterOfYear +import com.casic.smarttube.model.LineChartEntryModel +import com.casic.smarttube.utils.ChartViewHelper +import com.casic.smarttube.vm.DeviceViewModel +import com.casic.smarttube.widgets.DateSelectDialog +import com.github.mikephil.charting.data.Entry +import com.gyf.immersionbar.ImmersionBar +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.base.KotlinBaseActivity +import com.pengxh.kt.lite.extensions.convertColor +import com.pengxh.kt.lite.extensions.timestampToDate +import com.pengxh.kt.lite.extensions.timestampToLastMonthDate +import com.pengxh.kt.lite.extensions.timestampToLastWeekDate +import com.pengxh.kt.lite.utils.Constant +import com.pengxh.kt.lite.utils.ImmerseStatusBarUtil +import kotlinx.android.synthetic.main.activity_history_data.* +import java.util.* + +class HistoryDataActivity : KotlinBaseActivity() { + + private lateinit var deviceViewModel: DeviceViewModel + private lateinit var devCode: String + + override fun initLayoutView(): Int = R.layout.activity_history_data + + override fun setupTopBarLayout() { + ImmersionBar.with(this).statusBarDarkFont(false).init() + ImmerseStatusBarUtil.setColor(this, R.color.mainThemeColor.convertColor(this)) + leftBackView.setOnClickListener { finish() } + } + + override fun initData() { + devCode = intent.getStringExtra(Constant.INTENT_PARAM)!! + deviceViewModel = ViewModelProvider(this).get(DeviceViewModel::class.java) + } + + override fun initEvent() { + //默认选择近7天的数据 + periodSpinner.setSelection(3) + periodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected( + parent: AdapterView<*>?, view: View?, + position: Int, id: Long + ) { + val time = System.currentTimeMillis() + val calendar = Calendar.getInstance() + val year: Int = calendar.get(Calendar.YEAR) + when (position) { + 0 -> { + //本年度 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, "$year-01-01", time.timestampToDate() + ) + } + 1 -> { + //本季度 + val startDate = when (time.getQuarterOfYear()) { + 1 -> "$year-01-01" + 2 -> "$year-04-01" + 3 -> "$year-07-01" + 4 -> "$year-10-01" + else -> "" + } + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, time.timestampToDate() + ) + } + 2 -> { + //近30日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastMonthDate(), time.timestampToDate() + ) + } + 3 -> { + //近7日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToLastWeekDate(), time.timestampToDate() + ) + } + 4 -> { + //今日 + deviceViewModel.obtainDeviceHistoryData( + "", devCode, time.timestampToDate(), time.timestampToDate() + ) + } + 5 -> { + DateSelectDialog.Builder() + .setContext(this@HistoryDataActivity) + .setTitle("选择日期") + .setNegativeButton("取消") + .setPositiveButton("选好了") + .setOnDialogButtonClickListener(object : + DateSelectDialog.OnDialogButtonClickListener { + override fun onConfirmClick(startDate: String, endDate: String) { + deviceViewModel.obtainDeviceHistoryData( + "", devCode, startDate, endDate + ) + } + + override fun onCancelClick() { + //选择取消就默认加载近7天的数据 + periodSpinner.setSelection(3) + } + }) + .setFragmentManager(supportFragmentManager) + .setCalendarType(Type.YEAR_MONTH_DAY) + .build().show() + } + } + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + + } + } + deviceViewModel.historyDataModel.observe(this, { + if (it.code == 200) { + //两条线,电量和浓度线 + val xAxisLabel: MutableList = ArrayList() + val entryModels: MutableList = ArrayList() + + val entryModel = LineChartEntryModel() + //每个entries都是一条折线 + val entries: ArrayList = ArrayList() + val colors: ArrayList = ArrayList() + it.data!!.rows.forEachIndexed { i, rowsBean -> +// { +// "deviceType":"12", +// "deptName":"燃气集团总公司", +// "devcode":"342021000001", +// "strength":"0.00", +// "wellCode":"test001", +// "deptid":"24", +// "deviceTypeName":"管盯", +// "cell":"100", +// "descn":"", +// "logtime":"2022-06-25 10:39:47", +// "uptime":"2022-06-25 10:27:00" +// } + + // x 轴坐标 + val split = rowsBean.uptime.toString().split(" ") + xAxisLabel.add(split[1]) + + //电量线 + colors.add(R.color.greenColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "电量") + ) + + + //浓度线 + colors.add(R.color.redTextColor.convertColor(this)) + entries.add( + Entry(i.toFloat(), rowsBean.cell!!.toFloat(), "浓度") + ) + } + entryModel.lineColors = colors + entryModel.entryList = entries + entryModels.add(entryModel) + + ChartViewHelper.setLineChartData(dataLineChart, xAxisLabel, entryModels) + } + }) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt index 457c06f..ef4766d 100644 --- a/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt +++ b/app/src/main/java/com/casic/smarttube/view/WellDetailActivity.kt @@ -28,7 +28,6 @@ private lateinit var wellViewModel: WellViewModel private lateinit var authenticateViewModel: AuthenticateViewModel - private lateinit var wellId: String private lateinit var aMap: AMap private var latLng: LatLng? = null @@ -43,10 +42,12 @@ } override fun initData() { - wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! + val wellId = intent.getStringExtra(Constant.INTENT_PARAM)!! wellViewModel = ViewModelProvider(this).get(WellViewModel::class.java) authenticateViewModel = ViewModelProvider(this).get(AuthenticateViewModel::class.java) + wellViewModel.obtainWellDetail(wellId) + aMap = wellMapView.map aMap.mapType = AMap.MAP_TYPE_NORMAL val uiSettings = aMap.uiSettings @@ -89,7 +90,6 @@ } override fun initEvent() { - wellViewModel.obtainWellDetail(wellId) wellViewModel.detailModel.observe(this, { if (it.code == 200) { val wellDetail = it.data!! diff --git a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt index 6a12e14..4d0b36f 100644 --- a/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt +++ b/app/src/main/java/com/casic/smarttube/vm/DeviceViewModel.kt @@ -4,6 +4,7 @@ import com.casic.smarttube.base.BaseApplication import com.casic.smarttube.extensions.separateResponseCode import com.casic.smarttube.extensions.toErrorMessage +import com.casic.smarttube.model.DeviceHistoryDataModel import com.casic.smarttube.model.DeviceListModel import com.casic.smarttube.utils.retrofit.RetrofitServiceManager import com.google.gson.Gson @@ -16,20 +17,40 @@ private val gson = Gson() val deviceListModel = MutableLiveData() + val historyDataModel = MutableLiveData() - fun obtainDeviceListByType(deptid: String, keywords: String, isOnline: String, page: Int) = - launch({ - val response = - RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) - val responseCode = response.separateResponseCode() - if (responseCode == 200) { - deviceListModel.value = gson.fromJson( - response, object : TypeToken() {}.type - ) - } else { - response.toErrorMessage().show(BaseApplication.obtainInstance()) - } - }, { - it.printStackTrace() - }) + fun obtainDeviceListByType( + deptid: String, keywords: String, isOnline: String, page: Int + ) = launch({ + val response = + RetrofitServiceManager.obtainDeviceListByType(deptid, keywords, isOnline, page) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + deviceListModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) + + fun obtainDeviceHistoryData( + deptid: String, keywords: String, beginTime: String?, endTime: String? + ) = launch({ + val response = RetrofitServiceManager.obtainDeviceHistoryData( + deptid, keywords, beginTime, endTime + ) + val responseCode = response.separateResponseCode() + if (responseCode == 200) { + historyDataModel.value = gson.fromJson( + response, object : TypeToken() {}.type + ) + } else { + response.toErrorMessage().show(BaseApplication.obtainInstance()) + } + }, { + it.printStackTrace() + }) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt new file mode 100644 index 0000000..4fe46ee --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/DateSelectDialog.kt @@ -0,0 +1,173 @@ +package com.casic.smarttube.widgets + +import android.app.Dialog +import android.content.Context +import android.os.Bundle +import android.view.Gravity +import androidx.fragment.app.FragmentManager +import com.casic.smarttube.R +import com.casic.smarttube.utils.LocalConstant +import com.jzxiang.pickerview.TimePickerDialog +import com.jzxiang.pickerview.data.Type +import com.pengxh.kt.lite.extensions.* +import kotlinx.android.synthetic.main.dialog_select_date.* +import java.text.ParseException +import java.text.SimpleDateFormat +import java.util.* + +class DateSelectDialog private constructor(builder: Builder) : Dialog( + builder.context, R.style.UserDefinedDialogStyle +) { + + private val ctx: Context = builder.context + private val title: String = builder.title + private val negativeBtn: String = builder.negativeBtn + private val positiveBtn: String = builder.positiveBtn + private val listener: OnDialogButtonClickListener = builder.listener + private val fragmentManager: FragmentManager = builder.fragmentManager + private val type: Type = builder.type + + class Builder { + lateinit var context: Context + lateinit var title: String + lateinit var negativeBtn: String + lateinit var positiveBtn: String + lateinit var listener: OnDialogButtonClickListener + lateinit var fragmentManager: FragmentManager + lateinit var type: Type + + fun setContext(context: Context): Builder { + this.context = context + return this + } + + fun setTitle(title: String): Builder { + this.title = title + return this + } + + fun setNegativeButton(name: String): Builder { + this.negativeBtn = name + return this + } + + fun setPositiveButton(name: String): Builder { + this.positiveBtn = name + return this + } + + fun setOnDialogButtonClickListener(listener: OnDialogButtonClickListener): Builder { + this.listener = listener + return this + } + + fun setFragmentManager(fragmentManager: FragmentManager): Builder { + this.fragmentManager = fragmentManager + return this + } + + fun setCalendarType(calendarType: Type): Builder { + this.type = calendarType + return this + } + + fun build(): DateSelectDialog { + return DateSelectDialog(this) + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + this.resetParams(Gravity.CENTER, R.style.UserDefinedAnimation, 0.85) + setContentView(R.layout.dialog_select_date) + setCancelable(false) + setCanceledOnTouchOutside(false) + + if (title.isNotBlank()) { + dialogTitleView.text = title + } + + startDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + startDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + endDateView.setOnClickListener { + TimePickerDialog.Builder() + .setThemeColor(R.color.mainThemeColor.convertColor(ctx)) + .setTitleStringId("请选择起始时间") + .setWheelItemTextSize(16) + .setCyclic(false) + .setMinMillseconds(System.currentTimeMillis() - LocalConstant.FIVE_YEARS) + .setMaxMillseconds(System.currentTimeMillis()) + .setType(type) + .setCallBack { _: TimePickerDialog?, millSeconds: Long -> + val textValue = if (type == Type.ALL) { + millSeconds.timestampToTime() + } else { + millSeconds.timestampToDate() + } + endDateView.setText(textValue) + }.build().show(fragmentManager, "DateSelectDialog") + } + + dialogCancelButton.text = negativeBtn + dialogCancelButton.setOnClickListener { + listener.onCancelClick() + this.dismiss() + } + + dialogConfirmButton.text = positiveBtn + dialogConfirmButton.setOnClickListener { + //判断其实时间和结束时间 + val startDate = startDateView.text.toString() + val endDate = endDateView.text.toString() + if (isEarlierThanStart(startDate, endDate)) { + "结束时间不能早于开始时间".show(ctx) + return@setOnClickListener + } + listener.onConfirmClick(startDate, endDate) + this.dismiss() + } + } + + interface OnDialogButtonClickListener { + fun onConfirmClick(startDate: String, endDate: String) + + fun onCancelClick() + } + + /** + * 判断时间是否早于当前时间 + */ + private fun isEarlierThanStart(start: String, end: String): Boolean { + if (start.isBlank() || end.isBlank()) { + return false + } + val dateFormat = if (type == Type.ALL) { + SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.CHINA) + } else { + SimpleDateFormat("yyyy-MM-dd", Locale.CHINA) + } + try { + return dateFormat.parse(start)?.time!! > dateFormat.parse(end)?.time!! + } catch (e: ParseException) { + e.printStackTrace(); + } + return false + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt new file mode 100644 index 0000000..379b932 --- /dev/null +++ b/app/src/main/java/com/casic/smarttube/widgets/LineChartMarkerView.kt @@ -0,0 +1,43 @@ +package com.casic.smarttube.widgets + +import android.content.Context +import android.widget.TextView +import com.casic.smarttube.R +import com.github.mikephil.charting.components.MarkerView +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.highlight.Highlight +import com.github.mikephil.charting.utils.MPPointF +import java.text.DecimalFormat +import java.util.* + +class LineChartMarkerView(context: Context?) : + MarkerView(context, R.layout.popu_line_chart_marker) { + + private val decimalFormat = DecimalFormat("##0.0") + private val dayView: TextView = findViewById(R.id.dayView) + private val factoryView: TextView = findViewById(R.id.factoryView) + private val dataView: TextView = findViewById(R.id.dataView) + private var xAxisDate: MutableList = ArrayList() + + fun setXAxisDate(date: MutableList) { + this.xAxisDate = date + } + + //每次重绘,会调用此方法刷新数据 + override fun refreshContent(e: Entry, highlight: Highlight) { + super.refreshContent(e, highlight) + val data = e.data as String + try { + factoryView.text = data + dataView.text = String.format("数据:${decimalFormat.format(e.y.toString().toDouble())}t") + dayView.text = xAxisDate[(e.x).toInt()] + } catch (e1: Exception) { + e1.printStackTrace() + } + super.refreshContent(e, highlight) + } + + override fun getOffset(): MPPointF { + return MPPointF((-(width shr 1)).toFloat(), (-height).toFloat()) + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_blue.xml b/app/src/main/res/drawable/bg_stroke_layout_blue.xml new file mode 100644 index 0000000..26ddc25 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_left_right.xml b/app/src/main/res/drawable/ic_left_right.xml new file mode 100644 index 0000000..e80b0f5 --- /dev/null +++ b/app/src/main/res/drawable/ic_left_right.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_left_text_color.xml b/app/src/main/res/drawable/ic_left_text_color.xml new file mode 100644 index 0000000..e3af6b5 --- /dev/null +++ b/app/src/main/res/drawable/ic_left_text_color.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/layout/activity_history_data.xml b/app/src/main/res/layout/activity_history_data.xml new file mode 100644 index 0000000..d65443d --- /dev/null +++ b/app/src/main/res/layout/activity_history_data.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_select_date.xml b/app/src/main/res/layout/dialog_select_date.xml new file mode 100644 index 0000000..675f4e7 --- /dev/null +++ b/app/src/main/res/layout/dialog_select_date.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + +