first
This commit is contained in:
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
WateX
|
||||
6
.idea/AndroidProjectSystem.xml
generated
Normal file
6
.idea/AndroidProjectSystem.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AndroidProjectSystem">
|
||||
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/appInsightsSettings.xml
generated
Normal file
6
.idea/appInsightsSettings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AppInsightsSettings">
|
||||
<option name="selectedTabId" value="Android Vitals" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/compiler.xml
generated
Normal file
6
.idea/compiler.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel target="17" />
|
||||
</component>
|
||||
</project>
|
||||
18
.idea/deploymentTargetSelector.xml
generated
Normal file
18
.idea/deploymentTargetSelector.xml
generated
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
<DropdownSelection timestamp="2026-05-15T02:49:19.581976200Z">
|
||||
<Target type="DEFAULT_BOOT">
|
||||
<handle>
|
||||
<DeviceId pluginId="LocalEmulator" identifier="path=C:\Users\Admin\.android\avd\Pixel_7a_2.avd" />
|
||||
</handle>
|
||||
</Target>
|
||||
</DropdownSelection>
|
||||
<DialogSelection />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
17
.idea/deviceManager.xml
generated
Normal file
17
.idea/deviceManager.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DeviceTable">
|
||||
<option name="columnSorters">
|
||||
<list>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="API" />
|
||||
<option name="order" value="DESCENDING" />
|
||||
</ColumnSorterState>
|
||||
<ColumnSorterState>
|
||||
<option name="column" value="Type" />
|
||||
<option name="order" value="ASCENDING" />
|
||||
</ColumnSorterState>
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
13
.idea/easycode.ignore
generated
Normal file
13
.idea/easycode.ignore
generated
Normal file
@@ -0,0 +1,13 @@
|
||||
.idea
|
||||
.vscode
|
||||
node_modules/
|
||||
dist/
|
||||
vendor/
|
||||
cache/
|
||||
.*/
|
||||
*.min.*
|
||||
*.test.*
|
||||
*.spec.*
|
||||
*.bundle.*
|
||||
*.bundle-min.*
|
||||
*.log
|
||||
6
.idea/easycode/codebase-v2.xml
generated
Normal file
6
.idea/easycode/codebase-v2.xml
generated
Normal file
File diff suppressed because one or more lines are too long
47
.idea/emulatorDisplays.xml
generated
Normal file
47
.idea/emulatorDisplays.xml
generated
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EmulatorDisplays">
|
||||
<option name="displayStateByAvdFolder">
|
||||
<map>
|
||||
<entry key="$USER_HOME$/.android/avd/Pixel_7_Pro_API_35.avd">
|
||||
<value>
|
||||
<MultiDisplayState>
|
||||
<option name="displayDescriptors">
|
||||
<list>
|
||||
<DisplayDescriptor>
|
||||
<option name="height" value="3272" />
|
||||
<option name="width" value="1547" />
|
||||
</DisplayDescriptor>
|
||||
<DisplayDescriptor>
|
||||
<option name="displayId" value="1" />
|
||||
<option name="height" value="1280" />
|
||||
<option name="width" value="720" />
|
||||
</DisplayDescriptor>
|
||||
</list>
|
||||
</option>
|
||||
<option name="panelState">
|
||||
<PanelState>
|
||||
<option name="splitPanel">
|
||||
<SplitPanelState>
|
||||
<option name="proportion" value="0.9958592057228088" />
|
||||
<option name="firstComponent">
|
||||
<PanelState>
|
||||
<option name="displayId" value="0" />
|
||||
</PanelState>
|
||||
</option>
|
||||
<option name="secondComponent">
|
||||
<PanelState>
|
||||
<option name="displayId" value="1" />
|
||||
</PanelState>
|
||||
</option>
|
||||
</SplitPanelState>
|
||||
</option>
|
||||
</PanelState>
|
||||
</option>
|
||||
</MultiDisplayState>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/encodings.xml
generated
Normal file
6
.idea/encodings.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
||||
<file url="PROJECT" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
||||
5
.idea/fileTemplates/includes/File Header.java
generated
Normal file
5
.idea/fileTemplates/includes/File Header.java
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date ${DATE}
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
23
.idea/gradle.xml
generated
Normal file
23
.idea/gradle.xml
generated
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleJvm" value="jbr-17" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
<option value="$PROJECT_DIR$/app" />
|
||||
<option value="$PROJECT_DIR$/imagepicker" />
|
||||
<option value="$PROJECT_DIR$/imagepickerl" />
|
||||
<option value="$PROJECT_DIR$/imkit" />
|
||||
<option value="$PROJECT_DIR$/ryimkit" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
6
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="AndroidLintUnsafeImplicitIntentLaunch" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
</profile>
|
||||
</component>
|
||||
80
.idea/jarRepositories.xml
generated
Normal file
80
.idea/jarRepositories.xml
generated
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenRepo" />
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="BintrayJCenter" />
|
||||
<option name="name" value="BintrayJCenter" />
|
||||
<option name="url" value="https://jcenter.bintray.com/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="Google" />
|
||||
<option name="name" value="Google" />
|
||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="https://maven.aliyun.com/repository/central" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven2" />
|
||||
<option name="name" value="maven2" />
|
||||
<option name="url" value="https://maven.aliyun.com/repository/public" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven3" />
|
||||
<option name="name" value="maven3" />
|
||||
<option name="url" value="https://maven.aliyun.com/repository/google" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven4" />
|
||||
<option name="name" value="maven4" />
|
||||
<option name="url" value="https://maven.aliyun.com/repository/gradle-plugin" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven" />
|
||||
<option name="name" value="maven" />
|
||||
<option name="url" value="http://mvn.mob.com/android" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven6" />
|
||||
<option name="name" value="maven6" />
|
||||
<option name="url" value="https://jitpack.io" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven5" />
|
||||
<option name="name" value="maven5" />
|
||||
<option name="url" value="http://maven.aliyun.com/nexus/content/repositories/gradle-plugin" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven4" />
|
||||
<option name="name" value="maven4" />
|
||||
<option name="url" value="http://maven.aliyun.com/nexus/content/repositories/google" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven3" />
|
||||
<option name="name" value="maven3" />
|
||||
<option name="url" value="http://maven.aliyun.com/nexus/content/repositories/jcenter" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="maven2" />
|
||||
<option name="name" value="maven2" />
|
||||
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
||||
12
.idea/material_theme_project_new.xml
generated
Normal file
12
.idea/material_theme_project_new.xml
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MaterialThemeProjectNewConfig">
|
||||
<option name="metadata">
|
||||
<MTProjectMetadataState>
|
||||
<option name="migrated" value="true" />
|
||||
<option name="pristineConfig" value="false" />
|
||||
<option name="userId" value="-5fc63eca:197a6042756:-7ffe" />
|
||||
</MTProjectMetadataState>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
10
.idea/migrations.xml
generated
Normal file
10
.idea/migrations.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectMigrations">
|
||||
<option name="MigrateToGradleLocalJavaHome">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
16
.idea/misc.xml
generated
Normal file
16
.idea/misc.xml
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||
</component>
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
<component name="VisualizationToolProject">
|
||||
<option name="state">
|
||||
<ProjectState>
|
||||
<option name="scale" value="0.24901855468749995" />
|
||||
</ProjectState>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
17
.idea/runConfigurations.xml
generated
Normal file
17
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/studiobot.xml
generated
Normal file
6
.idea/studiobot.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="StudioBotProjectSettings">
|
||||
<option name="shareContext" value="OptedIn" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
1
app/.gitignore
vendored
Normal file
1
app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
231
app/build.gradle
Normal file
231
app/build.gradle
Normal file
@@ -0,0 +1,231 @@
|
||||
import java.text.SimpleDateFormat
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'com.hihonor.mcs.asplugin'
|
||||
apply plugin: 'io.freefair.lombok' // ✅ 加上这个
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
lintOptions {
|
||||
checkReleaseBuilds false // 关闭 release 打包时 lint 检查
|
||||
abortOnError false // 即使有错误也不终止编译
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file('../chengkong.jks')
|
||||
keyAlias 'chengkong'
|
||||
keyPassword '111111'
|
||||
storePassword '111111'
|
||||
}
|
||||
debug {
|
||||
storeFile file('../chengkong.jks')
|
||||
keyAlias 'chengkong'
|
||||
keyPassword '111111'
|
||||
storePassword '111111'
|
||||
}
|
||||
config {
|
||||
storeFile file('../chengkong.jks')
|
||||
keyAlias 'chengkong'
|
||||
keyPassword '111111'
|
||||
storePassword '111111'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
buildFeatures {
|
||||
dataBinding true
|
||||
}
|
||||
defaultConfig {
|
||||
applicationId "com.ckkj.water"
|
||||
minSdkVersion 26
|
||||
targetSdkVersion 30
|
||||
versionCode 1
|
||||
versionName "1.0.1"//version 1.0.0-appstore version 1.0.0-xh
|
||||
// 添加自定义字段
|
||||
buildConfigField "String", "APP_VERSION_NAME", "\"${versionName}\""
|
||||
buildConfigField "int", "APP_VERSION_CODE", "${versionCode}"
|
||||
resConfigs "zh", "en"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.config
|
||||
}
|
||||
release {
|
||||
signingConfig signingConfigs.config
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
jniLibs.srcDir 'libs'
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
ndk {
|
||||
//设置支持的SO库架构(开发者可以根据需要,选择一个或多个平台的so)
|
||||
abiFilters "arm64-v8a" // 同时支持 32 和 64 位
|
||||
// abiFilters "armeabi-v7a" // 只打 32 位
|
||||
// abiFilters "arm64-v8a" // 只打 64 位
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'META-INF/filepicker_release.kotlin_module'
|
||||
exclude 'lib/x86/libc++_shared.so'
|
||||
exclude 'lib/armeabi-v7a/libc++_shared.so'
|
||||
exclude 'lib/arm64-v8a/libc++_shared.so'
|
||||
exclude 'lib/x86_64/libc++_shared.so'
|
||||
}
|
||||
|
||||
repositories {
|
||||
flatDir {
|
||||
dirs 'libs'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||
implementation files('libs/QWeather_Public_Android_V5.1.2.jar')
|
||||
implementation 'com.google.android.material:material:1.6.0'
|
||||
// testImplementation 'junit:junit:4.+'
|
||||
// //(gson生成和解析库)
|
||||
implementation 'com.google.code.gson:gson:2.8.0'
|
||||
api ('com.squareup.retrofit2:converter-gson:2.0.2'){
|
||||
exclude group : 'com.google.code.gson'
|
||||
}
|
||||
implementation "androidx.core:core:1.5.0"
|
||||
//针对rxjava2.x(adapter-rxjava2的版本要 >= 2.2.0)
|
||||
api 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
|
||||
api 'io.reactivex.rxjava2:rxjava:2.1.7'
|
||||
api 'io.reactivex.rxjava2:rxandroid:2.0.1'
|
||||
//okhttp的log信息 implementation 'com.squareup.okhttp3:okhttp:4.9.3' // 替换为最新版本
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
implementation 'net.i2p.crypto:eddsa:0.3.0'
|
||||
implementation "com.mapzen:on-the-road:1.2.0"
|
||||
//fastJson
|
||||
implementation files('libs\\fastjson-1.2.40.jar')
|
||||
implementation project(path: ':imagepickerl')
|
||||
//消息传递
|
||||
implementation 'de.greenrobot:eventbus:3.0.0-beta1'
|
||||
implementation 'com.trello.rxlifecycle2:rxlifecycle:2.2.1'
|
||||
implementation 'com.trello.rxlifecycle2:rxlifecycle-android:2.2.1'
|
||||
implementation 'com.trello.rxlifecycle2:rxlifecycle-components:2.2.1'
|
||||
//banner
|
||||
implementation 'io.github.youth5201314:banner:2.2.3'
|
||||
implementation 'com.readystatesoftware.systembartint:systembartint:1.0.3'
|
||||
implementation("com.github.bumptech.glide:glide:4.12.0")
|
||||
annotationProcessor ("com.github.bumptech.glide:compiler:4.12.0")
|
||||
//BaseRecyclerViewAdapterHelper
|
||||
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
|
||||
//下拉刷新,上拉加载
|
||||
implementation 'io.github.scwang90:refresh-layout-kernel:2.0.6'
|
||||
implementation 'io.github.scwang90:refresh-header-classics:2.0.6'
|
||||
implementation 'io.github.scwang90:refresh-footer-classics:2.0.6'
|
||||
//权限获取
|
||||
implementation 'pub.devrel:easypermissions:3.0.0'
|
||||
implementation 'com.github.getActivity:XXPermissions:18.5'
|
||||
/*****高德相关*****/
|
||||
//定位功能
|
||||
// implementation 'com.amap.api:location:latest.integration'
|
||||
//圆形视图库
|
||||
implementation 'com.makeramen:roundedimageview:2.3.0'
|
||||
//字母索引View,
|
||||
implementation 'com.github.lzjin:SideBarView:1.0.1'
|
||||
//拼音工具类
|
||||
implementation 'com.belerweb:pinyin4j:2.5.0'
|
||||
//地区三级联动插件
|
||||
implementation 'com.contrarywind:Android-PickerView:4.1.9'
|
||||
// implementation 'com.contrarywind:Android-Picker:4.1.0'
|
||||
//富文本处理图片
|
||||
implementation 'org.jsoup:jsoup:1.11.2'
|
||||
//FlexboxLayoutManager 处理recycleview的不规整布局
|
||||
implementation 'com.google.android:flexbox:2.0.1'
|
||||
//吐司框架
|
||||
implementation 'com.github.getActivity:Toaster:12.5'
|
||||
//鲁班图片压缩
|
||||
implementation 'top.zibin:Luban:1.1.8'
|
||||
//带有侧滑功能的recyclerview
|
||||
// implementation 'com.yanzhenjie.recyclerview:x:1.3.2'
|
||||
implementation 'com.github.luqiming666:SwipeRecyclerView:1.4.8'
|
||||
//Activity与Fragmen实现沉浸式状态栏
|
||||
implementation 'com.github.tangguna:immersion:1.0.1'
|
||||
//viewpager2
|
||||
implementation 'androidx.viewpager2:viewpager2:1.0.0'
|
||||
//文件管理框架
|
||||
implementation 'com.droidninja:filepicker:2.2.5'
|
||||
// implementation 'com.github.angads25:filepicker:1.1.1'
|
||||
// implementation 'io.github.tutorialsandroid:filepicker:9.2.5'
|
||||
implementation 'me.rosuh:AndroidFilePicker:1.0.1'
|
||||
implementation 'com.github.ns3chz:Picker:1.0.2'
|
||||
implementation 'com.github.zzy0516alex:FileSelectorRelease:v6.2'
|
||||
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'//(最低版本)
|
||||
// implementation 'com.umeng.umsdk:share-wx:7.1.5' //微信完整版
|
||||
// implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.7.0'//微信官方依赖库,必选
|
||||
//商品评价星星
|
||||
// implementation 'me.zhanghai.android.materialratingbar:library:1.4.0'
|
||||
implementation 'com.google.android.material:material:1.6.0'
|
||||
//图片选择器
|
||||
implementation 'com.github.Mariovc:ImagePicker:1.2.2'
|
||||
|
||||
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2'
|
||||
|
||||
implementation 'com.github.barteksc:android-pdf-viewer:2.8.2'
|
||||
//zxing 依赖 二维码,扫描等使用
|
||||
implementation 'com.google.zxing:core:3.4.1'
|
||||
// implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
|
||||
implementation 'com.github.maning0303:MNZXingCode:V2.1.9'
|
||||
//该库专门用于在 ImageView 中处理 GIF 动画。
|
||||
// implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.23'
|
||||
//下载框架
|
||||
implementation 'io.github.chiclaim:downloader:1.0.2'
|
||||
implementation 'com.blankj:utilcodex:1.31.1'
|
||||
// debugImplementation("com.reqable.android:user-certificate-trust:1.0.0")
|
||||
implementation 'com.android.support:design:24.1.0'
|
||||
//以下依赖都需要添加
|
||||
implementation 'commons-codec:commons-codec:1.6'
|
||||
implementation 'androidx.annotation:annotation:1.1.0'
|
||||
|
||||
implementation 'com.aliyun.dpa:oss-android-sdk:2.9.21' //阿里云oss
|
||||
//图片裁剪
|
||||
implementation 'com.github.yalantis:ucrop:2.2.6'
|
||||
//XPopup 弹窗样式
|
||||
implementation 'com.github.li-xiaojun:XPopup:2.10.0'
|
||||
//处理 DeepSeek 返回的 markDown 格式
|
||||
implementation 'io.noties.markwon:core:4.6.2'
|
||||
//lottie动画依赖
|
||||
implementation 'com.airbnb.android:lottie:6.4.0'
|
||||
implementation 'cn.6tail:lunar:1.7.4'
|
||||
//开关控件
|
||||
implementation 'com.kyleduo.switchbutton:library:2.1.0'
|
||||
// lombok 库
|
||||
compileOnly 'org.projectlombok:lombok:1.18.30'
|
||||
annotationProcessor 'org.projectlombok:lombok:1.18.30'
|
||||
implementation 'me.jessyan:autosize:1.2.1'
|
||||
//黑白主题依赖
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
|
||||
implementation 'com.github.maning0303:MNMLKitScanner:V1.0.4'
|
||||
//下面版本自己控制,barcode-scanning>=17.0.2
|
||||
implementation 'com.google.mlkit:barcode-scanning:17.0.2'
|
||||
implementation "androidx.camera:camera-core:1.0.2"
|
||||
implementation "androidx.camera:camera-camera2:1.0.2"
|
||||
implementation "androidx.camera:camera-lifecycle:1.0.2"
|
||||
implementation "androidx.camera:camera-view:1.0.0-alpha25"
|
||||
}
|
||||
|
||||
|
||||
BIN
app/libs/AMap_Search_V9.4.0_20220808.jar
Normal file
BIN
app/libs/AMap_Search_V9.4.0_20220808.jar
Normal file
Binary file not shown.
BIN
app/libs/Msc.jar
Normal file
BIN
app/libs/Msc.jar
Normal file
Binary file not shown.
BIN
app/libs/QWeather_Public_Android_V5.1.2.jar
Normal file
BIN
app/libs/QWeather_Public_Android_V5.1.2.jar
Normal file
Binary file not shown.
BIN
app/libs/arm64-v8a/libmsc.so
Normal file
BIN
app/libs/arm64-v8a/libmsc.so
Normal file
Binary file not shown.
BIN
app/libs/armeabi-v7a/libmsc.so
Normal file
BIN
app/libs/armeabi-v7a/libmsc.so
Normal file
Binary file not shown.
BIN
app/libs/fastjson-1.2.40.jar
Normal file
BIN
app/libs/fastjson-1.2.40.jar
Normal file
Binary file not shown.
BIN
app/libs/umeng-link-2.0.0.aar
Normal file
BIN
app/libs/umeng-link-2.0.0.aar
Normal file
Binary file not shown.
BIN
app/libs/umeng-share-core-7.3.5.jar
Normal file
BIN
app/libs/umeng-share-core-7.3.5.jar
Normal file
Binary file not shown.
BIN
app/libs/umeng-sharetool-7.3.5.jar
Normal file
BIN
app/libs/umeng-sharetool-7.3.5.jar
Normal file
Binary file not shown.
33
app/proguard-rules.pro
vendored
Normal file
33
app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
-ignorewarnings
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Exceptions
|
||||
-keepattributes InnerClasses
|
||||
-keepattributes Signature
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep class com.hihonor.push.**{*;}
|
||||
#这里com.xiaomi.mipushdemo.DemoMessageRreceiver改成app中定义的完整类名
|
||||
-keep class com.ckkj.water.receiver.MiMsgPushReceiver {*;}
|
||||
-dontwarn com.xiaomi.mipush.sdk.**
|
||||
-keep public class com.xiaomi.mipush.sdk.* {*;}
|
||||
|
||||
BIN
app/release/app-release.apk
Normal file
BIN
app/release/app-release.apk
Normal file
Binary file not shown.
18
app/release/output-metadata.json
Normal file
18
app/release/output-metadata.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"version": 2,
|
||||
"artifactType": {
|
||||
"type": "APK",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.ckkj.water",
|
||||
"variantName": "processReleaseResources",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"versionCode": 5,
|
||||
"versionName": "version 1.0.2-xh",
|
||||
"outputFile": "app-release.apk"
|
||||
}
|
||||
]
|
||||
}
|
||||
222
app/src/main/AndroidManifest.xml
Normal file
222
app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,222 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="com.ckkj.water">
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_MEDIA_VIDEO"/>
|
||||
|
||||
<uses-permission
|
||||
android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission
|
||||
android:name="android.permission.WRITE_SETTINGS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<!-- 允许程序获取网络状态 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<!-- 用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<!-- 允许程序访问WiFi网络信息 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<!-- 允许程序读写手机状态和身份 -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<!-- 允许程序访问CellID或WiFi热点来获取粗略的位置 -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<!--后台获取位置信息,若需后台定位则必选-->
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<!--用于申请调用A-GPS模块,卫星定位加速-->
|
||||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||
<!-- 通常不需要专门权限播放通知铃声,但如果要震动等可加上 -->
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<!--从Android 11开始,需要在AndroidManifest.xml清单文件中加入query权限申请,
|
||||
才能检测到手机上安装的三方应用包安装状态,在主工程的AndroidManifest.xml 中增加标签,即可解决以上影响,代码如下:-->
|
||||
<queries>
|
||||
<package android:name="com.tencent.mm" />
|
||||
<package android:name="com.tencent.mobileqq" />
|
||||
<package android:name="com.sina.weibo" />
|
||||
<intent>
|
||||
<action android:name="com.hihonor.push.action.BIND_PUSH_SERVICE" />
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<!--icon_app_icon/icon_app_logo_ai-->
|
||||
<application
|
||||
android:name="com.ckkj.water.MyApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher"
|
||||
android:requestLegacyExternalStorage="true"
|
||||
android:theme="@style/custom_app_theme"
|
||||
android:supportsRtl="true"
|
||||
android:hardwareAccelerated="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
<!-- 高德地图 -->
|
||||
<meta-data android:name="com.amap.api.v2.apikey" android:value="a91364c6bbc2f5c773a949926fae7fb6">
|
||||
</meta-data>
|
||||
<!-- 表示当前项目已经适配了分区存储特性 -->
|
||||
<meta-data
|
||||
android:name="ScopedStorage"
|
||||
android:value="true" />
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.guide.LaunchActivity"
|
||||
android:theme="@style/AppTheme.FullScreen"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="com.ckkj.water.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_provider_paths"
|
||||
tools:replace="android:resource"/>
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.imagepicker.provider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/file_provider_paths_img"
|
||||
tools:replace="android:resource"/>
|
||||
</provider>
|
||||
<activity
|
||||
android:name="com.ckkj.water.custom.view.PhotoViewActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity android:name="com.yalantis.ucrop.UCropActivity"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.main.activity.MainActivity"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.chat.ChatHistoryActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.login.LoginActivity"
|
||||
android:theme="@style/AppTheme.FullScreen"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.mine.WebviewUserAgreement"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.mine.SettingsActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.mine.ChangePhoneActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.mine.UserLogOffAccountActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.guide.GuideActivity"
|
||||
android:theme="@style/AppTheme.FullScreen"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name="com.ckkj.water.mine.RewardRecordsActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.login.RegisterActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.login.RegisterSuccessActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.login.ForgetPasswordActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.permission.PermissionActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.device.AddDeviceActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
<activity
|
||||
android:name="com.ckkj.water.device.SelectWifiActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.maning.mlkitscanner.scan.ui.ScanPreviewActivity"
|
||||
android:theme="@style/ScanTheme"
|
||||
tools:replace="android:theme"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.device.DeviceConnectActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.device.DeviceReNameActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.device.DeviceControlActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.device.DeviceSettingsActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.device.DeviceInfoActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.plan.AddWaterPlanActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.plan.PlanDetailActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.mine.MineInfomationActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
<activity
|
||||
android:name="com.ckkj.water.mine.PsdManageActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
BIN
app/src/main/assets/iflytek/recognize.xml
Normal file
BIN
app/src/main/assets/iflytek/recognize.xml
Normal file
Binary file not shown.
BIN
app/src/main/assets/iflytek/voice_bg.9.png
Normal file
BIN
app/src/main/assets/iflytek/voice_bg.9.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
app/src/main/assets/iflytek/voice_empty.png
Normal file
BIN
app/src/main/assets/iflytek/voice_empty.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/assets/iflytek/voice_full.png
Normal file
BIN
app/src/main/assets/iflytek/voice_full.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/assets/iflytek/waiting.png
Normal file
BIN
app/src/main/assets/iflytek/waiting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/assets/iflytek/warning.png
Normal file
BIN
app/src/main/assets/iflytek/warning.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
19992
app/src/main/assets/lunar_1800_2099.json
Normal file
19992
app/src/main/assets/lunar_1800_2099.json
Normal file
File diff suppressed because it is too large
Load Diff
13386
app/src/main/assets/lunar_1899_2099.json
Normal file
13386
app/src/main/assets/lunar_1899_2099.json
Normal file
File diff suppressed because it is too large
Load Diff
131724
app/src/main/assets/lunar_calendar.json
Normal file
131724
app/src/main/assets/lunar_calendar.json
Normal file
File diff suppressed because it is too large
Load Diff
200
app/src/main/assets/nongli-1.json
Normal file
200
app/src/main/assets/nongli-1.json
Normal file
@@ -0,0 +1,200 @@
|
||||
[{"year":"1901","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1902","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1903","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":"1","isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1904","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1905","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1906","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"4","isRun":"1","isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1907","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1908","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1909","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"2","isRun":1,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1910","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1911","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"6","isRun":1,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1912","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1913","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1914","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":1,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1915","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1916","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1917","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"2","isRun":1,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1918","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1919","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"7","isRun":1,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1920","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1921","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1922","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":1,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1923","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1924","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1925","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"4","isRun":1,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1926","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1927","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1928","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"2","isRun":1,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1929","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1930","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"6","isRun":1,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1931","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1932","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1933","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"5","isRun":1,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1934","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1935","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1936","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"3","isRun":1,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1937","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1938","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"7","isRun":1,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1939","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1940","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1941","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1942","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1943","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1944","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"4","isRun":1,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1945","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1946","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1947","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"2","isRun":1,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1948","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1949","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"7","isRun":1,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1950","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1951","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1952","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":1,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1953","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1954","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1955","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"3","isRun":1,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1956","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1957","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"8","isRun":1,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1958","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1959","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1960","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1961","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1962","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1963","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1964","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1965","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1966","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"3","isRun":1,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1967","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1968","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"7","isRun":1,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1969","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1970","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1971","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"5","isRun":1,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1972","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1973","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1974","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1975","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1976","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"8","isRun":1,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1977","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1978","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1979","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"6","isRun":1,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1980","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1981","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1982","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1983","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1984","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"10","isRun":1,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1985","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1986","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1987","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1988","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1989","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1990","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"5","isRun":1,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1991","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1992","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1993","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"3","isRun":1,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1994","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1995","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"8","isRun":1,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1996","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1997","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"1998","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":1,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"1999","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2000","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2001","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2002","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2003","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2004","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"2","isRun":1,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2005","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2006","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"7","isRun":1,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2007","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2008","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2009","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"5","isRun":1,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2010","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2011","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2012","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2013","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2014","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"9","isRun":1,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2015","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2016","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2017","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2018","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2019","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2020","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2021","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2022","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2023","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"2","isRun":1,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2024","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2025","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"6","isRun":1,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2026","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2027","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2028","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"5","isRun":1,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2029","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2030","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2031","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"3","isRun":1,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2032","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2033","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"11","isRun":1,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2034","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2035","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2036","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"6","isRun":1,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2037","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2038","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2039","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"5","isRun":1,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2040","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2041","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2042","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"2","isRun":1,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2043","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2044","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"7","isRun":1,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2045","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2046","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2047","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":1,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2048","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2049","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2050","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"3","isRun":1,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2051","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2052","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"8","isRun":1,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2053","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2054","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2055","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2056","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2057","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2058","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2059","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2060","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2061","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"3","isRun":1,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2062","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2063","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"7","isRun":1,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2064","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2065","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2066","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":1,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2067","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2068","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2069","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2070","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2071","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"8","isRun":1,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2072","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2073","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2074","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2075","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2076","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2077","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2078","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2079","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2080","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"3","isRun":1,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2081","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2082","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"7","isRun":1,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2083","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2084","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2085","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"5","isRun":1,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2086","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2087","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2088","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2089","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2090","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"8","isRun":1,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2091","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2092","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2093","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":0},{"name":"6","isRun":1,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2094","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2095","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2096","month":[{"name":"1","isRun":0,"isAllDay":0},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"4","isRun":1,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":0},{"name":"10","isRun":0,"isAllDay":1},{"name":"11","isRun":0,"isAllDay":0},{"name":"12","isRun":0,"isAllDay":1}]},
|
||||
{"year":"2097","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"3","isRun":0,"isAllDay":1},{"name":"4","isRun":0,"isAllDay":0},{"name":"5","isRun":0,"isAllDay":1},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2098","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":0},{"name":"8","isRun":0,"isAllDay":1},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":0}]},
|
||||
{"year":"2099","month":[{"name":"1","isRun":0,"isAllDay":1},{"name":"2","isRun":0,"isAllDay":0},{"name":"2","isRun":1,"isAllDay":1},{"name":"3","isRun":0,"isAllDay":0},{"name":"4","isRun":0,"isAllDay":1},{"name":"5","isRun":0,"isAllDay":0},{"name":"6","isRun":0,"isAllDay":1},{"name":"7","isRun":0,"isAllDay":1},{"name":"8","isRun":0,"isAllDay":0},{"name":"9","isRun":0,"isAllDay":1},{"name":"10","isRun":0,"isAllDay":0},{"name":"11","isRun":0,"isAllDay":1},{"name":"12","isRun":0,"isAllDay":1}]}
|
||||
]
|
||||
2680
app/src/main/assets/yfj_city_info.json
Normal file
2680
app/src/main/assets/yfj_city_info.json
Normal file
File diff suppressed because it is too large
Load Diff
119
app/src/main/java/com/ckkj/water/AppConfig.java
Normal file
119
app/src/main/java/com/ckkj/water/AppConfig.java
Normal file
@@ -0,0 +1,119 @@
|
||||
package com.ckkj.water;
|
||||
|
||||
public class AppConfig {
|
||||
|
||||
|
||||
|
||||
/**************************生产*******************************/
|
||||
// public static String BASE_URL = "https://www.mingdengbazi.site/";//测试【http://114.55.12.112/】,,【https://www.mingdengbazi.site/】
|
||||
// public static String BASE_URL_TWO = BASE_URL;//测试
|
||||
// public static String BASE_URL_THREE = BASE_URL;//测试
|
||||
// public static boolean IS_TEST_REQUEST = false;
|
||||
|
||||
|
||||
/**************************测试*******************************/
|
||||
// public static String BASE_URL = "http://47.106.83.229:8081/";//测试http://47.106.83.166:8001/
|
||||
// public static String BASE_URL_TWO = BASE_URL;//测试
|
||||
// public static String BASE_URL_THREE = BASE_URL;//测试
|
||||
// public static boolean IS_TEST_REQUEST = true;
|
||||
|
||||
/**************************本地*******************************/
|
||||
public static String BASE_URL = "http://192.168.1.67:8081/";//测试
|
||||
public static String BASE_URL_TWO = BASE_URL;//测试
|
||||
public static String BASE_URL_THREE = BASE_URL;//测试
|
||||
public static boolean IS_TEST_REQUEST = true;
|
||||
|
||||
|
||||
/**************************生产*******************************/
|
||||
//
|
||||
// public static String BASE_URL = "https://gw.dingdingche.net/";//测试
|
||||
// public static String BASE_URL_TWO = "https://gw.dingdingche.net/";//测试
|
||||
// public static String BASE_URL_THREE = "https://gw.dingdingche.net/";//测试
|
||||
// public static String BASE_URL_LOCAL = "http://192.168.100.234:48080";//大宗测试
|
||||
// public static String RONGCLOUD_APPKEY = "n19jmcy5nh7s9";//融云通信AppKey
|
||||
// public static String KKFILE_PREVIEW_URL = "";//文件kkFile拼接预览
|
||||
// public static String SERVICE_WEB_URL = "https://mro.jkmass.com/testService?token=";//测试
|
||||
// public static boolean IS_TEST_REQUEST = false;
|
||||
|
||||
|
||||
public static boolean USER_CONFIRM_UPDATE_APP = false;
|
||||
//生成订单相关
|
||||
/**************************生产******************************/
|
||||
// public static String BASE_URL = "http://192.168.10.28:8083";//测试
|
||||
////用于登录页面便捷切换账号
|
||||
public final static boolean APP_TEST_FLAG = true;
|
||||
//App权限验证码
|
||||
public static String APP_ENTER_CODE = "";
|
||||
public static String USER_TOKEN = "";
|
||||
public static int MEMBER_ID = 0;
|
||||
//是否登录
|
||||
public static boolean USER_LOGIN = false;
|
||||
//用户是否设置了生辰八字
|
||||
public static boolean USER_SET_BIRTH_INFO = false;
|
||||
//用户头像
|
||||
public static String USER_INFO_AVATAR = "";
|
||||
//手机号验证码登录
|
||||
public static final int MEMBER_LOGIN = 2;
|
||||
//缘份居 API 调用的 key
|
||||
public static String YUANFENJU_API_KEY = "utEK5Kbx2JSkZqnlKypyuz1DK";//公司
|
||||
// public static String YUANFENJU_API_KEY = "jLCpL92dL8pPh2C9F4rfBattZ";//个人
|
||||
//密码校验正则/
|
||||
public static final String PSD_REGEX = "^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z\\d]{8,20}$";
|
||||
//高德地图 AppKey
|
||||
public static String GAODE_MAP_APP_KEY = "a91364c6bbc2f5c773a949926fae7fb6";//个人
|
||||
//友盟相关
|
||||
public static String UMENG_APP_KEY = "6709d097667bfe33f3be702e";
|
||||
/**************************支付宝相关******************************/
|
||||
//支付宝Appid
|
||||
public static final String ALIPAY_APPID = "9021000137698324";
|
||||
//用于支付宝账户登录授权业务的入参 pid。
|
||||
public static final String PID = "2088721037230300";
|
||||
/**************************字典相关******************************/
|
||||
//缓存商品单位的json
|
||||
public static String PRODUCT_UNIT_JSON = "";
|
||||
//缓存商品品牌的json
|
||||
public static String PRODUCT_BRAND_JSON = "";
|
||||
public static String WX_APPID = "wx66c35bc33549040a";
|
||||
|
||||
|
||||
//融云回话token
|
||||
public static String RONG_CLOUD_TALK_TOKEN = "";
|
||||
//用户userID,,不可见
|
||||
public static String USER_ID = "";
|
||||
//用户融云ID
|
||||
public static String USER_RONGCLOUD_ID = "";
|
||||
//阿里云配置相关
|
||||
public static String ALIYUN_ENDPOINT = "https://oss-cn-nanjing.aliyuncs.com";
|
||||
public static String ALIYUN_BUCKETNAME = "mdbz";
|
||||
//上传type
|
||||
public static final int UPLOAD_TYPE_100 = 100;//暂用于头像
|
||||
public static final int UPLOAD_TYPE_200 = 200;//暂用于车圈
|
||||
public static final int UPLOAD_TYPE_300 = 300;//暂用于车圈
|
||||
public static final int UPLOAD_TYPE_400 = 400;//暂用于反馈客服
|
||||
//汽车品牌在阿里云的地址
|
||||
public static String ALI_OSS_CAR_BRAND_LOGO = "https://oss.mingdengbazi.site/";
|
||||
//验证码使用场景值
|
||||
//登录
|
||||
public static String SMS_CODE_TYPE_LOGIN = "login";
|
||||
//注册
|
||||
public static String SMS_CODE_TYPE_REGISTER = "1";
|
||||
//修改手机号
|
||||
public static String SMS_CODE_TYPE_CHANGE_PHONE = "modify";
|
||||
//注销账号
|
||||
public static String SMS_CODE_TYPE_LOG_OFF = "cancel";
|
||||
//绑定支付宝
|
||||
public static String SMS_CODE_TYPE_BIND_ALIPAY = "4";
|
||||
//当前车圈筛选的值 0 全部 ;1 求购;2 出售
|
||||
public static String CURRENT_CAR_CIRCLE_OPTION_CODE = "0";
|
||||
//邀请页面注册页面的 url
|
||||
public static String INVITE_REGIST_URL = "https://esca.dingdingche.net/H5/index.html?";
|
||||
//测试使用 token
|
||||
public static String TEST_USER_ID = "1897194667309666304";
|
||||
//用户协议
|
||||
public static String USER_AGREEMENT = "https://sta.mingdengbazi.site/yhxy.html";
|
||||
//隐私政策
|
||||
public static String USER_PRIVACY = "https://sta.mingdengbazi.site/ysxy.html";
|
||||
//用户分享链接
|
||||
public static String USER_SHARE_URL = "https://sta.mingdengbazi.site/on/index.html?code=";
|
||||
|
||||
}
|
||||
118
app/src/main/java/com/ckkj/water/ConstantUtil.java
Normal file
118
app/src/main/java/com/ckkj/water/ConstantUtil.java
Normal file
@@ -0,0 +1,118 @@
|
||||
package com.ckkj.water;
|
||||
|
||||
/**
|
||||
* @author messi.mo
|
||||
* date:2019/7/30.
|
||||
* describe:常量池
|
||||
*/
|
||||
|
||||
public class ConstantUtil {
|
||||
//页面跳转来源
|
||||
public static final String ACTIVITY_NAVIGATE_FLAG = "activity_navigate_flag";
|
||||
|
||||
public static final String SHARE_PRE_NAME = "mingdengbazi_pre";
|
||||
public static final String FIRST_ENTER_APP_AGREEMENT_TIPS = "first_enter_app_agreement_tips";
|
||||
public static final String FIRST_ENTER_APP_FLAG = "first_enter_app_flag";
|
||||
public static final String USER_LOGIN = "user_login";
|
||||
public static final String USER_TOKEN = "user_token";
|
||||
public static final String USER_HAS_SET_BIRTH = "user_has_set_birth";
|
||||
public static final String USER_RONGCLOUD_TOKEN = "user_rongcloud_token";
|
||||
public static final String USER_ID = "user_id";
|
||||
public static final String USER_RONGCLOUD_ID = "user_rongcloud_id";
|
||||
public static final String USER_INFO_JSON_CONTENT = "user_info_json_content";
|
||||
public static final String SEARCH_HISTORY = "search_history";
|
||||
public static final String USER_CONFIRM_UPLOAD_INFO = "user_confirm_upload_info";
|
||||
public static final String GROUP_LAST_TIME = "group_last_time";
|
||||
//用户是否同意隐私政策
|
||||
public static final String PRIVACY_POLICY_AGREED = "privacy_policy_agreed";
|
||||
//App访问验证code
|
||||
public static final String APP_ENTER_CODE_VALUE = "app_enter_code_value";
|
||||
//用户是否允许定位授权
|
||||
public static final String USER_AUTH_LOCATION = "user_auth_location";
|
||||
//用户是否请求过定位权限
|
||||
public static final String USER_REQUEST_LOCATION_PERMISSION = "user_request_location_permission";
|
||||
//用户是否请求过文件访问权限
|
||||
public static final String USER_REQUEST_READ_WRITE_PERMISSION = "user_request_read_write_permission";
|
||||
//用户是否请求过麦克风权限
|
||||
public static final String USER_REQUEST_RECORD_AUDIO_PERMISSION = "user_request_record_audio_permission";
|
||||
//用户是否请求过相机权限
|
||||
public static final String USER_REQUEST_CAMERA_PERMISSION = "user_request_camera_permission";
|
||||
//用户当前定位省份
|
||||
public static final String USER_LOCATION_PROVICE_NAME = "user_location_provice_name";
|
||||
//用户当前定位城市
|
||||
public static final String USER_LOCATION_CITY_NAME = "user_location_city_name";
|
||||
//用户当前定位县区
|
||||
public static final String USER_LOCATION_COUNTY_NAME = "user_location_county_name";
|
||||
|
||||
public static final String USER_SELECT_PROVICE_NAME = "user_select_provice_name";
|
||||
//用户当前定位城市
|
||||
public static final String USER_SELECT_CITY_NAME = "user_select_city_name";
|
||||
//用户当前定位县区
|
||||
public static final String USER_SELECT_COUNTY_NAME = "user_select_county_name";
|
||||
//首页用户定位code
|
||||
public static final String INDEX_LOCATION_PROVINCE_CODE = "index_location_province_code";
|
||||
//用户当前定位县区
|
||||
public static final String INDEX_LOCATION_CITY_CODE = "index_location_city_code";
|
||||
//首页用户定位code
|
||||
public static final String INDEX_SELECT_PROVINCE_CODE = "index_select_province_code";
|
||||
//用户当前定位县区
|
||||
public static final String INDEX_SELECT_CITY_CODE = "index_select_city_code";
|
||||
//用户提交的企业会员认证结果
|
||||
public static final String USER_REVIEW_STATUS_CODE = "user_review_status_code";
|
||||
//用户是否为企业会员
|
||||
public static final String USER_IS_VIP_FLAG = "user_is_vip_flag";
|
||||
//用户资料中的个人手机号码
|
||||
public static final String USER_INFO_PHONE_NUMBER = "user_info_phone_number";
|
||||
//用户资料中头像
|
||||
public static final String USER_INFO_AVATAR = "user_info_avatar";
|
||||
//用户资料昵称
|
||||
public static final String USER_NICKNAME = "user_nickname";
|
||||
//企业名称
|
||||
public static final String USER_UPLOAD_COMPANY_NAME = "user_upload_company_name";
|
||||
//单位名称
|
||||
public static final String GOODS_UNIT_JSON = "goods_unit_json";
|
||||
//运费json
|
||||
public static final String TRANS_COST_JSON = "trans_cost_json";
|
||||
//品牌名称json
|
||||
public static final String GOODS_BRAND_JSON = "goods_brand_json";
|
||||
//所有字典
|
||||
public static final String MRO_BRAND_DICT_JSON = "mro_dict_json";
|
||||
/********************大宗相关*********************/
|
||||
public static final String DICT_DATAS_JSON = "dict_datas_json";
|
||||
//生成订单来自何处 100商品详情 200购物车
|
||||
public static final int CREAT_ORDER_FROM_PRODUCT_CODE = 100;
|
||||
public static final int CREAT_ORDER_FROM_SHOPCAR_CODE = 200;
|
||||
/********************订单相关*********************/
|
||||
public static final int ORDER_ALLCODE = -1;//全部
|
||||
public static final int ORDER_DAIZHIFU = 0;//待支付
|
||||
public static final int ORDER_WEIFAHUO = 1;//未发货
|
||||
public static final int ORDER_DAISHOUHUO = 2;//待收货
|
||||
public static final int ORDER_YIWANCHENG = 3;//已完成
|
||||
public static final int ORDER_CANCELED = 4;
|
||||
public static final int ORDER_SHOUHOU = 5;//待收货
|
||||
public static final int ORDER_BUFENFAHUO = 7;//待收货
|
||||
public static final int ORDER_DAIQUEREN = 8;//待确认
|
||||
public static final int ORDER_JIESUANZHONG = 9;//结算中
|
||||
public static final int ORDER_CHULIZHONG = 0;//处理中
|
||||
|
||||
/*******询价单********/
|
||||
public static final int XJ_BAOJIAZHONG_CODE = 0;//报价中
|
||||
public static final int XJ_YIBAOJIA_CODE = 1;//已报价
|
||||
public static final int XJ_YICHEXIAO_CODE = 2;//已撤销
|
||||
//权限申请请求
|
||||
public static final int PERMISSION_QUEST = 500;
|
||||
/***************权限相关*******************/
|
||||
//地址
|
||||
public static final int ACCESS_FINE_LOCATION = 1;
|
||||
//授权读取文件
|
||||
public static final int WRITE_FILE_PERMISSON_CPDE = 1001;
|
||||
//读取文件
|
||||
public static final int READ_EXTERNAL_STORAGE = 2;
|
||||
//相机权限
|
||||
public static final int CAMERA_AUTH_CODE = 1003;
|
||||
//快速下单,下载模板到手机
|
||||
public static final int DOWN_TEMPLATE_CODE = 1004;
|
||||
|
||||
|
||||
|
||||
}
|
||||
62
app/src/main/java/com/ckkj/water/EventMessage.java
Normal file
62
app/src/main/java/com/ckkj/water/EventMessage.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.ckkj.water;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* eventbus回调
|
||||
*/
|
||||
public class EventMessage {
|
||||
|
||||
public static final String DATA_REFRESH_EVENT = "data_refresh_event";
|
||||
public static final String USER_LOGIN_LOST = "user_login_lost";
|
||||
public static final String CODE_LOGIN_LOST = "code_login_lost";
|
||||
public static final String WX_PAY_SUCCESS = "wx_pay_success";
|
||||
public static final String USER_LOGIN_SUCCESS = "user_login_success";
|
||||
public static final String HISTORY_SESSIONID_DELETE_SUCCESS = "history_sessionid_delete_success";
|
||||
public static final String SWITCH_TO_FATE_FRAGMENT = "switch_to_fate_fragment";
|
||||
public int result_code;
|
||||
public String eventStrKey;
|
||||
public String msg;
|
||||
|
||||
|
||||
public String getEventStrKey() {
|
||||
return eventStrKey;
|
||||
}
|
||||
|
||||
public void setEventStrKey(String eventStrKey) {
|
||||
this.eventStrKey = eventStrKey;
|
||||
}
|
||||
|
||||
public EventMessage(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
|
||||
public EventMessage(String eventStr, String msg) {
|
||||
this.eventStrKey = eventStr;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public EventMessage(int result_code, String msg) {
|
||||
this.result_code = result_code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public int getResult_code() {
|
||||
return result_code;
|
||||
}
|
||||
|
||||
public void setResult_code(int result_code) {
|
||||
this.result_code = result_code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
187
app/src/main/java/com/ckkj/water/MyApplication.java
Normal file
187
app/src/main/java/com/ckkj/water/MyApplication.java
Normal file
@@ -0,0 +1,187 @@
|
||||
package com.ckkj.water;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.ckkj.water.fate.util.LunarDateLoader;
|
||||
import com.ckkj.water.login.entity.LoginEntity;
|
||||
import com.ckkj.water.network.NetWorkManager;
|
||||
import com.ckkj.water.utils.dataUtil.SharePreUtil;
|
||||
import com.ckkj.water.utils.manager.MingDengUserInfoManager;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.jessyan.autosize.AutoSizeConfig;
|
||||
|
||||
public class MyApplication extends Application {
|
||||
private static Context context;
|
||||
private static Activity mLaunchActivity;
|
||||
private static Activity currentActivity;
|
||||
private static MyApplication instance;
|
||||
private String TAG = "DINGDINGCAR-----";
|
||||
//口令跳转
|
||||
public static boolean hasJumped = false;
|
||||
|
||||
public static void setCurrentActivity(Activity activity) {
|
||||
mLaunchActivity = activity;
|
||||
}
|
||||
|
||||
public static Activity getLaunchActivity() {
|
||||
return mLaunchActivity;
|
||||
}
|
||||
|
||||
public static synchronized boolean canJump() {
|
||||
if (!hasJumped) {
|
||||
hasJumped = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void initializeUmengSDK(){
|
||||
//预初始化
|
||||
// UMConfigure.preInit(context, AppConfig.UMENG_APP_KEY, "Android");
|
||||
// UMConfigure.init(this,"5a12384aa40fa3551f0001d1"
|
||||
// ,"umeng",UMConfigure.DEVICE_TYPE_PHONE,"");
|
||||
// //日志开关
|
||||
// UMConfigure.setLogEnabled(true);
|
||||
// //科大讯飞 该段初始化代码必须要放在用户还同意隐私协议政策之后
|
||||
// // 将“12345678”替换成您申请的APPID,申请地址:http://www.xfyun.cn
|
||||
// // 请勿在“=”与appid之间添加任何空字符或者转义符
|
||||
// SpeechUtility.createUtility(context, SpeechConstant.APPID +"=322c51d1");
|
||||
//初始化厂商推送
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
instance = this;
|
||||
context = getApplicationContext();
|
||||
// 异步预加载农历数据缓存
|
||||
LunarDateLoader.preloadLunarJson(this);
|
||||
|
||||
boolean isUserAgreed = SharePreUtil.getBoolean(ConstantUtil.SHARE_PRE_NAME,context,ConstantUtil.PRIVACY_POLICY_AGREED);
|
||||
if(isUserAgreed){
|
||||
initializeUmengSDK();
|
||||
}
|
||||
NetWorkManager.getInstance().init(this);
|
||||
AppConfig.USER_LOGIN = SharePreUtil.getBoolean(ConstantUtil.SHARE_PRE_NAME,context,ConstantUtil.USER_LOGIN);
|
||||
AppConfig.USER_TOKEN = SharePreUtil.getString(ConstantUtil.SHARE_PRE_NAME,context,ConstantUtil.USER_TOKEN);
|
||||
AppConfig.USER_SET_BIRTH_INFO = SharePreUtil.getBoolean(ConstantUtil.SHARE_PRE_NAME,context,ConstantUtil.USER_HAS_SET_BIRTH);
|
||||
//单位JSON
|
||||
AppConfig.PRODUCT_UNIT_JSON = SharePreUtil.getString(ConstantUtil.SHARE_PRE_NAME,context,ConstantUtil.GOODS_UNIT_JSON);
|
||||
AppConfig.PRODUCT_BRAND_JSON = SharePreUtil.getString(ConstantUtil.SHARE_PRE_NAME,context,ConstantUtil.GOODS_BRAND_JSON);
|
||||
AppConfig.USER_ID = SharePreUtil.getString(ConstantUtil.SHARE_PRE_NAME,context, ConstantUtil.USER_ID);
|
||||
String userInfoJson = SharePreUtil.getString(ConstantUtil.SHARE_PRE_NAME,context, ConstantUtil.USER_INFO_JSON_CONTENT);
|
||||
if(!TextUtils.isEmpty(userInfoJson)){
|
||||
LoginEntity entity = new Gson().fromJson(userInfoJson, LoginEntity.class);
|
||||
MingDengUserInfoManager.getInstance().setEntity(entity);
|
||||
MingDengUserInfoManager.getInstance().setUserInfo(entity.getUser_info());
|
||||
}
|
||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||
@Override
|
||||
public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStarted(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResumed(@NonNull Activity activity) {
|
||||
if(activity != null){
|
||||
Log.i("currentAct", "当前所在页面===============" + activity.getLocalClassName()+ "=======================");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityStopped(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(@NonNull Activity activity) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||
@Override
|
||||
public void onActivityResumed(Activity activity) {
|
||||
currentActivity = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityPaused(Activity activity) {
|
||||
if (currentActivity == activity) {
|
||||
currentActivity = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 其他回调方法可以留空
|
||||
@Override
|
||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
||||
currentActivity = activity;
|
||||
}
|
||||
@Override
|
||||
public void onActivityStarted(Activity activity) {
|
||||
currentActivity = activity;
|
||||
}
|
||||
@Override
|
||||
public void onActivityStopped(Activity activity) {}
|
||||
@Override
|
||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {}
|
||||
});
|
||||
|
||||
AutoSizeConfig.getInstance()
|
||||
// 是否使用设备真实尺寸
|
||||
.setUseDeviceSize(true)
|
||||
// 是否支持 fragment
|
||||
.setCustomFragment(true);
|
||||
}
|
||||
|
||||
private boolean shouldInit() {
|
||||
ActivityManager am = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
|
||||
List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
|
||||
String mainProcessName = getApplicationInfo().processName;
|
||||
int myPid = android.os.Process.myPid();
|
||||
for (ActivityManager.RunningAppProcessInfo info : processInfos) {
|
||||
if (info.pid == myPid && mainProcessName.equals(info.processName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static Activity getCurrentActivity() {
|
||||
return instance.currentActivity;
|
||||
}
|
||||
|
||||
public static Context getContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.ckkj.water.adapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 作者 fjw
|
||||
* 日期 2025/3/7
|
||||
*/
|
||||
public class ViewPageAdapter extends FragmentStateAdapter {
|
||||
|
||||
private List<Fragment> list;
|
||||
|
||||
public ViewPageAdapter(@NonNull FragmentActivity fragmentActivity,
|
||||
List<Fragment> fragmentList) {
|
||||
super(fragmentActivity);
|
||||
list = fragmentList;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Fragment createFragment(int position) {
|
||||
return list.get(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return list.size();
|
||||
}
|
||||
}
|
||||
1116
app/src/main/java/com/ckkj/water/base/BaseActivity.java
Normal file
1116
app/src/main/java/com/ckkj/water/base/BaseActivity.java
Normal file
File diff suppressed because it is too large
Load Diff
440
app/src/main/java/com/ckkj/water/base/BaseActivityNoP.java
Normal file
440
app/src/main/java/com/ckkj/water/base/BaseActivityNoP.java
Normal file
@@ -0,0 +1,440 @@
|
||||
package com.ckkj.water.base;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.ckkj.water.ConstantUtil;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.dialog.LoadingDialog;
|
||||
import com.ckkj.water.receiver.NetworkChangeReceiver;
|
||||
import com.ckkj.water.utils.manager.ActivityManager;
|
||||
import com.ckkj.water.utils.permissions.PermissionUtils;
|
||||
import com.ckkj.water.utils.show.ToastUtil;
|
||||
import com.ckkj.water.utils.text.TextUtil;
|
||||
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 所有activity基类
|
||||
*/
|
||||
|
||||
@SuppressWarnings({ "unchecked" }) public abstract class BaseActivityNoP<T extends ViewBinding>
|
||||
extends RxAppCompatActivity implements IView {
|
||||
//P层主导
|
||||
protected Dialog loadingDialog;
|
||||
private NetworkChangeReceiver receiver;
|
||||
public static IView iView;
|
||||
public TextView tipTextView;
|
||||
protected T viewBinding;
|
||||
protected BaseActivityNoP mContext;
|
||||
|
||||
@Override protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
try {
|
||||
mContext = this;
|
||||
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
|
||||
Class cls = (Class) type.getActualTypeArguments()[0];
|
||||
Method inflate = cls.getDeclaredMethod("inflate", LayoutInflater.class);
|
||||
viewBinding = (T) inflate.invoke(null, getLayoutInflater());
|
||||
setContentView(viewBinding.getRoot());
|
||||
//在界面初始化之前初始化窗口
|
||||
initWindows();
|
||||
int layoutResID = getLayoutResId(savedInstanceState);
|
||||
if (layoutResID != 0) {
|
||||
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
|
||||
// setContentView(layoutResID);
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
initWidget();
|
||||
initData(savedInstanceState);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化窗口
|
||||
*/
|
||||
protected void initWindows() {
|
||||
//StatusBarUtils.setWindowStatusBarColor(this, R.color.color_blue01);
|
||||
// StatusBarUtil.setAndroidNativeLightStatusBar(this, true);
|
||||
}
|
||||
|
||||
protected void initWidget() {
|
||||
ActivityManager.addActivity(this, this.getClass().getName());
|
||||
iView = this;
|
||||
if (receiver == null) {
|
||||
receiver = new NetworkChangeReceiver();
|
||||
}
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
@Override protected void onDestroy() {
|
||||
unregisterReceiver(receiver);
|
||||
hideDialogLoading();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/***
|
||||
* 关闭等待页面
|
||||
*/
|
||||
public void hideDialogLoading() {
|
||||
LoadingDialog dialog = mLoadingDialog;
|
||||
try {
|
||||
if (dialog != null && mContext != null) {
|
||||
mLoadingDialog = null;
|
||||
dialog.dismiss();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//每个activity都需要创建setLayoutId
|
||||
public abstract int getLayoutResId(Bundle savedInstanceState);
|
||||
|
||||
public void initData(Bundle savedInstanceState) {
|
||||
createLoadingDialog(this, "加载中...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 模拟显示加载对话框
|
||||
*/
|
||||
@Override public void showLoading() {
|
||||
loadingDialog.show();
|
||||
}
|
||||
|
||||
//模拟处理统一的数据
|
||||
@Override public void handleError(Exception e) {
|
||||
e.printStackTrace();
|
||||
hideLoading();
|
||||
showMessage(e.getMessage());
|
||||
}
|
||||
|
||||
@Override public void hideLoading() {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
|
||||
@Override public void showMessage(String message) {
|
||||
ToastUtil.showShort(this, message);
|
||||
}
|
||||
|
||||
//加载进度
|
||||
protected void createLoadingDialog(Context context, String msg) {
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
@SuppressLint("InflateParams") View v = inflater.inflate(R.layout.dialog_loading, null);
|
||||
|
||||
LinearLayout layout = (LinearLayout) v.findViewById(R.id.dialog_loading_view);
|
||||
tipTextView = (TextView) v.findViewById(R.id.tipTextView);
|
||||
tipTextView.setText(msg);
|
||||
ImageView imgLoading = v.findViewById(R.id.img_loading);
|
||||
loadingDialog = new Dialog(context, R.style.MyDialogStyle);
|
||||
loadingDialog.setCanceledOnTouchOutside(false);
|
||||
loadingDialog.setContentView(layout,
|
||||
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT));
|
||||
Window window = loadingDialog.getWindow();
|
||||
if (window != null) {
|
||||
WindowManager.LayoutParams lp = window.getAttributes();
|
||||
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
window.setGravity(Gravity.CENTER);
|
||||
window.setAttributes(lp);
|
||||
window.setWindowAnimations(R.style.PopWindowAnimStyle);
|
||||
}
|
||||
loadingDialog.setCanceledOnTouchOutside(false);
|
||||
}
|
||||
|
||||
|
||||
protected LoadingDialog mLoadingDialog;
|
||||
public void showLoadingDialog() {
|
||||
LoadingDialog dialog = mLoadingDialog;
|
||||
if (dialog == null&& mContext != null) {
|
||||
dialog = new LoadingDialog(mContext);
|
||||
// 不可触摸取消
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
// 强制取消关闭界面
|
||||
dialog.setCancelable(true);
|
||||
dialog.setOnCancelListener(dialog1 -> finish());
|
||||
mLoadingDialog = dialog;
|
||||
} else {
|
||||
dialog.dismiss();
|
||||
}
|
||||
if (dialog != null && mContext != null) {
|
||||
try {
|
||||
dialog.show();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override public void onNetChange(int netModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
View view = getCurrentFocus();
|
||||
TextUtil.hideKeyboard(ev, view, this);//调用方法判断是否需要隐藏键盘
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return super.dispatchTouchEvent(ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* activity跳转
|
||||
*/
|
||||
protected void goTo(Context from, Class<? extends BaseActivityNoP> to, Bundle data) {
|
||||
Intent i = new Intent();
|
||||
i.setClass(from, to);
|
||||
if (data != null) i.putExtras(data);
|
||||
from.startActivity(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* activity跳转
|
||||
*/
|
||||
protected void goToWihoutNoBase(Context from, Class<? extends Activity> to, Bundle data) {
|
||||
Intent i = new Intent();
|
||||
i.setClass(from, to);
|
||||
if (data != null) i.putExtras(data);
|
||||
from.startActivity(i);
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转返回值
|
||||
*/
|
||||
protected void goToForResult(Context from, Class<? extends BaseActivityNoP> to, int questCode,
|
||||
Bundle bundle) {
|
||||
Intent i = new Intent();
|
||||
i.setClass(from, to);
|
||||
if (bundle != null) i.putExtras(bundle);
|
||||
startActivityForResult(i, questCode);
|
||||
}
|
||||
|
||||
protected void requestPermission(String... permissions) {
|
||||
if (PermissionUtils.isPermissionsGranted(this, ConstantUtil.PERMISSION_QUEST, permissions)) {
|
||||
Log.d("permission", "all");
|
||||
nextStep();
|
||||
}
|
||||
}
|
||||
|
||||
public void noAllowPermission() {
|
||||
|
||||
}
|
||||
|
||||
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
switch (requestCode) {
|
||||
case ConstantUtil.PERMISSION_QUEST:
|
||||
if (PermissionUtils.verifyPermissions(grantResults)) {
|
||||
nextStep();
|
||||
}else {
|
||||
noAllowPermission();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnDialogClick {
|
||||
void onCancelClick();
|
||||
void onConfirmClisk();
|
||||
void onView1Click();
|
||||
}
|
||||
|
||||
/**+
|
||||
*
|
||||
* @param title 标题
|
||||
* @param content 提示内容
|
||||
* @param hint 提示内容2
|
||||
* @param type 弹窗类型
|
||||
* @param cancelText 取消 文案
|
||||
* @param confirmText 确定 文案
|
||||
* @param click
|
||||
*/
|
||||
public void showDialog(String title, String content, String hint, String type,String cancelText,String confirmText, final OnDialogClick click) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public Dialog dialog = null;
|
||||
// 弹出一个确认对话框 并可以设置取消按钮事件
|
||||
public void showDialogtext(String title, String content, String okText, String cancelText, final OnDialogClick click) {
|
||||
View view = getLayoutInflater().inflate(R.layout.public_dialog_confirm, null);
|
||||
setTextView(R.id.tv_title, title, view);
|
||||
setTextView(R.id.tv_content, content, view);
|
||||
// ((EditText) view.findViewById(R.id.txtContent)).setText(cancelText);
|
||||
if(!TextUtils.isEmpty(okText) && !TextUtils.isEmpty(cancelText)){
|
||||
((TextView) view.findViewById(R.id.btnLeft)).setText(cancelText);
|
||||
((TextView) view.findViewById(R.id.btnRight)).setText(okText);
|
||||
}
|
||||
|
||||
view.findViewById(R.id.btnLeft).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onCancelClick();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.btnRight).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onConfirmClisk();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.tv_click).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
if (click != null)
|
||||
click.onView1Click();
|
||||
}
|
||||
});
|
||||
AlertDialog.Builder builder = null;//new AlertDialog.Builder(this, android.R.style.Theme_Holo_Dialog);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
builder = new AlertDialog.Builder(this, AlertDialog.THEME_HOLO_LIGHT);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(this);
|
||||
}
|
||||
builder.setInverseBackgroundForced(true);
|
||||
builder.setView(view);
|
||||
dialog = builder.show();
|
||||
try {
|
||||
((View) dialog.getWindow().getDecorView().findViewById(R.id.contentDialog).getParent().getParent()).setBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 弹出一个确认对话框 并可以设置取消按钮事件
|
||||
public void showDialogtext(Drawable imgRes, boolean isIconShow, boolean isTextShow, String title, String content, String okText, String cancelText,
|
||||
final BaseFragment.OnDialogClick click) {
|
||||
View view = getLayoutInflater().inflate(R.layout.public_dialog_index_permis, null);
|
||||
ImageView imgIcon = view.findViewById(R.id.img_dialog_icon);
|
||||
TextView tvOther = view.findViewById(R.id.tv_click);
|
||||
if(isIconShow){
|
||||
imgIcon.setVisibility(View.VISIBLE);
|
||||
if(imgRes != null ){
|
||||
imgIcon.setImageDrawable(imgRes);
|
||||
}
|
||||
}else{
|
||||
imgIcon.setVisibility(View.GONE);
|
||||
}
|
||||
if(isTextShow){
|
||||
tvOther.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
tvOther.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
setTextView(R.id.tv_title, title, view);
|
||||
setTextView(R.id.tv_content, content, view);
|
||||
// ((EditText) view.findViewById(R.id.txtContent)).setText(cancelText);
|
||||
if (!TextUtils.isEmpty(okText) && !TextUtils.isEmpty(cancelText)) {
|
||||
((TextView) view.findViewById(R.id.btnLeft)).setText(okText);
|
||||
((TextView) view.findViewById(R.id.btnRight)).setText(cancelText);
|
||||
}
|
||||
view.findViewById(R.id.btnLeft).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onCancelClick();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.btnRight).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onConfirmClick();
|
||||
}
|
||||
});
|
||||
AlertDialog.Builder builder = null;//new AlertDialog.Builder(this, android.R.style.Theme_Holo_Dialog);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
builder = new AlertDialog.Builder(mContext, AlertDialog.THEME_HOLO_LIGHT);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(mContext);
|
||||
}
|
||||
builder.setInverseBackgroundForced(true);
|
||||
builder.setView(view);
|
||||
dialog = builder.show();
|
||||
try {
|
||||
((View) dialog.getWindow().getDecorView().findViewById(R.id.contentDialog).getParent().getParent()).setBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置指定TextView的文本
|
||||
*
|
||||
* @param id
|
||||
* @param value textView的值
|
||||
*/
|
||||
public void setTextView(int id, String value, View view) {
|
||||
try {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
value = value.replaceAll("null", "");
|
||||
((TextView) view.findViewById(id)).setText(value);
|
||||
} else {
|
||||
((TextView) view.findViewById(id)).setText("");
|
||||
((TextView) view.findViewById(id)).setVisibility(View.GONE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void nextStep() {
|
||||
|
||||
}
|
||||
}
|
||||
890
app/src/main/java/com/ckkj/water/base/BaseFragment.java
Normal file
890
app/src/main/java/com/ckkj/water/base/BaseFragment.java
Normal file
@@ -0,0 +1,890 @@
|
||||
package com.ckkj.water.base;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.viewbinding.ViewBinding;
|
||||
|
||||
import com.esafirm.imagepicker.features.ImagePicker;
|
||||
import com.ckkj.water.AppConfig;
|
||||
import com.ckkj.water.ConstantUtil;
|
||||
import com.ckkj.water.EventMessage;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.dialog.LoadingDialog;
|
||||
import com.ckkj.water.login.LoginActivity;
|
||||
import com.ckkj.water.utils.dataUtil.SharePreUtil;
|
||||
import com.ckkj.water.utils.manager.ActivityManager;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import de.greenrobot.event.EventBus;
|
||||
import de.greenrobot.event.Subscribe;
|
||||
import de.greenrobot.event.ThreadMode;
|
||||
import pub.devrel.easypermissions.EasyPermissions;
|
||||
|
||||
/**
|
||||
* 所有Fragment基类
|
||||
* @param <P>
|
||||
*/
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public abstract class BaseFragment<T extends ViewBinding,P extends IPresenter> extends Fragment implements IView, EasyPermissions.PermissionCallbacks {
|
||||
protected String TAG = "MING_DENG";
|
||||
protected Activity activity;
|
||||
protected P mPresenter;
|
||||
protected Dialog loadingDialog;
|
||||
protected T viewBinding;
|
||||
protected Activity mContext;
|
||||
protected final int REQUEST_CODE_100 = 100;
|
||||
protected final int REQUEST_CODE_200 = 200;
|
||||
protected static final int REQUEST_EVENT_CODE_10001 = 10001;
|
||||
protected static final int REQUEST_EVENT_CODE_10002 = 10002;
|
||||
protected static final int REQUEST_EVENT_CODE_10003 = 10003;
|
||||
|
||||
private static final AtomicBoolean isDialogShown = new AtomicBoolean(false); // 使用 AtomicBoolean 保证线程安全
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
initArgs(getArguments());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
onResumeInitData();
|
||||
}
|
||||
|
||||
public boolean hasRecordPermission(String permission) {
|
||||
return EasyPermissions.hasPermissions(mContext, permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取权限
|
||||
*
|
||||
* @param permis
|
||||
* @param title
|
||||
* @param content
|
||||
* @param requestCode String... permis
|
||||
*/
|
||||
public void getPermissionRequst(String permis, String title, String content, int requestCode) {
|
||||
if (EasyPermissions.hasPermissions(mContext, permis)) {
|
||||
// 已有权限,不需要处理
|
||||
return;
|
||||
}
|
||||
// 还没权限,弹自定义确认弹窗
|
||||
showDialogtext(mContext.getResources().getDrawable(R.mipmap.img_location),
|
||||
false, false,
|
||||
title,
|
||||
content,
|
||||
"不允许", "允许",
|
||||
new BaseFragment.OnDialogClick() {
|
||||
@Override
|
||||
public void onCancelClick() {
|
||||
// 用户点了"不允许",什么都不用做
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirmClick() {
|
||||
showPermissionDialog(mContext.getResources().getDrawable(R.mipmap.img_permission_file),
|
||||
true, title, content);
|
||||
// 用户点了"允许",继续判断
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(mContext, permis)) {
|
||||
// 用户之前拒绝过,但没勾"不再询问" ➔ 直接请求权限
|
||||
// 修复:第一个参数应该是Fragment本身,而不是Activity的context
|
||||
EasyPermissions.requestPermissions(BaseFragment.this, content, requestCode, permis);
|
||||
} else {
|
||||
// 可能是第一次申请,也可能是勾了"不再询问"
|
||||
// 用EasyPermissions继续请求,系统自己决定弹不弹
|
||||
// 修复:第一个参数应该是Fragment本身,而不是Activity的context
|
||||
EasyPermissions.requestPermissions(BaseFragment.this, content, requestCode, permis);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断Fragment是否真正对用户可见
|
||||
*/
|
||||
protected boolean isFragmentVisible() {
|
||||
return isVisible() && isResumed();
|
||||
}
|
||||
|
||||
/**
|
||||
* 可见时初始化数据
|
||||
*/
|
||||
protected void onResumeInitData() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
createLoadingDialog(getActivity());
|
||||
mPresenter = createPresenter();//创建presenter
|
||||
}
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@Nullable LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle state) {
|
||||
mContext = getActivity();
|
||||
activity = getActivity();
|
||||
EventBus.getDefault().register(this);
|
||||
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
|
||||
Class cls = (Class) type.getActualTypeArguments()[0];
|
||||
try {
|
||||
Method inflate = cls.getDeclaredMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
|
||||
viewBinding = (T) inflate.invoke(null, inflater, container, false);
|
||||
} catch (NoSuchMethodException | IllegalAccessException| InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
initView();
|
||||
return viewBinding.getRoot();
|
||||
}
|
||||
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MainThread)
|
||||
public void onGetMessage(EventMessage message) {
|
||||
Log.d("DINGDING", "BaseFragment收到EventBus消息: " + message.msg);
|
||||
|
||||
if (message.msg.equals(EventMessage.USER_LOGIN_LOST)) {
|
||||
|
||||
Log.d("DINGDING","Fragment接收一次");
|
||||
Log.d("DINGDING", "当前Fragment状态: isDetached=" + isDetached() + ", isRemoving=" + isRemoving());
|
||||
|
||||
// 检查Fragment状态,如果正在销毁则不处理
|
||||
if (isDetached() || isRemoving()) {
|
||||
Log.d("DINGDING", "Fragment正在销毁,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查Activity状态,如果Activity正在销毁则不处理
|
||||
if (mContext == null || mContext.isFinishing() || mContext.isDestroyed()) {
|
||||
Log.d("DINGDING", "Fragment所属Activity正在销毁,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDialogShown.compareAndSet(false, true)) {
|
||||
Log.d("DINGDING","Fragment触发弹窗");
|
||||
AppConfig.USER_LOGIN = false;
|
||||
AppConfig.MEMBER_ID = 0;
|
||||
AppConfig.USER_TOKEN = "";
|
||||
AppConfig.USER_ID = "";
|
||||
SharePreUtil.putBoolean(ConstantUtil.SHARE_PRE_NAME, mContext, ConstantUtil.USER_LOGIN, AppConfig.USER_LOGIN);
|
||||
|
||||
// 确保在主线程中执行
|
||||
mContext.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// 再次检查Fragment和Activity状态
|
||||
if (isDetached() || isRemoving() || mContext == null || mContext.isFinishing() || mContext.isDestroyed()) {
|
||||
Log.d("DINGDING", "Fragment或Activity已销毁,取消弹窗");
|
||||
isDialogShown.set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
showDialogtextInterBackKey(null, false, false,
|
||||
"提示",
|
||||
"检测到您的账号在异地登录。若非本人操作,请立即修改密码并检查账号安全!",
|
||||
"我知道了", "", // 交换参数位置
|
||||
new OnDialogClick() {
|
||||
@Override
|
||||
public void onCancelClick() {
|
||||
Log.d("DINGDING", "用户点击取消");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirmClick() {
|
||||
Log.d("DINGDING", "用户点击确定");
|
||||
ActivityManager.removeAllActivityExceptMain();
|
||||
goTo(mContext, LoginActivity.class, null);
|
||||
isDialogShown.set(false);
|
||||
}
|
||||
}, true);
|
||||
Log.d("DINGDING", "Fragment弹窗显示成功");
|
||||
} catch (Exception e) {
|
||||
Log.e("DINGDING", "Fragment弹窗显示失败", e);
|
||||
isDialogShown.set(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.d("DINGDING", "Fragment弹窗已显示,跳过");
|
||||
}
|
||||
} else if (message.msg.equals(EventMessage.CODE_LOGIN_LOST)) {
|
||||
// 检查是否满足跳转条件
|
||||
// if (MyApplication.canJump()) { // MyApplication is not defined in this file
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
protected void initView() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* activity跳转
|
||||
*/
|
||||
protected void goToWihoutNoPresent(Context from, Class<? extends BaseActivityNoP> to, Bundle data) {
|
||||
Intent i = new Intent();
|
||||
i.setClass(from, to);
|
||||
if (data != null) i.putExtras(data);
|
||||
from.startActivity(i);
|
||||
}
|
||||
|
||||
|
||||
protected LoadingDialog mLoadingDialog;
|
||||
public void showLoadingDialog() {
|
||||
LoadingDialog dialog = mLoadingDialog;
|
||||
if (dialog == null&& mContext != null) {
|
||||
dialog = new LoadingDialog(mContext);
|
||||
// 不可触摸取消
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
// 强制取消关闭界面
|
||||
dialog.setCancelable(true);
|
||||
// dialog.setOnCancelListener(dialog1 -> finish());
|
||||
mLoadingDialog = dialog;
|
||||
} else {
|
||||
dialog.dismiss();
|
||||
}
|
||||
if (dialog != null && mContext != null) {
|
||||
try {
|
||||
dialog.show();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void createLoadingDialog(Context context){
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
@SuppressLint("InflateParams") View v = inflater.inflate(R.layout.dialog_loading, null);
|
||||
LinearLayout layout = (LinearLayout) v.findViewById(R.id.dialog_loading_view);
|
||||
ImageView imgLoading = v.findViewById(R.id.img_loading);
|
||||
loadingDialog = new Dialog(context, R.style.MyDialogStyle);
|
||||
loadingDialog.setCanceledOnTouchOutside(false);
|
||||
loadingDialog.setContentView(layout,
|
||||
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.MATCH_PARENT));
|
||||
Window window = loadingDialog.getWindow();
|
||||
if (window != null) {
|
||||
WindowManager.LayoutParams lp = window.getAttributes();
|
||||
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
|
||||
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
|
||||
window.setGravity(Gravity.CENTER);
|
||||
window.setAttributes(lp);
|
||||
window.setWindowAnimations(R.style.PopWindowAnimStyle);
|
||||
}
|
||||
loadingDialog.setCanceledOnTouchOutside(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if (mPresenter != null) {
|
||||
mPresenter.attachView(this);
|
||||
}
|
||||
initData(savedInstanceState);
|
||||
}
|
||||
|
||||
|
||||
public void imagePicker(int limitCount,int requestCode,Fragment fragment){
|
||||
//获取相册
|
||||
ImagePicker.create(fragment)
|
||||
.folderMode(false)
|
||||
.showCamera(false).limit(limitCount)
|
||||
.start(requestCode);
|
||||
String[] permis = {Manifest.permission.READ_EXTERNAL_STORAGE};
|
||||
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||
// //获取到了权限,可以请求地址显示
|
||||
// if (EasyPermissions.hasPermissions(mContext, permis)) {
|
||||
//
|
||||
// }else{
|
||||
// showDialogtext(mContext.getResources().getDrawable(R.mipmap.img_location), false, false,
|
||||
// "相册访问权限", "超越仓需要您的授权,访问相册来上传资料",
|
||||
// "不允许", "允许", new BaseFragment.OnDialogClick() {
|
||||
// @Override
|
||||
// public void onCancelClick() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onConfirmClick() {
|
||||
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||
//// Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
|
||||
//// mContext.startActivity(intent);
|
||||
// EasyPermissions.requestPermissions(mContext, "应用需要获相册授权",
|
||||
// ConstantUtil.READ_EXTERNAL_STORAGE
|
||||
// , Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
// } else {
|
||||
// EasyPermissions.requestPermissions(mContext, "应用需要获相册授权",
|
||||
// ConstantUtil.READ_EXTERNAL_STORAGE
|
||||
// , Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//// XXPermissions.with(mContext)
|
||||
//// // 申请单个权限
|
||||
//// .permission(Permission.READ_EXTERNAL_STORAGE)
|
||||
//// .interceptor(new PermissionInterceptor())
|
||||
//// .request(new OnPermissionCallback() {
|
||||
//// @Override
|
||||
//// public void onGranted(List<String> permissions, boolean all) {
|
||||
////
|
||||
//// }
|
||||
////
|
||||
//// @Override
|
||||
//// public void onDenied(List<String> permissions, boolean never) {
|
||||
//// if (never) {
|
||||
//// Toast.makeText(mContext, "被永久拒绝授权,请手动授予权限", Toast.LENGTH_SHORT).show();
|
||||
//// // 如果是被永久拒绝就跳转到应用权限系统设置页面
|
||||
//// XXPermissions.startPermissionActivity(mContext, permissions);
|
||||
//// } else {
|
||||
//// Toast.makeText(mContext, "获取权限失败", Toast.LENGTH_SHORT).show();
|
||||
//// }
|
||||
//// return;
|
||||
//// }
|
||||
//// });
|
||||
//
|
||||
// } else {
|
||||
// //获取到了权限,可以请求地址显示
|
||||
// if (EasyPermissions.hasPermissions(mContext, permis)) {
|
||||
// //获取相册
|
||||
// ImagePicker.create(fragment)
|
||||
// .folderMode(false)
|
||||
// .showCamera(false).limit(limitCount)
|
||||
// .start(requestCode);
|
||||
// } else {
|
||||
// showDialogtext(mContext.getResources().getDrawable(R.mipmap.img_location), false, false,
|
||||
// "相册访问权限", "超越仓需要您的授权,访问相册来上传资料",
|
||||
// "不允许", "允许", new BaseFragment.OnDialogClick() {
|
||||
// @Override
|
||||
// public void onCancelClick() {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onConfirmClick() {
|
||||
// if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||
// Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
|
||||
// mContext.startActivity(intent);
|
||||
// } else {
|
||||
// EasyPermissions.requestPermissions(mContext, "应用需要获相册授权",
|
||||
// ConstantUtil.READ_EXTERNAL_STORAGE
|
||||
// , Manifest.permission.READ_EXTERNAL_STORAGE);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
public Dialog dialog = null;
|
||||
// 弹出一个确认对话框 并可以设置取消按钮事件
|
||||
public void showDialogtext(Drawable imgRes,boolean isIconShow, boolean isTextShow, String title,
|
||||
String content, String okText, String cancelText,
|
||||
final OnDialogClick click) {
|
||||
View view = getLayoutInflater().inflate(R.layout.public_dialog_index_permis, null);
|
||||
ImageView imgIcon = view.findViewById(R.id.img_dialog_icon);
|
||||
TextView tvOther = view.findViewById(R.id.tv_click);
|
||||
TextView tvLeft = view.findViewById(R.id.btnLeft);
|
||||
if(isIconShow){
|
||||
imgIcon.setVisibility(View.VISIBLE);
|
||||
if(imgRes != null ){
|
||||
imgIcon.setImageDrawable(imgRes);
|
||||
}
|
||||
}else{
|
||||
imgIcon.setVisibility(View.GONE);
|
||||
}
|
||||
if(isTextShow){
|
||||
tvOther.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
tvOther.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
setTextView(R.id.tv_title, title, view);
|
||||
setTextView(R.id.tv_content, content, view);
|
||||
// ((EditText) view.findViewById(R.id.txtContent)).setText(cancelText);
|
||||
if (!TextUtils.isEmpty(okText) && !TextUtils.isEmpty(cancelText)) {
|
||||
((TextView) view.findViewById(R.id.btnLeft)).setText(okText);
|
||||
((TextView) view.findViewById(R.id.btnRight)).setText(cancelText);
|
||||
}
|
||||
view.findViewById(R.id.btnLeft).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onCancelClick();
|
||||
}
|
||||
});
|
||||
view.findViewById(R.id.btnRight).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onConfirmClick();
|
||||
}
|
||||
});
|
||||
if(!TextUtils.isEmpty(cancelText)){
|
||||
tvLeft.setVisibility(View.VISIBLE);
|
||||
}else{
|
||||
tvLeft.setVisibility(View.GONE);
|
||||
|
||||
}
|
||||
AlertDialog.Builder builder = null;//new AlertDialog.Builder(this, android.R.style.Theme_Holo_Dialog);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
builder = new AlertDialog.Builder(mContext, AlertDialog.THEME_HOLO_LIGHT);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(mContext);
|
||||
}
|
||||
builder.setInverseBackgroundForced(true);
|
||||
builder.setView(view);
|
||||
dialog = builder.show();
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
try {
|
||||
((View) dialog.getWindow().getDecorView().findViewById(R.id.contentDialog).getParent().getParent()).setBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制登出,并且拦截返回键
|
||||
* @param imgRes
|
||||
* @param isIconShow
|
||||
* @param isTextShow
|
||||
* @param title
|
||||
* @param content
|
||||
* @param okText
|
||||
* @param cancelText
|
||||
* @param click
|
||||
* @param interceptBackKey
|
||||
*/
|
||||
public void showDialogtextInterBackKey(Drawable imgRes, boolean isIconShow, boolean isTextShow, String title,
|
||||
String content, String okText, String cancelText,
|
||||
final OnDialogClick click, boolean interceptBackKey) {
|
||||
View view = getLayoutInflater().inflate(R.layout.public_dialog_index_permis, null);
|
||||
ImageView imgIcon = view.findViewById(R.id.img_dialog_icon);
|
||||
TextView tvOther = view.findViewById(R.id.tv_click);
|
||||
TextView tvLeft = view.findViewById(R.id.btnLeft);
|
||||
|
||||
if (isIconShow) {
|
||||
imgIcon.setVisibility(View.VISIBLE);
|
||||
if (imgRes != null) {
|
||||
imgIcon.setImageDrawable(imgRes);
|
||||
}
|
||||
} else {
|
||||
imgIcon.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
tvOther.setVisibility(isTextShow ? View.VISIBLE : View.GONE);
|
||||
|
||||
setTextView(R.id.tv_title, title, view);
|
||||
setTextView(R.id.tv_content, content, view);
|
||||
|
||||
if (!TextUtils.isEmpty(okText) && !TextUtils.isEmpty(cancelText)) {
|
||||
((TextView) view.findViewById(R.id.btnLeft)).setText(okText);
|
||||
((TextView) view.findViewById(R.id.btnRight)).setText(cancelText);
|
||||
}
|
||||
|
||||
view.findViewById(R.id.btnLeft).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onCancelClick();
|
||||
}
|
||||
});
|
||||
|
||||
view.findViewById(R.id.btnRight).setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
if (dialog != null && dialog.isShowing())
|
||||
dialog.dismiss();
|
||||
if (click != null)
|
||||
click.onConfirmClick();
|
||||
}
|
||||
});
|
||||
|
||||
tvLeft.setVisibility(TextUtils.isEmpty(cancelText) ? View.GONE : View.VISIBLE);
|
||||
|
||||
AlertDialog.Builder builder;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
builder = new AlertDialog.Builder(mContext, AlertDialog.THEME_HOLO_LIGHT);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(mContext);
|
||||
}
|
||||
|
||||
builder.setInverseBackgroundForced(true);
|
||||
builder.setView(view);
|
||||
|
||||
dialog = builder.show();
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
|
||||
// 🔒 返回键拦截逻辑
|
||||
if (interceptBackKey) {
|
||||
dialog.setCancelable(false);
|
||||
dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(DialogInterface dialogInterface, int keyCode, KeyEvent event) {
|
||||
return keyCode == KeyEvent.KEYCODE_BACK;
|
||||
}
|
||||
});
|
||||
}
|
||||
try {
|
||||
((View) dialog.getWindow().getDecorView()
|
||||
.findViewById(R.id.contentDialog)
|
||||
.getParent().getParent())
|
||||
.setBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
} catch (Exception e) {
|
||||
// 安全兜底
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void showPermissionDialog(Drawable imgRes,boolean isIconShow, String title,
|
||||
String content) {
|
||||
View view = getLayoutInflater().inflate(R.layout.permisson_top_dialog, null);
|
||||
ImageView imgIcon = view.findViewById(R.id.img_permission_icon);
|
||||
TextView tvTitle = view.findViewById(R.id.tv_permission_title);
|
||||
TextView tvContent = view.findViewById(R.id.tv_permission_content);
|
||||
tvTitle.setText(title);
|
||||
tvContent.setText(content);
|
||||
if(isIconShow){
|
||||
imgIcon.setVisibility(View.VISIBLE);
|
||||
if(imgRes != null ){
|
||||
imgIcon.setImageDrawable(imgRes);
|
||||
}
|
||||
}else{
|
||||
imgIcon.setVisibility(View.GONE);
|
||||
}
|
||||
AlertDialog.Builder builder = null;//new AlertDialog.Builder(this, android.R.style.Theme_Holo_Dialog);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
builder = new AlertDialog.Builder(mContext, AlertDialog.THEME_HOLO_LIGHT);
|
||||
} else {
|
||||
builder = new AlertDialog.Builder(mContext);
|
||||
}
|
||||
builder.setInverseBackgroundForced(true);
|
||||
builder.setView(view);
|
||||
dialog = builder.create();
|
||||
// 获取 dialog 的 Window 对象
|
||||
Window window = dialog.getWindow();
|
||||
if (window != null) {
|
||||
// 设置 dialog 在屏幕顶部显示
|
||||
WindowManager.LayoutParams params = window.getAttributes();
|
||||
params.gravity = Gravity.TOP; // 设置对话框顶部显示
|
||||
window.setAttributes(params);
|
||||
}
|
||||
// 显示 AlertDialog
|
||||
dialog.show();
|
||||
// dialog = builder.show();
|
||||
try {
|
||||
((View) dialog.getWindow().getDecorView().findViewById(R.id.contentDialog).getParent().getParent()).setBackgroundColor(getResources().getColor(R.color.transparent));
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置指定TextView的文本
|
||||
*
|
||||
* @param id
|
||||
* @param value textView的值
|
||||
*/
|
||||
public void setTextView(int id, String value, View view) {
|
||||
try {
|
||||
if (!TextUtils.isEmpty(value)) {
|
||||
value = value.replaceAll("null", "");
|
||||
((TextView) view.findViewById(id)).setText(value);
|
||||
((TextView) view.findViewById(id)).setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
((TextView) view.findViewById(id)).setText("");
|
||||
((TextView) view.findViewById(id)).setVisibility(View.GONE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface OnDialogClick {
|
||||
public void onCancelClick();
|
||||
|
||||
public void onConfirmClick();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化参数
|
||||
* @param bundle 需要初始化的参数
|
||||
*/
|
||||
protected void initArgs(Bundle bundle) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化控件
|
||||
*/
|
||||
protected void initWidget(View root) {
|
||||
}
|
||||
/**
|
||||
* 初始化views
|
||||
*
|
||||
* @param state
|
||||
*/
|
||||
public abstract void initData(Bundle state);
|
||||
public abstract P createPresenter();
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
EventBus.getDefault().unregister(this);
|
||||
if (mPresenter != null) {
|
||||
mPresenter.onDestroy();//释放资源
|
||||
}
|
||||
this.mPresenter = null;
|
||||
hideDialogLoading();
|
||||
|
||||
// 重置弹窗状态,让其他Fragment可以显示弹窗
|
||||
isDialogShown.set(false);
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
//此处try catch 是因为unbinder.unbind() 在清空状态下,会造成崩溃
|
||||
//其他处不影响使用
|
||||
try {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
this.activity = null;
|
||||
}
|
||||
@Override
|
||||
public void showLoading() {
|
||||
loadingDialog.show();
|
||||
}
|
||||
@Override
|
||||
public void hideLoading() {
|
||||
loadingDialog.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showMessage(String message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(Exception e) {
|
||||
hideLoading();
|
||||
showMessage(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转
|
||||
*
|
||||
* @param data 携带数据
|
||||
*/
|
||||
protected void goTo(Context from, Class<? extends BaseActivity> to, Bundle data) {
|
||||
Intent i = new Intent();
|
||||
i.setClass(from, to);
|
||||
if(data!=null) i.putExtras(data);
|
||||
from.startActivity(i);
|
||||
}
|
||||
/**
|
||||
* 跳转返回
|
||||
*
|
||||
*
|
||||
*/
|
||||
protected void goToForResult(Context from, Class<? extends BaseActivity> to, int questCode, Bundle data) {
|
||||
Intent i = new Intent();
|
||||
i.setClass(from, to);
|
||||
if(data!=null) i.putExtras(data);
|
||||
startActivityForResult(i,questCode);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 关闭等待页面
|
||||
*/
|
||||
public void hideDialogLoading() {
|
||||
LoadingDialog dialog = mLoadingDialog;
|
||||
try {
|
||||
if (dialog != null && mContext != null) {
|
||||
mLoadingDialog = null;
|
||||
dialog.dismiss();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void hidePermissionDialog(){
|
||||
if(dialog != null && dialog.isShowing()){
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void clearLoginInfo(){
|
||||
AppConfig.USER_LOGIN = false;
|
||||
SharePreUtil.putString(ConstantUtil.SHARE_PRE_NAME,mContext,ConstantUtil.USER_INFO_PHONE_NUMBER,"");
|
||||
SharePreUtil.putString(ConstantUtil.SHARE_PRE_NAME,mContext,ConstantUtil.USER_UPLOAD_COMPANY_NAME,"未登录");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理登录丢失的统一方法
|
||||
* 子类可以直接调用此方法来处理401错误
|
||||
*/
|
||||
protected void handleLoginLost() {
|
||||
Log.d("DINGDING", "BaseFragment.handleLoginLost() 被调用");
|
||||
|
||||
// 检查Fragment状态
|
||||
if (isDetached() || isRemoving()) {
|
||||
Log.d("DINGDING", "Fragment正在销毁,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查Activity状态
|
||||
if (mContext == null || mContext.isFinishing() || mContext.isDestroyed()) {
|
||||
Log.d("DINGDING", "Fragment所属Activity正在销毁,跳过处理");
|
||||
return;
|
||||
}
|
||||
|
||||
// 重置登录信息
|
||||
resetLoginInfo();
|
||||
|
||||
// 显示401弹窗
|
||||
show401Dialog();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置登录信息
|
||||
*/
|
||||
private void resetLoginInfo() {
|
||||
AppConfig.USER_LOGIN = false;
|
||||
AppConfig.MEMBER_ID = 0;
|
||||
AppConfig.USER_TOKEN = "";
|
||||
AppConfig.USER_ID = "";
|
||||
SharePreUtil.putBoolean(ConstantUtil.SHARE_PRE_NAME, mContext, ConstantUtil.USER_LOGIN, AppConfig.USER_LOGIN);
|
||||
Log.d("DINGDING", "登录信息已重置");
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示401弹窗
|
||||
*/
|
||||
private void show401Dialog() {
|
||||
if (mContext == null || mContext.isFinishing() || mContext.isDestroyed()) {
|
||||
Log.d("DINGDING", "Activity状态异常,无法显示弹窗");
|
||||
return;
|
||||
}
|
||||
|
||||
mContext.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
// 再次检查状态
|
||||
if (isDetached() || isRemoving() || mContext == null || mContext.isFinishing() || mContext.isDestroyed()) {
|
||||
Log.d("DINGDING", "Fragment或Activity已销毁,取消弹窗");
|
||||
return;
|
||||
}
|
||||
|
||||
showDialogtextInterBackKey(null, false, false,
|
||||
"提示",
|
||||
"检测到您的账号在异地登录。若非本人操作,请立即修改密码并检查账号安全!",
|
||||
"我知道了", "",
|
||||
new OnDialogClick() {
|
||||
@Override
|
||||
public void onCancelClick() {
|
||||
Log.d("DINGDING", "用户点击取消");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfirmClick() {
|
||||
Log.d("DINGDING", "用户点击确定");
|
||||
ActivityManager.removeAllActivityExceptMain();
|
||||
goTo(mContext, LoginActivity.class, null);
|
||||
}
|
||||
}, true);
|
||||
Log.d("DINGDING", "BaseFragment 401弹窗显示成功");
|
||||
} catch (Exception e) {
|
||||
Log.e("DINGDING", "BaseFragment 401弹窗显示失败", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限请求结果回调
|
||||
*/
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
// 将权限结果传递给EasyPermissions处理
|
||||
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限被授予时的回调
|
||||
*/
|
||||
@Override
|
||||
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
|
||||
// 这个方法会在子Fragment中重写,这里可以留空或者提供默认实现
|
||||
}
|
||||
|
||||
/**
|
||||
* 权限被拒绝时的回调
|
||||
*/
|
||||
@Override
|
||||
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
||||
// 这个方法会在子Fragment中重写,这里可以留空或者提供默认实现
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
31
app/src/main/java/com/ckkj/water/base/BasePresenter.java
Normal file
31
app/src/main/java/com/ckkj/water/base/BasePresenter.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.ckkj.water.base;
|
||||
|
||||
public abstract class BasePresenter<V extends IView> implements IPresenter<V> {
|
||||
|
||||
//View 显示回显的接口
|
||||
protected V mRootView;
|
||||
|
||||
public BasePresenter() {
|
||||
onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
this.mRootView = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void attachView(V view) {
|
||||
this.mRootView = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V getView() {
|
||||
return mRootView;
|
||||
}
|
||||
|
||||
}
|
||||
21
app/src/main/java/com/ckkj/water/base/IPresenter.java
Normal file
21
app/src/main/java/com/ckkj/water/base/IPresenter.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.ckkj.water.base;
|
||||
|
||||
public interface IPresenter<T extends IView> {
|
||||
|
||||
/**
|
||||
* 做一些初始化操作
|
||||
*/
|
||||
void onStart();
|
||||
|
||||
/**
|
||||
* 销毁
|
||||
*/
|
||||
void onDestroy();
|
||||
|
||||
/**
|
||||
* 绑定View
|
||||
*/
|
||||
void attachView(T view);
|
||||
|
||||
T getView();
|
||||
}
|
||||
47
app/src/main/java/com/ckkj/water/base/IView.java
Normal file
47
app/src/main/java/com/ckkj/water/base/IView.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.ckkj.water.base;
|
||||
|
||||
import com.ckkj.water.network.BaseBean;
|
||||
|
||||
public interface IView {
|
||||
|
||||
/**
|
||||
* 网络状态改变时的回调
|
||||
* @param netModel
|
||||
*/
|
||||
void onNetChange(int netModel);
|
||||
|
||||
/**
|
||||
* 显示加载
|
||||
*/
|
||||
void showLoading();
|
||||
|
||||
/**
|
||||
* 隐藏加载
|
||||
*/
|
||||
void hideLoading();
|
||||
|
||||
/**
|
||||
* 显示信息
|
||||
* @param message
|
||||
*/
|
||||
void showMessage(String message);
|
||||
|
||||
|
||||
/**
|
||||
* 显示错误信息
|
||||
* @param message
|
||||
*/
|
||||
void showError(String message);
|
||||
|
||||
/**
|
||||
* 统一消息处理
|
||||
* @param e
|
||||
*/
|
||||
void handleError(Exception e);
|
||||
|
||||
/**
|
||||
* 登录失效
|
||||
* @param
|
||||
*/
|
||||
void logOut(BaseBean bean);
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ckkj.water.base.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/28
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class MineUserInfoBean implements Serializable {
|
||||
private UserInfoEntity userInfo;
|
||||
private boolean hasEightCharacters;
|
||||
private String constellation;
|
||||
private String birthTime;
|
||||
|
||||
|
||||
|
||||
public String getConstellation() {
|
||||
|
||||
return constellation;
|
||||
}
|
||||
|
||||
public void setConstellation(String constellation) {
|
||||
this.constellation = constellation;
|
||||
}
|
||||
|
||||
public String getBirthTime() {
|
||||
return birthTime;
|
||||
}
|
||||
|
||||
public void setBirthTime(String birthTime) {
|
||||
this.birthTime = birthTime;
|
||||
}
|
||||
|
||||
public UserInfoEntity getUserInfo() {
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
public void setUserInfo(UserInfoEntity userInfo) {
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
|
||||
public boolean isHasEightCharacters() {
|
||||
return hasEightCharacters;
|
||||
}
|
||||
|
||||
public void setHasEightCharacters(boolean hasEightCharacters) {
|
||||
this.hasEightCharacters = hasEightCharacters;
|
||||
}
|
||||
}
|
||||
279
app/src/main/java/com/ckkj/water/base/entity/UserInfoEntity.java
Normal file
279
app/src/main/java/com/ckkj/water/base/entity/UserInfoEntity.java
Normal file
@@ -0,0 +1,279 @@
|
||||
package com.ckkj.water.base.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/21
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class UserInfoEntity implements Serializable {
|
||||
private String name;
|
||||
private String gender;
|
||||
private String genderText;
|
||||
private String birthType;
|
||||
private String birthTypeText;
|
||||
private String birthTime;
|
||||
private String birthPlace;
|
||||
private String currentPlace;
|
||||
private String trueSolarTime;
|
||||
private String longitude;
|
||||
private String latitude;
|
||||
private String constellation;
|
||||
private BaziSizhu baziSizhu;
|
||||
private long userId;
|
||||
private String mobile;
|
||||
private String username;
|
||||
private String nickname;
|
||||
private String email;
|
||||
private int status;
|
||||
private String registerTime;
|
||||
private String updateTime;
|
||||
private int membershipStatus;
|
||||
private String membershipExpireTime;
|
||||
private String inviteCode;
|
||||
private String userRole;
|
||||
private String avatar;
|
||||
|
||||
|
||||
public String getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public void setAvatar(String avatar) {
|
||||
this.avatar = avatar;
|
||||
}
|
||||
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getMobile() {
|
||||
return mobile;
|
||||
}
|
||||
|
||||
public void setMobile(String mobile) {
|
||||
this.mobile = mobile;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(int status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getRegisterTime() {
|
||||
return registerTime;
|
||||
}
|
||||
|
||||
public void setRegisterTime(String registerTime) {
|
||||
this.registerTime = registerTime;
|
||||
}
|
||||
|
||||
public String getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(String updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public int getMembershipStatus() {
|
||||
return membershipStatus;
|
||||
}
|
||||
|
||||
public void setMembershipStatus(int membershipStatus) {
|
||||
this.membershipStatus = membershipStatus;
|
||||
}
|
||||
|
||||
public String getMembershipExpireTime() {
|
||||
return membershipExpireTime;
|
||||
}
|
||||
|
||||
public void setMembershipExpireTime(String membershipExpireTime) {
|
||||
this.membershipExpireTime = membershipExpireTime;
|
||||
}
|
||||
|
||||
public String getInviteCode() {
|
||||
return inviteCode;
|
||||
}
|
||||
|
||||
public void setInviteCode(String inviteCode) {
|
||||
this.inviteCode = inviteCode;
|
||||
}
|
||||
|
||||
public String getUserRole() {
|
||||
return userRole;
|
||||
}
|
||||
|
||||
public void setUserRole(String userRole) {
|
||||
this.userRole = userRole;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setGender(String gender) {
|
||||
this.gender = gender;
|
||||
}
|
||||
public String getGender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
public void setGenderText(String genderText) {
|
||||
this.genderText = genderText;
|
||||
}
|
||||
public String getGenderText() {
|
||||
return genderText;
|
||||
}
|
||||
|
||||
public void setBirthType(String birthType) {
|
||||
this.birthType = birthType;
|
||||
}
|
||||
public String getBirthType() {
|
||||
return birthType;
|
||||
}
|
||||
|
||||
public void setBirthTypeText(String birthTypeText) {
|
||||
this.birthTypeText = birthTypeText;
|
||||
}
|
||||
public String getBirthTypeText() {
|
||||
return birthTypeText;
|
||||
}
|
||||
|
||||
public void setBirthTime(String birthTime) {
|
||||
this.birthTime = birthTime;
|
||||
}
|
||||
public String getBirthTime() {
|
||||
return birthTime;
|
||||
}
|
||||
|
||||
public void setBirthPlace(String birthPlace) {
|
||||
this.birthPlace = birthPlace;
|
||||
}
|
||||
public String getBirthPlace() {
|
||||
return birthPlace;
|
||||
}
|
||||
|
||||
public void setCurrentPlace(String currentPlace) {
|
||||
this.currentPlace = currentPlace;
|
||||
}
|
||||
public String getCurrentPlace() {
|
||||
return currentPlace;
|
||||
}
|
||||
|
||||
public void setTrueSolarTime(String trueSolarTime) {
|
||||
this.trueSolarTime = trueSolarTime;
|
||||
}
|
||||
public String getTrueSolarTime() {
|
||||
return trueSolarTime;
|
||||
}
|
||||
|
||||
public void setLongitude(String longitude) {
|
||||
this.longitude = longitude;
|
||||
}
|
||||
public String getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
|
||||
public void setLatitude(String latitude) {
|
||||
this.latitude = latitude;
|
||||
}
|
||||
public String getLatitude() {
|
||||
return latitude;
|
||||
}
|
||||
|
||||
public void setConstellation(String constellation) {
|
||||
this.constellation = constellation;
|
||||
}
|
||||
public String getConstellation() {
|
||||
return constellation;
|
||||
}
|
||||
|
||||
public void setBaziSizhu(BaziSizhu baziSizhu) {
|
||||
this.baziSizhu = baziSizhu;
|
||||
}
|
||||
public BaziSizhu getBaziSizhu() {
|
||||
return baziSizhu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copyright 2025 bejson.com
|
||||
*/
|
||||
/**
|
||||
* Auto-generated: 2025-07-21 17:23:17
|
||||
*
|
||||
* @author bejson.com (i@bejson.com)
|
||||
* @website http://www.bejson.com/java2pojo/
|
||||
*/
|
||||
public static class BaziSizhu implements Serializable{
|
||||
|
||||
private String nianzhu;
|
||||
private String yuezhu;
|
||||
private String rizhu;
|
||||
private String shizhu;
|
||||
public void setNianzhu(String nianzhu) {
|
||||
this.nianzhu = nianzhu;
|
||||
}
|
||||
public String getNianzhu() {
|
||||
return nianzhu;
|
||||
}
|
||||
|
||||
public void setYuezhu(String yuezhu) {
|
||||
this.yuezhu = yuezhu;
|
||||
}
|
||||
public String getYuezhu() {
|
||||
return yuezhu;
|
||||
}
|
||||
|
||||
public void setRizhu(String rizhu) {
|
||||
this.rizhu = rizhu;
|
||||
}
|
||||
public String getRizhu() {
|
||||
return rizhu;
|
||||
}
|
||||
|
||||
public void setShizhu(String shizhu) {
|
||||
this.shizhu = shizhu;
|
||||
}
|
||||
public String getShizhu() {
|
||||
return shizhu;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ckkj.water.base.inter;
|
||||
|
||||
import com.alibaba.sdk.android.oss.ClientException;
|
||||
import com.alibaba.sdk.android.oss.ServiceException;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface UploadCallback {
|
||||
void onSuccess(List<String> urls);
|
||||
void onFailure(ClientException clientException, ServiceException serviceException);
|
||||
}
|
||||
900
app/src/main/java/com/ckkj/water/chat/ChatFragment.java
Normal file
900
app/src/main/java/com/ckkj/water/chat/ChatFragment.java
Normal file
@@ -0,0 +1,900 @@
|
||||
package com.ckkj.water.chat;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.ckkj.water.AppConfig;
|
||||
import com.ckkj.water.EventMessage;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.base.BaseFragment;
|
||||
import com.ckkj.water.chat.adapter.ChatQuestionDetailAdapter;
|
||||
import com.ckkj.water.chat.adapter.ChatZixunAdapter;
|
||||
import com.ckkj.water.chat.entity.ChatQuestionEntity;
|
||||
import com.ckkj.water.custom.GridSpacingItemDecoration;
|
||||
import com.ckkj.water.databinding.IndexLayoutBinding;
|
||||
import com.ckkj.water.chat.adapter.IndexChatAdapter;
|
||||
import com.ckkj.water.chat.adapter.IndexOptionAdapter;
|
||||
import com.ckkj.water.chat.adapter.IndexEnterHintAdapter;
|
||||
import com.ckkj.water.chat.adapter.IndexQuickAskAdapter;
|
||||
import com.ckkj.water.chat.entity.CharHistoryEntity;
|
||||
import com.ckkj.water.chat.entity.ChatAiMsgEntity;
|
||||
import com.ckkj.water.chat.entity.ChatMultiItem;
|
||||
import com.ckkj.water.chat.entity.IndexTemplateEntity;
|
||||
import com.ckkj.water.chat.mvp.IndexContract;
|
||||
import com.ckkj.water.chat.mvp.IndexImpl;
|
||||
import com.ckkj.water.chat.mvp.IndexPresenter;
|
||||
import com.ckkj.water.dialog.ContentReportDialog;
|
||||
import com.ckkj.water.login.LoginActivity;
|
||||
import com.ckkj.water.network.BaseBean;
|
||||
import com.ckkj.water.plate.entity.BaziResultBean;
|
||||
import com.ckkj.water.plate.entity.PaipanCache;
|
||||
import com.ckkj.water.utils.click.ClickUtil;
|
||||
import com.ckkj.water.utils.manager.ColorManage;
|
||||
import com.ckkj.water.utils.show.ToastUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import de.greenrobot.event.Subscribe;
|
||||
import de.greenrobot.event.ThreadMode;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class ChatFragment extends BaseFragment<IndexLayoutBinding, IndexPresenter> implements IndexContract.IndexView {
|
||||
|
||||
//顶部 adapter
|
||||
private IndexOptionAdapter mOptionAdapter;
|
||||
private ChatZixunAdapter mZixunQuestAdapter;
|
||||
private ChatQuestionDetailAdapter mQuesDetailAdapter;
|
||||
//快速提问 adapter
|
||||
private IndexQuickAskAdapter mQuickAskAdapter;
|
||||
private List<IndexTemplateEntity> mQuickAskList = new ArrayList<>();
|
||||
|
||||
private List<ChatMultiItem> mChatMsgList = new ArrayList<>();
|
||||
//聊天 adapter
|
||||
private IndexChatAdapter mChatAdapter;
|
||||
//欢迎语 adapter
|
||||
private IndexEnterHintAdapter mHintAdapter;
|
||||
//输入的内容
|
||||
private String mCurrentInputContent = "";
|
||||
//当前options 的 pos
|
||||
private int mCurrentStreamPos = 0;
|
||||
//模板数据 list
|
||||
private List<IndexTemplateEntity> mIndexTemList = new ArrayList<>();
|
||||
//输出是否完成
|
||||
private boolean mIsStreamStop = true;
|
||||
//当前选中 option 的 typeID
|
||||
private String mSelectTypeID = "1";
|
||||
//会话 ID
|
||||
private String mSessionId = "";
|
||||
|
||||
// 添加流式数据累积变量
|
||||
private StringBuilder mStreamContentBuilder = new StringBuilder();
|
||||
private ChatAiMsgEntity mCurrentStreamEntity = null;
|
||||
|
||||
// 智能滚动管理
|
||||
private boolean mIsUserScrolling = false;
|
||||
|
||||
// 优化防抖机制
|
||||
private Handler mUpdateHandler = new Handler();
|
||||
private Runnable mUpdateRunnable;
|
||||
|
||||
private List<ChatQuestionEntity> mQuesTypeList = new ArrayList<>();
|
||||
private boolean mIsShowQuestions = true;
|
||||
|
||||
@Override
|
||||
public void initData(Bundle state) {
|
||||
|
||||
mOptionAdapter = new IndexOptionAdapter(mContext, R.layout.index_device_list_item, mIndexTemList);
|
||||
viewBinding.rvOptions.setAdapter(mOptionAdapter);
|
||||
mQuickAskAdapter = new IndexQuickAskAdapter(mContext, R.layout.index_home_quick_ask_item, mQuickAskList);
|
||||
viewBinding.rvQuickAsk.setAdapter(mQuickAskAdapter);
|
||||
mChatAdapter = new IndexChatAdapter(mContext, mChatMsgList, viewBinding.rvChat);
|
||||
viewBinding.rvChat.setAdapter(mChatAdapter);
|
||||
//提问类型
|
||||
GridLayoutManager manager = new GridLayoutManager(mContext, 2);
|
||||
viewBinding.rvChatQuick.setLayoutManager(manager);
|
||||
List<ChatQuestionEntity.SubheadingsDTO> subList = new ArrayList<>();
|
||||
mQuesDetailAdapter = new ChatQuestionDetailAdapter(R.layout.chat_quest_detail_item, subList);
|
||||
viewBinding.rvChatQuick.setAdapter(mQuesDetailAdapter);
|
||||
viewBinding.rvChatQuick.addItemDecoration(new GridSpacingItemDecoration(2, 10, true));
|
||||
mZixunQuestAdapter = new ChatZixunAdapter(mContext, R.layout.chat_zixun_type_item, mQuesTypeList);
|
||||
viewBinding.rvChatType.setAdapter(mZixunQuestAdapter);
|
||||
|
||||
// 设置聊天RecyclerView的LayoutManager(禁用滚动)
|
||||
androidx.recyclerview.widget.LinearLayoutManager chatLayoutManager =
|
||||
new androidx.recyclerview.widget.LinearLayoutManager(mContext);
|
||||
chatLayoutManager.setStackFromEnd(false);
|
||||
viewBinding.rvChat.setLayoutManager(chatLayoutManager);
|
||||
|
||||
// 禁用RecyclerView的滚动,让NestedScrollView处理滚动
|
||||
viewBinding.rvChat.setNestedScrollingEnabled(false);
|
||||
|
||||
mHintAdapter = new IndexEnterHintAdapter(mContext, R.layout.index_enter_hint_item, new ArrayList<>());
|
||||
viewBinding.rvEnterHint.setAdapter(mHintAdapter);
|
||||
|
||||
setAdapterClick();
|
||||
|
||||
// 添加EditText的焦点监听器
|
||||
viewBinding.editInput.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
// EditText获取焦点时,延迟滚动到底部,确保键盘弹出后再滚动
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
scrollNestedScrollViewToBottom();
|
||||
}
|
||||
}, 300); // 延迟300ms,等待键盘弹出
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
viewBinding.editInput.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (s != null) {
|
||||
mCurrentInputContent = s.toString().trim();
|
||||
if (TextUtils.isEmpty(s.toString().trim())) {
|
||||
viewBinding.imgSend.setImageDrawable(ContextCompat.getDrawable(mContext, R.mipmap.icon_index_send));
|
||||
viewBinding.editInput.setHint("请输入您的问题");
|
||||
} else {
|
||||
viewBinding.imgSend.setImageDrawable(ContextCompat.getDrawable(mContext, R.mipmap.icon_index_send_b));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//请求页面模板数据
|
||||
mPresenter.getIndexTemplateDatas();
|
||||
mPresenter.getChatTemplateDatas();
|
||||
//组件增加点击区域
|
||||
ClickUtil.addClickPart(viewBinding.imgCloseQuick, 30);
|
||||
ClickUtil.addClickPart(viewBinding.imgRefresh, 30);
|
||||
ClickUtil.addClickPart(viewBinding.imgHistory, 30);
|
||||
|
||||
// 设置智能滚动监听
|
||||
setupSmartScrollListener();
|
||||
// 设置页面点击监听,用于隐藏键盘
|
||||
setupPageClickListener();
|
||||
// 检查是否有传递过来的参数
|
||||
checkAndHandleBundle();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并处理传递过来的Bundle参数
|
||||
*/
|
||||
private void checkAndHandleBundle() {
|
||||
Bundle args = getArguments();
|
||||
if (args != null) {
|
||||
handleBirthInfoBundle(args);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理出生信息Bundle参数
|
||||
*
|
||||
* @param bundle 包含出生信息的Bundle
|
||||
*/
|
||||
public void handleBirthInfoBundle(Bundle bundle) {
|
||||
if (bundle != null) {
|
||||
BaziResultBean baseEntity = PaipanCache.get();
|
||||
// 获取出生信息
|
||||
BaziResultBean.BaseInfoDTO birthInfo = baseEntity.getBaseInfo();
|
||||
BaziResultBean.DetailInfoDTO.SizhuInfoDTO sizhuInfoDTO = baseEntity.getDetailInfo().getSizhuInfo();
|
||||
BaziResultBean.DetailInfoDTO.DayunInfoDTO defaulLiunian = (BaziResultBean.DetailInfoDTO.DayunInfoDTO) bundle.getSerializable("defaul_liunian");
|
||||
if (birthInfo != null) {
|
||||
viewBinding.editInput.setText("我叫" + birthInfo.getName() + "," +
|
||||
((birthInfo.getSex().equals("乾造") ? "男" : "女") + "," +
|
||||
"生于公历" + birthInfo.getGongli() + "," + "当前大运为" + defaulLiunian.getDayunStartYear() + "--" +
|
||||
defaulLiunian.getDayunEndYear() + "," + defaulLiunian.getDayunStartGanzhi() + "大运,四柱为"
|
||||
+ sizhuInfoDTO.getYear().getTg() + sizhuInfoDTO.getYear().getDz() + "、" +
|
||||
sizhuInfoDTO.getMonth().getTg() + sizhuInfoDTO.getMonth().getDz() + "、" +
|
||||
sizhuInfoDTO.getDay().getTg() + sizhuInfoDTO.getDay().getDz() + "、" +
|
||||
sizhuInfoDTO.getHour().getTg() + sizhuInfoDTO.getHour().getDz() + "," +
|
||||
"现在需要你根据我的八字,给我具体分析一下我的事业、感情、健康、财富、格局、喜用神"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 当Fragment参数更新时调用(用于处理onNewIntent的情况)
|
||||
*/
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// 检查是否有新的参数需要处理
|
||||
Bundle args = getArguments();
|
||||
if (args != null && args.getBoolean("goto_index_fragment", false)) {
|
||||
// 处理参数
|
||||
handleBirthInfoBundle(args);
|
||||
|
||||
// 清除标记,避免重复处理
|
||||
args.remove("goto_index_fragment");
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MainThread)
|
||||
public void onGetMessage(EventMessage message) {
|
||||
//用户添加地址成功
|
||||
if (message.getEventStrKey().equals(EventMessage.HISTORY_SESSIONID_DELETE_SUCCESS)) {
|
||||
if (message.getMsg().equals(mSessionId)) {
|
||||
// viewBinding.linearOptionHint.setVisibility(View.VISIBLE);
|
||||
mChatMsgList.clear();
|
||||
mChatAdapter.setNewData(mChatMsgList);
|
||||
mSessionId = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置页面点击监听器
|
||||
*/
|
||||
private void setupPageClickListener() {
|
||||
viewBinding.rvChat.setOnTouchListener(new View.OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
// 当用户触摸NestedScrollView时,隐藏键盘并清除焦点
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
hideKeyboardAndClearFocus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏键盘并清除EditText焦点
|
||||
*/
|
||||
private void hideKeyboardAndClearFocus() {
|
||||
// 清除EditText焦点
|
||||
viewBinding.editInput.clearFocus();
|
||||
|
||||
// 隐藏键盘
|
||||
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm != null) {
|
||||
imm.hideSoftInputFromWindow(viewBinding.editInput.getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 滚动NestedScrollView到底部
|
||||
*/
|
||||
private void scrollNestedScrollViewToBottom() {
|
||||
if (viewBinding.nestedScrollChat != null) {
|
||||
// 获取NestedScrollView的子视图(RecyclerView)
|
||||
View childView = viewBinding.nestedScrollChat.getChildAt(0);
|
||||
if (childView != null) {
|
||||
// 滚动到底部
|
||||
viewBinding.nestedScrollChat.smoothScrollTo(0, childView.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置智能滚动监听器(修改为监听NestedScrollView)
|
||||
*/
|
||||
private void setupSmartScrollListener() {
|
||||
// 监听NestedScrollView的滚动
|
||||
viewBinding.nestedScrollChat.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
|
||||
@Override
|
||||
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
|
||||
// 检测用户是否向上滑动
|
||||
if (scrollY < oldScrollY) {
|
||||
// 用户向上滑动
|
||||
mIsUserScrolling = true;
|
||||
} else if (scrollY > oldScrollY) {
|
||||
// 用户向下滑动
|
||||
mIsUserScrolling = true;
|
||||
}
|
||||
|
||||
// 检查是否滚动到底部
|
||||
if (scrollY >= (v.getChildAt(0).getHeight() - v.getHeight())) {
|
||||
// 滚动到底部,恢复自动滚动
|
||||
mIsUserScrolling = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void setAdapterClick() {
|
||||
//顶部的选项 adapter 点击事件
|
||||
mOptionAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
if (mCurrentStreamPos != position) {
|
||||
if (mIsStreamStop) {
|
||||
viewBinding.rlQuickAsk.setVisibility(View.GONE);
|
||||
mOptionAdapter.setSelectPos(position);
|
||||
setOptionSelStyle(position);
|
||||
mCurrentStreamPos = position;
|
||||
mSessionId = "";
|
||||
mSelectTypeID = mIndexTemList.get(position).getId();
|
||||
} else {
|
||||
ToastUtil.showShort(mContext, "Ai解答中,请稍后操作");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//咨询类型 adapter
|
||||
mZixunQuestAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
if (mIsStreamStop) {
|
||||
mZixunQuestAdapter.setSelectPos(position);
|
||||
mQuesDetailAdapter.setNewData(mQuesTypeList.get(position).getSubheadings());
|
||||
} else {
|
||||
ToastUtil.showShort(mContext, "Ai解答中,请稍后操作");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//快速提问
|
||||
mQuesDetailAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
if (!AppConfig.USER_LOGIN) {
|
||||
goTo(mContext, LoginActivity.class, null);
|
||||
return;
|
||||
}
|
||||
if (!mIsStreamStop) {
|
||||
ToastUtil.showShort(mContext, "Ai解答中,请稍后操作");
|
||||
return;
|
||||
}
|
||||
String quickAskContent = mQuesTypeList.get(mZixunQuestAdapter.getmSelPos()).
|
||||
getSubheadings().get(position).getContent();
|
||||
sendMsgToAi(quickAskContent);
|
||||
}
|
||||
});
|
||||
|
||||
//流式输出,是否完成
|
||||
mChatAdapter.setOnStreamCompleteListener(new IndexChatAdapter.OnStreamCompleteListener() {
|
||||
@Override
|
||||
//此时已经流式输出完成
|
||||
public void onStreamComplete(int position) {
|
||||
mCurrentStreamPos = position;
|
||||
viewBinding.imgSend.setVisibility(View.VISIBLE);
|
||||
viewBinding.imgStop.setVisibility(View.GONE);
|
||||
mIsStreamStop = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamStop() {
|
||||
viewBinding.imgSend.setVisibility(View.VISIBLE);
|
||||
viewBinding.imgStop.setVisibility(View.GONE);
|
||||
mIsStreamStop = true;
|
||||
}
|
||||
});
|
||||
mChatAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
|
||||
@Override
|
||||
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
switch (view.getId()) {
|
||||
case R.id.img_jb:
|
||||
ContentReportDialog cancelDialog = new ContentReportDialog(mContext, R.layout.dialog_report_reason, "");
|
||||
cancelDialog.show();
|
||||
cancelDialog.setOnDialogListener(new ContentReportDialog.DialogListener() {
|
||||
@Override
|
||||
public void callBackDatas(String reason) {
|
||||
showLoadingDialog();
|
||||
//举报
|
||||
mPresenter.commitReport(reason);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 设置长按菜单监听器
|
||||
mChatAdapter.setOnItemLongClickMenuListener(new IndexChatAdapter.OnItemLongClickMenuListener() {
|
||||
@Override
|
||||
public void onCopyClick(ChatMultiItem item, int position) {
|
||||
// 处理复制操作
|
||||
String content = item.getMessage().getContent();
|
||||
if (!TextUtils.isEmpty(content)) {
|
||||
ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
ClipData clip = ClipData.newPlainText("chat_content", content);
|
||||
clipboard.setPrimaryClip(clip);
|
||||
ToastUtil.showShort(mContext, "内容已复制");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReportClick(ChatMultiItem item, int position) {
|
||||
// 处理举报操作
|
||||
ContentReportDialog cancelDialog = new ContentReportDialog(mContext, R.layout.dialog_report_reason, "");
|
||||
cancelDialog.show();
|
||||
cancelDialog.setOnDialogListener(new ContentReportDialog.DialogListener() {
|
||||
@Override
|
||||
public void callBackDatas(String reason) {
|
||||
showLoadingDialog();
|
||||
//举报
|
||||
mPresenter.commitReport(reason);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 添加长按监听器
|
||||
// mChatAdapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {
|
||||
// @Override
|
||||
// public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
// switch (view.getId()) {
|
||||
// case R.id.tv_text: // 文本内容的view id
|
||||
// XPopup.fixLongClick(view); // 能保证弹窗弹出后,下层的View无法滑动
|
||||
//
|
||||
// // 获取当前消息内容
|
||||
// ChatMultiItem item = mChatMsgList.get(position);
|
||||
// String content = item.getMessage().getContent();
|
||||
//
|
||||
// // 使用链式调用,确保atView在asAttachList之前
|
||||
// new XPopup.Builder(getContext())
|
||||
// .hasShadowBg(false)
|
||||
// .atView(view) // 使用atView而不是watchView
|
||||
// .asAttachList(new String[]{"复制", "举报"},
|
||||
// null,
|
||||
// new OnSelectListener() {
|
||||
// @Override
|
||||
// public void onSelect(int selectPosition, String text) {
|
||||
// switch (selectPosition) {
|
||||
// case 0: // 复制
|
||||
// if (!TextUtils.isEmpty(content)) {
|
||||
// ClipboardManager clipboard = (ClipboardManager) mContext.getSystemService(Context.CLIPBOARD_SERVICE);
|
||||
// ClipData clip = ClipData.newPlainText("chat_content", content);
|
||||
// clipboard.setPrimaryClip(clip);
|
||||
// ToastUtil.showShort(mContext, "内容已复制");
|
||||
// }
|
||||
// break;
|
||||
// case 1: // 举报
|
||||
// ContentReportDialog cancelDialog = new ContentReportDialog(mContext, R.layout.dialog_report_reason, "");
|
||||
// cancelDialog.show();
|
||||
// cancelDialog.setOnDialogListener(new ContentReportDialog.DialogListener() {
|
||||
// @Override
|
||||
// public void callBackDatas(String reason) {
|
||||
// showLoadingDialog();
|
||||
// //举报
|
||||
// mPresenter.commitReport(reason);
|
||||
// }
|
||||
// });
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// .show();
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 停止输出
|
||||
*/
|
||||
private void stopSteamOutput() {
|
||||
// 停止当前网络请求
|
||||
mPresenter.stopCurrentRequest();
|
||||
|
||||
// 获取当前正在流式输出的位置
|
||||
int currentPosition = mChatMsgList.size() - 1;
|
||||
|
||||
// 标记当前消息为被停止状态
|
||||
mChatAdapter.markAsStopped(currentPosition);
|
||||
|
||||
// 停止适配器中的流式输出
|
||||
mChatAdapter.setStreamerStop(currentPosition);
|
||||
|
||||
// 清除当前流式输出位置
|
||||
mChatAdapter.setCurrentStreamingPosition(-1);
|
||||
|
||||
// 强制更新当前item以显示停止标识
|
||||
mChatAdapter.notifyItemChanged(currentPosition);
|
||||
|
||||
// 恢复UI状态
|
||||
viewBinding.imgSend.setVisibility(View.VISIBLE);
|
||||
viewBinding.imgStop.setVisibility(View.GONE);
|
||||
mIsStreamStop = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (data != null) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
switch (requestCode) {
|
||||
case REQUEST_EVENT_CODE_10001:
|
||||
String sessionId = data.getStringExtra("session_id");
|
||||
String numerologyType = data.getStringExtra("numerology_type");
|
||||
int showSelPos = -1;
|
||||
for (int i = 0; i < mIndexTemList.size(); i++) {
|
||||
if (numerologyType.equals(mIndexTemList.get(i).getId())) {
|
||||
showSelPos = i;
|
||||
}
|
||||
}
|
||||
if (mCurrentStreamPos != showSelPos) {
|
||||
|
||||
}
|
||||
if (mIsStreamStop) {
|
||||
viewBinding.rlQuickAsk.setVisibility(View.GONE);
|
||||
mOptionAdapter.setSelectPos(showSelPos);
|
||||
setOptionSelStyle(showSelPos);
|
||||
mCurrentStreamPos = showSelPos;
|
||||
mSelectTypeID = mIndexTemList.get(showSelPos).getId();
|
||||
if (!TextUtils.isEmpty(sessionId)) {
|
||||
mPresenter.getChatDetailByID(sessionId);
|
||||
}
|
||||
} else {
|
||||
ToastUtil.showShort(mContext, "Ai解答中,请稍后操作");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息给 AI
|
||||
*/
|
||||
private void sendMsgToAi(String senMsg) {
|
||||
if (!AppConfig.USER_LOGIN) {
|
||||
goTo(mContext, LoginActivity.class, null);
|
||||
return;
|
||||
}
|
||||
viewBinding.cardQuestion.setVisibility(View.GONE);
|
||||
viewBinding.imgClose.setImageDrawable(ContextCompat.getDrawable(mContext, R.mipmap.icon_chat_down));
|
||||
mIsShowQuestions = false;
|
||||
viewBinding.linearOptionHint.setVisibility(View.GONE);
|
||||
// 重置滚动状态
|
||||
mIsUserScrolling = false;
|
||||
// 清理适配器缓存
|
||||
mChatAdapter.clearCache();
|
||||
|
||||
// 创建用户消息
|
||||
ChatAiMsgEntity chatMsgEntity = new ChatAiMsgEntity();
|
||||
chatMsgEntity.setSessionId(mSessionId);
|
||||
chatMsgEntity.setType(mSelectTypeID);
|
||||
chatMsgEntity.setContent(senMsg);
|
||||
ChatMultiItem userEntity = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_RIGHT, chatMsgEntity);
|
||||
mChatMsgList.add(userEntity);
|
||||
mChatAdapter.notifyItemInserted(mChatMsgList.size() - 1);
|
||||
|
||||
// 创建AI回复消息(初始为空)
|
||||
mCurrentStreamEntity = new ChatAiMsgEntity();
|
||||
mCurrentStreamEntity.setSessionId(mSessionId);
|
||||
mCurrentStreamEntity.setType(mSelectTypeID);
|
||||
mCurrentStreamEntity.setContent(""); // 初始为空
|
||||
ChatMultiItem aiEntity = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_LEFT, mCurrentStreamEntity);
|
||||
mChatMsgList.add(aiEntity);
|
||||
|
||||
// 设置当前流式输出位置
|
||||
int aiMessagePosition = mChatMsgList.size() - 1;
|
||||
mChatAdapter.setCurrentStreamingPosition(aiMessagePosition);
|
||||
mChatAdapter.notifyItemInserted(aiMessagePosition);
|
||||
|
||||
// 重置流式数据累积器
|
||||
mStreamContentBuilder.setLength(0);
|
||||
|
||||
// 清空输入框
|
||||
viewBinding.editInput.setText("");
|
||||
|
||||
// 设置UI状态
|
||||
viewBinding.imgSend.setVisibility(View.GONE);
|
||||
viewBinding.imgStop.setVisibility(View.VISIBLE);
|
||||
|
||||
// 发送消息后自动滚动到底部
|
||||
scrollToBottomAfterSend();
|
||||
|
||||
// 发起流式请求
|
||||
mPresenter.talkToAi(senMsg, mSelectTypeID, mSessionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IndexPresenter createPresenter() {
|
||||
return new IndexPresenter(new IndexImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTalkResultSuccess(ChatAiMsgEntity bean) {
|
||||
hideDialogLoading();
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页数据获取成功
|
||||
*
|
||||
* @param list
|
||||
*/
|
||||
@Override
|
||||
public void getIndexTemplateSuccess(List<IndexTemplateEntity> list) {
|
||||
if (list != null && list.size() != 0) {
|
||||
mIndexTemList = list;
|
||||
mOptionAdapter.setNewData(mIndexTemList);
|
||||
setAdapterClick();
|
||||
setOptionSelStyle(0);
|
||||
mSelectTypeID = mIndexTemList.get(0).getId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换设置显示内容
|
||||
*
|
||||
* @param pos
|
||||
*/
|
||||
private void setOptionSelStyle(int pos) {
|
||||
try {
|
||||
mChatMsgList.clear();
|
||||
mChatAdapter.setNewData(mChatMsgList);
|
||||
// 清理缓存
|
||||
mChatAdapter.clearCache();
|
||||
// viewBinding.linearOptionHint.setVisibility(View.VISIBLE);
|
||||
IndexTemplateEntity defaulEntity = mIndexTemList.get(pos);
|
||||
viewBinding.tvTitleExpert.setText(defaulEntity.getTitle() + "专家");
|
||||
viewBinding.tvSelectOptionLable.setText(defaulEntity.getTitle() + "专家");
|
||||
viewBinding.tvSelectOptionSlogan.setText(defaulEntity.getSubheading());
|
||||
if (ColorManage.getInstance().isParsableColor(defaulEntity.getColor())) {
|
||||
viewBinding.tvSelectOptionSlogan.setTextColor(Color.parseColor(defaulEntity.getColor()));
|
||||
} else {
|
||||
viewBinding.tvSelectOptionSlogan.setTextColor(ContextCompat.getColor(mContext, R.color.color_zhu));
|
||||
}
|
||||
//提示语
|
||||
List<String> hintMsgList = new ArrayList<>();
|
||||
hintMsgList = Arrays.asList(defaulEntity.getIntermediateContent().split("#"));
|
||||
mHintAdapter.setNewData(hintMsgList);
|
||||
//快速提问
|
||||
mQuickAskList.clear();
|
||||
List<String> quickAskList = new ArrayList<>();
|
||||
quickAskList = Arrays.asList(defaulEntity.getQuickQuestions().split("#"));
|
||||
for (String content : quickAskList) {
|
||||
IndexTemplateEntity entity = new IndexTemplateEntity();
|
||||
entity.setColor(defaulEntity.getColor());
|
||||
entity.setBlackcolor(defaulEntity.getBlackcolor());
|
||||
entity.setSpliteItemContent(content);
|
||||
mQuickAskList.add(entity);
|
||||
}
|
||||
mQuickAskAdapter.setNewData(mQuickAskList);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNetChange(int netModel) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showError(String message) {
|
||||
hideDialogLoading();
|
||||
ToastUtil.showShort(mContext, message);
|
||||
// 流式传输完成,恢复UI状态
|
||||
viewBinding.imgSend.setVisibility(View.VISIBLE);
|
||||
viewBinding.imgStop.setVisibility(View.GONE);
|
||||
mIsStreamStop = true;
|
||||
|
||||
// 可以在这里处理会话ID等
|
||||
if (mCurrentStreamEntity != null && !TextUtils.isEmpty(mCurrentStreamEntity.getSessionId())) {
|
||||
mSessionId = mCurrentStreamEntity.getSessionId();
|
||||
}
|
||||
|
||||
// 清理当前流式实体
|
||||
mCurrentStreamEntity = null;
|
||||
mStreamContentBuilder.setLength(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logOut(BaseBean bean) {
|
||||
|
||||
}
|
||||
|
||||
// 实现流式消息接收回调
|
||||
@Override
|
||||
public void onStreamMessageReceived(String messageChunk) {
|
||||
mIsStreamStop = false;
|
||||
if (mCurrentStreamEntity != null) {
|
||||
// 更新当前AI消息的内容
|
||||
mCurrentStreamEntity.setContent(messageChunk);
|
||||
|
||||
// 取消之前的更新任务
|
||||
if (mUpdateRunnable != null) {
|
||||
mUpdateHandler.removeCallbacks(mUpdateRunnable);
|
||||
}
|
||||
|
||||
mUpdateRunnable = () -> {
|
||||
// 只更新最后一个item
|
||||
int lastPosition = mChatMsgList.size() - 1;
|
||||
if (lastPosition >= 0) {
|
||||
// 使用更轻量的更新方式,避免重新布局
|
||||
mChatAdapter.notifyItemChanged(lastPosition, "content_only");
|
||||
|
||||
// 流式输出时,如果用户没有手动滑动,则自动滚动NestedScrollView
|
||||
if (!mIsUserScrolling) {
|
||||
smoothScrollNestedScrollView();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 增加延迟时间,减少更新频率
|
||||
mUpdateHandler.postDelayed(mUpdateRunnable, 100);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 实现流式完成回调
|
||||
@Override
|
||||
public void onStreamComplete(String complateMsg) {
|
||||
// 流式传输完成,恢复UI状态
|
||||
viewBinding.imgSend.setVisibility(View.VISIBLE);
|
||||
viewBinding.imgStop.setVisibility(View.GONE);
|
||||
mIsStreamStop = true;
|
||||
|
||||
// 清除当前流式输出位置
|
||||
mChatAdapter.setCurrentStreamingPosition(-1);
|
||||
|
||||
// 注意:这里不标记为停止状态,因为这是正常完成
|
||||
|
||||
// 可以在这里处理会话ID等
|
||||
if (mCurrentStreamEntity != null && !TextUtils.isEmpty(mCurrentStreamEntity.getSessionId())) {
|
||||
mSessionId = mCurrentStreamEntity.getSessionId();
|
||||
}
|
||||
|
||||
// 清理当前流式实体
|
||||
mCurrentStreamEntity = null;
|
||||
mStreamContentBuilder.setLength(0);
|
||||
// 假设你最后一个消息是流式的 placeholder,现在替换它
|
||||
ChatMultiItem lastMessage = mChatMsgList.get(mChatMsgList.size() - 1);
|
||||
lastMessage.getMessage().setContent(complateMsg); // 你可以解析 Markdown 变 PlainText,或保留 Markdown 渲染
|
||||
// mChatAdapter.notifyItemChanged(mChatMsgList.size() - 1); // 更新 UI
|
||||
int lastPos = mChatAdapter.getItemCount() - 1;
|
||||
mChatAdapter.updateTipsVisibility(lastPos);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据会话 id 查询对话详情
|
||||
*
|
||||
* @param list
|
||||
*/
|
||||
@Override
|
||||
public void getChatDetailSuccess(List<ChatAiMsgEntity> list) {
|
||||
mChatMsgList.clear();
|
||||
if (list != null && list.size() != 0) {
|
||||
mSessionId = list.get(0).getSessionId();
|
||||
}
|
||||
for (ChatAiMsgEntity entity : list) {
|
||||
ChatMultiItem item;
|
||||
if (entity.getRole().equals("user")) {
|
||||
item = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_RIGHT, entity);
|
||||
} else {
|
||||
item = new ChatMultiItem(ChatMultiItem.TYPE_TEXT_LEFT, entity);
|
||||
}
|
||||
mChatMsgList.add(item);
|
||||
}
|
||||
mChatAdapter.setNewData(mChatMsgList);
|
||||
viewBinding.linearOptionHint.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginLost() {
|
||||
if (isFragmentVisible()) {
|
||||
handleLoginLost();
|
||||
}
|
||||
stopSteamOutput();
|
||||
if (mChatAdapter != null) {
|
||||
mChatAdapter.remove(mChatMsgList.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取咨询模板成功
|
||||
*
|
||||
* @param list
|
||||
*/
|
||||
@Override
|
||||
public void getChatZixunSuccess(List<ChatQuestionEntity> list) {
|
||||
this.mQuesTypeList = list;
|
||||
if (list != null) {
|
||||
mZixunQuestAdapter.setNewData(list);
|
||||
mQuesDetailAdapter.setNewData(list.get(0).getSubheadings());
|
||||
setAdapterClick();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 举报成功
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void commitReportSuccess(BaseBean bean) {
|
||||
ToastUtil.showShort(mContext, "星语明灯感谢您的反馈");
|
||||
hideDialogLoading();
|
||||
}
|
||||
|
||||
// 实现sessionId接收回调
|
||||
@Override
|
||||
public void onSessionReceived(String sessionId) {
|
||||
// 保存sessionId
|
||||
mSessionId = sessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getHistoryDataSuccess(CharHistoryEntity entity) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteHistorySuccess(BaseBean bean, int delPos) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 平滑滚动NestedScrollView到底部
|
||||
*/
|
||||
private void smoothScrollNestedScrollView() {
|
||||
if (mChatAdapter != null && mChatAdapter.getItemCount() > 0) {
|
||||
// 直接滚动NestedScrollView到底部
|
||||
viewBinding.nestedScrollChat.post(() -> {
|
||||
viewBinding.nestedScrollChat.fullScroll(View.FOCUS_DOWN);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 发送消息后滚动到底部
|
||||
*/
|
||||
private void scrollToBottomAfterSend() {
|
||||
new Handler().postDelayed(() -> {
|
||||
if (isFragmentVisible()) {
|
||||
viewBinding.nestedScrollChat.fullScroll(View.FOCUS_DOWN);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
|
||||
|
||||
}
|
||||
}
|
||||
225
app/src/main/java/com/ckkj/water/chat/ChatHistoryActivity.java
Normal file
225
app/src/main/java/com/ckkj/water/chat/ChatHistoryActivity.java
Normal file
@@ -0,0 +1,225 @@
|
||||
package com.ckkj.water.chat;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.gyf.immersionbar.ImmersionBar;
|
||||
import com.ckkj.water.chat.entity.ChatQuestionEntity;
|
||||
import com.scwang.smart.refresh.footer.ClassicsFooter;
|
||||
import com.scwang.smart.refresh.layout.api.RefreshHeader;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.base.BaseActivity;
|
||||
import com.ckkj.water.custom.view.CustomRefreshHeader;
|
||||
import com.ckkj.water.databinding.IndexHistoryLayoutBinding;
|
||||
import com.ckkj.water.chat.adapter.ChatHistoryAdapter;
|
||||
import com.ckkj.water.chat.entity.CharHistoryEntity;
|
||||
import com.ckkj.water.chat.entity.ChatAiMsgEntity;
|
||||
import com.ckkj.water.chat.entity.IndexTemplateEntity;
|
||||
import com.ckkj.water.chat.mvp.IndexContract;
|
||||
import com.ckkj.water.chat.mvp.IndexImpl;
|
||||
import com.ckkj.water.chat.mvp.IndexPresenter;
|
||||
import com.ckkj.water.network.BaseBean;
|
||||
import com.ckkj.water.utils.show.ToastUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/11
|
||||
* @description 历史记录
|
||||
*/
|
||||
|
||||
public class ChatHistoryActivity extends BaseActivity<IndexHistoryLayoutBinding, IndexPresenter>
|
||||
implements IndexContract.IndexView {
|
||||
private int mCurrentPage = 1;
|
||||
private ChatHistoryAdapter mAdapter;
|
||||
//历史记录
|
||||
private List<CharHistoryEntity.Sessions> mChatList = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public IndexPresenter createPresenter() {
|
||||
return new IndexPresenter(new IndexImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLayoutResId(Bundle savedInstanceState) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initData(Bundle savedInstanceState) {
|
||||
super.initData(savedInstanceState);
|
||||
ImmersionBar.with(this)
|
||||
.statusBarColor(R.color.white)
|
||||
.statusBarDarkFont(true)
|
||||
.titleBar(viewBinding.rlTitle) // 替换为你的标题栏View
|
||||
.keyboardEnable(true)
|
||||
.navigationBarDarkIcon(true)
|
||||
.init();
|
||||
viewBinding.includedTitle.tvTitle.setText("历史记录");
|
||||
viewBinding.includedTitle.imgBack.setOnClickListener(c ->finish());
|
||||
mAdapter = new ChatHistoryAdapter(mContext, R.layout.history_item_layout, mChatList);
|
||||
viewBinding.rvData.setAdapter(mAdapter);
|
||||
setAdapterClick();
|
||||
// 设置自定义刷新头
|
||||
RefreshHeader header = new CustomRefreshHeader(mContext);
|
||||
viewBinding.refresh.setRefreshHeader(header);
|
||||
viewBinding.refresh.setRefreshFooter(new ClassicsFooter(mContext));
|
||||
viewBinding.refresh.setOnRefreshListener(layout -> {
|
||||
mCurrentPage = 1;
|
||||
getHistoryDatas();
|
||||
});
|
||||
viewBinding.refresh.setOnLoadMoreListener(layout -> {
|
||||
mCurrentPage++;
|
||||
getHistoryDatas();
|
||||
});
|
||||
showLoadingDialog();
|
||||
getHistoryDatas();
|
||||
}
|
||||
|
||||
private void setAdapterClick() {
|
||||
mAdapter.setOnItemChildClickListener(new BaseQuickAdapter.OnItemChildClickListener() {
|
||||
@Override
|
||||
public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
switch (view.getId()){
|
||||
case R.id.img_delete:
|
||||
showLoadingDialog();
|
||||
mPresenter.deleteHistoryBySessionID(mChatList.get(position).getSessionId(),position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
mAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("session_id",mChatList.get(position).getSessionId());
|
||||
intent.putExtra("numerology_type",mChatList.get(position).getNumerologyType());
|
||||
setResult(RESULT_OK,intent);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void getHistoryDatas() {
|
||||
mPresenter.getHistoryDatas(mCurrentPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询历史数据成功 g
|
||||
*
|
||||
* @param entity
|
||||
*/
|
||||
@Override
|
||||
public void getHistoryDataSuccess(CharHistoryEntity entity) {
|
||||
hideDialogLoading();
|
||||
int totalPage = entity.getPages();
|
||||
viewBinding.refresh.finishRefresh(300);
|
||||
viewBinding.refresh.finishLoadMore(300);
|
||||
List<CharHistoryEntity.Sessions> list = entity.getSessions();
|
||||
if (mCurrentPage == 1) {
|
||||
mChatList.clear(); // 只在刷新时清除
|
||||
mChatList = list;
|
||||
} else {
|
||||
mChatList.addAll(list);
|
||||
}
|
||||
mAdapter.setNewData(mChatList);
|
||||
// 4. 判断是否还有更多数据
|
||||
if (totalPage == mCurrentPage || list == null || list.size() == 0) {
|
||||
// ✅ 告诉 SmartRefreshLayout 没有更多数据了
|
||||
viewBinding.refresh.setNoMoreData(true);
|
||||
viewBinding.relNoMore.setVisibility(View.VISIBLE); // 自定义底部提示“暂无更多数据”
|
||||
} else {
|
||||
viewBinding.refresh.setNoMoreData(false); // 重置状态
|
||||
viewBinding.relNoMore.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// 5. 控制空布局和内容显示
|
||||
if (mAdapter.getItemCount() != 0) {
|
||||
viewBinding.refresh.setVisibility(View.VISIBLE);
|
||||
viewBinding.relNoresult.setVisibility(View.GONE);
|
||||
} else {
|
||||
viewBinding.refresh.setVisibility(View.GONE);
|
||||
viewBinding.relNoresult.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除历史会话记录成功
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void deleteHistorySuccess(BaseBean bean, int delPos) {
|
||||
hideDialogLoading();
|
||||
mAdapter.remove(delPos);
|
||||
if(mAdapter.getItemCount() == 0){
|
||||
viewBinding.refresh.setVisibility(View.GONE);
|
||||
viewBinding.relNoresult.setVisibility(View.VISIBLE);
|
||||
viewBinding.relNoMore.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getChatDetailSuccess(List<ChatAiMsgEntity> list) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginLost() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getChatZixunSuccess(List<ChatQuestionEntity> list) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void commitReportSuccess(BaseBean bean) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getTalkResultSuccess(ChatAiMsgEntity bean) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getIndexTemplateSuccess(List<IndexTemplateEntity> list) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamMessageReceived(String messageChunk) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStreamComplete(String complateMsg) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionReceived(String sessionId) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void showError(String message) {
|
||||
viewBinding.refresh.finishRefresh(500);
|
||||
viewBinding.refresh.finishLoadMore(200);
|
||||
ToastUtil.showShort(mContext, message);
|
||||
hideDialogLoading();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logOut(BaseBean bean) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.ckkj.water.chat.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.chat.entity.CharHistoryEntity;
|
||||
import com.ckkj.water.utils.time.ZYTimeUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/11
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class ChatHistoryAdapter extends BaseQuickAdapter<CharHistoryEntity.Sessions, BaseViewHolder> {
|
||||
private Context mContext;
|
||||
|
||||
public ChatHistoryAdapter(Context context,int layoutResId, @Nullable List<CharHistoryEntity.Sessions> data) {
|
||||
super(layoutResId, data);
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, CharHistoryEntity.Sessions item) {
|
||||
ImageView imgType = helper.getView(R.id.img_logo);
|
||||
switch (item.getNumerologyType()){
|
||||
case "1"://八字命理
|
||||
imgType.setImageDrawable(ContextCompat.getDrawable(mContext,R.mipmap.icon_index_bzml));
|
||||
helper.setBackgroundRes(R.id.tv_type_name,R.drawable.shape_history_type_bzml_bg);
|
||||
helper.setTextColor(R.id.tv_type_name,ContextCompat.getColor(mContext,R.color.color_319EF4));
|
||||
break;
|
||||
case "2"://紫微斗数
|
||||
imgType.setImageDrawable(ContextCompat.getDrawable(mContext,R.mipmap. icon_index_zwds));
|
||||
helper.setBackgroundRes(R.id.tv_type_name,R.drawable.shape_history_type_zwds_bg);
|
||||
helper.setTextColor(R.id.tv_type_name,ContextCompat.getColor(mContext,R.color.color_B85CE6));
|
||||
break;
|
||||
case "3"://风水堪舆
|
||||
imgType.setImageDrawable(ContextCompat.getDrawable(mContext,R.mipmap.icon_index_fsky));
|
||||
helper.setBackgroundRes(R.id.tv_type_name,R.drawable.shape_history_type_fsky_bg);
|
||||
helper.setTextColor(R.id.tv_type_name,ContextCompat.getColor(mContext,R.color.color_24B326));
|
||||
break;
|
||||
case "6"://奇门遁甲
|
||||
imgType.setImageDrawable(ContextCompat.getDrawable(mContext,R.mipmap.icon_index_qmdj));
|
||||
helper.setBackgroundRes(R.id.tv_type_name,R.drawable.shape_history_type_qmdj_bg);
|
||||
helper.setTextColor(R.id.tv_type_name,ContextCompat.getColor(mContext,R.color.color_2A5CAA));
|
||||
break;
|
||||
case "10"://五行起名
|
||||
imgType.setImageDrawable(ContextCompat.getDrawable(mContext,R.mipmap. icon_index_wxqm));
|
||||
helper.setBackgroundRes(R.id.tv_type_name,R.drawable.shape_history_type_wxqm_bg);
|
||||
helper.setTextColor(R.id.tv_type_name,ContextCompat.getColor(mContext,R.color.color_E69900));
|
||||
break;
|
||||
default:
|
||||
imgType.setImageDrawable(ContextCompat.getDrawable(mContext,R.mipmap.icon_index_bzml));
|
||||
helper.setBackgroundRes(R.id.tv_type_name,R.drawable.shape_history_type_bzml_bg);
|
||||
helper.setTextColor(R.id.tv_type_name,ContextCompat.getColor(mContext,R.color.color_319EF4));
|
||||
break;
|
||||
}
|
||||
helper.setText(R.id.tv_type_content,item.getFirstUserMessage());
|
||||
helper.setText(R.id.tv_type_name,item.getSessionName());
|
||||
String chatTime = ZYTimeUtils.formatDateOrOneYearAgo(item.getCreateTime());
|
||||
helper.setText(R.id.tv_time,chatTime);
|
||||
helper.addOnClickListener(R.id.img_delete);
|
||||
// helper.addOnClickListener(R.id.rl_title);
|
||||
// helper.addOnClickListener(R.id.tv_type_content);
|
||||
// helper.addOnClickListener(R.id.img_logo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.ckkj.water.chat.adapter;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.chat.entity.ChatQuestionEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/8/19
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class ChatQuestionDetailAdapter extends BaseQuickAdapter<ChatQuestionEntity.SubheadingsDTO, BaseViewHolder> {
|
||||
|
||||
public ChatQuestionDetailAdapter(int layoutResId, @Nullable List<ChatQuestionEntity.SubheadingsDTO> data) {
|
||||
super(layoutResId, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, ChatQuestionEntity.SubheadingsDTO item) {
|
||||
helper.setText(R.id.tv_title,item.getTitle());
|
||||
helper.setText(R.id.tv_content,item.getContent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.ckkj.water.chat.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.chat.entity.ChatQuestionEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class ChatZixunAdapter extends BaseQuickAdapter<ChatQuestionEntity, BaseViewHolder> {
|
||||
private Context mContext;
|
||||
private int mSelPos = 0;
|
||||
|
||||
public ChatZixunAdapter(Context context, int layoutResId, @Nullable List<ChatQuestionEntity> data) {
|
||||
super(layoutResId, data);
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, ChatQuestionEntity item) {
|
||||
helper.setText(R.id.tv_content,item.getTeb());
|
||||
if(helper.getLayoutPosition() == mSelPos){
|
||||
helper.setTextColor(R.id.tv_content,mContext.getColor(R.color.color_zhu));
|
||||
helper.setBackgroundRes(R.id.tv_content, R.drawable.shape_chat_zixun_type);
|
||||
}else{
|
||||
helper.setTextColor(R.id.tv_content,mContext.getColor(R.color.color_7A8699));
|
||||
helper.setBackgroundRes(R.id.tv_content, R.drawable.shape_trans_touming);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSelectPos(int position) {
|
||||
this.mSelPos = position;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getmSelPos() {
|
||||
return mSelPos;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,244 @@
|
||||
package com.ckkj.water.chat.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Spanned;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.chat.entity.ChatAiMsgEntity;
|
||||
import com.ckkj.water.chat.entity.ChatMultiItem;
|
||||
import com.ckkj.water.utils.show.ToastUtil;
|
||||
import com.ckkj.water.utils.stream.MarkdownStreamer;
|
||||
import com.lxj.xpopup.XPopup;
|
||||
import com.lxj.xpopup.interfaces.OnSelectListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.noties.markwon.Markwon;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexChatAdapter extends BaseMultiItemQuickAdapter<ChatMultiItem, BaseViewHolder> {
|
||||
private Context mContext;
|
||||
private RecyclerView recyclerView;
|
||||
private OnStreamCompleteListener streamCompleteListener;
|
||||
//convert() 中每次绑定 item 时缓存 MarkdownStreamer 实例
|
||||
private final Map<Integer, MarkdownStreamer> streamerMap = new HashMap<>();
|
||||
|
||||
// 新增:Markdown 解析器
|
||||
private Markwon markwon;
|
||||
|
||||
// 新增:当前正在流式输出的位置
|
||||
private int mCurrentStreamingPosition = -1;
|
||||
// 用于标记哪个 position 需要显示 llTips
|
||||
// 在 IndexChatAdapter 类中新增字段
|
||||
private Integer pendingTipsCheckPos = null;
|
||||
// 新增:记录被停止的位置
|
||||
private final Map<Integer, Boolean> stoppedPositions = new HashMap<>();
|
||||
|
||||
public IndexChatAdapter(Context context, List<ChatMultiItem> data, RecyclerView recyclerView) {
|
||||
super(data);
|
||||
this.mContext = context;
|
||||
this.recyclerView = recyclerView;
|
||||
this.markwon = Markwon.create(context);
|
||||
addItemType(ChatMultiItem.TYPE_TEXT_LEFT, R.layout.item_text_left);
|
||||
addItemType(ChatMultiItem.TYPE_TEXT_RIGHT, R.layout.item_text_right);
|
||||
}
|
||||
|
||||
public void setStreamerStop(int position) {
|
||||
MarkdownStreamer streamer = streamerMap.get(position);
|
||||
if (streamer != null) {
|
||||
streamer.stopStreaming();
|
||||
streamerMap.remove(position);
|
||||
}
|
||||
if (mCurrentStreamingPosition == position) {
|
||||
mCurrentStreamingPosition = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 标记某个位置为被停止的状态
|
||||
*/
|
||||
public void markAsStopped(int position) {
|
||||
stoppedPositions.put(position, true);
|
||||
// 通知该位置更新显示
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
|
||||
public interface OnStreamCompleteListener {
|
||||
void onStreamComplete(int position);
|
||||
void onStreamStop();
|
||||
}
|
||||
|
||||
public void setOnStreamCompleteListener(OnStreamCompleteListener listener) {
|
||||
this.streamCompleteListener = listener;
|
||||
}
|
||||
|
||||
// 新增:长按菜单项点击回调接口
|
||||
public interface OnItemLongClickMenuListener {
|
||||
void onCopyClick(ChatMultiItem item, int position);
|
||||
void onReportClick(ChatMultiItem item, int position);
|
||||
}
|
||||
|
||||
private OnItemLongClickMenuListener mLongClickMenuListener;
|
||||
|
||||
public void setOnItemLongClickMenuListener(OnItemLongClickMenuListener listener) {
|
||||
this.mLongClickMenuListener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前正在流式输出的位置
|
||||
*/
|
||||
public void setCurrentStreamingPosition(int position) {
|
||||
mCurrentStreamingPosition = position;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 对外暴露的方法:检查某个 position 是否为最后一条,并据此显示/隐藏 llTips。
|
||||
* 仅记录“待检查的位置”并触发该 position 的刷新;实际显示逻辑在 convert() 末尾统一处理。
|
||||
*/
|
||||
public void updateTipsVisibility(int position) {
|
||||
if (position < 0 || position >= getItemCount()) return;
|
||||
pendingTipsCheckPos = position;
|
||||
// notifyItemChanged(position);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setPendingTipsCheckPos(Integer pendingTipsCheckPos) {
|
||||
this.pendingTipsCheckPos = pendingTipsCheckPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, ChatMultiItem item) {
|
||||
ChatAiMsgEntity msgEntity = item.getMessage();
|
||||
TextView tvContent = helper.getView(R.id.tv_text);
|
||||
LinearLayout llThinking = helper.getView(R.id.linear_thinking);
|
||||
LinearLayout llStop = helper.getView(R.id.linear_stop);
|
||||
LinearLayout llTips = helper.getView(R.id.linear_tips);
|
||||
int position = helper.getBindingAdapterPosition();
|
||||
helper.addOnClickListener(R.id.img_jb);
|
||||
// helper.addOnLongClickListener(R.id.tv_text);
|
||||
|
||||
if (item.getItemType() == ChatMultiItem.TYPE_TEXT_LEFT) {
|
||||
String content = msgEntity.getContent();
|
||||
if(TextUtils.isEmpty(content)){
|
||||
llThinking.setVisibility(View.VISIBLE);
|
||||
tvContent.setText("");
|
||||
llStop.setVisibility(View.GONE);
|
||||
} else {
|
||||
llThinking.setVisibility(View.GONE);
|
||||
|
||||
// 优化流式输出更新逻辑
|
||||
if (position == mCurrentStreamingPosition) {
|
||||
// 当前正在流式输出的位置
|
||||
try {
|
||||
Spanned spanned = markwon.toMarkdown(content);
|
||||
tvContent.setText(spanned);
|
||||
} catch (Exception e) {
|
||||
tvContent.setText(content);
|
||||
}
|
||||
|
||||
// 显示停止标识(如果被停止)
|
||||
if (stoppedPositions.containsKey(position) && stoppedPositions.get(position)) {
|
||||
llStop.setVisibility(View.VISIBLE);
|
||||
llTips.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
llStop.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
// 历史消息,直接显示完整内容
|
||||
try {
|
||||
Spanned spanned = markwon.toMarkdown(content);
|
||||
tvContent.setText(spanned);
|
||||
} catch (Exception e) {
|
||||
tvContent.setText(content);
|
||||
}
|
||||
|
||||
// 历史消息也检查是否被停止
|
||||
if (stoppedPositions.containsKey(position) && stoppedPositions.get(position)) {
|
||||
llStop.setVisibility(View.VISIBLE);
|
||||
llTips.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
llStop.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
Log.i("mingdenglog","XXXXX---position======" + pendingTipsCheckPos);
|
||||
if (pendingTipsCheckPos != null && position == pendingTipsCheckPos) {
|
||||
Log.i("mingdenglog","position======" + position);
|
||||
Log.i("mingdenglog","getItemCount() - 1 ------" + (getItemCount() - 1) );
|
||||
// 仅当是最后一条才显示 llTips,否则隐藏
|
||||
llTips.setVisibility(position == getItemCount() - 1 ? View.VISIBLE : View.GONE);
|
||||
// 用一次即清
|
||||
// pendingTipsCheckPos = null;
|
||||
}else{
|
||||
llTips.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
switch (item.getItemType()) {
|
||||
case ChatMultiItem.TYPE_TEXT_RIGHT:
|
||||
tvContent.setText(msgEntity.getContent());
|
||||
break;
|
||||
}
|
||||
|
||||
// //必须要在事件发生之前就watch
|
||||
final XPopup.Builder builder = new XPopup.Builder(mContext)
|
||||
.hasShadowBg(false).watchView(tvContent);
|
||||
tvContent.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
// 如果正在流式输出,则拦截长按事件,不执行任何操作
|
||||
if (mCurrentStreamingPosition != -1) {
|
||||
// 可以选择性地提示用户
|
||||
ToastUtil.showShort(mContext, "Ai解答中,请稍后操作");
|
||||
return true; // 拦截事件
|
||||
}
|
||||
|
||||
builder.asAttachList(new String[]{"复制", "举报"}, null, new OnSelectListener() {
|
||||
@Override
|
||||
public void onSelect(int menuPosition, String text) {
|
||||
// 通过接口回调处理菜单项点击事件
|
||||
if (mLongClickMenuListener != null) {
|
||||
switch (menuPosition){
|
||||
case 0: // 复制
|
||||
mLongClickMenuListener.onCopyClick(item, position);
|
||||
break;
|
||||
case 1: // 举报
|
||||
mLongClickMenuListener.onReportClick(item, position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理缓存
|
||||
*/
|
||||
public void clearCache() {
|
||||
streamerMap.clear();
|
||||
stoppedPositions.clear();
|
||||
mCurrentStreamingPosition = -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.ckkj.water.chat.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.ckkj.water.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexEnterHintAdapter extends BaseQuickAdapter<String, BaseViewHolder> {
|
||||
private Context mContext;
|
||||
private int mSelPos = 0;
|
||||
private String textColor;
|
||||
private String bgColor;
|
||||
|
||||
public void setColor(String textColor,String bgColor){
|
||||
this.textColor = textColor;
|
||||
this.bgColor = bgColor;
|
||||
}
|
||||
public IndexEnterHintAdapter(Context context, int layoutResId, @Nullable List<String> data) {
|
||||
super(layoutResId, data);
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, String item) {
|
||||
helper.setText(R.id.tv_quick_ask_name,item);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ckkj.water.chat.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.chat.entity.IndexTemplateEntity;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexOptionAdapter extends BaseQuickAdapter<IndexTemplateEntity, BaseViewHolder> {
|
||||
private Context mContext;
|
||||
private int mSelPos = 0;
|
||||
|
||||
public IndexOptionAdapter(Context context,int layoutResId, @Nullable List<IndexTemplateEntity> data) {
|
||||
super(layoutResId, data);
|
||||
this.mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, IndexTemplateEntity item) {
|
||||
// helper.setText(R.id.tv_option_name,item.getTitle());
|
||||
// if(helper.getLayoutPosition() == mSelPos){
|
||||
// helper.setTextColor(R.id.tv_option_name,mContext.getColor(R.color.white));
|
||||
// helper.setBackgroundRes(R.id.tv_option_name, R.drawable.shape_index_option_selected);
|
||||
// }else{
|
||||
// helper.setTextColor(R.id.tv_option_name,mContext.getColor(R.color.color_zhu));
|
||||
// helper.setBackgroundRes(R.id.tv_option_name, R.drawable.shape_index_option_un_selected);
|
||||
// }
|
||||
}
|
||||
|
||||
public void setSelectPos(int position) {
|
||||
this.mSelPos = position;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.ckkj.water.chat.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.GradientDrawable;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.chad.library.adapter.base.BaseQuickAdapter;
|
||||
import com.chad.library.adapter.base.BaseViewHolder;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.chat.entity.IndexTemplateEntity;
|
||||
import com.ckkj.water.utils.manager.ColorManage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/8
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexQuickAskAdapter extends BaseQuickAdapter<IndexTemplateEntity, BaseViewHolder> {
|
||||
private Context context;
|
||||
public IndexQuickAskAdapter(Context context,int layoutResId, @Nullable List<IndexTemplateEntity> data) {
|
||||
super(layoutResId, data);
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void convert(BaseViewHolder helper, IndexTemplateEntity item) {
|
||||
helper.setText(R.id.tv_quick_ask_name,item.getSpliteItemContent());
|
||||
if(ColorManage.getInstance().isParsableColor(item.getColor())){
|
||||
helper.setTextColor(R.id.tv_quick_ask_name, Color.parseColor(item.getColor()));
|
||||
}else{
|
||||
helper.setTextColor(R.id.tv_quick_ask_name, ContextCompat.getColor(mContext,R.color.color_zhu));
|
||||
}
|
||||
if(ColorManage.getInstance().isParsableColor(item.getBlackcolor())){
|
||||
setRoundedBackground(helper.getView(R.id.tv_quick_ask_name),Color.parseColor(item.getBlackcolor()),30);
|
||||
}else{
|
||||
setRoundedBackground(helper.getView(R.id.tv_quick_ask_name),ContextCompat.getColor(mContext,R.color.color_E5F2FB),30);
|
||||
}
|
||||
}
|
||||
|
||||
private void setRoundedBackground(View view, int fillColor, float cornerRadiusDp) {
|
||||
GradientDrawable drawable = new GradientDrawable();
|
||||
drawable.setShape(GradientDrawable.RECTANGLE);
|
||||
drawable.setColor(fillColor); // 设置填充色
|
||||
float radiusPx = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, cornerRadiusDp, view.getResources().getDisplayMetrics()
|
||||
);
|
||||
drawable.setCornerRadius(radiusPx); // 设置圆角半径(单位:px)
|
||||
view.setBackground(drawable); // 应用背景
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.ckkj.water.chat.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/11
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class CharHistoryEntity implements Serializable {
|
||||
private int total;
|
||||
private List<Sessions> sessions;
|
||||
private int pages;
|
||||
private int pageSize;
|
||||
private long userId;
|
||||
private int pageNum;
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setSessions(List<Sessions> sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
public List<Sessions> getSessions() {
|
||||
return sessions;
|
||||
}
|
||||
|
||||
public void setPages(int pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
public int getPages() {
|
||||
return pages;
|
||||
}
|
||||
|
||||
public void setPageSize(int pageSize) {
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
public int getPageSize() {
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setPageNum(int pageNum) {
|
||||
this.pageNum = pageNum;
|
||||
}
|
||||
public int getPageNum() {
|
||||
return pageNum;
|
||||
}
|
||||
|
||||
|
||||
public static class Sessions implements Serializable{
|
||||
|
||||
private String sessionId;
|
||||
private long userId;
|
||||
private String sessionName;
|
||||
private String numerologyType;
|
||||
private String firstUserMessage;
|
||||
private Date createTime;
|
||||
private Date updateTime;
|
||||
public void setSessionId(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
public String getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public void setUserId(long userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
public long getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setSessionName(String sessionName) {
|
||||
this.sessionName = sessionName;
|
||||
}
|
||||
public String getSessionName() {
|
||||
return sessionName;
|
||||
}
|
||||
|
||||
public void setNumerologyType(String numerologyType) {
|
||||
this.numerologyType = numerologyType;
|
||||
}
|
||||
public String getNumerologyType() {
|
||||
return numerologyType;
|
||||
}
|
||||
|
||||
public void setFirstUserMessage(String firstUserMessage) {
|
||||
this.firstUserMessage = firstUserMessage;
|
||||
}
|
||||
public String getFirstUserMessage() {
|
||||
return firstUserMessage;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package com.ckkj.water.chat.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class ChatAiMsgEntity implements Serializable {
|
||||
private int id;
|
||||
private String sessionId;
|
||||
private String type;
|
||||
private String content;
|
||||
private String role;
|
||||
private String messageOrder;
|
||||
private String createTime;
|
||||
|
||||
public String getSessionId() {
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public void setSessionId(String sessionId) {
|
||||
this.sessionId = sessionId;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(String role) {
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
public String getMessageOrder() {
|
||||
return messageOrder;
|
||||
}
|
||||
|
||||
public void setMessageOrder(String messageOrder) {
|
||||
this.messageOrder = messageOrder;
|
||||
}
|
||||
|
||||
public String getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(String createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.ckkj.water.chat.entity;
|
||||
|
||||
import com.chad.library.adapter.base.entity.MultiItemEntity;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class ChatMultiItem implements MultiItemEntity {
|
||||
public static final int TYPE_TEXT_LEFT = 1;
|
||||
public static final int TYPE_TEXT_RIGHT = 2;
|
||||
public static final int TYPE_IMAGE_LEFT = 3;
|
||||
public static final int TYPE_IMAGE_RIGHT = 4;
|
||||
public static final int TYPE_VOICE_LEFT = 5;
|
||||
public static final int TYPE_VOICE_RIGHT = 6;
|
||||
public static final int TYPE_TIME = 7; // 新增时间类型
|
||||
|
||||
private int itemType;
|
||||
private ChatAiMsgEntity message;
|
||||
|
||||
public ChatMultiItem(int itemType, ChatAiMsgEntity message) {
|
||||
this.itemType = itemType;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemType() {
|
||||
return itemType;
|
||||
}
|
||||
|
||||
public void setItemType(int itemType) {
|
||||
this.itemType = itemType;
|
||||
}
|
||||
|
||||
public ChatAiMsgEntity getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(ChatAiMsgEntity message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.ckkj.water.chat.entity;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/8/19
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class ChatQuestionEntity implements Serializable {
|
||||
|
||||
@SerializedName("teb")
|
||||
private String teb;
|
||||
@SerializedName("subheadings")
|
||||
private List<SubheadingsDTO> subheadings;
|
||||
@SerializedName("id")
|
||||
private String id;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public static class SubheadingsDTO {
|
||||
@SerializedName("title")
|
||||
private String title;
|
||||
@SerializedName("content")
|
||||
private String content;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.ckkj.water.chat.entity;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/8
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexTemplateEntity implements Serializable {
|
||||
private String id;
|
||||
private String title;
|
||||
private String titletp;
|
||||
private String color;
|
||||
private String blackcolor;
|
||||
private String subheading;
|
||||
private String intermediateContent;
|
||||
private String quickQuestions;
|
||||
private String hide;
|
||||
private String type;
|
||||
private String spliteItemContent;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getTitletp() {
|
||||
return titletp;
|
||||
}
|
||||
|
||||
public void setTitletp(String titletp) {
|
||||
this.titletp = titletp;
|
||||
}
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public String getBlackcolor() {
|
||||
return blackcolor;
|
||||
}
|
||||
|
||||
public void setBlackcolor(String blackcolor) {
|
||||
this.blackcolor = blackcolor;
|
||||
}
|
||||
|
||||
public String getSubheading() {
|
||||
return subheading;
|
||||
}
|
||||
|
||||
public void setSubheading(String subheading) {
|
||||
this.subheading = subheading;
|
||||
}
|
||||
|
||||
public String getIntermediateContent() {
|
||||
return intermediateContent;
|
||||
}
|
||||
|
||||
public void setIntermediateContent(String intermediateContent) {
|
||||
this.intermediateContent = intermediateContent;
|
||||
}
|
||||
|
||||
public String getQuickQuestions() {
|
||||
return quickQuestions;
|
||||
}
|
||||
|
||||
public void setQuickQuestions(String quickQuestions) {
|
||||
this.quickQuestions = quickQuestions;
|
||||
}
|
||||
|
||||
public String getHide() {
|
||||
return hide;
|
||||
}
|
||||
|
||||
public void setHide(String hide) {
|
||||
this.hide = hide;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getSpliteItemContent() {
|
||||
return spliteItemContent;
|
||||
}
|
||||
|
||||
public void setSpliteItemContent(String spliteItemContent) {
|
||||
this.spliteItemContent = spliteItemContent;
|
||||
}
|
||||
}
|
||||
78
app/src/main/java/com/ckkj/water/chat/mvp/IndexContract.java
Normal file
78
app/src/main/java/com/ckkj/water/chat/mvp/IndexContract.java
Normal file
@@ -0,0 +1,78 @@
|
||||
package com.ckkj.water.chat.mvp;
|
||||
|
||||
import com.ckkj.water.base.IView;
|
||||
import com.ckkj.water.chat.entity.CharHistoryEntity;
|
||||
import com.ckkj.water.chat.entity.ChatAiMsgEntity;
|
||||
import com.ckkj.water.chat.entity.ChatQuestionEntity;
|
||||
import com.ckkj.water.chat.entity.IndexTemplateEntity;
|
||||
import com.ckkj.water.network.BaseBean;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexContract {
|
||||
public interface DataModel{
|
||||
//发送消息给 AI
|
||||
void sendMsgToAi(Map<String,Object> map, CallBack callBack);
|
||||
//发送消息给 AI
|
||||
void sendMsgToAi(Map<String,Object> map, AiStreamCallback callBack);
|
||||
//停止当前请求
|
||||
void stopCurrentRequest();
|
||||
//获取首页数据
|
||||
void getIndexTemplateDatas(CallBack callBack);
|
||||
//获取会话历史
|
||||
void getHistoryChatDatas(Map<String,Object> map, CallBack callBack);
|
||||
//删除会话
|
||||
void deleteHistoryBySessionID(Map<String,Object> map, CallBack callBack);
|
||||
//根据会话 id,查询记录详情
|
||||
void getChatDetailById(Map<String,Object> map, CallBack callBack);
|
||||
//首页咨询模板
|
||||
void getChatemplateDatas(CallBack callBack);
|
||||
//举报好友
|
||||
void commitReport(Map<String,Object> map,CallBack callBack);
|
||||
}
|
||||
|
||||
public interface CallBack<T> {
|
||||
void success(T msg);
|
||||
void fail(String msg);
|
||||
}
|
||||
|
||||
public interface AiStreamCallback {
|
||||
void onMessage(String messageChunk); // 每次返回一段内容
|
||||
void onError(String error);
|
||||
void onComplete(String complateContent); // 结束
|
||||
void onSessionReceived(String sessionId); // 新增:接收sessionId
|
||||
void loginLost();
|
||||
}
|
||||
|
||||
public interface IndexView extends IView {
|
||||
//发送消息给 AI,获取结果
|
||||
void getTalkResultSuccess(ChatAiMsgEntity bean);
|
||||
//获取首页数据成功
|
||||
void getIndexTemplateSuccess(List<IndexTemplateEntity> list);
|
||||
// 新增流式回调方法
|
||||
void onStreamMessageReceived(String messageChunk);
|
||||
//完成
|
||||
void onStreamComplete(String complateMsg);
|
||||
//接收sessionId
|
||||
void onSessionReceived(String sessionId);
|
||||
//查询历史记录成功 g
|
||||
void getHistoryDataSuccess(CharHistoryEntity entity);
|
||||
//删除会话成功
|
||||
void deleteHistorySuccess(BaseBean bean,int delPos);
|
||||
//根据 id 查询会话详情
|
||||
void getChatDetailSuccess(List<ChatAiMsgEntity> list);
|
||||
//登录失效
|
||||
void loginLost();
|
||||
//获取首页聊天模板
|
||||
void getChatZixunSuccess(List<ChatQuestionEntity> list);
|
||||
//提交举报反馈成功
|
||||
void commitReportSuccess(BaseBean bean);
|
||||
}
|
||||
}
|
||||
575
app/src/main/java/com/ckkj/water/chat/mvp/IndexImpl.java
Normal file
575
app/src/main/java/com/ckkj/water/chat/mvp/IndexImpl.java
Normal file
@@ -0,0 +1,575 @@
|
||||
package com.ckkj.water.chat.mvp;
|
||||
|
||||
import static android.content.ContentValues.TAG;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.ckkj.water.AppConfig;
|
||||
import com.ckkj.water.chat.entity.CharHistoryEntity;
|
||||
import com.ckkj.water.chat.entity.ChatAiMsgEntity;
|
||||
import com.ckkj.water.chat.entity.ChatQuestionEntity;
|
||||
import com.ckkj.water.chat.entity.IndexTemplateEntity;
|
||||
import com.ckkj.water.network.BaseBean;
|
||||
import com.ckkj.water.network.NetWorkManager;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.net.SocketTimeoutException;
|
||||
|
||||
import io.reactivex.Observer;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexImpl implements IndexContract.DataModel{
|
||||
|
||||
@Override
|
||||
public void sendMsgToAi(Map<String, Object> map, IndexContract.CallBack callBack) {
|
||||
try {
|
||||
NetWorkManager.getRequest().indexTalkToAi(NetWorkManager.getToken(),map)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseBean<ChatAiMsgEntity>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseBean<ChatAiMsgEntity> bean) {
|
||||
if(bean.getCode() == 200){
|
||||
callBack.success(bean.getData());
|
||||
}else{
|
||||
callBack.fail(bean.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
callBack.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息给 AI - 流式版本
|
||||
* @param map
|
||||
* @param callBack
|
||||
*/
|
||||
private final OkHttpClient client = new OkHttpClient.Builder()
|
||||
.connectTimeout(60, TimeUnit.SECONDS) // 连接超时60秒
|
||||
.readTimeout(60, TimeUnit.SECONDS) // 读取超时60秒
|
||||
.writeTimeout(60, TimeUnit.SECONDS) // 写入超时60秒
|
||||
.callTimeout(60, TimeUnit.SECONDS) // 整个调用超时60秒
|
||||
.build();
|
||||
|
||||
private Call currentCall = null; // 新增:保存当前请求的Call对象
|
||||
private volatile boolean isRequestStopped = false; // 新增:标记是否已停止请求
|
||||
|
||||
@Override
|
||||
public void sendMsgToAi(Map<String, Object> map, IndexContract.AiStreamCallback callBack) {
|
||||
try {
|
||||
String finalUrl = AppConfig.BASE_URL + "mobile/context?" + buildQueryParams(map);
|
||||
Log.d(TAG, "Request URL: " + finalUrl);
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.addHeader("Authorization", "Bearer " + AppConfig.USER_TOKEN)
|
||||
.url(finalUrl)
|
||||
.get()
|
||||
.build();
|
||||
currentCall = client.newCall(request);
|
||||
isRequestStopped = false;
|
||||
|
||||
currentCall.enqueue(new Callback() {
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
if (isRequestStopped) return; // 如果已停止,不处理失败回调
|
||||
|
||||
// 检查是否是超时异常
|
||||
String errorMessage = e.getMessage();
|
||||
if (e instanceof SocketTimeoutException ||
|
||||
(errorMessage != null && errorMessage.contains("timeout"))) {
|
||||
errorMessage = "请求超时,请稍后重试";
|
||||
}
|
||||
|
||||
String finalErrorMessage = errorMessage;
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null) callBack.onError(finalErrorMessage);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) {
|
||||
if (isRequestStopped) return;
|
||||
|
||||
if (!response.isSuccessful()) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null) callBack.onError("请求失败: " + response.code());
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
InputStream inputStream = response.body().byteStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
try {
|
||||
reader.mark(1024); // 标记流的当前位置
|
||||
String peekLine = reader.readLine();
|
||||
reader.reset(); // 回到标记位置
|
||||
|
||||
// 判断是否是标准 JSON(非流式错误返回)
|
||||
if (peekLine != null && peekLine.trim().startsWith("{")) {
|
||||
StringBuilder jsonBuilder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonBuilder.append(line);
|
||||
}
|
||||
String responseJson = jsonBuilder.toString();
|
||||
|
||||
JSONObject json = new JSONObject(responseJson);
|
||||
int code = json.optInt("code", 0);
|
||||
String msg = json.optString("msg", "");
|
||||
if (code == 401) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null) callBack.loginLost();
|
||||
});
|
||||
} else {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null) callBack.onError("未知错误: " + msg);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 否则处理为 SSE 流式数据
|
||||
handleSSEStream(reader, callBack);
|
||||
|
||||
} catch (Exception e) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
// if (callBack != null) callBack.onError("响应异常: " + e.getMessage());
|
||||
});
|
||||
} finally {
|
||||
try {
|
||||
reader.close();
|
||||
response.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null) callBack.onError("请求异常: " + e.getMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSSEStream(BufferedReader reader, IndexContract.AiStreamCallback callBack) throws IOException {
|
||||
String line;
|
||||
StringBuilder accumulatedContent = new StringBuilder();
|
||||
StringBuilder lastLineBuffer = new StringBuilder();
|
||||
String currentEvent = null;
|
||||
String currentData = null;
|
||||
String sessionId = "";
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (isRequestStopped) break;
|
||||
|
||||
if (line.startsWith("event:")) {
|
||||
currentEvent = line.substring(6).trim();
|
||||
} else if (line.startsWith("data:")) {
|
||||
currentData = line.substring(5).trim();
|
||||
|
||||
if ("session".equals(currentEvent)) {
|
||||
try {
|
||||
JsonObject sessionData = JsonParser.parseString(currentData).getAsJsonObject();
|
||||
sessionId = sessionData.get("sessionId").getAsString();
|
||||
if (callBack != null && !isRequestStopped) {
|
||||
callBack.onSessionReceived(sessionId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "解析session数据失败", e);
|
||||
}
|
||||
} else if ("chunk".equals(currentEvent)) {
|
||||
try {
|
||||
JsonObject chunkData = JsonParser.parseString(currentData).getAsJsonObject();
|
||||
String content = chunkData.get("content").getAsString();
|
||||
boolean hasNewline = chunkData.get("hasNewline").getAsBoolean();
|
||||
|
||||
if (isTableLineFragment(lastLineBuffer.toString(), content)) {
|
||||
lastLineBuffer.append(content);
|
||||
if (hasNewline) {
|
||||
accumulatedContent.append(lastLineBuffer).append("\n");
|
||||
lastLineBuffer.setLength(0);
|
||||
}
|
||||
} else {
|
||||
if (lastLineBuffer.length() > 0) {
|
||||
accumulatedContent.append(lastLineBuffer);
|
||||
lastLineBuffer.setLength(0);
|
||||
}
|
||||
lastLineBuffer.append(content);
|
||||
if (hasNewline) {
|
||||
accumulatedContent.append(lastLineBuffer).append("\n");
|
||||
lastLineBuffer.setLength(0);
|
||||
}
|
||||
}
|
||||
|
||||
final String currentContent = accumulatedContent.toString();
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null && !isRequestStopped) {
|
||||
callBack.onMessage(currentContent);
|
||||
}
|
||||
});
|
||||
|
||||
} catch (Exception e) {
|
||||
accumulatedContent.append(currentData);
|
||||
final String currentContent = accumulatedContent.toString();
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null && !isRequestStopped) {
|
||||
callBack.onMessage(currentContent);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if ("complete".equals(currentEvent)) {
|
||||
// 先处理剩余的 lastLineBuffer 内容,但不通过 onMessage 回调
|
||||
if (lastLineBuffer.length() > 0) {
|
||||
accumulatedContent.append(lastLineBuffer);
|
||||
// 注意:这里不调用 callBack.onMessage(),避免触发 onStreamMessageReceived
|
||||
}
|
||||
|
||||
String complateContent = "";
|
||||
try {
|
||||
JsonObject completeData = JsonParser.parseString(currentData).getAsJsonObject();
|
||||
complateContent = completeData.get("fullResponse").getAsString();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "解析complete数据失败", e);
|
||||
}
|
||||
|
||||
final String finalComplateContent = complateContent;
|
||||
new Handler(Looper.getMainLooper()).post(() -> {
|
||||
if (callBack != null && !isRequestStopped) {
|
||||
callBack.onComplete(finalComplateContent); // 只调用 onComplete
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理结束前残留内容
|
||||
// if (lastLineBuffer.length() > 0 && !isRequestStopped) {
|
||||
// accumulatedContent.append(lastLineBuffer);
|
||||
// final String finalContent = accumulatedContent.toString();
|
||||
// new Handler(Looper.getMainLooper()).post(() -> {
|
||||
// if (callBack != null && !isRequestStopped) {
|
||||
// callBack.onMessage(finalContent);
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止当前请求
|
||||
*/
|
||||
public void stopCurrentRequest() {
|
||||
isRequestStopped = true;
|
||||
if (currentCall != null && !currentCall.isCanceled()) {
|
||||
currentCall.cancel();
|
||||
currentCall = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否是表格分隔线片段
|
||||
*/
|
||||
private boolean isTableLineFragment(String last, String curr) {
|
||||
return (last.contains("|") && last.contains("-")) || (curr.contains("|") && curr.contains("-"));
|
||||
}
|
||||
|
||||
// 构造 GET 参数
|
||||
private String buildQueryParams(Map<String, Object> map) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
try {
|
||||
if (sb.length() > 0) sb.append("&");
|
||||
sb.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
|
||||
sb.append("=");
|
||||
sb.append(URLEncoder.encode(String.valueOf(entry.getValue()), "UTF-8"));
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Encoding error", e);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取首页数据
|
||||
*/
|
||||
@Override
|
||||
public void getIndexTemplateDatas(IndexContract.CallBack callBack) {
|
||||
try {
|
||||
NetWorkManager.getRequest().getIndexTemplateDatas()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseBean<List<IndexTemplateEntity>>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseBean<List<IndexTemplateEntity>> bean) {
|
||||
if(bean.getCode() == 200){
|
||||
callBack.success(bean.getData());
|
||||
}else{
|
||||
callBack.fail(bean.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
callBack.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话历史记录
|
||||
* @param map
|
||||
* @param callBack
|
||||
*/
|
||||
@Override
|
||||
public void getHistoryChatDatas(Map<String, Object> map, IndexContract.CallBack callBack) {
|
||||
try {
|
||||
NetWorkManager.getRequest().getHistoryList(NetWorkManager.getToken(),map)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseBean<CharHistoryEntity>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseBean<CharHistoryEntity> bean) {
|
||||
if(bean.getCode() == 200){
|
||||
callBack.success(bean.getData());
|
||||
}else{
|
||||
callBack.fail(bean.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
callBack.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除历史会话
|
||||
* @param map
|
||||
* @param callBack
|
||||
*/
|
||||
@Override
|
||||
public void deleteHistoryBySessionID(Map<String, Object> map, IndexContract.CallBack callBack) {
|
||||
try {
|
||||
NetWorkManager.getRequest().deleteHistoryBySessionID(NetWorkManager.getToken(),map)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseBean>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseBean bean) {
|
||||
if(bean.getCode() == 200){
|
||||
callBack.success(bean);
|
||||
}else{
|
||||
callBack.fail(bean.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
callBack.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 根据会话 id 查询详情
|
||||
* @param map
|
||||
* @param callBack
|
||||
*/
|
||||
@Override
|
||||
public void getChatDetailById(Map<String, Object> map, IndexContract.CallBack callBack) {
|
||||
try {
|
||||
NetWorkManager.getRequest().getChatDetailById(NetWorkManager.getToken(),map)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseBean<List<ChatAiMsgEntity>>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseBean<List<ChatAiMsgEntity>> bean) {
|
||||
if(bean.getCode() == 200){
|
||||
callBack.success(bean.getData());
|
||||
}else{
|
||||
callBack.fail(bean.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
callBack.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对话页,咨询模板获取
|
||||
* @param callBack
|
||||
*/
|
||||
@Override
|
||||
public void getChatemplateDatas(IndexContract.CallBack callBack) {
|
||||
try {
|
||||
NetWorkManager.getRequest().aitebcontent()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseBean<List<ChatQuestionEntity>>>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseBean<List<ChatQuestionEntity>> bean) {
|
||||
if(bean.getCode() == 200){
|
||||
callBack.success(bean.getData());
|
||||
}else{
|
||||
callBack.fail(bean.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
callBack.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 举报反馈
|
||||
* @param map
|
||||
* @param callBack
|
||||
*/
|
||||
@Override
|
||||
public void commitReport(Map<String, Object> map, IndexContract.CallBack callBack) {
|
||||
try {
|
||||
NetWorkManager.getRequest().commitReporting(NetWorkManager.getToken(),map)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.unsubscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(new Observer<BaseBean>() {
|
||||
@Override
|
||||
public void onSubscribe(@NonNull Disposable d) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNext(@NonNull BaseBean bean) {
|
||||
if(bean.getCode() == 200){
|
||||
callBack.success(bean.getData());
|
||||
}else{
|
||||
callBack.fail(bean.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull Throwable e) {
|
||||
callBack.fail(e.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete() {
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
249
app/src/main/java/com/ckkj/water/chat/mvp/IndexPresenter.java
Normal file
249
app/src/main/java/com/ckkj/water/chat/mvp/IndexPresenter.java
Normal file
@@ -0,0 +1,249 @@
|
||||
package com.ckkj.water.chat.mvp;
|
||||
|
||||
import com.ckkj.water.EventMessage;
|
||||
import com.ckkj.water.base.BasePresenter;
|
||||
import com.ckkj.water.chat.entity.CharHistoryEntity;
|
||||
import com.ckkj.water.chat.entity.ChatAiMsgEntity;
|
||||
import com.ckkj.water.chat.entity.ChatQuestionEntity;
|
||||
import com.ckkj.water.chat.entity.IndexTemplateEntity;
|
||||
import com.ckkj.water.network.BaseBean;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.greenrobot.event.EventBus;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/7
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class IndexPresenter extends BasePresenter<IndexContract.IndexView> {
|
||||
private IndexImpl impl;
|
||||
|
||||
public IndexPresenter(IndexImpl impl) {
|
||||
this.impl = impl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息给 AI
|
||||
*
|
||||
* @param content
|
||||
*/
|
||||
// public void talkToAi(String content,String type) {
|
||||
// Map<String,Object> map = new HashMap<>();
|
||||
// map.put("content",content);
|
||||
// map.put("type",type);
|
||||
// map.put("sessionId","");
|
||||
// impl.sendMsgToAi(map, new IndexContract.CallBack<ChatAiMsgEntity>() {
|
||||
// @Override
|
||||
// public void success(ChatAiMsgEntity bean) {
|
||||
// if( IndexPresenter.this.getView() != null){
|
||||
// IndexPresenter.this.getView().getTalkResultSuccess(bean);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void fail(String msg) {
|
||||
// if( IndexPresenter.this.getView() != null){
|
||||
// IndexPresenter.this.getView().showError(msg);
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
public void talkToAi(String content, String type, String sessionID) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("content", content);
|
||||
map.put("type", type);
|
||||
map.put("sessionId", sessionID);
|
||||
|
||||
impl.sendMsgToAi(map, new IndexContract.AiStreamCallback() {
|
||||
@Override
|
||||
public void onMessage(String messageChunk) {
|
||||
// 流式数据到达时,通知View更新UI
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().onStreamMessageReceived(messageChunk);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String msg) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().showError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(String complateMsg) {
|
||||
// 流式传输完成
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().onStreamComplete(complateMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionReceived(String sessionId) {
|
||||
// 接收到sessionId时,通知View
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().onSessionReceived(sessionId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loginLost() {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().loginLost();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止当前流式请求
|
||||
*/
|
||||
public void stopCurrentRequest() {
|
||||
impl.stopCurrentRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* 首页模板消息数据获取
|
||||
*/
|
||||
public void getIndexTemplateDatas() {
|
||||
impl.getIndexTemplateDatas(new IndexContract.CallBack<List<IndexTemplateEntity>>() {
|
||||
@Override
|
||||
public void success(List<IndexTemplateEntity> list) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().getIndexTemplateSuccess(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String msg) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().showError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取历史记录
|
||||
* @param mCurrentPage
|
||||
*/
|
||||
public void getHistoryDatas(int mCurrentPage) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("pageNum", mCurrentPage);
|
||||
map.put("pageSize", 10);
|
||||
impl.getHistoryChatDatas(map, new IndexContract.CallBack<CharHistoryEntity>() {
|
||||
@Override
|
||||
public void success(CharHistoryEntity entity) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().getHistoryDataSuccess(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String msg) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().showError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除历史记录
|
||||
* @param sessionID
|
||||
*/
|
||||
public void deleteHistoryBySessionID(String sessionID,int delPos) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("sessionId", sessionID);
|
||||
impl.deleteHistoryBySessionID(map, new IndexContract.CallBack<BaseBean>() {
|
||||
@Override
|
||||
public void success(BaseBean entity) {
|
||||
EventBus.getDefault().post(new EventMessage(EventMessage.HISTORY_SESSIONID_DELETE_SUCCESS,sessionID));
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().deleteHistorySuccess(entity,delPos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String msg) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().showError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* 根据sessionID 查询消息记录
|
||||
* @param sessionId
|
||||
*/
|
||||
public void getChatDetailByID(String sessionId) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("sessionId", sessionId);
|
||||
impl.getChatDetailById(map, new IndexContract.CallBack<List<ChatAiMsgEntity>>() {
|
||||
@Override
|
||||
public void success(List<ChatAiMsgEntity> list) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().getChatDetailSuccess(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String msg) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().showError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取首页咨询会话模板
|
||||
*/
|
||||
public void getChatTemplateDatas() {
|
||||
impl.getChatemplateDatas(new IndexContract.CallBack<List<ChatQuestionEntity>>() {
|
||||
@Override
|
||||
public void success(List<ChatQuestionEntity> list) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().getChatZixunSuccess(list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String msg) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().showError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 举报
|
||||
* @param reason
|
||||
*/
|
||||
public void commitReport(String reason) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("content", reason);
|
||||
impl.commitReport(map, new IndexContract.CallBack<BaseBean>() {
|
||||
@Override
|
||||
public void success(BaseBean bean) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().commitReportSuccess(bean);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fail(String msg) {
|
||||
if (IndexPresenter.this.getView() != null) {
|
||||
IndexPresenter.this.getView().showError(msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
38
app/src/main/java/com/ckkj/water/custom/CustomFileType.java
Normal file
38
app/src/main/java/com/ckkj/water/custom/CustomFileType.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.ckkj.water.custom;
|
||||
|
||||
import me.rosuh.filepicker.filetype.FileType;
|
||||
import com.ckkj.water.R;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CustomFileType implements FileType {
|
||||
|
||||
@Override
|
||||
public int getFileIconResId() {
|
||||
return R.drawable.ic_unknown_file_picker;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFileType() {
|
||||
return "Excel";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verify(@NotNull String fileName) {
|
||||
boolean isHasSuffix = fileName.contains(".");
|
||||
if (!isHasSuffix) {
|
||||
// 如果没有 . 符号,即是没有文件后缀
|
||||
return false;
|
||||
}
|
||||
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
|
||||
|
||||
return "pdf".equals(suffix)
|
||||
|| "ppt".equals(suffix)
|
||||
|| "pptx".equals(suffix)
|
||||
|| "doc".equals(suffix)
|
||||
|| "docx".equals(suffix)
|
||||
|| "xls".equals(suffix)
|
||||
|| "xlsx".equals(suffix);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
//package com.ckkj.water.custom;
|
||||
//
|
||||
//import android.content.Context;
|
||||
//import android.graphics.Color;
|
||||
//import android.view.View;
|
||||
//import android.widget.Toast;
|
||||
//
|
||||
//import androidx.annotation.NonNull;
|
||||
//
|
||||
//import com.lxj.xpopup.core.BubbleHorizontalAttachPopupView;
|
||||
//import com.lxj.xpopup.util.XPopupUtils;
|
||||
//import com.ckkj.water.R;
|
||||
//
|
||||
///**
|
||||
// * Description: 自定义Attach弹窗,水平方向的带气泡的弹窗
|
||||
// * Create by lxj, at 2019/3/13
|
||||
// */
|
||||
//public class CustomHorizontalBubbleAttachPopup extends BubbleHorizontalAttachPopupView {
|
||||
// private Context mContext;
|
||||
// public CustomHorizontalBubbleAttachPopup(@NonNull Context context) {
|
||||
// super(context);
|
||||
// this.mContext = context;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected int getImplLayoutId() {
|
||||
// return R.layout.custom_attach_popup;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// protected void onCreate() {
|
||||
// super.onCreate();
|
||||
// setBubbleBgColor(Color.parseColor("#4D5063"));
|
||||
// setBubbleShadowSize(XPopupUtils.dp2px(getContext(), 3));
|
||||
// setBubbleShadowColor(Color.BLACK);
|
||||
// getPopupImplView().setBackgroundResource(0);
|
||||
// findViewById(R.id.tv_zan).setOnClickListener(new OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// Toast.makeText(mContext, "赞", Toast.LENGTH_LONG).show();
|
||||
// dismiss();
|
||||
// }
|
||||
// });
|
||||
// findViewById(R.id.tv_comment).setOnClickListener(new OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(View v) {
|
||||
// Toast.makeText(mContext, "评论", Toast.LENGTH_LONG).show();
|
||||
// dismiss();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.ckkj.water.custom;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bigkoo.pickerview.builder.TimePickerBuilder;
|
||||
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
|
||||
import com.bigkoo.pickerview.view.TimePickerView;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.utils.show.ToastUtil;
|
||||
import com.ckkj.water.utils.time.ZYTimeUtils;
|
||||
import com.lxj.xpopup.impl.PartShadowPopupView;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Description: 自定义局部阴影弹窗
|
||||
* Create by dance, at
|
||||
*/
|
||||
public class CustomTimeFilterPopupView extends PartShadowPopupView implements View.OnClickListener {
|
||||
private Context mContext;
|
||||
private String mStartTime,mEndTime;
|
||||
private OnClickListener listener;
|
||||
|
||||
public CustomTimeFilterPopupView(@NonNull Context context,OnClickListener listener) {
|
||||
super(context);
|
||||
this.mContext = context;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public interface OnClickListener{
|
||||
void callBack(String startTime,String endTime);
|
||||
}
|
||||
|
||||
public void setOnclickListener(OnClickListener listener){
|
||||
this.listener = listener;
|
||||
}
|
||||
@Override
|
||||
protected int getImplLayoutId() {
|
||||
return R.layout.history_filter_time_dialog;
|
||||
}
|
||||
|
||||
TextView tvStartTime,tvEndTime,tvReset,tvFinish;
|
||||
@Override
|
||||
protected void onCreate() {
|
||||
super.onCreate();
|
||||
tvStartTime = findViewById(R.id.tv_start_time);
|
||||
tvEndTime = findViewById(R.id.tv_end_time);
|
||||
tvReset = findViewById(R.id.tv_reset);
|
||||
tvFinish = findViewById(R.id.tv_finish);
|
||||
tvStartTime.setOnClickListener(this);
|
||||
tvEndTime.setOnClickListener(this);
|
||||
tvReset.setOnClickListener(this);
|
||||
tvFinish.setOnClickListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()){
|
||||
case R.id.tv_start_time:
|
||||
boolean times[] = {true, true, true, false, false, false};
|
||||
//时间选择器
|
||||
TimePickerView pvTime = new TimePickerBuilder(mContext, new OnTimeSelectListener() {
|
||||
@Override
|
||||
public void onTimeSelect(Date date, View v) {
|
||||
tvStartTime.setText(ZYTimeUtils.getStrTimeData_YYYY_MM_dd(date));
|
||||
mStartTime = ZYTimeUtils.getStrTimeData_YYYY_MM_dd(date);
|
||||
}
|
||||
}).setType(times)
|
||||
.setCancelColor(mContext.getColor(R.color.color_999999))
|
||||
.setSubmitColor(mContext.getColor(R.color.color_zhu))
|
||||
.setTextColorCenter(mContext.getColor(R.color.color_zhu))
|
||||
.build();
|
||||
pvTime.show();
|
||||
|
||||
break;
|
||||
|
||||
case R.id.tv_end_time:
|
||||
boolean endTimes[] = {true, true, true, false, false, false};
|
||||
//时间选择器
|
||||
TimePickerView pvEndTime = new TimePickerBuilder(mContext, new OnTimeSelectListener() {
|
||||
@Override
|
||||
public void onTimeSelect(Date date, View v) {
|
||||
tvEndTime.setText(ZYTimeUtils.getStrTimeData_YYYY_MM_dd(date));
|
||||
mEndTime = ZYTimeUtils.getStrTimeData_YYYY_MM_dd(date);
|
||||
}
|
||||
}).setType(endTimes)
|
||||
.setCancelColor(mContext.getColor(R.color.color_999999))
|
||||
.setSubmitColor(mContext.getColor(R.color.color_zhu))
|
||||
.setTextColorCenter(mContext.getColor(R.color.color_zhu))
|
||||
.build();
|
||||
pvEndTime.show();
|
||||
break;
|
||||
|
||||
case R.id.tv_reset:
|
||||
tvStartTime.setText("");
|
||||
tvEndTime.setText("");
|
||||
mStartTime = "";
|
||||
mEndTime = "";
|
||||
break;
|
||||
|
||||
case R.id.tv_finish:
|
||||
if(TextUtils.isEmpty(mStartTime)){
|
||||
ToastUtil.showShort(mContext,mContext.getString(R.string.history_filter_start_time_toast));
|
||||
return;
|
||||
}
|
||||
if(TextUtils.isEmpty(mEndTime)){
|
||||
ToastUtil.showShort(mContext,mContext.getString(R.string.history_filter_end_time_toast));
|
||||
return;
|
||||
}
|
||||
// 比较结束时间和开始时间,结束时间不能早于开始时间
|
||||
if (!ZYTimeUtils.isEndTimeAfterStartTime(mStartTime, mEndTime)) {
|
||||
ToastUtil.showShort(mContext, mContext.getString(R.string.history_filter_end_time_error));
|
||||
return;
|
||||
}
|
||||
|
||||
if(listener != null){
|
||||
listener.callBack(mStartTime,mEndTime);
|
||||
this.dismiss();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShow() {
|
||||
super.onShow();
|
||||
Log.e("tag","CustomPartShadowPopupView onShow");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDismiss() {
|
||||
super.onDismiss();
|
||||
Log.e("tag","CustomPartShadowPopupView onDismiss");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.ckkj.water.custom;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bigkoo.pickerview.builder.TimePickerBuilder;
|
||||
import com.bigkoo.pickerview.listener.OnTimeSelectListener;
|
||||
import com.bigkoo.pickerview.view.TimePickerView;
|
||||
import com.ckkj.water.R;
|
||||
import com.ckkj.water.utils.show.ToastUtil;
|
||||
import com.ckkj.water.utils.time.ZYTimeUtils;
|
||||
import com.lxj.xpopup.impl.PartShadowPopupView;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Description: 自定义局部阴影弹窗
|
||||
* Create by dance, at
|
||||
*/
|
||||
public class CustomTypeFilterPopupView extends PartShadowPopupView implements View.OnClickListener {
|
||||
private Context mContext;
|
||||
private OnClickListener listener;
|
||||
private TextView tvManual,tvAuto,tvReset,tvFinish;
|
||||
//是否选择了手动
|
||||
private boolean mSelManual = false;
|
||||
//是否选择了自动排程
|
||||
private boolean mSelAuto = false;
|
||||
public CustomTypeFilterPopupView(@NonNull Context context, OnClickListener listener) {
|
||||
super(context);
|
||||
this.mContext = context;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public interface OnClickListener{
|
||||
void callBack(boolean mSelManual,boolean mSelAuto);
|
||||
}
|
||||
|
||||
public void setOnclickListener(OnClickListener listener){
|
||||
this.listener = listener;
|
||||
}
|
||||
@Override
|
||||
protected int getImplLayoutId() {
|
||||
return R.layout.history_filter_type_dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate() {
|
||||
super.onCreate();
|
||||
tvManual = findViewById(R.id.tv_manual);
|
||||
tvAuto = findViewById(R.id.tv_auto);
|
||||
tvReset = findViewById(R.id.tv_reset);
|
||||
tvFinish = findViewById(R.id.tv_finish);
|
||||
tvManual.setOnClickListener(this);
|
||||
tvAuto.setOnClickListener(this);
|
||||
tvReset.setOnClickListener(this);
|
||||
tvFinish.setOnClickListener(this);
|
||||
tvManual.setSelected(false);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
switch (v.getId()){
|
||||
case R.id.tv_manual:
|
||||
if(mSelManual){
|
||||
mSelManual = false;
|
||||
tvManual.setTextColor(mContext.getColor(R.color.color_zhu));
|
||||
tvManual.setSelected(mSelManual);
|
||||
}else{
|
||||
mSelManual = true;
|
||||
tvManual.setTextColor(mContext.getColor(R.color.white));
|
||||
tvManual.setSelected(mSelManual);
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.tv_auto:
|
||||
if(mSelAuto){
|
||||
mSelAuto = false;
|
||||
tvAuto.setTextColor(mContext.getColor(R.color.color_zhu));
|
||||
tvAuto.setSelected(mSelAuto);
|
||||
}else{
|
||||
mSelAuto = true;
|
||||
tvAuto.setTextColor(mContext.getColor(R.color.white));
|
||||
tvAuto.setSelected(mSelAuto);
|
||||
}
|
||||
break;
|
||||
|
||||
case R.id.tv_reset:
|
||||
mSelManual = false;
|
||||
mSelAuto = false;
|
||||
tvManual.setTextColor(mContext.getColor(R.color.color_zhu));
|
||||
tvAuto.setTextColor(mContext.getColor(R.color.color_zhu));
|
||||
tvManual.setSelected(mSelManual);
|
||||
tvAuto.setSelected(mSelAuto);
|
||||
break;
|
||||
|
||||
case R.id.tv_finish:
|
||||
if(!mSelManual && !mSelAuto){
|
||||
ToastUtil.showShort(mContext,mContext.getString(R.string.history_filter_type_toast));
|
||||
return;
|
||||
}
|
||||
if(listener != null){
|
||||
listener.callBack(mSelManual,mSelAuto);
|
||||
this.dismiss();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShow() {
|
||||
super.onShow();
|
||||
Log.e("tag","CustomPartShadowPopupView onShow");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDismiss() {
|
||||
super.onDismiss();
|
||||
Log.e("tag","CustomPartShadowPopupView onDismiss");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.ckkj.water.custom;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
|
||||
private final Paint paint;
|
||||
private final int height;
|
||||
|
||||
public DividerItemDecoration(int color, int height) {
|
||||
paint = new Paint();
|
||||
paint.setColor(color);
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
|
||||
int left = parent.getPaddingLeft();
|
||||
int right = parent.getWidth() - parent.getPaddingRight();
|
||||
|
||||
for (int i = 0; i < parent.getChildCount() - 1; i++) {
|
||||
View child = parent.getChildAt(i);
|
||||
int top = child.getBottom();
|
||||
int bottom = top + height;
|
||||
c.drawRect(left, top, right, bottom, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.ckkj.water.custom;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.view.View;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
|
||||
private final int spanCount; // 列数
|
||||
private final int spacing; // 间距
|
||||
private final boolean includeEdge; // 是否包含边缘
|
||||
|
||||
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
|
||||
this.spanCount = spanCount;
|
||||
this.spacing = spacing;
|
||||
this.includeEdge = includeEdge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getItemOffsets(@NonNull Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
|
||||
int position = parent.getChildAdapterPosition(view); // item 位置
|
||||
int column = position % spanCount; // 列数
|
||||
|
||||
if (includeEdge) {
|
||||
outRect.left = spacing - column * spacing / spanCount; // 左边距
|
||||
outRect.right = (column + 1) * spacing / spanCount; // 右边距
|
||||
|
||||
if (position < spanCount) { // 第一行
|
||||
outRect.top = spacing; // 上边距
|
||||
}
|
||||
outRect.bottom = spacing; // 下边距
|
||||
} else {
|
||||
outRect.left = column * spacing / spanCount; // 左边距
|
||||
outRect.right = spacing - (column + 1) * spacing / spanCount; // 右边距
|
||||
|
||||
if (position >= spanCount) {
|
||||
outRect.top = spacing; // 上边距
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.ckkj.water.custom.helper;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Helper for accessing features in {@link KeyEvent} introduced after
|
||||
* API level 4 in a backwards compatible fashion.
|
||||
*/
|
||||
public final class KeyEventCompat {
|
||||
/**
|
||||
* Interface for the full API.
|
||||
*/
|
||||
interface KeyEventVersionImpl {
|
||||
int normalizeMetaState(int metaState);
|
||||
boolean metaStateHasModifiers(int metaState, int modifiers);
|
||||
boolean metaStateHasNoModifiers(int metaState);
|
||||
boolean isCtrlPressed(KeyEvent event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface implementation that doesn't use anything about v4 APIs.
|
||||
*/
|
||||
static class BaseKeyEventVersionImpl implements KeyEventVersionImpl {
|
||||
private static final int META_MODIFIER_MASK =
|
||||
KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON
|
||||
| KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON
|
||||
| KeyEvent.META_SYM_ON;
|
||||
|
||||
// Mask of all lock key meta states.
|
||||
private static final int META_ALL_MASK = META_MODIFIER_MASK;
|
||||
|
||||
private static int metaStateFilterDirectionalModifiers(int metaState,
|
||||
int modifiers, int basic, int left, int right) {
|
||||
final boolean wantBasic = (modifiers & basic) != 0;
|
||||
final int directional = left | right;
|
||||
final boolean wantLeftOrRight = (modifiers & directional) != 0;
|
||||
|
||||
if (wantBasic) {
|
||||
if (wantLeftOrRight) {
|
||||
throw new IllegalArgumentException("bad arguments");
|
||||
}
|
||||
return metaState & ~directional;
|
||||
} else if (wantLeftOrRight) {
|
||||
return metaState & ~basic;
|
||||
} else {
|
||||
return metaState;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int normalizeMetaState(int metaState) {
|
||||
if ((metaState & (KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_RIGHT_ON)) != 0) {
|
||||
metaState |= KeyEvent.META_SHIFT_ON;
|
||||
}
|
||||
if ((metaState & (KeyEvent.META_ALT_LEFT_ON | KeyEvent.META_ALT_RIGHT_ON)) != 0) {
|
||||
metaState |= KeyEvent.META_ALT_ON;
|
||||
}
|
||||
return metaState & META_ALL_MASK;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean metaStateHasModifiers(int metaState, int modifiers) {
|
||||
metaState = normalizeMetaState(metaState) & META_MODIFIER_MASK;
|
||||
metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
|
||||
KeyEvent.META_SHIFT_ON, KeyEvent.META_SHIFT_LEFT_ON, KeyEvent.META_SHIFT_RIGHT_ON);
|
||||
metaState = metaStateFilterDirectionalModifiers(metaState, modifiers,
|
||||
KeyEvent.META_ALT_ON, KeyEvent.META_ALT_LEFT_ON, KeyEvent.META_ALT_RIGHT_ON);
|
||||
return metaState == modifiers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean metaStateHasNoModifiers(int metaState) {
|
||||
return (normalizeMetaState(metaState) & META_MODIFIER_MASK) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCtrlPressed(KeyEvent event) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface implementation for devices with at least v11 APIs.
|
||||
*/
|
||||
static class HoneycombKeyEventVersionImpl extends BaseKeyEventVersionImpl {
|
||||
@Override
|
||||
public int normalizeMetaState(int metaState) {
|
||||
return KeyEventCompatHoneycomb.normalizeMetaState(metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean metaStateHasModifiers(int metaState, int modifiers) {
|
||||
return KeyEventCompatHoneycomb.metaStateHasModifiers(metaState, modifiers);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean metaStateHasNoModifiers(int metaState) {
|
||||
return KeyEventCompatHoneycomb.metaStateHasNoModifiers(metaState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCtrlPressed(KeyEvent event) {
|
||||
return KeyEventCompatHoneycomb.isCtrlPressed(event);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the correct implementation to use for the current platform.
|
||||
*/
|
||||
static final KeyEventVersionImpl IMPL;
|
||||
static {
|
||||
if (android.os.Build.VERSION.SDK_INT >= 11) {
|
||||
IMPL = new HoneycombKeyEventVersionImpl();
|
||||
} else {
|
||||
IMPL = new BaseKeyEventVersionImpl();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
public static int normalizeMetaState(int metaState) {
|
||||
return IMPL.normalizeMetaState(metaState);
|
||||
}
|
||||
|
||||
public static boolean metaStateHasModifiers(int metaState, int modifiers) {
|
||||
return IMPL.metaStateHasModifiers(metaState, modifiers);
|
||||
}
|
||||
|
||||
public static boolean metaStateHasNoModifiers(int metaState) {
|
||||
return IMPL.metaStateHasNoModifiers(metaState);
|
||||
}
|
||||
|
||||
public static boolean hasModifiers(KeyEvent event, int modifiers) {
|
||||
return IMPL.metaStateHasModifiers(event.getMetaState(), modifiers);
|
||||
}
|
||||
|
||||
public static boolean hasNoModifiers(KeyEvent event) {
|
||||
return IMPL.metaStateHasNoModifiers(event.getMetaState());
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Call {@link KeyEvent#startTracking()} directly. This method will be removed in a
|
||||
* future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public static void startTracking(KeyEvent event) {
|
||||
event.startTracking();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Call {@link KeyEvent#isTracking()} directly. This method will be removed in a
|
||||
* future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean isTracking(KeyEvent event) {
|
||||
return event.isTracking();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Call {@link View#getKeyDispatcherState()} directly. This method will be removed
|
||||
* in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public static Object getKeyDispatcherState(View view) {
|
||||
return view.getKeyDispatcherState();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Call
|
||||
* {@link KeyEvent#dispatch(KeyEvent.Callback, KeyEvent.DispatcherState, Object)} directly.
|
||||
* This method will be removed in a future release.
|
||||
*/
|
||||
@Deprecated
|
||||
public static boolean dispatch(KeyEvent event, KeyEvent.Callback receiver, Object state,
|
||||
Object target) {
|
||||
return event.dispatch(receiver, (KeyEvent.DispatcherState)state, target);
|
||||
}
|
||||
|
||||
public static boolean isCtrlPressed(KeyEvent event) {
|
||||
return IMPL.isCtrlPressed(event);
|
||||
}
|
||||
|
||||
private KeyEventCompat() {}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.ckkj.water.custom.helper;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
/**
|
||||
* Implementation of key event compatibility that can call Honeycomb APIs.
|
||||
*/
|
||||
|
||||
@RequiresApi(11)
|
||||
@TargetApi(11)
|
||||
class KeyEventCompatHoneycomb {
|
||||
public static int normalizeMetaState(int metaState) {
|
||||
return KeyEvent.normalizeMetaState(metaState);
|
||||
}
|
||||
|
||||
public static boolean metaStateHasModifiers(int metaState, int modifiers) {
|
||||
return KeyEvent.metaStateHasModifiers(metaState, modifiers);
|
||||
}
|
||||
|
||||
public static boolean metaStateHasNoModifiers(int metaState) {
|
||||
return KeyEvent.metaStateHasNoModifiers(metaState);
|
||||
}
|
||||
|
||||
public static boolean isCtrlPressed(KeyEvent event) {
|
||||
return event.isCtrlPressed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class CircleCheckView extends View {
|
||||
private Paint circlePaint;
|
||||
private Paint checkPaint;
|
||||
private int backgroundColor = 0xFF000000; // 默认黑色
|
||||
private boolean showCheck = false; // 是否显示对号
|
||||
|
||||
public CircleCheckView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public CircleCheckView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public CircleCheckView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
circlePaint.setColor(backgroundColor);
|
||||
circlePaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
checkPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
checkPaint.setColor(0xFFFFFFFF); // 默认白色对号
|
||||
checkPaint.setStyle(Paint.Style.STROKE);
|
||||
checkPaint.setStrokeWidth(8f); // 对号线宽
|
||||
checkPaint.setStrokeCap(Paint.Cap.ROUND);
|
||||
checkPaint.setStrokeJoin(Paint.Join.ROUND);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int radius = Math.min(width, height) / 2;
|
||||
|
||||
// 画圆
|
||||
canvas.drawCircle(width / 2f, height / 2f, radius, circlePaint);
|
||||
|
||||
// 画对号
|
||||
if (showCheck) {
|
||||
drawCheckMark(canvas, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawCheckMark(Canvas canvas, int width, int height) {
|
||||
Path path = new Path();
|
||||
float size = Math.min(width, height) * 0.2f; // 对号大小大约是圆直径40%
|
||||
float centerX = width / 2f;
|
||||
float centerY = height / 2f;
|
||||
|
||||
// 起点 (左下)
|
||||
path.moveTo(centerX - size / 2, centerY);
|
||||
// 中间点 (中间)
|
||||
path.lineTo(centerX, centerY + size / 2);
|
||||
// 终点 (右上)
|
||||
path.lineTo(centerX + size / 2, centerY - size / 2);
|
||||
|
||||
canvas.drawPath(path, checkPaint);
|
||||
}
|
||||
|
||||
// 外部调用,设置背景色
|
||||
@Override
|
||||
public void setBackgroundColor(int color) {
|
||||
backgroundColor = color;
|
||||
circlePaint.setColor(backgroundColor);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// 外部调用,控制显示或隐藏对号
|
||||
public void setShowCheck(boolean show) {
|
||||
this.showCheck = show;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// 外部调用,可以改变对号颜色
|
||||
public void setCheckColor(int color) {
|
||||
checkPaint.setColor(color);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// 外部调用,可以改变对号粗细
|
||||
public void setCheckStrokeWidth(float width) {
|
||||
checkPaint.setStrokeWidth(width);
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.ckkj.water.R;
|
||||
import com.lxj.xpopup.core.AttachPopupView;
|
||||
|
||||
/**
|
||||
* Description: 自定义背景的Attach弹窗
|
||||
* Create by lxj, at 2019/3/13
|
||||
*/
|
||||
public class CustomAttachPopup extends AttachPopupView {
|
||||
public CustomAttachPopup(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getImplLayoutId() {
|
||||
return R.layout.custom_attach_popup;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate() {
|
||||
super.onCreate();
|
||||
final TextView tv = findViewById(R.id.tv_content);
|
||||
tv.setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// tv.setText(tv.getText() + "\n 啊哈哈哈啊哈");
|
||||
// tv.setText("\n 啊哈哈哈啊哈");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.ckkj.water.R;
|
||||
import com.lxj.xpopup.core.BubbleAttachPopupView;
|
||||
import com.lxj.xpopup.util.XPopupUtils;
|
||||
|
||||
/**
|
||||
* Description: 自定义气泡Attach弹窗
|
||||
* Create by lxj, at 2019/3/13
|
||||
*/
|
||||
public class CustomBubbleAttachPopup extends BubbleAttachPopupView {
|
||||
private String mContent;
|
||||
public CustomBubbleAttachPopup(@NonNull Context context,String content) {
|
||||
super(context);
|
||||
this.mContent = content;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getImplLayoutId() {
|
||||
return R.layout.custom_bubble_attach_popup;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate() {
|
||||
super.onCreate();
|
||||
final TextView tv = findViewById(R.id.tv);
|
||||
tv.setText(mContent);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.core.widget.NestedScrollView;
|
||||
|
||||
public class CustomNestedScrollView extends NestedScrollView {
|
||||
private boolean isScrollable = true;
|
||||
|
||||
public CustomNestedScrollView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CustomNestedScrollView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CustomNestedScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public void setScrollable(boolean scrollable) {
|
||||
this.isScrollable = scrollable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
return isScrollable && super.onInterceptTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
return isScrollable && super.onTouchEvent(ev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
public class CustomNoTouchRecyclerView extends RecyclerView {
|
||||
public CustomNoTouchRecyclerView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public CustomNoTouchRecyclerView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CustomNoTouchRecyclerView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
// 返回 false 以便父布局可以处理触摸事件
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import com.ckkj.water.R;
|
||||
|
||||
public class CustomProgressBar extends View {
|
||||
private Bitmap bitmap;
|
||||
private Paint paint;
|
||||
private float rotation = 0;
|
||||
|
||||
public CustomProgressBar(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
paint = new Paint();
|
||||
// 加载自定义图片
|
||||
bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.img_loading_progressbar); // 替换为你的图片资源
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
// 保存当前画布状态
|
||||
canvas.save();
|
||||
// 旋转画布
|
||||
canvas.rotate(rotation, getWidth() / 2, getHeight() / 2);
|
||||
// 绘制图片
|
||||
canvas.drawBitmap(bitmap, (getWidth() - bitmap.getWidth()) / 2, (getHeight() - bitmap.getHeight()) / 2, paint);
|
||||
// 恢复画布状态
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
public void setRotation(float rotation) {
|
||||
this.rotation = rotation;
|
||||
invalidate(); // 重新绘制
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.scwang.smart.refresh.layout.api.RefreshHeader;
|
||||
import com.scwang.smart.refresh.layout.api.RefreshKernel;
|
||||
import com.scwang.smart.refresh.layout.api.RefreshLayout;
|
||||
import com.scwang.smart.refresh.layout.constant.RefreshState;
|
||||
import com.scwang.smart.refresh.layout.constant.SpinnerStyle;
|
||||
import com.ckkj.water.R;
|
||||
|
||||
/**
|
||||
* @author fengxiaoyang
|
||||
* @date 2025/7/11
|
||||
* @description TODO: 描述该类的作用
|
||||
*/
|
||||
|
||||
public class CustomRefreshHeader extends RelativeLayout implements RefreshHeader {
|
||||
|
||||
private ImageView ivRefresh;
|
||||
private ObjectAnimator rotateAnimator;
|
||||
|
||||
public CustomRefreshHeader(Context context) {
|
||||
super(context);
|
||||
init(context);
|
||||
}
|
||||
|
||||
public CustomRefreshHeader(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init(context);
|
||||
}
|
||||
|
||||
private void init(Context context) {
|
||||
LayoutInflater.from(context).inflate(R.layout.view_refresh_header, this);
|
||||
ivRefresh = findViewById(R.id.ivRefresh);
|
||||
|
||||
// 初始化 ObjectAnimator
|
||||
rotateAnimator = ObjectAnimator.ofFloat(ivRefresh, "rotation", 0f, 360f);
|
||||
rotateAnimator.setDuration(1500);
|
||||
rotateAnimator.setRepeatCount(ValueAnimator.INFINITE);
|
||||
rotateAnimator.setInterpolator(new LinearInterpolator()); // 匀速旋转
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void onStartAnimator(@NonNull RefreshLayout layout, int height, int maxDragHeight) {
|
||||
if (rotateAnimator != null && !rotateAnimator.isRunning()) {
|
||||
rotateAnimator.start();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public int onFinish(@NonNull RefreshLayout layout, boolean success) {
|
||||
if (rotateAnimator != null && rotateAnimator.isRunning()) {
|
||||
// 为了平滑停止,先设置减速插值器,再 cancel 动画
|
||||
rotateAnimator.setInterpolator(new DecelerateInterpolator());
|
||||
postDelayed(() -> {
|
||||
if (rotateAnimator != null) {
|
||||
rotateAnimator.cancel();
|
||||
rotateAnimator.setInterpolator(new LinearInterpolator()); // 恢复为匀速
|
||||
}
|
||||
}, 300); // 给一点缓冲时间
|
||||
}
|
||||
return 500; // 动画停止后延迟 500ms 收起 Header
|
||||
}
|
||||
|
||||
// --- 必须实现的方法 ---
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public SpinnerStyle getSpinnerStyle() {
|
||||
return SpinnerStyle.Translate; // Header 跟随内容滑动
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupportHorizontalDrag() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void setPrimaryColors(@ColorInt int... colors) {}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void onInitialized(@NonNull RefreshKernel kernel, int height, int maxDragHeight) {}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void onMoving(boolean isDragging, float percent, int offset, int height, int maxDragHeight) {}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void onReleased(@NonNull RefreshLayout layout, int height, int maxDragHeight) {}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void onHorizontalDrag(float percentX, int offsetX, int offsetMax) {}
|
||||
|
||||
@Override
|
||||
public boolean autoOpen(int duration, float dragRate, boolean animationOnly) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
@Override
|
||||
public void onStateChanged(@NonNull RefreshLayout refreshLayout, @NonNull RefreshState oldState, @NonNull RefreshState newState) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public class DashedLineView extends View {
|
||||
private Paint paint;
|
||||
|
||||
public DashedLineView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public DashedLineView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public DashedLineView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
paint = new Paint();
|
||||
paint.setColor(0xFF0000FF); // 蓝色
|
||||
paint.setStrokeWidth(1f); // 高度为1px
|
||||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setPathEffect(new android.graphics.DashPathEffect(new float[]{2, 2}, 0)); // 虚线效果
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
float width = getWidth();
|
||||
float height = getHeight();
|
||||
canvas.drawLine(0, height / 2, width, height / 2, paint); // 绘制虚线
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class DottedRoundRectDrawable_blue extends Drawable {
|
||||
|
||||
private Paint mPaint;
|
||||
private RectF mRectF;
|
||||
private float mCornerRadius;
|
||||
|
||||
public DottedRoundRectDrawable_blue(float cornerRadius) {
|
||||
mPaint = new Paint();
|
||||
mPaint.setColor(Color.parseColor("#1A72FF")); // 设置虚线颜色
|
||||
mPaint.setStyle(Paint.Style.STROKE); // 设置为描边
|
||||
mPaint.setStrokeWidth(3); // 设置虚线宽度
|
||||
// 设置虚线效果
|
||||
mPaint.setPathEffect(new DashPathEffect(new float[]{2, 2}, 0)); // 虚线的长度和间隔
|
||||
|
||||
mCornerRadius = cornerRadius; // 圆角半径
|
||||
mRectF = new RectF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
// 获取当前 Drawable 的边界
|
||||
mRectF.set(getBounds());
|
||||
// 绘制圆角矩形虚线
|
||||
canvas.drawRoundRect(mRectF, mCornerRadius, mCornerRadius, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(android.graphics.ColorFilter colorFilter) {
|
||||
mPaint.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public class DottedRoundRectDrawable_gray extends Drawable {
|
||||
|
||||
private Paint mPaint;
|
||||
private RectF mRectF;
|
||||
private float mCornerRadius;
|
||||
|
||||
public DottedRoundRectDrawable_gray(float cornerRadius) {
|
||||
mPaint = new Paint();
|
||||
mPaint.setColor(Color.parseColor("#BDBDBD")); // 设置虚线颜色
|
||||
mPaint.setStyle(Paint.Style.STROKE); // 设置为描边
|
||||
mPaint.setStrokeWidth(3); // 设置虚线宽度
|
||||
// 设置虚线效果
|
||||
mPaint.setPathEffect(new DashPathEffect(new float[]{2, 2}, 0)); // 虚线的长度和间隔
|
||||
|
||||
mCornerRadius = cornerRadius; // 圆角半径
|
||||
mRectF = new RectF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
// 获取当前 Drawable 的边界
|
||||
mRectF.set(getBounds());
|
||||
// 绘制圆角矩形虚线
|
||||
canvas.drawRoundRect(mRectF, mCornerRadius, mCornerRadius, mPaint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
mPaint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(android.graphics.ColorFilter colorFilter) {
|
||||
mPaint.setColorFilter(colorFilter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity() {
|
||||
return PixelFormat.TRANSLUCENT;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ckkj.water.custom.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
/**
|
||||
* Hacky fix for Issue #4 and
|
||||
* http://code.google.com/p/android/issues/detail?id=18990
|
||||
* <p/>
|
||||
* ScaleGestureDetector seems to mess up the touch events, which means that
|
||||
* ViewGroups which make use of onInterceptTouchEvent throw a lot of
|
||||
* IllegalArgumentException: pointerIndex out of range.
|
||||
* <p/>
|
||||
* There's not much I can do in my code for now, but we can mask the result by
|
||||
* just catching the problem and ignoring it.
|
||||
*
|
||||
* @author Chris Banes
|
||||
*/
|
||||
public class HackyViewPager extends ViewPager {
|
||||
|
||||
public HackyViewPager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public HackyViewPager(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
try {
|
||||
return super.onInterceptTouchEvent(ev);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
1716
app/src/main/java/com/ckkj/water/custom/view/LazyViewPager.java
Normal file
1716
app/src/main/java/com/ckkj/water/custom/view/LazyViewPager.java
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user