瀏覽代碼

电子班牌

master
YunLei 2 年之前
當前提交
cfd8165b5e
共有 100 個文件被更改,包括 9988 次插入0 次删除
  1. +16
    -0
      .gitignore
  2. +1
    -0
      .idea/.name
  3. +122
    -0
      .idea/codeStyles/Project.xml
  4. +5
    -0
      .idea/codeStyles/codeStyleConfig.xml
  5. +6
    -0
      .idea/compiler.xml
  6. +20
    -0
      .idea/gradle.xml
  7. +7
    -0
      .idea/inspectionProfiles/Project_Default.xml
  8. +45
    -0
      .idea/jarRepositories.xml
  9. +6
    -0
      .idea/kotlinc.xml
  10. +88
    -0
      .idea/misc.xml
  11. +6
    -0
      .idea/render.experimental.xml
  12. +6
    -0
      .idea/vcs.xml
  13. +3
    -0
      README.MD
  14. +1
    -0
      app/.gitignore
  15. +207
    -0
      app/build.gradle
  16. +104
    -0
      app/proguard-rules.pro
  17. +24
    -0
      app/src/androidTest/java/com/yzx/ebrand/ExampleInstrumentedTest.kt
  18. +88
    -0
      app/src/main/AndroidManifest.xml
  19. +132
    -0
      app/src/main/assets/weex/components/HelloWorld.js
  20. +322
    -0
      app/src/main/assets/weex/index.js
  21. +287
    -0
      app/src/main/assets/weex/reader.js
  22. +77
    -0
      app/src/main/java/com/yzx/ebrand/App.kt
  23. +638
    -0
      app/src/main/java/com/yzx/ebrand/MainActivity.kt
  24. +24
    -0
      app/src/main/java/com/yzx/ebrand/activity/CameraActivity.kt
  25. +304
    -0
      app/src/main/java/com/yzx/ebrand/activity/HomeActivity.kt
  26. +247
    -0
      app/src/main/java/com/yzx/ebrand/activity/LoginActivity.kt
  27. +502
    -0
      app/src/main/java/com/yzx/ebrand/activity/WebActivity.kt
  28. +121
    -0
      app/src/main/java/com/yzx/ebrand/activity/base/BaseActivity.kt
  29. +94
    -0
      app/src/main/java/com/yzx/ebrand/adapter/ChangeDialogStepAdapter.kt
  30. +80
    -0
      app/src/main/java/com/yzx/ebrand/adapter/ChangeListAdapter.kt
  31. +14
    -0
      app/src/main/java/com/yzx/ebrand/adapter/HomeAdapter.kt
  32. +102
    -0
      app/src/main/java/com/yzx/ebrand/adapter/HomeDialogStepAdapter.kt
  33. +74
    -0
      app/src/main/java/com/yzx/ebrand/adapter/HomeListAdapter.kt
  34. +49
    -0
      app/src/main/java/com/yzx/ebrand/adapter/VisitorDialogStepAdapter.kt
  35. +121
    -0
      app/src/main/java/com/yzx/ebrand/adapter/VisitorListAdapter.kt
  36. +154
    -0
      app/src/main/java/com/yzx/ebrand/adapter/base/BaseListAdapter.java
  37. +19
    -0
      app/src/main/java/com/yzx/ebrand/adapter/base/BaseViewHolder.java
  38. +92
    -0
      app/src/main/java/com/yzx/ebrand/adapter/base/EasyAdapter.java
  39. +204
    -0
      app/src/main/java/com/yzx/ebrand/adapter/base/GroupAdapter.java
  40. +15
    -0
      app/src/main/java/com/yzx/ebrand/adapter/base/IViewHolder.java
  41. +42
    -0
      app/src/main/java/com/yzx/ebrand/adapter/base/ViewHolderImpl.java
  42. +39
    -0
      app/src/main/java/com/yzx/ebrand/config/Config.kt
  43. +89
    -0
      app/src/main/java/com/yzx/ebrand/config/RefreshToken.kt
  44. +52
    -0
      app/src/main/java/com/yzx/ebrand/config/YzxInterface.kt
  45. +428
    -0
      app/src/main/java/com/yzx/ebrand/fragment/ChangeFragment.kt
  46. +509
    -0
      app/src/main/java/com/yzx/ebrand/fragment/ClassBrandFragment.kt
  47. +557
    -0
      app/src/main/java/com/yzx/ebrand/fragment/HomeFragment.kt
  48. +174
    -0
      app/src/main/java/com/yzx/ebrand/fragment/MyFragment.kt
  49. +449
    -0
      app/src/main/java/com/yzx/ebrand/fragment/VisitorFragment.kt
  50. +105
    -0
      app/src/main/java/com/yzx/ebrand/fragment/base/BaseFragment.kt
  51. +16
    -0
      app/src/main/java/com/yzx/ebrand/model/BaseBean.kt
  52. +24
    -0
      app/src/main/java/com/yzx/ebrand/model/Book.kt
  53. +75
    -0
      app/src/main/java/com/yzx/ebrand/model/CBClassInfo.kt
  54. +7
    -0
      app/src/main/java/com/yzx/ebrand/model/HomeItem.kt
  55. +39
    -0
      app/src/main/java/com/yzx/ebrand/model/MessageEvent.kt
  56. +7
    -0
      app/src/main/java/com/yzx/ebrand/model/Note.kt
  57. +8
    -0
      app/src/main/java/com/yzx/ebrand/model/QrCode.kt
  58. +5
    -0
      app/src/main/java/com/yzx/ebrand/model/ReToken.kt
  59. +209
    -0
      app/src/main/java/com/yzx/ebrand/model/StuChange.kt
  60. +199
    -0
      app/src/main/java/com/yzx/ebrand/model/StuLeave.kt
  61. +21
    -0
      app/src/main/java/com/yzx/ebrand/model/TabEntity.kt
  62. +102
    -0
      app/src/main/java/com/yzx/ebrand/model/TeacherInfo.kt
  63. +13
    -0
      app/src/main/java/com/yzx/ebrand/model/UploadBean.kt
  64. +105
    -0
      app/src/main/java/com/yzx/ebrand/model/User.kt
  65. +21
    -0
      app/src/main/java/com/yzx/ebrand/model/Vacation.kt
  66. +11
    -0
      app/src/main/java/com/yzx/ebrand/model/Version.kt
  67. +7
    -0
      app/src/main/java/com/yzx/ebrand/model/ViewImage.kt
  68. +113
    -0
      app/src/main/java/com/yzx/ebrand/model/Visitor.kt
  69. +25
    -0
      app/src/main/java/com/yzx/ebrand/model/YzxClientInfo.kt
  70. +77
    -0
      app/src/main/java/com/yzx/ebrand/presenter/ChangePresenter.kt
  71. +176
    -0
      app/src/main/java/com/yzx/ebrand/presenter/ClassBrandPresenter.kt
  72. +131
    -0
      app/src/main/java/com/yzx/ebrand/presenter/HomePresenter.kt
  73. +207
    -0
      app/src/main/java/com/yzx/ebrand/presenter/LoginPresenter.kt
  74. +48
    -0
      app/src/main/java/com/yzx/ebrand/presenter/MainPresenter.kt
  75. +51
    -0
      app/src/main/java/com/yzx/ebrand/presenter/MyPresenter.kt
  76. +140
    -0
      app/src/main/java/com/yzx/ebrand/presenter/VisitorPresenter.kt
  77. +19
    -0
      app/src/main/java/com/yzx/ebrand/presenter/base/BasePresenter.kt
  78. +50
    -0
      app/src/main/java/com/yzx/ebrand/presenter/base/Convert.java
  79. +12
    -0
      app/src/main/java/com/yzx/ebrand/presenter/base/IView.kt
  80. +193
    -0
      app/src/main/java/com/yzx/ebrand/presenter/base/JsonCallBack.java
  81. +20
    -0
      app/src/main/java/com/yzx/ebrand/presenter/base/SimpleResponse.java
  82. +27
    -0
      app/src/main/java/com/yzx/ebrand/presenter/base/YzxListResponse.java
  83. +30
    -0
      app/src/main/java/com/yzx/ebrand/presenter/base/YzxResponse.java
  84. +21
    -0
      app/src/main/java/com/yzx/ebrand/receiver/BootReceiver.kt
  85. +49
    -0
      app/src/main/java/com/yzx/ebrand/utils/FileUpload.kt
  86. +117
    -0
      app/src/main/java/com/yzx/ebrand/utils/KotlinX.kt
  87. +130
    -0
      app/src/main/java/com/yzx/ebrand/utils/Monitor.kt
  88. +15
    -0
      app/src/main/java/com/yzx/ebrand/utils/YzxFileProvider.kt
  89. +39
    -0
      app/src/main/java/com/yzx/ebrand/widget/BaseDialog.kt
  90. +122
    -0
      app/src/main/java/com/yzx/ebrand/widget/ChangeDialog.kt
  91. +100
    -0
      app/src/main/java/com/yzx/ebrand/widget/LeaveDialog.kt
  92. +28
    -0
      app/src/main/java/com/yzx/ebrand/widget/TimeView.kt
  93. +56
    -0
      app/src/main/java/com/yzx/ebrand/widget/ViewImageDialog.kt
  94. +190
    -0
      app/src/main/java/com/yzx/ebrand/widget/VisitorDialog.kt
  95. +26
    -0
      app/src/main/java/com/yzx/ebrand/widget/YzxPDFViewPager.kt
  96. +8
    -0
      app/src/main/res/anim/rotate_0_to_180.xml
  97. +8
    -0
      app/src/main/res/anim/rotate_180_to_360.xml
  98. +7
    -0
      app/src/main/res/anim/slide_bottom_in.xml
  99. +7
    -0
      app/src/main/res/anim/slide_bottom_out.xml
  100. +6
    -0
      app/src/main/res/anim/slide_left_in.xml

+ 16
- 0
.gitignore 查看文件

@@ -0,0 +1,16 @@
*.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
/app/debug
/app/release

+ 1
- 0
.idea/.name 查看文件

@@ -0,0 +1 @@
WebScreen

+ 122
- 0
.idea/codeStyles/Project.xml 查看文件

@@ -0,0 +1,122 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

+ 5
- 0
.idea/codeStyles/codeStyleConfig.xml 查看文件

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

+ 6
- 0
.idea/compiler.xml 查看文件

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="1.8" />
</component>
</project>

+ 20
- 0
.idea/gradle.xml 查看文件

@@ -0,0 +1,20 @@
<?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="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

+ 7
- 0
.idea/inspectionProfiles/Project_Default.xml 查看文件

@@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="AndroidLintLockedOrientationActivity" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="AndroidLintSourceLockedOrientationActivity" enabled="false" level="ERROR" enabled_by_default="false" />
</profile>
</component>

+ 45
- 0
.idea/jarRepositories.xml 查看文件

@@ -0,0 +1,45 @@
<?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="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://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="maven2" />
<option name="name" value="maven2" />
<option name="url" value="https://dl.bintray.com/umsdk/release" />
</remote-repository>
<remote-repository>
<option name="id" value="maven3" />
<option name="name" value="maven3" />
<option name="url" value="https://dl.bintray.com/qichuan/maven/" />
</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>
</component>
</project>

+ 6
- 0
.idea/kotlinc.xml 查看文件

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.6.21" />
</component>
</project>

+ 88
- 0
.idea/misc.xml 查看文件

@@ -0,0 +1,88 @@
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/work/classbrand/app/src/main/res/drawable/btn_blue_select.xml" value="0.248" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/btn_select.xml" value="0.248" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/login_bg.xml" value="0.248" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_b_a_round.xml" value="0.292" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_blue.xml" value="0.292" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_corner.xml" value="0.242" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_corner_plain.xml" value="0.242" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_dialog.xml" value="0.2155" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_green.xml" value="0.292" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_login_form.xml" value="0.2155" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_login_round.xml" value="0.248" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_purple.xml" value="0.292" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_red.xml" value="0.292" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_school_name.xml" value="0.242" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_select.xml" value="0.242" />
<entry key="..\:/work/classbrand/app/src/main/res/drawable/shape_w_round.xml" value="0.292" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/activity_login.xml" value="0.1" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/activity_main.xml" value="0.1" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/fragment_class_brand.xml" value="0.1" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/fragment_my.xml" value="0.1076388888888889" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_brand_active_info.xml" value="0.25" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_brand_class_info.xml" value="0.25" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_brand_image_info.xml" value="0.1076388888888889" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_brand_tea_info.xml" value="0.1076388888888889" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_brand_timetable_info.xml" value="0.1076388888888889" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_change_table.xml" value="0.1076388888888889" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_class_active_item.xml" value="0.1" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_class_empty.xml" value="0.1" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_class_tea_item.xml" value="0.1" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/layout_time_table_item.xml" value="0.1" />
<entry key="..\:/work/classbrand/app/src/main/res/layout/view_time.xml" value="0.1076388888888889" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/btn_select.xml" value="0.321" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/progress_horizontal.xml" value="0.341" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/ripple_water.xml" value="0.3255" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/s_app_btn_bule.xml" value="0.161" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/seekbar_bg.xml" value="0.2335" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/selector_btn_read_setting.xml" value="0.321" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/selector_category_unload.xml" value="0.2335" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/shape_corner.xml" value="0.268" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/shape_corner_plain.xml" value="0.331" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/switch_ios_thumb.xml" value="0.372" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/switch_ios_track_off.xml" value="0.372" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/switch_ios_track_on.xml" value="0.372" />
<entry key="..\:/work/escreen/app/src/main/res/drawable/switch_ios_track_selector.xml" value="0.372" />
<entry key="..\:/work/escreen/app/src/main/res/layout/activity_book.xml" value="0.37135416666666665" />
<entry key="..\:/work/escreen/app/src/main/res/layout/activity_home.xml" value="0.12378472222222223" />
<entry key="..\:/work/escreen/app/src/main/res/layout/activity_main.xml" value="0.10822707953855495" />
<entry key="..\:/work/escreen/app/src/main/res/layout/activity_main1.xml" value="0.37135416666666665" />
<entry key="..\:/work/escreen/app/src/main/res/layout/activity_note.xml" value="0.37135416666666665" />
<entry key="..\:/work/escreen/app/src/main/res/layout/activity_read.xml" value="0.31567028985507245" />
<entry key="..\:/work/escreen/app/src/main/res/layout/activity_web.xml" value="0.1" />
<entry key="..\:/work/escreen/app/src/main/res/layout/dialog_change.xml" value="0.12378472222222223" />
<entry key="..\:/work/escreen/app/src/main/res/layout/dialog_exit.xml" value="0.30483112441214194" />
<entry key="..\:/work/escreen/app/src/main/res/layout/dialog_leave.xml" value="0.30483112441214194" />
<entry key="..\:/work/escreen/app/src/main/res/layout/dialog_test.xml" value="0.29827742520398914" />
<entry key="..\:/work/escreen/app/src/main/res/layout/dialog_vacation.xml" value="0.10822707953855495" />
<entry key="..\:/work/escreen/app/src/main/res/layout/dialog_view_img.xml" value="0.1" />
<entry key="..\:/work/escreen/app/src/main/res/layout/dialog_visitor.xml" value="0.11302083333333333" />
<entry key="..\:/work/escreen/app/src/main/res/layout/fragment_change.xml" value="0.10822707953855495" />
<entry key="..\:/work/escreen/app/src/main/res/layout/fragment_home.xml" value="0.10822707953855495" />
<entry key="..\:/work/escreen/app/src/main/res/layout/fragment_my.xml" value="0.10822707953855495" />
<entry key="..\:/work/escreen/app/src/main/res/layout/fragment_visitor.xml" value="0.1" />
<entry key="..\:/work/escreen/app/src/main/res/layout/item_home.xml" value="0.12378472222222223" />
<entry key="..\:/work/escreen/app/src/main/res/layout/layout_change_table.xml" value="0.12378472222222223" />
<entry key="..\:/work/escreen/app/src/main/res/layout/layout_empty.xml" value="0.37135416666666665" />
<entry key="..\:/work/escreen/app/src/main/res/layout/layout_leave_step.xml" value="0.1" />
<entry key="..\:/work/escreen/app/src/main/res/layout/layout_leave_table.xml" value="0.21462163317657118" />
<entry key="..\:/work/escreen/app/src/main/res/layout/layout_loading.xml" value="0.30483112441214194" />
<entry key="..\:/work/escreen/app/src/main/res/layout/layout_visitor_step.xml" value="0.11302083333333333" />
<entry key="..\:/work/escreen/app/src/main/res/layout/layout_visitor_table.xml" value="0.19660493827160494" />
<entry key="..\:/work/escreen/app/src/main/res/layout/leave_dialog_title.xml" value="0.37135416666666665" />
<entry key="..\:/work/escreen/app/src/main/res/layout/version_dialog.xml" value="0.30483112441214194" />
<entry key="..\:/work/escreen/app/src/main/res/layout/view_time.xml" value="0.12378472222222223" />
<entry key="..\:/work/escreen/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml" value="0.331" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

+ 6
- 0
.idea/render.experimental.xml 查看文件

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RenderSettings">
<option name="showDecorations" value="true" />
</component>
</project>

+ 6
- 0
.idea/vcs.xml 查看文件

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

+ 3
- 0
README.MD 查看文件

@@ -0,0 +1,3 @@
### 电子书项目

#### 开发工具 AndroidStudio

+ 1
- 0
app/.gitignore 查看文件

@@ -0,0 +1 @@
/build

+ 207
- 0
app/build.gradle 查看文件

@@ -0,0 +1,207 @@
apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

//apply from: 'https://raw.githubusercontent.com/apache/incubator-weex/release/0.28/android/sdk/buildSrc/download_jsc.gradle'

//apply plugin: 'org.greenrobot.greendao'

androidExtensions {
experimental = true
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.yzx.ebrand"
// minSdkVersion 26
minSdkVersion 21
targetSdkVersion 25
versionCode 20109
versionName "2.1.9"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

ndk {
abiFilters "armeabi-v7a", "arm64-v8a", "x86"
}
}
signingConfigs {
yzx {
keyAlias ALIAS_NAME
keyPassword ALIAS_PWD
storeFile file(KEY_PATH)
storePassword KEY_PWD
v2SigningEnabled false
}
release {
// storeFile file("../buildKey/wenote.jks")
// keyAlias 'wetao'
// keyPassword 'lhb@123'
// storePassword 'lhb@123'
keyAlias ALIAS_NAME
keyPassword ALIAS_PWD
storeFile file(KEY_PATH)
storePassword KEY_PWD
v2SigningEnabled false
}
debug {
// storeFile file("../buildKey/wenote.jks")
// keyAlias 'wetao'
// keyPassword 'lhb@123'
// storePassword 'lhb@123'
keyAlias ALIAS_NAME
keyPassword ALIAS_PWD
storeFile file(KEY_PATH)
storePassword KEY_PWD
v2SigningEnabled false
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
// zipAlignEnabled true
// debuggable false
signingConfig signingConfigs.release
// 移除无用的resource文件
// shrinkResources false
buildConfigField "String", "BASE_URL", '"https://oa.qbjjyyun.net/api"'
buildConfigField "String", "M_URL", '"https://m.qbjjyyun.net"'
buildConfigField "String", "OA_URL", '"https://oa.qbjjyyun.net"'
buildConfigField "String", "APP_NAME", '"电子班牌"'
buildConfigField "String", "MP_APPID", '"wx358f1c471740cb95"'
buildConfigField "String", "WS_URL", '"wss://oa.qbjjyyun.net/ws2api/"'
// buildConfigField "String", "BASE_URL", '"http://192.168.69.99:9009"'
// buildConfigField "String", "M_URL", '"http://192.168.69.99:8098"'
// buildConfigField "String", "APP_NAME", '"家校互通(测试)"'
}

debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true
signingConfig signingConfigs.release
// 移除无用的resource文件
shrinkResources false
// buildConfigField "String", "BASE_URL", '"http://192.168.69.99:9009"'
// buildConfigField "String", "M_URL", '"http://192.168.69.112:8098"'
buildConfigField "String", "BASE_URL", '"https://oa.qbjjyyun.net/api"'
buildConfigField "String", "OA_URL", '"https://oa.live.educlouddata.com"'
// buildConfigField "String", "OA_URL", '"http://192.168.69.114:3000"'
buildConfigField "String", "M_URL", '"https://m.live.educlouddata.com/"'
// buildConfigField "String", "BASE_URL", '"https://oa.live.educlouddata.com/api"'
buildConfigField "String", "APP_NAME", '"一体化平台(开发)"'
buildConfigField "String", "MP_APPID", '"wxbb397ddae71bb14c"'
// buildConfigField "String", "WS_URL", '"ws://192.168.69.114:9801/"'
buildConfigField "String", "WS_URL", '"wss://oa.live.educlouddata.com/ws2api/"'
}

yzx_test {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
debuggable true
signingConfig signingConfigs.release
// 移除无用的resource文件
// shrinkResources false
buildConfigField "String", "BASE_URL", '"http://192.168.69.99:9009"'
buildConfigField "String", "M_URL", '"http://192.168.69.99:8098"'
buildConfigField "String", "APP_NAME", '"家校互通(测试)"'
buildConfigField "String", "MP_APPID", '"wxbb397ddae71bb14c"'
buildConfigField "String", "WS_URL", '"wss://oa.live.educlouddata.com/ws2api/"'
}

applicationVariants.all { variant ->
variant.outputs.all { output ->
def fileName
fileName = "Yzx_${variant.versionName}.apk"
output.outputFileName = fileName
}
}

}

lintOptions {
checkReleaseBuilds false
// Or, if you prefer, you can continue to check for errors in release builds,
// but continue the build even when errors are found:
abortOnError false
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}


//greendao{
// schemaVersion 4
// daoPackage 'com.yzx.webebook.model.gen'
// targetGenDir 'src/main/java'
//}

repositories {
maven {
url 'https://dl.bintray.com/qichuan/maven/'
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "org.jetbrains.anko:anko:$anko_version"
// 基础依赖包,必须要依赖
implementation 'com.gyf.immersionbar:immersionbar:3.0.0'
// fragment快速实现(可选)
implementation 'com.gyf.immersionbar:immersionbar-components:3.0.0'
// kotlin扩展(可选)
implementation 'com.gyf.immersionbar:immersionbar-ktx:3.0.0'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'com.lzy.net:okgo:3.0.4'
implementation 'com.blankj:utilcodex:1.30.5'
implementation 'com.google.code.gson:gson:2.8.6'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.AlexLiuSheng:CheckVersionLib:2.4.1_androidx'
// 友盟统计SDK
implementation 'com.umeng.umsdk:common:9.3.6' // 必选
implementation 'com.umeng.umsdk:asms:1.2.1' // 必选
implementation 'com.github.thomhurst:RoundImageView:1.0.2'
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.4'

// implementation 'org.apache.weex:sdk:0.28.0'
// implementation 'com.alibaba:fastjson:1.1.46.android'


//ORM Database
// implementation deps.greendao.runtime
// testImplementation deps.testing.junit

//RxJava
// implementation deps.reactivex.rxandroid
// implementation deps.reactivex.rxjava2

implementation 'es.voghdev.pdfviewpager:library:1.1.2'

implementation 'io.github.h07000223:flycoTabLayout:3.0.0'
implementation 'com.qmuiteam:qmui:2.0.0-alpha10'

api 'com.tencent.tbs:tbssdk:44181'
implementation 'com.github.HuanTanSheng:EasyPhotos:3.1.5'

implementation("org.greenrobot:eventbus:3.3.1")

implementation 'com.github.chrisbanes:PhotoView:2.0.0'

implementation "org.java-websocket:Java-WebSocket:1.5.1"

implementation 'com.github.wanggaowan:PhotoPreview:2.5.5'
}

+ 104
- 0
app/proguard-rules.pro 查看文件

@@ -0,0 +1,104 @@
# 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

-flattenpackagehierarchy
-allowaccessmodification
-keepattributes Exceptions,InnerClasses,Signature,SourceFile,LineNumberTable
-dontskipnonpubliclibraryclassmembers
-ignorewarnings
#kotlin
-keep class kotlin.Metadata { *; }
-dontwarn kotlin.**
-keepclassmembers class **$WhenMappings {
<fields>;
}
-keepclassmembers class kotlin.Metadata {
public <methods>;
}
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
}

-keepclasseswithmembernames class * {
native <methods>;
}

-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keep class **.R$* {*;}
-keepclassmembers enum * { *;}




#Gson
-keepclassmembers public class com.google.gson.**
-keepclassmembers public class com.google.gson.** {public private protected *;}
-keepclassmembers public class com.project.mocha_patient.login.SignResponseData { private *; }
-keepclassmembers class sun.misc.Unsafe { *; }
-keep @interface com.google.gson.annotations.SerializedName
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
}

#bean
-keep class com.yzx.ebrand.model.** { *; }
-keep class com.yzx.ebrand.model.Note { *; }
-keep class com.yzx.ebrand.model.UploadBean { *; }
-keep class com.yzx.ebrand.model.UploadContent { *; }

-keep class **$Properties {*;}

#Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# for DexGuard only
#-keepresourcexmlelements manifest/application/meta-data@value=GlideModule
-dontwarn com.bumptech.glide.**


# ProGuard configurations for Bugtags
-keepattributes LineNumberTable,SourceFile
-dontwarn com.bugtags.library.**
-dontwarn io.bugtags.**
-dontwarn org.apache.http.**
-dontwarn android.net.http.AndroidHttpClient

# x5
-dontwarn dalvik.**
-dontwarn com.tencent.smtt.**

-keep class com.tencent.smtt.** {
*;
}

-keep class com.tencent.tbs.** {
*;
}

+ 24
- 0
app/src/androidTest/java/com/yzx/ebrand/ExampleInstrumentedTest.kt 查看文件

@@ -0,0 +1,24 @@
package com.yzx.ebrand

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.yzx.webebook", appContext.packageName)
}
}

+ 88
- 0
app/src/main/AndroidManifest.xml 查看文件

@@ -0,0 +1,88 @@
<?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.yzx.ebrand"
android:installLocation="internalOnly">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CAMERA" />

<application
android:name="com.yzx.ebrand.App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true">
<activity
android:name="com.yzx.ebrand.activity.LoginActivity"
android:exported="false"/>
<activity
android:name="com.yzx.ebrand.activity.CameraActivity"
android:exported="false" />
<activity
android:name="com.yzx.ebrand.MainActivity"
android:configChanges="orientation|keyboard"
android:launchMode="singleInstance"
android:screenOrientation="landscape"
android:windowSoftInputMode="adjustPan|stateHidden">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<!-- <category android:name="android.intent.category.HOME" /> -->
<!-- <category android:name="android.intent.category.DEFAULT" /> -->
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.yzx.ebrand.activity.WebActivity"
android:configChanges="orientation|keyboard"
android:screenOrientation="landscape" /> <!-- <activity -->
<!-- android:name="com.yzx.escreen.MainActivity" -->
<!-- android:configChanges="orientation|keyboard" -->
<!-- android:launchMode="singleTask" -->
<!-- android:screenOrientation="portrait" /> -->
<provider
android:name="com.yzx.ebrand.utils.YzxFileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="name,authorities,exported,grantUriPermissions">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"
tools:replace="name,resource" />
</provider>

<service
android:name="com.tencent.smtt.export.external.DexClassLoaderProviderService"
android:label="dexopt"
android:process=":dexopt" />

<receiver
android:name="com.yzx.ebrand.receiver.BootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>

</manifest>

+ 132
- 0
app/src/main/assets/weex/components/HelloWorld.js 查看文件

@@ -0,0 +1,132 @@
// { "framework": "Vue"}

/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 2);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

var __vue_exports__, __vue_options__
var __vue_styles__ = []

/* template */
var __vue_template__ = __webpack_require__(1)
__vue_options__ = __vue_exports__ = __vue_exports__ || {}
if (
typeof __vue_exports__.default === "object" ||
typeof __vue_exports__.default === "function"
) {
if (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}
__vue_options__ = __vue_exports__ = __vue_exports__.default
}
if (typeof __vue_options__ === "function") {
__vue_options__ = __vue_options__.options
}
__vue_options__.__file = "D:\\demo\\androidweex\\src\\components\\HelloWorld.vue"
__vue_options__.render = __vue_template__.render
__vue_options__.staticRenderFns = __vue_template__.staticRenderFns
__vue_options__.style = __vue_options__.style || {}
__vue_styles__.forEach(function (module) {
for (var name in module) {
__vue_options__.style[name] = module[name]
}
})
if (typeof __register_static_styles__ === "function") {
__register_static_styles__(__vue_options__._scopeId, __vue_styles__)
}

module.exports = __vue_exports__


/***/ }),
/* 1 */
/***/ (function(module, exports) {

module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
return _c('text', {
staticClass: ["message"]
}, [_vm._v("Now, let's use Vue.js to build your Weex app.")])
},staticRenderFns: []}
module.exports.render._withStripped = true

/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _HelloWorld = __webpack_require__(0);

var _HelloWorld2 = _interopRequireDefault(_HelloWorld);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

_HelloWorld2.default.el = '#root';
new Vue(_HelloWorld2.default);

/***/ })
/******/ ]);

+ 322
- 0
app/src/main/assets/weex/index.js
文件差異過大導致無法顯示
查看文件


+ 287
- 0
app/src/main/assets/weex/reader.js 查看文件

@@ -0,0 +1,287 @@
// { "framework": "Vue"}

/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 9);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

var __vue_exports__, __vue_options__
var __vue_styles__ = []

/* template */
var __vue_template__ = __webpack_require__(1)
__vue_options__ = __vue_exports__ = __vue_exports__ || {}
if (
typeof __vue_exports__.default === "object" ||
typeof __vue_exports__.default === "function"
) {
if (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}
__vue_options__ = __vue_exports__ = __vue_exports__.default
}
if (typeof __vue_options__ === "function") {
__vue_options__ = __vue_options__.options
}
__vue_options__.__file = "D:\\demo\\androidweex\\src\\components\\HelloWorld.vue"
__vue_options__.render = __vue_template__.render
__vue_options__.staticRenderFns = __vue_template__.staticRenderFns
__vue_options__.style = __vue_options__.style || {}
__vue_styles__.forEach(function (module) {
for (var name in module) {
__vue_options__.style[name] = module[name]
}
})
if (typeof __register_static_styles__ === "function") {
__register_static_styles__(__vue_options__._scopeId, __vue_styles__)
}

module.exports = __vue_exports__


/***/ }),
/* 1 */
/***/ (function(module, exports) {

module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
return _c('text', {
staticClass: ["message"]
}, [_vm._v("Now, let's use Vue.js to build your Weex app.")])
},staticRenderFns: []}
module.exports.render._withStripped = true

/***/ }),
/* 2 */,
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _reader = __webpack_require__(10);

var _reader2 = _interopRequireDefault(_reader);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

_reader2.default.el = '#root';
new Vue(_reader2.default);

/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

var __vue_exports__, __vue_options__
var __vue_styles__ = []

/* styles */
__vue_styles__.push(__webpack_require__(11)
)

/* script */
__vue_exports__ = __webpack_require__(12)

/* template */
var __vue_template__ = __webpack_require__(13)
__vue_options__ = __vue_exports__ = __vue_exports__ || {}
if (
typeof __vue_exports__.default === "object" ||
typeof __vue_exports__.default === "function"
) {
if (Object.keys(__vue_exports__).some(function (key) { return key !== "default" && key !== "__esModule" })) {console.error("named exports are not supported in *.vue files.")}
__vue_options__ = __vue_exports__ = __vue_exports__.default
}
if (typeof __vue_options__ === "function") {
__vue_options__ = __vue_options__.options
}
__vue_options__.__file = "D:\\demo\\androidweex\\src\\reader.vue"
__vue_options__.render = __vue_template__.render
__vue_options__.staticRenderFns = __vue_template__.staticRenderFns
__vue_options__._scopeId = "data-v-06390049"
__vue_options__.style = __vue_options__.style || {}
__vue_styles__.forEach(function (module) {
for (var name in module) {
__vue_options__.style[name] = module[name]
}
})
if (typeof __register_static_styles__ === "function") {
__register_static_styles__(__vue_options__._scopeId, __vue_styles__)
}

module.exports = __vue_exports__


/***/ }),
/* 11 */
/***/ (function(module, exports) {

module.exports = {
"wrapper": {
"justifyContent": "center",
"alignItems": "center"
},
"logo": {
"width": "424",
"height": "200"
},
"greeting": {
"textAlign": "center",
"marginTop": "70",
"fontSize": "50",
"color": "#41b883"
},
"message": {
"marginTop": "30",
"marginRight": "30",
"marginBottom": "30",
"marginLeft": "30",
"fontSize": "32",
"color": "#727272"
}
}

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
value: true
});

var _HelloWorld = __webpack_require__(0);

var _HelloWorld2 = _interopRequireDefault(_HelloWorld);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.default = {
name: 'App',
components: {
HelloWorld: _HelloWorld2.default
},
data: function data() {
return {
logo: 'https://gw.alicdn.com/tfs/TB1yopEdgoQMeJjy1XaXXcSsFXa-640-302.png',
params: "1"
};
},
mounted: function mounted() {
this.params = weex.config.params;
},

methods: {
onJumpClick: function onJumpClick() {
var json = {
url: "weex/index.js",
params: "你好首页,我是reader"
};
weex.requireModule("activity").navigateTo(json);
}
}
}; //
//
//
//
//
//
//
//
//
//

/***/ }),
/* 13 */
/***/ (function(module, exports) {

module.exports={render:function (){var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;
return _c('div', {
staticClass: ["wrapper"]
}, [_c('image', {
staticClass: ["logo"],
attrs: {
"src": _vm.logo
},
on: {
"click": _vm.onJumpClick
}
}), _c('text', {
staticClass: ["greeting"]
}, [_vm._v("这是读书页面")]), _c('text', {
staticClass: ["greeting"]
}, [_vm._v(_vm._s(_vm.params))])])
},staticRenderFns: []}
module.exports.render._withStripped = true

/***/ })
/******/ ]);

+ 77
- 0
app/src/main/java/com/yzx/ebrand/App.kt 查看文件

@@ -0,0 +1,77 @@
package com.yzx.ebrand

import android.app.Application
import com.blankj.utilcode.util.Utils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.HttpHeaders
import com.lzy.okgo.model.HttpParams
import com.tencent.smtt.export.external.TbsCoreSettings
import com.tencent.smtt.sdk.QbSdk
import com.umeng.analytics.MobclickAgent
import com.umeng.commonsdk.UMConfigure
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.model.User


class App : Application() {


companion object {
var app: App? = null
fun getContext(): App {
return app ?: App()
}
}

override fun onCreate() {
super.onCreate()
app = this

val headers = HttpHeaders()
val user = User.getUser()
headers.put("phone",user.phone)
headers.put("token",user.token)
val params = HttpParams()
params.put("app_id",Config.APP_ID)
OkGo.getInstance()
.addCommonHeaders(headers)
.addCommonParams(params)
.init(this)


Utils.init(this)

UMConfigure.init(
this,
"60334d01425ec25f10fbd5b4",
"ebook",
UMConfigure.DEVICE_TYPE_PHONE,
""
)
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)

// 在调用TBS初始化、创建WebView之前进行如下配置
val map = HashMap<String, Any>()
map[TbsCoreSettings.TBS_SETTINGS_USE_SPEEDY_CLASSLOADER] = true
map[TbsCoreSettings.TBS_SETTINGS_USE_DEXLOADER_SERVICE] = true
QbSdk.initTbsSettings(map)
//腾讯x5内核
QbSdk.initX5Environment(this, object : QbSdk.PreInitCallback {
override fun onCoreInitFinished() {
}

/**
* 预初始化结束
* 由于X5内核体积较大,需要依赖网络动态下发,所以当内核不存在的时候,默认会回调false,此时将会使用系统内核代替
* @param isX5 是否使用X5内核
*/
override fun onViewInitFinished(isX5: Boolean) {
}
})
QbSdk.setDownloadWithoutWifi(true)


}


}

+ 638
- 0
app/src/main/java/com/yzx/ebrand/MainActivity.kt 查看文件

@@ -0,0 +1,638 @@
package com.yzx.ebrand

import android.annotation.SuppressLint
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.KeyEvent
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.widget.ContentLoadingProgressBar
import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.allenliu.versionchecklib.v2.AllenVersionChecker
import com.allenliu.versionchecklib.v2.builder.UIData
import com.allenliu.versionchecklib.v2.callback.CustomDownloadingDialogListener
import com.blankj.utilcode.constant.PermissionConstants
import com.blankj.utilcode.util.*
import com.flyco.tablayout.listener.CustomTabEntity
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.Response
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.yzx.ebrand.activity.LoginActivity
import com.yzx.ebrand.activity.base.BaseActivity
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.config.RefreshToken
import com.yzx.ebrand.fragment.ChangeFragment
import com.yzx.ebrand.fragment.ClassBrandFragment
import com.yzx.ebrand.fragment.MyFragment
import com.yzx.ebrand.fragment.VisitorFragment
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.MainPresenter
import com.yzx.ebrand.presenter.MainView
import com.yzx.ebrand.utils.hideNavigationBar
import com.yzx.ebrand.widget.*
import kotlinx.android.synthetic.main.activity_main.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.java_websocket.client.WebSocketClient
import org.java_websocket.drafts.Draft_6455
import org.java_websocket.handshake.ServerHandshake
import org.jetbrains.anko.find
import org.jetbrains.anko.toast
import java.net.URI
import java.util.*


/**
* Yun.Lei
* 2020年5月6日14:49:10
*/
class MainActivity : BaseActivity<MainPresenter>(), NetworkUtils.OnNetworkStatusChangedListener,
MainView {


override val inflateId: Int
get() = R.layout.activity_main
var netLoadingDialog: QMUIDialog? = null
var netErrorDialog: QMUIDialog? = null
private val netLoadingRun = Runnable {
netLoadingDialog?.apply {
dismiss()
}
showNetworkError()
}
private var idsLoading = false
private var isAutoShowLeave = false
private var isAutoShowChange = false

private val mHandler = Handler(Looper.getMainLooper())
private val runnable = object : Runnable {
override fun run() {
val isAutoShowLeave = SPUtils.getInstance().getBoolean("auto_show_leave", false)
val isAutoShowChange = SPUtils.getInstance().getBoolean("auto_show_change", false)
if (isAutoShowLeave || isAutoShowChange) {
if (!idsLoading) {
idsLoading = true
LogUtils.d("获取详情开始--ids", TimeUtils.getNowMills())
mPresenter?.getLeaveShowIds()
}
mHandler.postDelayed(this, 2000)
} else {
mHandler.removeCallbacks(this)
}

}
}

private val mTimeHandler = Handler(Looper.getMainLooper())
private val timeRunnable = object : Runnable {
override fun run() {
EventBus.getDefault().post(TimeShow().getNowObj())
mTimeHandler.postDelayed(this, 1000)
}
}

private val dialogList = mutableListOf<ConstraintLayout>()

private var client: WebSocketClient? = null

override fun initView() {
if (NetworkUtils.isConnected()) {
if (!User.isLogin() && User.getUser().token.isEmpty()) {
// WebActivity.active(this, "${Config.OA_URL}/login")
LoginActivity.active(this)
finish()
}
if (!User.isLogin()) {
RefreshToken.refresh(object : RefreshToken.RefreshCallback {
override fun onSuccess() {
checkVersion()
checkAuto()
}

override fun onError() {

}
})
} else {
checkVersion()
checkAuto()
RefreshToken.refresh(object : RefreshToken.RefreshCallback {
override fun onSuccess() {
}

override fun onError() {

}
})
}
} else {
showNetworkLoading() //显示网络检查中
}
val tabData = arrayListOf<CustomTabEntity>()
// tabData.add(TabEntity("学生请假", R.mipmap.leave_select, R.mipmap.leave_unselect))
// tabData.add(TabEntity("学籍异动", R.mipmap.change_select, R.mipmap.change_unselect))
// tabData.add(TabEntity("访客管理", R.mipmap.visitor_select, R.mipmap.visitor_unselect))
// tabData.add(TabEntity("我的", R.mipmap.my_select, R.mipmap.my_unselect))
// tabLayout.setTabData(tabData)
// tabLayout.visibility = View.GONE

viewPager2.adapter = HomePagerAdapter(this)
viewPager2.offscreenPageLimit = 1
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageSelected(position: Int) {
super.onPageSelected(position)
// tabLayout.currentTab = position
}
})
// tabLayout.setOnTabSelectListener(object : OnTabSelectListener {
// override fun onTabSelect(position: Int) {
//// viewPager2.currentItem = position
// viewPager2.setCurrentItem(position, false)
// KeyboardUtils.hideSoftInput(viewPager2)
// }
//
// override fun onTabReselect(position: Int) {
// }
//
// })
viewPager2.setCurrentItem(0, false)

mTimeHandler.post(timeRunnable)
}

private fun checkAuto() {
isAutoShowLeave = SPUtils.getInstance().getBoolean("auto_show_leave", false)
isAutoShowChange = SPUtils.getInstance().getBoolean("auto_show_change", false)
// if (isAutoShowLeave || isAutoShowChange) {
// mHandler.removeCallbacks(runnable)
// mHandler.postDelayed(runnable, 2000)
// } else {
// mHandler.removeCallbacks(runnable)
// }
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: AutoSwitchChange) {
checkAuto()
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: UserLoginEvent) {
if (client?.isOpen == true) {
client?.close()
}
client = null
}

override fun onDestroy() {
super.onDestroy()
mTimeHandler.removeCallbacks(timeRunnable)
if (client?.isOpen == true) {
client?.close()
}
}

//接收请假消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(detail: StuLeave) {
removeOld(detail.id, 0)
val dialog = LeaveDialog(this)
dialog.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
dialog.setData(detail)
dialog.setTag(R.id.tag_dialog_name, detail.id)
dialog.setTag(R.id.tag_dialog_type, 0)
dialog.onCloseClick = {
dialogLayout.removeView(it)
dialogList.remove(it)
}
dialogLayout.addView(dialog)
dialogList.add(dialog)
}

//接收异动消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(detail: StuChange) {
removeOld(detail.id, 1)
val dialog = ChangeDialog(this)
dialog.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
dialog.setData(detail)
dialog.setTag(R.id.tag_dialog_name, detail.id)
dialog.setTag(R.id.tag_dialog_type, 1)
dialog.onCloseClick = {
dialogLayout.removeView(it)
dialogList.remove(it)
}
dialogLayout.addView(dialog, 0) //请假权限更高,异动插入到最底层
dialogList.add(dialog)
}

//接收访客消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(detail: Visitor) {
removeOld(detail.id, 2)
val dialog = VisitorDialog(this)
dialog.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
dialog.setData(detail)
dialog.setTag(R.id.tag_dialog_name, detail.id)
dialog.setTag(R.id.tag_dialog_type, 2)
dialog.onCloseClick = {
dialogLayout.removeView(it)
dialogList.remove(it)
}
dialogLayout.addView(dialog, 0) //请假权限更高,访客插入到最底层
dialogList.add(dialog)
}

//接收查看图片消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(detail: ViewImage) {
removeOld(detail.id, 3)
val dialog = ViewImageDialog(this)
dialog.layoutParams = ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
dialog.setData(detail)
dialog.setTag(R.id.tag_dialog_name, detail.id)
dialog.setTag(R.id.tag_dialog_type, 3)
dialog.onCloseClick = {
dialogLayout.removeView(it)
dialogList.remove(it)
}
dialogLayout.addView(dialog)
dialogList.add(dialog)
}

private fun removeOld(id: Int, type: Int) {
val view = dialogList.find {
val tagId: Int = it.getTag(R.id.tag_dialog_name) as Int
val tagType: Int = it.getTag(R.id.tag_dialog_type) as Int
return@find id == tagId && type == tagType
}
view?.apply {
dialogList.remove(this)
dialogLayout.removeView(this)
}
}

override fun initData() {
NetworkUtils.registerNetworkStatusChangedListener(this)
PermissionUtils.permissionGroup(PermissionConstants.STORAGE)
.rationale { activity, shouldRequest ->

}.callback(object : PermissionUtils.FullCallback {
override fun onGranted(granted: MutableList<String>) {
LogUtils.d("权限通过", granted)
}

override fun onDenied(
deniedForever: MutableList<String>,
denied: MutableList<String>
) {
LogUtils.d("权限拒绝", denied)
}

}).theme { activity -> ScreenUtils.setFullScreen(activity) }
.request()

}

override fun onResume() {
super.onResume()
if (NetworkUtils.isConnected() && User.isLogin() && User.getUser().user_id > 0 && client?.isOpen !== true) {
// initWs()
}
}

private fun initWs() {
client =
object : WebSocketClient(URI.create(Config.WS_URL), Draft_6455(), null, 10 * 1000) {
override fun onOpen(handshakedata: ServerHandshake?) {
LogUtils.d("WebSocketClient-onOpen", handshakedata)
val user = User.getUser()
val clientInfo = YzxClientInfo()
clientInfo.type = 70
clientInfo.user_id = user.user_id.toString()
clientInfo.unit_id = user.school_id.toString()
clientInfo.token = user.token

client?.send(Gson().toJson(clientInfo))

}

override fun onClose(code: Int, reason: String?, remote: Boolean) {
LogUtils.d("WebSocketClient-onClose", code, reason, remote)

}

override fun onMessage(message: String?) {
LogUtils.d("WebSocketClient-onMessage", message)
if (message?.startsWith("ECHO:", true) == false) {
viewPager2.post {
wsMessage(message)
}
}
}

override fun onError(ex: Exception?) {
LogUtils.d("WebSocketClient-onError", ex)

}

}
try {
client?.connectBlocking()
wsHeart()
} catch (e: InterruptedException) {
e.printStackTrace()
LogUtils.d("WebSocketClient-catch", e)
}
}

private fun wsMessage(msg: String) {
val resultType = object : TypeToken<YzxClientInfo>() {}.type
val gson = Gson()
val res = gson.fromJson<YzxClientInfo>(msg, resultType)
if (res.data.student_id > 0) {
if (isAutoShowLeave || isAutoShowChange) {
mPresenter?.getLeaveShowIds("${res.data.student_id}")
}
}
}

private fun wsHeart() {
viewPager2.postDelayed({
if (client?.isOpen == true) {
client?.apply {
send(Gson().toJson(YzxHeart().getYzxHeader()))
}
} else {
if (client != null) {
client?.reconnectBlocking()
} else {
initWs()
}
}
wsHeart()
}, 10 * 1000)
}

private fun showNetworkError() {
if (!NetworkUtils.isConnected()) { //无网提示
val builder = QMUIDialog.MessageDialogBuilder(this)

builder.setMessage("你还没有连接网络,请先连接网络!")
.setTitle("温馨提示")
.addAction(
"去设置"
) { dialog, index ->
NetworkUtils.openWirelessSettings()
}
.setCancelable(false)
.setCanceledOnTouchOutside(false)
netErrorDialog = builder.show()
netErrorDialog?.hideNavigationBar()
}
}

private fun showNetworkLoading() {
val builder = QMUIDialog.MessageDialogBuilder(this)

builder.setMessage("网络检查中,请稍后...")
.setTitle("温馨提示")
.setCancelable(false)
.setCanceledOnTouchOutside(false)
netLoadingDialog = builder.show()
netLoadingDialog?.hideNavigationBar()

viewPager2.postDelayed(netLoadingRun, 5000)
}

override fun initPresenter(): MainPresenter = MainPresenter(this)

@SuppressLint("SetTextI18n")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
}

override fun onBackPressed() {
// super.onBackPressed()
}

override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME) {
return true
}
return super.onKeyUp(keyCode, event)
}

override fun onDisconnected() {
showNetworkError()
}

override fun onConnected(networkType: NetworkUtils.NetworkType?) {
netLoadingDialog?.apply {
if (isShowing) {
dismiss()
}
}
netErrorDialog?.apply {
if (isShowing) {
dismiss()
}
}
viewPager2.removeCallbacks(netLoadingRun)
if (!User.isLogin()) {
// WebActivity.active(this, "${Config.OA_URL}/login?logout=1")
LoginActivity.active(this)
finish()
}
checkVersion()
checkAuto()
initWs()
}

private fun checkVersion(userCheck: Boolean = false): Unit {
val BASE_URL = Config.BASE_URL
OkGo.post<String>("$BASE_URL/parent/common/getInkBottleMaxVersion")
.tag(this)
.params("app_id", Config.APP_ID)
.execute(object : StringCallback() {

override fun onSuccess(response: Response<String>) {
val json = response.body()
Log.d("checkVersion", "onSuccess: ${json}")
val resultType = object : TypeToken<BaseBean<Version>>() {}.type
val gson = Gson()
val res = gson.fromJson<BaseBean<Version>>(json, resultType)
if (res.code == 0) {
val appVersion = AppUtils.getAppVersionName()
val appVersionCode = AppUtils.getAppVersionCode()
val versionCode = res?.data?.version_code ?: 0
val curr = Date().time
val lastTipTime = SPUtils.getInstance()
.getLong("last_tip_time${res.data.version_code}", 0)
if (versionCode > appVersionCode) { //有新版本
when {
res.data.type == 1 -> { //强制升级
updateApp(res.data)
}
curr - lastTipTime > 24 * 60 * 60 * 1000 -> { //非强制一天以内提示一次
updateApp(res.data)
}
userCheck -> { //
updateApp(res.data)
}
}

} else {
if (userCheck) {
toast("已经是最新版本了!")
}
}
}
}

})


}


private fun updateApp(version: Version) {
AllenVersionChecker
.getInstance()
.downloadOnly(
UIData.create()
.setTitle("检测到新版本")
.setContent(version.explain)
.setDownloadUrl(version.app_src)
)
.setCustomVersionDialogListener { context, versionBundle ->
val dialog = BaseDialog(context, R.style.BaseDialog, R.layout.version_dialog)
val title = dialog.find<TextView>(R.id.tv_title)
title.text = "检测到新版本"
val content = dialog.find<TextView>(R.id.tv_msg)
content.text = version.explain
val cancelBtn = dialog.find<View>(R.id.cancel_btn)
if (version.type == 1) {
cancelBtn.visibility = View.GONE
}
dialog.hideNavigationBar()
return@setCustomVersionDialogListener dialog
}
.setOnCancelListener {
SPUtils.getInstance().put("last_tip_time${version.version_code}", Date().time)
}
.setCustomDownloadingDialogListener(object : CustomDownloadingDialogListener {
@SuppressLint("SetTextI18n")
override fun updateUI(dialog: Dialog?, progress: Int, versionBundle: UIData?) {
val tvProgress: TextView = dialog!!.findViewById(R.id.tv_progress)
val progressBar: ContentLoadingProgressBar = dialog.findViewById(R.id.pb)
progressBar.progress = progress
tvProgress.text = "$progress%"

Log.d("checkVersion", "onSuccess: ${progress}")
}

override fun getCustomDownloadingDialog(
context: Context?,
progress: Int,
versionBundle: UIData?
): Dialog {
val downDialog = BaseDialog(
context!!,
R.style.BaseDialog,
R.layout.download_dialog
)
downDialog.hideNavigationBar()
return downDialog
}

})
.executeMission(this)
}

override fun onLeaveIDsSuccess(list: MutableList<LeaveID>) {
idsLoading = false
LogUtils.d("获取详情结束--ids", TimeUtils.getNowMills())
val listLeave = list.filter { it.type == 0 }.toMutableList()
val listChange = list.filter { it.type == 1 }.toMutableList()
var type = 0
if (listLeave.isNotEmpty() && isAutoShowLeave) {
viewPager2.currentItem = 0
type = 0
} else if (listChange.isNotEmpty() && isAutoShowChange) {
viewPager2.currentItem = 1
type = 1
}
if (list.isNotEmpty() && (isAutoShowLeave || isAutoShowChange)) {
viewPager2.postDelayed({
EventBus.getDefault().post(MessageEventAuto(list, type))
}, 500)
}
}

override fun onLeaveIDsError() {
LogUtils.d("获取详情结束--ids", TimeUtils.getNowMills())
idsLoading = false
}

override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}

override fun onStop() {
mHandler.removeCallbacks(runnable)
super.onStop()
EventBus.getDefault().unregister(this)
}
}

class HomePagerAdapter(act: AppCompatActivity) : FragmentStateAdapter(act) {
override fun getItemCount(): Int = 1

override fun createFragment(position: Int): Fragment {
when (position) {
0 -> {
return ClassBrandFragment.getNewInstance()
}
1 -> {
return ChangeFragment.getNewInstance()
}
2 -> {
return VisitorFragment.getNewInstance()
}
3 -> {
return MyFragment.getNewInstance()
}
}
return ClassBrandFragment.getNewInstance()
}

}

+ 24
- 0
app/src/main/java/com/yzx/ebrand/activity/CameraActivity.kt 查看文件

@@ -0,0 +1,24 @@
package com.yzx.ebrand.activity

import android.os.Bundle
import com.yzx.ebrand.R
import com.yzx.ebrand.activity.base.BaseActivity
import com.yzx.ebrand.presenter.base.BasePresenter

class CameraActivity : BaseActivity<BasePresenter<*>>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
}

override val inflateId: Int
get() = R.layout.activity_camera

override fun initView() {
}

override fun initData() {
}

override fun initPresenter(): BasePresenter<*>? = null
}

+ 304
- 0
app/src/main/java/com/yzx/ebrand/activity/HomeActivity.kt 查看文件

@@ -0,0 +1,304 @@
package com.yzx.ebrand.activity

import android.Manifest
import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.core.widget.ContentLoadingProgressBar
import androidx.recyclerview.widget.GridLayoutManager
import com.allenliu.versionchecklib.v2.AllenVersionChecker
import com.allenliu.versionchecklib.v2.builder.UIData
import com.allenliu.versionchecklib.v2.callback.CustomDownloadingDialogListener
import com.blankj.utilcode.constant.PermissionConstants
import com.blankj.utilcode.util.*
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.Response
import com.yzx.ebrand.MainActivity
import com.yzx.ebrand.R
import com.yzx.ebrand.activity.base.BaseActivity
import com.yzx.ebrand.adapter.HomeAdapter
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.model.BaseBean
import com.yzx.ebrand.model.HomeItem
import com.yzx.ebrand.model.User
import com.yzx.ebrand.model.Version
import com.yzx.ebrand.widget.BaseDialog
import com.yzx.ebrand.presenter.base.BasePresenter
import kotlinx.android.synthetic.main.activity_home.*
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
import java.util.*

class HomeActivity : BaseActivity<BasePresenter<*>>(), NetworkUtils.OnNetworkStatusChangedListener {

private val mAdapter: HomeAdapter by lazy {
val list = mutableListOf<HomeItem>()
list.add(HomeItem("家庭作业", R.mipmap.ic_home_work, "/homework/ebook_list"))
list.add(HomeItem("笔记本", R.mipmap.ic_home_notebook, "/notebook/list"))
list.add(HomeItem("背诵默写", R.mipmap.ic_home_write, "/write/index"))
list.add(HomeItem("阅读", R.mipmap.ic_home_rack,"/read/index"))
list.add(HomeItem("错题本", R.mipmap.ic_home_errorbook, "/errorbook/ebookindex"))
list.add(HomeItem("随堂检测", R.mipmap.ic_home_classwork))
list.add(HomeItem("我的", R.mipmap.ic_home_my, "/mine/ebook"))
HomeAdapter(list)
}

private var count = 0
private val run = Runnable {
count = 0
}

private var netDialog:AlertDialog ?= null

override val inflateId: Int
get() = R.layout.activity_home



override fun initView() {

NetworkUtils.registerNetworkStatusChangedListener(this)


val layoutManager = GridLayoutManager(this, 3)
homeGridView.layoutManager = layoutManager
homeGridView.adapter = mAdapter

switchBtn.setOnClickListener {
val url = "${Config.M_URL}/choiceunit.html?from=ehome"
WebActivity.active(this, url)
}

loginBtn.setOnClickListener {
val url = "${Config.M_URL}/login.html?from=ehome"
WebActivity.active(this, url)
}

testBtn.setOnClickListener {
count++
testBtn.removeCallbacks(run)
testBtn.postDelayed(run, 1000)
if (count >= 5) {
startActivity<MainActivity>()
}
}
}

override fun initData() {
mAdapter.setOnItemClickListener { adapter, view, position ->
if (User.getUser().user_id == 0) {
val url = "${Config.M_URL}/login.html?from=ehome"
WebActivity.active(this, url)
} else {
val list = mAdapter.data
val item = list[position]
if (StringUtils.isTrimEmpty(item.url)) {
toast("功能设计中,敬请期待")
} else {
val url = Config.M_URL + item.url
WebActivity.active(this, url)
}
}
}


//请求权限
// ActivityCompat.requestPermissions(
// this,
// PERMISSIONS,
// PERMISSIONS_REQUEST_STORAGE
// )

PermissionUtils.permissionGroup(PermissionConstants.STORAGE)
.rationale { activity, shouldRequest ->

}.callback(object :PermissionUtils.FullCallback{
override fun onGranted(granted: MutableList<String>) {
LogUtils.d("权限通过",granted)
}

override fun onDenied(
deniedForever: MutableList<String>,
denied: MutableList<String>
) {
LogUtils.d("权限拒绝",denied)
}

}).theme { activity -> ScreenUtils.setFullScreen(activity) }
.request()


}

private val PERMISSIONS_REQUEST_STORAGE = 1

val PERMISSIONS = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)

override fun initPresenter(): BasePresenter<*>? {
return null
}

@SuppressLint("SetTextI18n")
override fun onResume() {
super.onResume()
val user = User.getUser()
if (user.user_id != 0) {
userNameTv.text = "你好,${user.user_name}"
// userInfoTv.text = "${user.school_name} | ${user.grade_name}${user.class_name}"
userInfoTv.visibility = View.VISIBLE
loginBtn.visibility = View.GONE
switchBtn.visibility = if (User.getUnitCount() > 1) {
View.VISIBLE
} else {
View.GONE
}
} else {
userNameTv.text = "未登录"
userInfoTv.text = ""
userInfoTv.visibility = View.GONE
loginBtn.visibility = View.VISIBLE
switchBtn.visibility = View.GONE
}
titleTv.text = Config.APP_NAME
if (NetworkUtils.isConnected()) {
checkVersion(false)
}else{
checkNetwork()
}
}

private fun checkNetwork() {
if(netDialog==null){
val builder = AlertDialog.Builder(this)
builder.setTitle("温馨提示")
builder.setMessage("你还没有连接网络,请先连接网络!")
builder.setPositiveButton("去设置") { _, _ ->
NetworkUtils.openWirelessSettings()
}
builder.setCancelable(false)
netDialog = builder.create()
netDialog?.setCanceledOnTouchOutside(false)
netDialog?.getButton(DialogInterface.BUTTON_NEGATIVE)?.visibility = View.GONE
}
netDialog?.show()
}

private fun checkVersion(userCheck: Boolean = false): Unit {
val BASE_URL = Config.BASE_URL
OkGo.post<String>("$BASE_URL/parent/common/getInkBottleMaxVersion")
.tag(this)
.execute(object : StringCallback() {

override fun onSuccess(response: Response<String>) {
val json = response.body()
Log.d("checkVersion", "onSuccess: ${json}")
val resultType = object : TypeToken<BaseBean<Version>>() {}.type
val gson = Gson()
val res = gson.fromJson<BaseBean<Version>>(json, resultType)
if (res.code == 0) {
val appVersion = AppUtils.getAppVersionName()
val appVersionCode = AppUtils.getAppVersionCode()
val versionCode = res?.data?.version_code ?: 0
val curr = Date().time
val lastTipTime = SPUtils.getInstance()
.getLong("last_tip_time${res.data.version_code}", 0)
if (versionCode > appVersionCode) { //有新版本
when {
res.data.type == 1 -> { //强制升级
updateApp(res.data)
}
curr - lastTipTime > 24 * 60 * 60 * 1000 -> { //非强制一天以内提示一次
updateApp(res.data)
}
userCheck -> { //
updateApp(res.data)
}
}

} else {
if (userCheck) {
toast("已经是最新版本了!")
}
}
}
}

})


}


private fun updateApp(version: Version) {
AllenVersionChecker
.getInstance()
.downloadOnly(
UIData.create()
.setTitle("检测到新版本")
.setContent(version.explain)
.setDownloadUrl(version.app_src)
)
.setCustomVersionDialogListener { context, versionBundle ->
val dialog = BaseDialog(context, R.style.BaseDialog, R.layout.version_dialog)
val title = dialog.find<TextView>(R.id.tv_title)
title.text = "检测到新版本"
val content = dialog.find<TextView>(R.id.tv_msg)
content.text = version.explain
dialog.window?.setDimAmount(0.5f)
val cancelBtn = dialog.find<View>(R.id.cancel_btn)
if (version.type == 1) {
cancelBtn.visibility = View.GONE
}

return@setCustomVersionDialogListener dialog
}
.setOnCancelListener {
SPUtils.getInstance().put("last_tip_time${version.version_code}", Date().time)
}
.setCustomDownloadingDialogListener(object : CustomDownloadingDialogListener {
@SuppressLint("SetTextI18n")
override fun updateUI(dialog: Dialog?, progress: Int, versionBundle: UIData?) {
val tvProgress: TextView = dialog!!.findViewById(R.id.tv_progress)
val progressBar: ContentLoadingProgressBar = dialog.findViewById(R.id.pb)
progressBar.progress = progress
tvProgress.text = "$progress%"

Log.d("checkVersion", "onSuccess: ${progress}")
}

override fun getCustomDownloadingDialog(
context: Context?,
progress: Int,
versionBundle: UIData?
): Dialog {
return BaseDialog(
context!!,
R.style.BaseDialog,
R.layout.download_dialog
)
}

})
.executeMission(this)
}

override fun onConnected(networkType: NetworkUtils.NetworkType?) {
netDialog?.dismiss()
}

override fun onDisconnected() {
checkNetwork()
}
}

+ 247
- 0
app/src/main/java/com/yzx/ebrand/activity/LoginActivity.kt 查看文件

@@ -0,0 +1,247 @@
package com.yzx.ebrand.activity

import android.app.Activity
import android.view.View
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.SPUtils
import com.flyco.tablayout.listener.CustomTabEntity
import com.flyco.tablayout.listener.OnTabSelectListener
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog.Builder.ICON_TYPE_FAIL
import com.yzx.ebrand.MainActivity
import com.yzx.ebrand.R
import com.yzx.ebrand.activity.base.BaseActivity
import com.yzx.ebrand.model.BaseUser
import com.yzx.ebrand.model.TabEntity
import com.yzx.ebrand.model.User
import com.yzx.ebrand.presenter.LoginPresenter
import com.yzx.ebrand.presenter.LoginView
import com.yzx.ebrand.utils.hideNavigationBar
import com.yzx.ebrand.utils.setSrc
import kotlinx.android.synthetic.main.activity_login.accountEdit
import kotlinx.android.synthetic.main.activity_login.accountLayout
import kotlinx.android.synthetic.main.activity_login.loginBtn
import kotlinx.android.synthetic.main.activity_login.pswCheckbox
import kotlinx.android.synthetic.main.activity_login.pswEdit
import kotlinx.android.synthetic.main.activity_login.qrCodeImg
import kotlinx.android.synthetic.main.activity_login.qrLayout
import kotlinx.android.synthetic.main.activity_login.tabLayout
import org.jetbrains.anko.startActivity

class LoginActivity : BaseActivity<LoginPresenter>(), LoginView {

companion object {
fun active(act: Activity) {
act.startActivity<LoginActivity>()
}
}

private var mTicket = ""

override val inflateId: Int
get() = R.layout.activity_login

override fun initView() {
val tabData = arrayListOf<CustomTabEntity>()
tabData.add(TabEntity("账号密码登录", 0, 0))
tabData.add(TabEntity("微信扫码登录", 0, 0))
tabLayout.setTabData(tabData)
tabLayout.setOnTabSelectListener(object : OnTabSelectListener {
override fun onTabSelect(position: Int) {
if (position == 0) {
qrLayout.visibility = View.GONE
accountLayout.visibility = View.VISIBLE
SPUtils.getInstance().put("last_login_tab_index",0)
} else {
qrLayout.visibility = View.VISIBLE
accountLayout.visibility = View.GONE
SPUtils.getInstance().put("last_login_tab_index",1)
KeyboardUtils.hideSoftInput(this@LoginActivity)
}
}

override fun onTabReselect(position: Int) {

}
})
val lastLoginTabIndex = SPUtils.getInstance().getInt("last_login_tab_index",0)
if(lastLoginTabIndex == 1){
qrLayout.visibility = View.VISIBLE
accountLayout.visibility = View.GONE
tabLayout.currentTab = 1
}
loginBtn.setOnClickListener {
this.doLogin()
}
val isSavePsw = SPUtils.getInstance().getBoolean("is_save_psw", false)
if (isSavePsw) {
pswCheckbox.isChecked = true
val phone = SPUtils.getInstance().getString("login_save_phone", "")
val psw = SPUtils.getInstance().getString("login_save_psw", "")
accountEdit.setText(phone)
pswEdit.setText(psw)
} else {
pswCheckbox.isChecked = false
}
}

private fun doLogin() {
val phone = accountEdit.text.toString()
val psw = pswEdit.text.toString()
if (phone.isBlank()) {
showDialogToast("请输入账号", icon = QMUITipDialog.Builder.ICON_TYPE_FAIL)
return
}
if (psw.isBlank()) {
showDialogToast("请输入密码", icon = QMUITipDialog.Builder.ICON_TYPE_FAIL)
return
}
showLoading("登录中...")
if(pswCheckbox.isChecked){
SPUtils.getInstance().put("is_save_psw",true)
SPUtils.getInstance().put("login_save_phone",phone)
SPUtils.getInstance().put("login_save_psw",psw)
}else{
SPUtils.getInstance().put("is_save_psw",false)
SPUtils.getInstance().remove("login_save_phone")
SPUtils.getInstance().remove("login_save_psw")
}
mPresenter?.login(phone, psw)
}

override fun initData() {
mPresenter?.getWXQrCode()
}

override fun initPresenter(): LoginPresenter = LoginPresenter(this)

override fun onLoginSuccess(user: BaseUser, list: MutableList<BaseUser>) {
val teaList = list.filter {
return@filter it.type == 0
}
when {
teaList.isEmpty() -> {

if(user.type == 0){
mPresenter?.switchUser(user.token, user.user_id, user.school_id)
}else{
hideLoading()
this.showDialogToast("无登录权限", icon = ICON_TYPE_FAIL)
}
}

teaList.size == 1 -> { //多个角色
val item = teaList[0]
mPresenter?.switchUser(user.token, item.user_id, item.unit_id)
}

else -> {
mPresenter?.getUserRoleList(user.token)
}
}
}

override fun onLoginError(msg: String) {
hideLoading()
showDialogToast(msg, icon = ICON_TYPE_FAIL)
}

override fun onUserInfoSuccess(user: User) {
hideLoading()
startActivity<MainActivity>()
finish()
}

override fun onWxQrCodeSuccess(imgUrl: String, ticket: String) {
qrCodeImg.setSrc(imgUrl)
mTicket = ticket
mPresenter?.loginQuery(ticket)
}

override fun onDestroy() {
qrCodeImg?.apply {
removeCallbacks(null)
}
super.onDestroy()
}

private var mBindDialog: QMUIDialog? = null
private var mOverTimeDialog: QMUIDialog? = null

override fun onLoginQuerySuccess(user: BaseUser, code: Int) {
when (code) {
0 -> {
if (user.direct_login == 1) {
mPresenter?.getUserLoginInfo(user.token)
} else {
mPresenter?.getUserRoleInfoByPhone(user.phone, user.tmp_token)
}
}

451 -> {
if (mBindDialog == null) {
mBindDialog = QMUIDialog.MessageDialogBuilder(this)
.setTitle("温馨提示")
.setMessage("您还未绑定微信公众,请绑定后再试!")
.addAction("知道了") { dialog, index ->
dialog.dismiss()
}
.create()
mBindDialog?.show()
mBindDialog?.hideNavigationBar()
} else if (!mBindDialog!!.isShowing) {
mBindDialog?.show()
}
qrCodeImg.postDelayed({
mPresenter?.loginQuery(mTicket)
}, 1000)
}

452 -> {
qrCodeImg.postDelayed({
mPresenter?.loginQuery(mTicket)
}, 1000)
}

else -> {
if (mOverTimeDialog == null) {
mOverTimeDialog = QMUIDialog.MessageDialogBuilder(this)
.setTitle("温馨提示")
.setMessage("二维码已使用,请重新扫码!")
.addAction("知道了") { dialog, index ->
dialog.dismiss()
}
.create()
mOverTimeDialog!!.show()
mOverTimeDialog!!.hideNavigationBar()
} else if (!mOverTimeDialog!!.isShowing) {
mOverTimeDialog?.show()
}
mPresenter?.getWXQrCode()
}
}
}

override fun onUserListSuccess(list: MutableList<BaseUser>, token: String) {
LogUtils.d("onUserListSuccess", list)
hideLoading()
val builder = QMUIDialog.MenuDialogBuilder(this)
list.forEach {
builder.addItem(
it.unit_name
) { dialog, which ->
LogUtils.d("itemClick", which)
val item = list[which]
showLoading("登录中...")
if(item.school_id>0){
mPresenter?.switchUnit(item.user_id, item.unit_id,token)
}else{
mPresenter?.switchUser(token, item.user_id, item.unit_id)
}
}
}
builder.show()
}
}

+ 502
- 0
app/src/main/java/com/yzx/ebrand/activity/WebActivity.kt 查看文件

@@ -0,0 +1,502 @@
package com.yzx.ebrand.activity

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.os.Build
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.ViewGroup
import android.webkit.JavascriptInterface
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.core.widget.ContentLoadingProgressBar
import com.allenliu.versionchecklib.v2.AllenVersionChecker
import com.allenliu.versionchecklib.v2.builder.UIData
import com.allenliu.versionchecklib.v2.callback.CustomDownloadingDialogListener
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.NetworkUtils
import com.blankj.utilcode.util.SPUtils
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.Response
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.tencent.smtt.export.external.interfaces.*
import com.tencent.smtt.sdk.WebChromeClient
import com.tencent.smtt.sdk.WebSettings
import com.tencent.smtt.sdk.WebView
import com.tencent.smtt.sdk.WebViewClient
import com.yzx.ebrand.MainActivity
import com.yzx.ebrand.R
import com.yzx.ebrand.activity.base.BaseActivity
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.model.BaseBean
import com.yzx.ebrand.model.User
import com.yzx.ebrand.model.UserLoginEvent
import com.yzx.ebrand.model.Version
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.utils.hideNavigationBar
import com.yzx.ebrand.widget.BaseDialog
import kotlinx.android.synthetic.main.activity_web.*
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.ctx
import org.jetbrains.anko.find
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast
import java.util.*

/**
* 类名:WebActivity
* 作者:Yun.Lei
* 功能:
* 创建日期:2020年5月6日14:42:16
* 修改人:
* 修改时间:
* 修改备注:
*/
class WebActivity : BaseActivity<BasePresenter<*>>(), NetworkUtils.OnNetworkStatusChangedListener {


companion object {
fun active(act: Activity, link: String) {
act.startActivity<WebActivity>("link" to link)
}
}

private val webView: WebView by lazy { WebView(this) }
private var url: String = ""
private var count = 0
private val run = Runnable {
count = 0
}
var netErrorDialog: QMUIDialog? = null

override val inflateId: Int
get() = R.layout.activity_web

override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
url = intent?.getStringExtra("link") ?: "https://m.qbjjyyun.net/"
this.initData()
}

fun checkVersion(userCheck: Boolean = false): Unit {
val BASE_URL = Config.BASE_URL
OkGo.post<String>("$BASE_URL/parent/common/getInkBottleMaxVersion")
.tag(this)
.execute(object : StringCallback() {

override fun onSuccess(response: Response<String>) {
val json = response.body()
Log.d("checkVersion", "onSuccess: ${json}")
val resultType = object : TypeToken<BaseBean<Version>>() {}.type
val gson = Gson()
val res = gson.fromJson<BaseBean<Version>>(json, resultType)
if (res.code == 0) {
val appVersion = AppUtils.getAppVersionName()
val appVersionCode = AppUtils.getAppVersionCode()
val versionCode = res?.data?.version_code ?: 0
val curr = Date().time
val lastTipTime = SPUtils.getInstance()
.getLong("last_tip_time${res.data.version_code}", 0)
if (versionCode > appVersionCode) { //有新版本
when {
res.data.type == 1 -> { //强制升级
updateApp(res.data)
}
curr - lastTipTime > 24 * 60 * 60 * 1000 -> { //非强制一天以内提示一次
updateApp(res.data)
}
userCheck -> { //
updateApp(res.data)
}
}

} else {
if (userCheck) {
toast("已经是最新版本了!")
}
}
}
}

})


}

private fun updateApp(version: Version) {
AllenVersionChecker
.getInstance()
.downloadOnly(
UIData.create()
.setTitle("检测到新版本")
.setContent(version.explain)
.setDownloadUrl(version.app_src)
)
.setCustomVersionDialogListener { context, versionBundle ->
val dialog = BaseDialog(context, R.style.BaseDialog, R.layout.version_dialog)
val title = dialog.find<TextView>(R.id.tv_title)
title.text = "检测到新版本"
val content = dialog.find<TextView>(R.id.tv_msg)
content.text = version.explain
dialog.window?.setDimAmount(0.5f)
val cancelBtn = dialog.find<View>(R.id.cancel_btn)
if (version.type == 1) {
cancelBtn.visibility = View.GONE
}

return@setCustomVersionDialogListener dialog
}
.setOnCancelListener {
SPUtils.getInstance().put("last_tip_time${version.version_code}", Date().time)
}
.setCustomDownloadingDialogListener(object : CustomDownloadingDialogListener {
@SuppressLint("SetTextI18n")
override fun updateUI(dialog: Dialog?, progress: Int, versionBundle: UIData?) {
val tvProgress: TextView = dialog!!.findViewById(R.id.tv_progress)
val progressBar: ContentLoadingProgressBar = dialog.findViewById(R.id.pb)
progressBar.progress = progress
tvProgress.text = "$progress%"

Log.d("checkVersion", "onSuccess: ${progress}")
}

override fun getCustomDownloadingDialog(
context: Context?,
progress: Int,
versionBundle: UIData?
): Dialog {
return BaseDialog(
context!!,
R.style.BaseDialog,
R.layout.download_dialog
)
}

})
.executeMission(this)
}

@SuppressLint("SetJavaScriptEnabled")
override fun initView() {
url = intent?.getStringExtra("link") ?: "https://m.qbjjyyun.net/"
// titleTv.setOnClickListener {
// count++
// titleTv.removeCallbacks(run)
// titleTv.postDelayed(run, 1000)
// if (count >= 5) {
// startActivity<MainActivity>()
// }
// }
btnBack.setOnClickListener { onBackPressed() }
btnClose.setOnClickListener {
// webView.loadUrl(url)
finish()
}
btnRefresh.setOnClickListener {
webView.reload()
}
btnSetting.setOnClickListener {
NetworkUtils.openWirelessSettings()
}
webView.layoutParams = LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
webLayout.addView(webView)
webView.addJavascriptInterface(YzxJavascriptInterface(this), "YZX_SCREEN")
val userAgent = webView.settings.userAgentString
webView.settings.apply {
allowFileAccess = true
javaScriptEnabled = true
loadWithOverviewMode = true
useWideViewPort = true
defaultTextEncodingName = "gb2312"
setAppCacheEnabled(true)
mediaPlaybackRequiresUserGesture = false
javaScriptCanOpenWindowsAutomatically = true
cacheMode = WebSettings.LOAD_DEFAULT
databaseEnabled = true
setRenderPriority(WebSettings.RenderPriority.HIGH)
blockNetworkImage = false
domStorageEnabled = true
setAppCacheMaxSize(1024 * 1024 * 8)
setAppCachePath(ctx.cacheDir.absolutePath)
mixedContentMode = android.webkit.WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE
userAgentString = "$userAgent app/escreen"
}
webView.webViewClient = object : WebViewClient() {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
view?.loadUrl(request?.url.toString())
return super.shouldOverrideUrlLoading(view, request)
}

// 即使加载失败后,webview执行完onReceivedError()方法也会执行这个方法
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
webView.settings.blockNetworkImage = false
if (!TextUtils.isEmpty(view.title)) {
// titleTv.text = view.title//webView获取到网页title
}
}

override fun onReceivedSslError(
view: WebView,
handler: SslErrorHandler,
error: SslError
) {
handler.proceed()
}

override fun onReceivedError(
p0: WebView?,
p1: WebResourceRequest?,
p2: WebResourceError?
) {
super.onReceivedError(p0, p1, p2)
LogUtils.e("weberror-onReceivedError")
// showNetworkError("网络环境异常或服务器数据加载异常,请检查!", force = true)
}

override fun onReceivedError(p0: WebView?, p1: Int, p2: String?, p3: String?) {
super.onReceivedError(p0, p1, p2, p3)
LogUtils.e("weberror-onReceivedError2")
}
}
webView.webChromeClient = object : WebChromeClient() {
override fun onProgressChanged(view: WebView?, newProgress: Int) {
super.onProgressChanged(view, newProgress)
progressbar.progress = newProgress
if (newProgress >= 100) {
view?.post {
progressbar.visibility = View.GONE
if (view.canGoBack()) {
// btnBack.visibility = View.VISIBLE
// btnClose.visibility = View.VISIBLE
} else {
// btnBack.visibility = View.GONE
// btnClose.visibility = View.GONE
}
}
} else {
if (progressbar.visibility == View.GONE) {
view?.post { progressbar.visibility = View.VISIBLE }
}
}
}

override fun onJsAlert(
view: WebView?,
url: String?,
message: String?,
result: JsResult?
): Boolean {
val b = AlertDialog.Builder(this@WebActivity)
b.setTitle(message)
b.setPositiveButton("确定") { _, _ ->
result?.confirm()
}
return true
}
}
WebView.setWebContentsDebuggingEnabled(true) //将 WebViews 配置为可调试状态
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null)
}

override fun initData() {
webView.loadUrl(url)
showNetworkError()

}

override fun initPresenter(): BasePresenter<*>? {
return null
}

override fun onResume() {
super.onResume()
webView.onResume()
// checkVersion()
}

override fun onPause() {
super.onPause()
webView.onPause()
}

override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}

override fun onDestroy() {
super.onDestroy()
webView.apply {
// webViewClient = null
webChromeClient = null
(parent as ViewGroup).removeView(webView)
removeAllViews()
destroy()
}
AllenVersionChecker.getInstance().cancelAllMission()
}

/**
* 调用js方法
*/
private fun evaluateJavascript(funName: String, data: String) {
webView.post {
webView.evaluateJavascript("javascript:$funName('$data')") {
Log.d("javascriptCallBack:", it)
//toast(it)
}
}
}

@SuppressLint("SetTextI18n")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

}

override fun onDisconnected() {

}

override fun onConnected(networkType: NetworkUtils.NetworkType?) {

}

private fun showNetworkError(msg: String = "你还没有连接网络,请先连接网络!", force: Boolean = false) {
if (!NetworkUtils.isConnected() || force) { //无网提示
val builder = QMUIDialog.MessageDialogBuilder(this)

builder.setMessage(msg)
.setTitle("温馨提示")

.setCancelable(false)
.setCanceledOnTouchOutside(false)
if (force) {
builder.addAction("关闭") { dialog, index ->
finish()
}
}
builder.addAction(
"去设置"
) { dialog, index ->
NetworkUtils.openWirelessSettings()
}
netErrorDialog = builder.show()
netErrorDialog?.hideNavigationBar()
}
}

}


class YzxJavascriptInterface(var ctx: Activity) {

/**
* 获取电子书的clientId
*/
@JavascriptInterface
fun getClientId(): Int = 602

/**
* 提示
*/
@JavascriptInterface
fun toast(msg: String) {
ctx.toast("android:$msg")
}

/**
* 检查版本升级
*/
@JavascriptInterface
fun mCheckVersion() {
Log.d("mCheckVersion", "mCheckVersion: -------------------->")
val act = ctx as WebActivity
act.checkVersion(true)
}

/**
* 保存用户信息
*/
@JavascriptInterface
fun saveUserInfo(json: String) {
val resultType = object : TypeToken<User>() {}.type
val gson = Gson()
val user = gson.fromJson<User>(json, resultType)
EventBus.getDefault().post(UserLoginEvent())
user?.save()
}

@JavascriptInterface
fun saveUnitCount(count: Int) {
User.saveUnitCount(count)
}

@JavascriptInterface
fun toHome() {
ctx.startActivity<MainActivity>()
ctx.finish()
}

@JavascriptInterface
fun logout() {
val sp = SPUtils.getInstance()
sp.remove("user_name")
sp.remove("user_id")
sp.remove("type")
sp.remove("token")
sp.remove("school_id")
sp.remove("school_name")
sp.remove("phone")
sp.remove("grade_name")
sp.remove("grade_id")
sp.remove("class_name")
sp.remove("class_id")
sp.remove("ticket")
sp.remove("login_start")
sp.remove("unit_count")
ctx.startActivity<HomeActivity>()
}

}





















+ 121
- 0
app/src/main/java/com/yzx/ebrand/activity/base/BaseActivity.kt 查看文件

@@ -0,0 +1,121 @@
package com.yzx.ebrand.activity.base

import android.os.Bundle
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.utils.hideNavigationBar

/**
* 类名:BaseActivity
* 作者:Yun.Lei
* 功能:
* 创建日期:2020年5月6日14:27:04
* 修改人:
* 修改时间:
* 修改备注:
*/
abstract class BaseActivity<out P : BasePresenter<*>> : AppCompatActivity() {

/**
* 当前页面需要加载的layoutId,等价setContentView
*/
abstract val inflateId: Int

private var mLoadingDialog: QMUITipDialog? = null

/**
* 初始化视图操作在这里执行,执行时机为onCreate之后
*/
abstract fun initView(): Unit

/**
* 数据初始化在这里执行,执行时机为initView之后
*/
abstract fun initData(): Unit

//kotlin 懒加载,在第一次使用Presenter时初始化,这种设计是针对一个View只针对一个Presenter。
//多个Presenter的情况此处不应该使用泛型
protected val mPresenter: P? by lazy { initPresenter() }

abstract fun initPresenter(): P?


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
hideBottomUIMenu()
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
actionBar?.hide()
setContentView(inflateId)
initView()
initData()
setStatusBar()

}

open fun setStatusBar() {
// immersionBar {
// statusBarColor(R.color.white)
// fitsSystemWindows(false)
// statusBarDarkFont(true, 0.2f)
// keyboardEnable(true)
// init()
// }
}


private fun hideBottomUIMenu() {
val params: WindowManager.LayoutParams = window.attributes
params.systemUiVisibility =
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE
window.attributes = params
}


override fun onBackPressed() {
super.onBackPressed()
}

override fun onDestroy() {
super.onDestroy()

}

fun showDialogToast(
msg: String,
duration: Long = 1500,
@QMUITipDialog.Builder.IconType icon: Int = QMUITipDialog.Builder.ICON_TYPE_SUCCESS
) {
val tipDialog = QMUITipDialog.Builder(this)
.setIconType(icon)
.setTipWord(msg)
.create()
tipDialog.show()
tipDialog.hideNavigationBar()
window.decorView.postDelayed({
tipDialog.dismiss()
}, duration)

}

fun showLoading(msg: String = "加载中...") {
mLoadingDialog = QMUITipDialog.Builder(this)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord(msg)
.create()
mLoadingDialog?.apply {
show()
}
}

fun hideLoading() {
mLoadingDialog?.apply {
if (isShowing) {
dismiss()
}
}
}

}

+ 94
- 0
app/src/main/java/com/yzx/ebrand/adapter/ChangeDialogStepAdapter.kt 查看文件

@@ -0,0 +1,94 @@
package com.yzx.ebrand.adapter

import android.annotation.SuppressLint
import android.graphics.Color
import android.view.View
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yzx.ebrand.R
import com.yzx.ebrand.model.ChangeActivity
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.layout_leave_step.view.*
import org.jetbrains.anko.dip

class ChangeDialogStepAdapter(list: MutableList<ChangeActivity>) :
BaseQuickAdapter<ChangeActivity, BaseViewHolder>(R.layout.layout_leave_step, list) {

@SuppressLint("SetTextI18n")
override fun convert(holder: BaseViewHolder, item: ChangeActivity) {
holder.itemView.inImg.visibility = View.GONE
holder.itemView.visibility = View.VISIBLE
holder.itemView.addUserTypeName.visibility = View.GONE
holder.itemView.activityName.visibility = View.GONE
holder.itemView.addUserName.visibility = View.VISIBLE
when (item.is_approve) {
0 -> {

holder.itemView.addUserTypeName.visibility = View.GONE
holder.itemView.addUserName.text = "${item.add_user_name}发起异动申请${
if (item.is_auto_pass == 1) {
"(直接通过)"
} else {
""
}
}"
holder.itemView.approvalComments.visibility = View.GONE
}
1 -> {
holder.itemView.addUserName.text = "班主任审批"
holder.itemView.statusName.text = when (item.approval_status) {
0,1 -> "(待审批)"
2 -> "(通过)"
3 -> "(拒绝)"
else -> ""
}
holder.itemView.statusName.setTextColor(when (item.approval_status) {
0,1 -> Color.parseColor("#3c7ef6")
2 -> Color.parseColor("#07c160")
3 -> Color.parseColor("#ff4040")
else -> 0
})
holder.itemView.approvalComments.visibility = View.VISIBLE
var str = "审批人:${item.add_user_name}"
if (item.approval_comments.isNotEmpty()) {
str += "。${item.approval_comments}"
}
holder.itemView.approvalComments.text = str
}
2->{
holder.itemView.addUserName.text = "提前结束"
holder.itemView.approvalComments.visibility = View.VISIBLE
var str = "操作人:${item.add_user_name}"
if (item.approval_comments.isNotEmpty()) {
str += "。${item.approval_comments}"
}
holder.itemView.approvalComments.text = str
}
else -> {
holder.itemView.visibility = View.GONE
}
}

holder.itemView.signImg.visibility = if(item.sign_key?.isNotEmpty() == true){
holder.itemView.signImg.setSrc(item.sign_identity,item.sign_key)
View.VISIBLE
}else{
View.GONE
}

holder.itemView.stepTime.text = item.add_time.toTime()

if (holder.adapterPosition == 0) {
holder.itemView.line1.setBackgroundResource(R.color.transparent)
} else {
holder.itemView.line1.setBackgroundResource(R.color.gray_1)
}

if (holder.adapterPosition == data.size - 1) {
holder.itemView.contentLayout.setPadding(0, 0, 0, 0)
} else {
holder.itemView.contentLayout.setPadding(0, 0, 0, holder.itemView.contentLayout.dip(20))
}
}
}

+ 80
- 0
app/src/main/java/com/yzx/ebrand/adapter/ChangeListAdapter.kt 查看文件

@@ -0,0 +1,80 @@
package com.yzx.ebrand.adapter

import android.annotation.SuppressLint
import android.graphics.Color
import android.view.View
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yzx.ebrand.R
import com.yzx.ebrand.model.StuChange
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toDay
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.layout_change_table.view.*
import org.jetbrains.anko.textColor

class ChangeListAdapter(list: MutableList<StuChange>) :
BaseQuickAdapter<StuChange, BaseViewHolder>(R.layout.layout_change_table, list) {

init {
addChildClickViewIds(R.id.cancelBtn,R.id.faceEmpty)
}

@SuppressLint("SetTextI18n")
override fun convert(holder: BaseViewHolder, item: StuChange) {
holder.itemView.studentName.text = item.status_change_student_name
if (item.face_key.isNullOrBlank()) {
holder.itemView.faceEmpty.visibility = View.VISIBLE
holder.itemView.faceImg.visibility = View.GONE
} else {
holder.itemView.faceImg.visibility = View.VISIBLE
holder.itemView.faceEmpty.visibility = View.GONE
holder.itemView.faceImg.setSrc(item.face_identity, item.face_key)
}
holder.itemView.className.text = "${item.grade_name}${item.class_name}"
holder.itemView.typeName.text = item.status_change_type_name

var time = "--"
if (item.start_time > 0) {
time = item.start_time.toDay()
}
if (item.end_time > 0) {
time = "$time -- ${item.end_time.toDay()}"
}
holder.itemView.leaveTime.text = time

holder.itemView.statusName.text = when (item.status) {
1 -> "待处理"
2 -> "已确认"
3 -> "已拒绝"
else -> "--"
}
holder.itemView.statusName.textColor = when (item.status) {
1 -> Color.parseColor("#333333")
2 -> Color.parseColor("#3c7ef6")
3 -> Color.parseColor("#ff4040")
4 -> Color.parseColor("#3c7ef6")
5 -> Color.parseColor("#ff4040")
else -> Color.parseColor("#333333")
}
if (item.getSubStatusName().isNotEmpty()) {
holder.itemView.subStatusName.text = "(${item.getSubStatusName()})"
holder.itemView.subStatusName.textColor = when (item.sub_status) {
0, 2 -> Color.parseColor("#ff4040")
1, 3 -> Color.parseColor("#07c160")
else -> Color.parseColor("#333333")
}
} else {
holder.itemView.subStatusName.text = ""
}

holder.itemView.applyTime.text = item.add_time.toTime()

holder.itemView.bottomLine.visibility = if (holder.adapterPosition == data.size - 1) {
View.GONE
} else {
View.VISIBLE
}
holder.itemView.addUser.text = item.add_user_name
}
}

+ 14
- 0
app/src/main/java/com/yzx/ebrand/adapter/HomeAdapter.kt 查看文件

@@ -0,0 +1,14 @@
package com.yzx.ebrand.adapter

import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yzx.ebrand.R
import com.yzx.ebrand.model.HomeItem
import kotlinx.android.synthetic.main.item_home.view.*

class HomeAdapter(list: MutableList<HomeItem>) : BaseQuickAdapter<HomeItem, BaseViewHolder>(R.layout.item_home,list) {
override fun convert(holder: BaseViewHolder, item: HomeItem) {
holder.itemView.img.setImageResource(item.img)
holder.itemView.name.text = item.title
}
}

+ 102
- 0
app/src/main/java/com/yzx/ebrand/adapter/HomeDialogStepAdapter.kt 查看文件

@@ -0,0 +1,102 @@
package com.yzx.ebrand.adapter

import android.annotation.SuppressLint
import android.graphics.Color
import android.view.View
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yzx.ebrand.R
import com.yzx.ebrand.model.LeaveActivity
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.layout_leave_step.view.*
import org.jetbrains.anko.dip
import org.jetbrains.anko.textColor

class HomeDialogStepAdapter(list: MutableList<LeaveActivity>) :
BaseQuickAdapter<LeaveActivity, BaseViewHolder>(R.layout.layout_leave_step, list) {

@SuppressLint("SetTextI18n")
override fun convert(holder: BaseViewHolder, item: LeaveActivity) {
holder.itemView.inImg.visibility = View.GONE
when (item.is_approve) {
0 -> {
holder.itemView.addUserName.visibility = View.VISIBLE
holder.itemView.addUserName.text = item.add_user_name
holder.itemView.approvalComments.visibility = View.GONE
}
2 -> {
holder.itemView.addUserName.visibility = View.GONE
holder.itemView.approvalComments.visibility = View.VISIBLE
holder.itemView.approvalComments.text = item.approval_comments
holder.itemView.approvalComments.textColor = if (item.color.isNotEmpty()) {
Color.parseColor(item.color)
} else {
Color.parseColor("#333333")
}

val inItem = item.getInImg()
if (inItem != null) {
holder.itemView.inImg.visibility = View.VISIBLE
holder.itemView.inImg.setSrc(inItem.identity, inItem.attachment_id)
} else {
holder.itemView.inImg.visibility = View.GONE
}
}
else -> {
holder.itemView.addUserName.visibility = View.GONE
holder.itemView.approvalComments.visibility = View.VISIBLE
var str = "审批人:${item.add_user_name}"
if (item.approval_comments != null && item.approval_comments.isNotEmpty()) {
str += "。${item.approval_comments}"
}
holder.itemView.approvalComments.text = str
}
}
if (item.add_user_type_name.isNullOrBlank()) {
holder.itemView.addUserTypeName.visibility = View.GONE
} else {
holder.itemView.addUserTypeName.visibility = View.VISIBLE
holder.itemView.addUserTypeName.text = "(${item.add_user_type_name})"
}
holder.itemView.activityName.text = item.activity_name

if (item.is_approve == 1 && item.approval_status > 0) {
holder.itemView.statusName.visibility = View.VISIBLE
holder.itemView.statusName.text = when (item.approval_status) {
1 -> "(待审批)"
2 -> "(通过)"
3 -> "(拒绝)"
else -> ""
}
} else {
holder.itemView.statusName.visibility = View.GONE
}

if (item?.sign_key != null && item?.sign_key?.isNotEmpty()) {
holder.itemView.signImg.visibility = View.VISIBLE
holder.itemView.signImg.setSrc(item.sign_identity, item.sign_key)
} else {
holder.itemView.signImg.visibility = View.GONE
}

if (item.is_approve == 0 || item.approval_status > 1) {
holder.itemView.stepTime.visibility = View.VISIBLE
holder.itemView.stepTime.text = item.add_time.toTime()
} else {
holder.itemView.stepTime.visibility = View.GONE
}

if (holder.adapterPosition == 0) {
holder.itemView.line1.setBackgroundResource(R.color.transparent)
} else {
holder.itemView.line1.setBackgroundResource(R.color.gray_1)
}

if (holder.adapterPosition == data.size - 1) {
holder.itemView.contentLayout.setPadding(0, 0, 0, 0)
} else {
holder.itemView.contentLayout.setPadding(0, 0, 0, holder.itemView.contentLayout.dip(20))
}
}
}

+ 74
- 0
app/src/main/java/com/yzx/ebrand/adapter/HomeListAdapter.kt 查看文件

@@ -0,0 +1,74 @@
package com.yzx.ebrand.adapter

import android.annotation.SuppressLint
import android.graphics.Color
import android.view.View
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yzx.ebrand.R
import com.yzx.ebrand.model.StuLeave
import com.yzx.ebrand.utils.durationStr
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.layout_leave_table.view.*
import org.jetbrains.anko.textColor

class HomeListAdapter(list: MutableList<StuLeave>) :
BaseQuickAdapter<StuLeave, BaseViewHolder>(R.layout.layout_leave_table, list) {

init {
addChildClickViewIds(R.id.cancelBtn,R.id.faceEmpty)

}

@SuppressLint("SetTextI18n")
override fun convert(holder: BaseViewHolder, item: StuLeave) {
holder.itemView.studentName.text = item.leave_student_name
if (item.face_key.isNullOrBlank()) {
holder.itemView.faceEmpty.visibility = View.VISIBLE
holder.itemView.faceImg.visibility = View.GONE
} else {
holder.itemView.faceImg.visibility = View.VISIBLE
holder.itemView.faceEmpty.visibility = View.GONE
holder.itemView.faceImg.setSrc(item.face_identity, item.face_key)
}
holder.itemView.className.text = "${item.grade_name}${item.class_name}"
holder.itemView.typeName.text = item.leave_request_type_name
holder.itemView.leaveTime.text =
"${item.start_time.toTime()} -- -- ${item.end_time.toTime()}"
holder.itemView.durationStrName.text = (item.end_time - item.start_time).durationStr()
holder.itemView.statusName.text = when (item.status) {
1 -> "待处理"
2 -> "已确认"
3 -> "已拒绝"
4 -> "正常销假"
5 -> "超时销假"
else -> "--"
}
holder.itemView.statusName.textColor = when (item.status) {
1 -> Color.parseColor("#333333")
2 -> Color.parseColor("#3c7ef6")
3 -> Color.parseColor("#ff4040")
4 -> Color.parseColor("#3c7ef6")
5 -> Color.parseColor("#ff4040")
else -> Color.parseColor("#333333")
}
holder.itemView.applyTime.text = item.add_time.toTime()

holder.itemView.bottomLine.visibility = if (holder.adapterPosition == data.size - 1) {
View.GONE
} else {
View.VISIBLE
}


holder.itemView.cancelBtn.visibility = if(item.is_cancel_leave ==1 ){
holder.itemView.placeHolder.visibility = View.GONE
View.VISIBLE
}else{
holder.itemView.placeHolder.visibility = View.VISIBLE
View.GONE
}

}
}

+ 49
- 0
app/src/main/java/com/yzx/ebrand/adapter/VisitorDialogStepAdapter.kt 查看文件

@@ -0,0 +1,49 @@
package com.yzx.ebrand.adapter

import android.annotation.SuppressLint
import android.graphics.Color
import android.view.View
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yzx.ebrand.R
import com.yzx.ebrand.model.AuditRecordOut
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.layout_visitor_step.view.*
import org.jetbrains.anko.dip
import org.jetbrains.anko.textColor

class VisitorDialogStepAdapter(list: MutableList<AuditRecordOut>) :
BaseQuickAdapter<AuditRecordOut, BaseViewHolder>(R.layout.layout_visitor_step, list) {

@SuppressLint("SetTextI18n")
override fun convert(holder: BaseViewHolder, item: AuditRecordOut) {

holder.itemView.visibility = View.VISIBLE
holder.itemView.addUserName.text = item.getTitle()
holder.itemView.approvalComments.visibility = if(item.audit_user_name.isNotEmpty()){
holder.itemView.approvalComments.text = "审批人:${item.audit_user_name}。${item.audit_remark}"
holder.itemView.approvalComments.textColor = when (item.audit_status) {
0 -> Color.parseColor("#ff4040")
1 -> Color.parseColor("#3c7ef6")
2 -> Color.parseColor("#ff4040")
-1 -> Color.parseColor("#999999")
else -> Color.parseColor("#333333")
}
View.VISIBLE
}else{
View.GONE
}
holder.itemView.approvalTime.text = item.add_time.toTime()
if (holder.adapterPosition == 0) {
holder.itemView.line1.setBackgroundResource(R.color.transparent)
} else {
holder.itemView.line1.setBackgroundResource(R.color.gray_1)
}

if (holder.adapterPosition == data.size - 1) {
holder.itemView.contentLayout.setPadding(0, 0, 0, 0)
} else {
holder.itemView.contentLayout.setPadding(0, 0, 0, holder.itemView.contentLayout.dip(20))
}
}
}

+ 121
- 0
app/src/main/java/com/yzx/ebrand/adapter/VisitorListAdapter.kt 查看文件

@@ -0,0 +1,121 @@
package com.yzx.ebrand.adapter

import android.annotation.SuppressLint
import android.graphics.Color
import android.view.View
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.yzx.ebrand.R
import com.yzx.ebrand.model.Visitor
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.layout_visitor_table.view.*
import org.jetbrains.anko.textColor

class VisitorListAdapter(list: MutableList<Visitor>) :
BaseQuickAdapter<Visitor, BaseViewHolder>(R.layout.layout_visitor_table, list) {

init {
addChildClickViewIds(R.id.faceEmpty,R.id.nucleinEmpty,R.id.tripCodeEmpty,R.id.healthCodeEmpty)
}

@SuppressLint("SetTextI18n", "Range")
override fun convert(holder: BaseViewHolder, item: Visitor) {
holder.itemView.userName.text = item.user_name
if (item.face_key.isNotEmpty()) {
holder.itemView.faceImg.visibility = View.VISIBLE
holder.itemView.faceEmpty.visibility = View.GONE
holder.itemView.faceImg.setSrc(item.face_identity, item.face_key)
} else {
holder.itemView.faceEmpty.visibility = View.VISIBLE
holder.itemView.faceImg.visibility = View.GONE
}
when {
item.health_code_status >= 0 -> {
holder.itemView.healthCodeStatusLayout.visibility = View.VISIBLE
holder.itemView.healthCodeImg.visibility = View.GONE
holder.itemView.healthCodeEmpty.visibility = View.GONE
when (item.health_code_status) {
0 -> {
holder.itemView.healthCodeStatus.text = "状态:绿码"
holder.itemView.healthCodeStatus.textColor = Color.parseColor("#5DAD64")
}
1 -> {
holder.itemView.healthCodeStatus.text = "状态:黄码"
holder.itemView.healthCodeStatus.textColor = Color.parseColor("#FCCF13")
}
10 -> {
holder.itemView.healthCodeStatus.text = "状态:红码"
holder.itemView.healthCodeStatus.textColor = Color.parseColor("#FC0416")
}
}
}
item.health_code_key.isNotEmpty() -> {
holder.itemView.healthCodeStatusLayout.visibility = View.GONE
holder.itemView.healthCodeImg.visibility = View.VISIBLE
holder.itemView.healthCodeEmpty.visibility = View.GONE
holder.itemView.healthCodeImg.setSrc(
item.health_code_identity,
item.health_code_key
)

}
else -> {
holder.itemView.healthCodeStatusLayout.visibility = View.GONE
holder.itemView.healthCodeEmpty.visibility = View.VISIBLE
holder.itemView.healthCodeImg.visibility = View.GONE
}
}
if(item.nuclein_file_key.isNullOrBlank()){
holder.itemView.nucleinEmpty.visibility = View.VISIBLE
holder.itemView.nucleinImg.visibility = View.GONE
}else{
holder.itemView.nucleinImg.visibility = View.VISIBLE
holder.itemView.nucleinEmpty.visibility = View.GONE
holder.itemView.nucleinImg.setSrc(item.nuclein_file_identity, item.nuclein_file_key)
}
if(item.nuclein_time>0){
holder.itemView.nucleinStatusLayout.visibility = View.VISIBLE
holder.itemView.nucleinStatus.text = item.getNucleinStatusObj().nuclein_name
holder.itemView.nucleinStatus.setTextColor(Color.parseColor(item.getNucleinStatusObj().nuclein_color))
}else{
holder.itemView.nucleinStatusLayout.visibility = View.GONE
}
if (item.trip_code_key.isNullOrBlank()) {
holder.itemView.tripCodeEmpty.visibility = View.VISIBLE
holder.itemView.tripCodeImg.visibility = View.GONE
} else {
holder.itemView.tripCodeImg.visibility = View.VISIBLE
holder.itemView.tripCodeEmpty.visibility = View.GONE
holder.itemView.tripCodeImg.setSrc(item.trip_code_identity, item.trip_code_key)
}
holder.itemView.isDrive.text = if (item.is_drive == 1) {
"是"
} else {
"否"
}
holder.itemView.receptionUser.text = item.reception_user
holder.itemView.statusName.text = when (item.audit_status) {
0 -> "待审核"
1 -> "可通行"
2 -> "审核拒绝"
-1 -> "已失效"
else -> "--"
}
holder.itemView.statusName.textColor = when (item.audit_status) {
0 -> Color.parseColor("#333333")
1 -> Color.parseColor("#3c7ef6")
2 -> Color.parseColor("#ff4040")
-1 -> Color.parseColor("#999999")
else -> Color.parseColor("#333333")
}

holder.itemView.applyTime.text = item.add_time.toTime()

holder.itemView.bottomLine.visibility = if (holder.adapterPosition == data.size - 1) {
View.GONE
} else {
View.VISIBLE
}
}
}

+ 154
- 0
app/src/main/java/com/yzx/ebrand/adapter/base/BaseListAdapter.java 查看文件

@@ -0,0 +1,154 @@
package com.yzx.ebrand.adapter.base;

import android.os.Handler;
import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Created by newbiechen on 17-3-21.
*/

public abstract class BaseListAdapter <T> extends RecyclerView.Adapter<RecyclerView.ViewHolder>{

private static final String TAG = "BaseListAdapter";
/*common statement*/
protected final List<T> mList = new ArrayList<>();
protected OnItemClickListener mClickListener;
protected OnItemLongClickListener mLongClickListener;

/************************abstract area************************/
protected abstract IViewHolder<T> createViewHolder(int viewType);

/*************************rewrite logic area***************************************/
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
IViewHolder<T> viewHolder = createViewHolder(viewType);

View view = viewHolder.createItemView(parent);
//初始化
RecyclerView.ViewHolder holder = new BaseViewHolder(view, viewHolder);
return holder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//防止别人直接使用RecyclerView.ViewHolder调用该方法
if (!(holder instanceof BaseViewHolder))
throw new IllegalArgumentException("The ViewHolder item must extend BaseViewHolder");

IViewHolder<T> iHolder = ((BaseViewHolder) holder).holder;
iHolder.onBind(getItem(position),position);

//设置点击事件
holder.itemView.setOnClickListener((v)->{
if (mClickListener != null){
mClickListener.onItemClick(v,position);
}
//adapter监听点击事件
iHolder.onClick();
onItemClick(v,position);
});
//设置长点击事件
holder.itemView.setOnLongClickListener(
(v) -> {
boolean isClicked = false;
if (mLongClickListener != null){
isClicked = mLongClickListener.onItemLongClick(v,position);
}
//Adapter监听长点击事件
onItemLongClick(v,position);
return isClicked;
}
);
}

@Override
public int getItemCount() {
return mList.size();
}

protected void onItemClick(View v,int pos){
}

protected void onItemLongClick(View v,int pos){
}

/******************************public area***********************************/

public void setOnItemClickListener(OnItemClickListener mListener) {
this.mClickListener = mListener;
}

public void setOnItemLongClickListener(OnItemLongClickListener mListener){
this.mLongClickListener = mListener;
}

public void addItem(T value){
mList.add(value);
notifyDataSetChanged();
}

public void addItem(int index,T value){
mList.add(index, value);
notifyDataSetChanged();
}

public void addItems(List<T> values){
mList.addAll(values);

Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
});
}

public void removeItem(T value){
mList.remove(value);
notifyDataSetChanged();
}

public void removeItems(List<T> value){
mList.removeAll(value);
notifyDataSetChanged();
}

public T getItem(int position){
return mList.get(position);
}

public List<T> getItems(){
return Collections.unmodifiableList(mList);
}

public int getItemSize(){
return mList.size();
}

public void refreshItems(List<T> list){
mList.clear();
mList.addAll(list);
notifyDataSetChanged();
}

public void clear(){
mList.clear();
}

/***************************inner class area***********************************/
public interface OnItemClickListener{
void onItemClick(View view, int pos);
}

public interface OnItemLongClickListener{
boolean onItemLongClick(View view, int pos);
}
}

+ 19
- 0
app/src/main/java/com/yzx/ebrand/adapter/base/BaseViewHolder.java 查看文件

@@ -0,0 +1,19 @@
package com.yzx.ebrand.adapter.base;

import android.view.View;

import androidx.recyclerview.widget.RecyclerView;

/**
* Created by newbiechen on 17-5-17.
*/

public class BaseViewHolder<T> extends RecyclerView.ViewHolder{
public IViewHolder<T> holder;

public BaseViewHolder(View itemView, IViewHolder<T> holder) {
super(itemView);
this.holder = holder;
holder.initView();
}
}

+ 92
- 0
app/src/main/java/com/yzx/ebrand/adapter/base/EasyAdapter.java 查看文件

@@ -0,0 +1,92 @@
package com.yzx.ebrand.adapter.base;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Created by newbiechen on 17-6-5.
* ListView 使用的Adapter
*/

public abstract class EasyAdapter<T> extends BaseAdapter {

private List<T> mList = new ArrayList<T>();

@Override
public int getCount() {
return mList.size();
}

@Override
public T getItem(int position) {
return mList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

public void addItem(T value){
mList.add(value);
notifyDataSetChanged();
}

public void addItem(int index,T value){
mList.add(index, value);
notifyDataSetChanged();
}

public void addItems(List<T> values){
mList.addAll(values);
notifyDataSetChanged();
}

public void removeItem(T value){
mList.remove(value);
notifyDataSetChanged();
}

public List<T> getItems(){
return Collections.unmodifiableList(mList);
}

public int getItemSize(){
return mList.size();
}

public void refreshItems(List<T> list){
mList.clear();
mList.addAll(list);
notifyDataSetChanged();
}

public void clear(){
mList.clear();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
IViewHolder holder = null;
if (convertView == null){
holder = onCreateViewHolder(getItemViewType(position));
convertView = holder.createItemView(parent);
convertView.setTag(holder);
//初始化
holder.initView();
}
else {
holder = (IViewHolder)convertView.getTag();
}
//执行绑定
holder.onBind(getItem(position),position);
return convertView;
}

protected abstract IViewHolder<T> onCreateViewHolder(int viewType);
}

+ 204
- 0
app/src/main/java/com/yzx/ebrand/adapter/base/GroupAdapter.java 查看文件

@@ -0,0 +1,204 @@
package com.yzx.ebrand.adapter.base;

import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
* Created by newbiechen on 17-5-5.
* 用于头标签 + 表格的布局View
*/

public abstract class GroupAdapter<T,R> extends RecyclerView.Adapter{
private static final String TAG = "GroupAdapter";

private static final int TYPE_GROUP = 1;
private static final int TYPE_CHILD = 2;

private OnGroupClickListener mGroupListener;
private OnChildClickListener mChildClickListener;

public abstract int getGroupCount();
public abstract int getChildCount(int groupPos);

public abstract T getGroupItem(int groupPos);
public abstract R getChildItem(int groupPos,int childPos);

protected abstract IViewHolder<T> createGroupViewHolder();
protected abstract IViewHolder<R> createChildViewHolder();

public GroupAdapter(RecyclerView recyclerView,int spanSize){
GridLayoutManager manager = new GridLayoutManager(recyclerView.getContext(),spanSize);
manager.setSpanSizeLookup(new GroupSpanSizeLookup(spanSize));
recyclerView.setLayoutManager(manager);
}

public void setOnGroupItemListener(OnGroupClickListener listener){
mGroupListener = listener;
}

public void setOnChildItemListener(OnChildClickListener listener) {
mChildClickListener = listener;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
IViewHolder iViewHolder = null;
View view = null;
if (viewType == TYPE_GROUP){
iViewHolder = createGroupViewHolder();
view = iViewHolder.createItemView(parent);
}
else if (viewType == TYPE_CHILD){
iViewHolder = createChildViewHolder();
view = iViewHolder.createItemView(parent);
}
RecyclerView.ViewHolder viewHolder = new BaseViewHolder(view, iViewHolder);
return viewHolder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (! (holder instanceof BaseViewHolder))
throw new IllegalArgumentException("The ViewHolder item must extend BaseViewHolder");

IViewHolder iHolder = ((BaseViewHolder) holder).holder;
int type = getItemViewType(position);
if (type == TYPE_GROUP){
//计算当前的group
int groupPos = calculateGroup(position);
holder.itemView.setOnClickListener(
(v) -> {
iHolder.onClick();
if (mGroupListener != null){
mGroupListener.onGroupClick(v,groupPos);
}
}
);
iHolder.onBind(getGroupItem(groupPos),groupPos);
}
else if (type == TYPE_CHILD){
int groupPos = calculateGroup(position);
int childPos = calculateChild(position);

holder.itemView.setOnClickListener(
v -> {
iHolder.onClick();
if (mChildClickListener != null) {
mChildClickListener.onChildClick(v,groupPos,childPos);
}
}
);
//这里有点小问题,返回的是childPos
iHolder.onBind(getChildItem(groupPos,childPos),childPos);
}
}

//计算position是哪个group中的头
private int calculateGroup(int position){
int total = 0;
for (int i=0; i<getGroupCount(); ++i){
total += getChildCount(i)+1; //当前group的大小范围
if (total > position){ //判断是否pos在total内
return i;
}
}
return -1;
}

//计算position是那个group中的child
protected int calculateChild(int position){
for (int i=0; i<getGroupCount(); ++i){
int total = getChildCount(i)+1; //每个队列的总和
int loc = position - total; //Loc表示在第二队列的位置
if (loc < 0){ //如果 < 0 表示在上一队列中,则返回
return position-1;
}
else { //否则设置当前队列为pos
position = loc;
}
}
//返回child在指定group的位置
return -1;
}

@Override
public int getItemCount() {
int groupCount = getGroupCount();
//因为Group需要有头部
int totalCount = groupCount;
for (int i=0; i<groupCount; ++i){
totalCount += getChildCount(i);
}
return totalCount;
}

//判断获取的item是group还是child
@Override
public int getItemViewType(int position) {
if (position == 0){
return TYPE_GROUP;
}

for (int i=0; i<getGroupCount(); ++i){
int total = getChildCount(i)+1; //每个队列的总和
if (position == 0){
return TYPE_GROUP;
}
else if (position < 0){
return TYPE_CHILD;
}
position -= total;
}
//剩下的肯定是最后一行
return TYPE_CHILD;
}

/**
* 设置Group与child在GridLayoutManager情况下占用的格子
*/
class GroupSpanSizeLookup extends GridLayoutManager.SpanSizeLookup{
private int maxSize;
public GroupSpanSizeLookup(int maxSize) {
this.maxSize = maxSize;
}

@Override
public int getSpanSize(int position) {
if (getItemViewType(position) == TYPE_GROUP){
return maxSize;
}
else {
return 1;
}
}
}

public int getGroupToPosition(int groupPos){
int position = 0;
for (int i=0; i<groupPos; ++i){
position += getChildCount(groupPos)+1;
}
return position;
}

//child转换成position
public int getChildToPosition(int groupPos, int childPos){
int position = 0;
for (int i=0; i<groupPos; ++i){
position += getChildCount(i)+1;
}
position += childPos + 1;
return position;
}

public interface OnGroupClickListener {
void onGroupClick(View view,int pos);
}

public interface OnChildClickListener {
void onChildClick(View view,int groupPos,int childPos);
}
}

+ 15
- 0
app/src/main/java/com/yzx/ebrand/adapter/base/IViewHolder.java 查看文件

@@ -0,0 +1,15 @@
package com.yzx.ebrand.adapter.base;

import android.view.View;
import android.view.ViewGroup;

/**
* Created by newbiechen on 17-5-17.
*/

public interface IViewHolder<T> {
View createItemView(ViewGroup parent);
void initView();
void onBind(T data,int pos);
void onClick();
}

+ 42
- 0
app/src/main/java/com/yzx/ebrand/adapter/base/ViewHolderImpl.java 查看文件

@@ -0,0 +1,42 @@
package com.yzx.ebrand.adapter.base;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
* Created by newbiechen on 17-5-17.
*/

public abstract class ViewHolderImpl<T> implements IViewHolder<T> {
private View view;
private Context context;
/****************************************************/
protected abstract int getItemLayoutId();


@Override
public View createItemView(ViewGroup parent) {
view = LayoutInflater.from(parent.getContext())
.inflate(getItemLayoutId(), parent, false);
context = parent.getContext();
return view;
}

protected <V extends View> V findById(int id){
return (V) view.findViewById(id);
}

protected Context getContext(){
return context;
}

protected View getItemView(){
return view;
}

@Override
public void onClick() {
}
}

+ 39
- 0
app/src/main/java/com/yzx/ebrand/config/Config.kt 查看文件

@@ -0,0 +1,39 @@
package com.yzx.ebrand.config

import com.yzx.ebrand.BuildConfig
import com.yzx.ebrand.model.StuChangeType

object Config {
var BASE_URL = BuildConfig.BASE_URL
var APP_NAME = BuildConfig.APP_NAME
var M_URL = BuildConfig.M_URL
var OA_URL = BuildConfig.OA_URL
var WS_URL = BuildConfig.WS_URL
var MP_APPID = BuildConfig.MP_APPID
val APP_ID = 701


const val STU_CHANGE_STATUS_DROP_OUT = 42001
const val STU_CHANGE_STATUS_LEAVE_SCHOOL = 42002
const val STU_CHANGE_STATUS_RETURN_SCHOOL = 42003
const val STU_CHANGE_STATUS_OUT_SCHOOL = 42004
const val STU_CHANGE_STATUS_TRANSFER_SCHOOL = 42005
const val STU_CHANGE_STATUS_REPEAT = 42006
const val STU_CHANGE_STATUS_DOWNGRADE = 42007
const val STU_CHANGE_STATUS_TRANSFER_OUT = 42008
const val STU_CHANGE_STATUS_INTROSPECTION = 42009
const val STU_CHANGE_STATUS_INTERNSHIP = 42010

val STU_CHANGE_STATUS_LIST = mutableListOf(
StuChangeType(STU_CHANGE_STATUS_DROP_OUT,"辍学",""),
StuChangeType(STU_CHANGE_STATUS_LEAVE_SCHOOL,"休学",""),
StuChangeType(STU_CHANGE_STATUS_RETURN_SCHOOL,"复学",""),
StuChangeType(STU_CHANGE_STATUS_OUT_SCHOOL,"退学",""),
StuChangeType(STU_CHANGE_STATUS_TRANSFER_SCHOOL,"转学",""),
StuChangeType(STU_CHANGE_STATUS_REPEAT,"留级",""),
StuChangeType(STU_CHANGE_STATUS_TRANSFER_OUT,"转出",""),
StuChangeType(STU_CHANGE_STATUS_DOWNGRADE,"降级",""),
StuChangeType(STU_CHANGE_STATUS_INTROSPECTION,"回家反省","反省"),
StuChangeType(STU_CHANGE_STATUS_INTERNSHIP,"实习","反省")
)
}

+ 89
- 0
app/src/main/java/com/yzx/ebrand/config/RefreshToken.kt 查看文件

@@ -0,0 +1,89 @@
package com.yzx.ebrand.config

import android.content.Intent
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.App.Companion.getContext
import com.yzx.ebrand.MainActivity
import com.yzx.ebrand.activity.LoginActivity
import com.yzx.ebrand.config.Config.OA_URL
import com.yzx.ebrand.model.ReToken
import com.yzx.ebrand.model.RefreshTokenEvent
import com.yzx.ebrand.model.User
import com.yzx.ebrand.presenter.base.JsonCallBack
import com.yzx.ebrand.presenter.base.YzxResponse
import org.greenrobot.eventbus.EventBus
import java.util.*

object RefreshToken {
fun refresh(callBack:RefreshCallback) {
val user = User.getUser()
val lastLoginTime = user.loginTime
val currTime = Date().time
if (currTime - lastLoginTime > 12L * 60 * 60 * 1000 && currTime - lastLoginTime < 365L * 24 * 60 * 60 * 1000) {
if (user.user_id > 0) {
val url = Config.BASE_URL + YzxInterface.INTERFACE_REFRESH_TOKEN
OkGo.post<YzxResponse<ReToken>>(url)
.tag(this)
.params("old_token", User.getUser().token)
.params("type", 1)
.params("source", "201")
.execute(object : JsonCallBack<YzxResponse<ReToken>>() {
override fun onSuccess(response: Response<YzxResponse<ReToken>>?) {
LogUtils.d(response)
val token = response?.body()?.data?.token ?: ""
if (token.isNotBlank()) {
user.token = token
user.loginTime = Date().time
user.save()
callBack.onSuccess()
EventBus.getDefault().post(RefreshTokenEvent(token))
}
}

override fun onError(response: Response<YzxResponse<ReToken>>?) {
super.onError(response)
LogUtils.d(response)
User.clearUserInfo()
// val intent = Intent(getContext(), WebActivity::class.java)
val intent = Intent(getContext(), LoginActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("link", OA_URL + "/login?logout=1")
ActivityUtils.startActivity(intent)
ActivityUtils.finishActivity(MainActivity::class.java)
callBack.onError()
}
})
}else{
User.clearUserInfo()
// val intent = Intent(getContext(), WebActivity::class.java)
val intent = Intent(getContext(), LoginActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("link", OA_URL + "/login?logout=1")
ActivityUtils.startActivity(intent)
ActivityUtils.finishActivity(MainActivity::class.java)
callBack.onError()
}
}else{
if (currTime - lastLoginTime > 365L * 24 * 60 * 60 * 1000){
User.clearUserInfo()
// val intent = Intent(getContext(), WebActivity::class.java)
val intent = Intent(getContext(), LoginActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.putExtra("link", OA_URL + "/login?logout=1")
ActivityUtils.startActivity(intent)
ActivityUtils.finishActivity(MainActivity::class.java)
callBack.onError()
}else{
callBack.onSuccess()
}
}
}

interface RefreshCallback{
fun onSuccess()
fun onError()
}
}

+ 52
- 0
app/src/main/java/com/yzx/ebrand/config/YzxInterface.kt 查看文件

@@ -0,0 +1,52 @@
package com.yzx.ebrand.config

object YzxInterface {

const val FILE_UPLOAD_URL = "https://fileupload.oa.qbjjyyun.net/edufile/fileUpload"

const val INTERFACE_LOGIN_ALL= "/login/user2/doLoginAll" //老师学生统一登录
const val INTERFACE_USER_ROLE_LIST= "/login/user2/getUserLoginRoleList" //多角色获取角色列表
const val INTERFACE_USER_ROLE_LIST_BY_PHONE= "/edu/weixin/getRolesByPhone" //多角色获取角色列表
const val INTERFACE_USER_SWITCH= "/login/user2/switchLoginRole" //切换角色
const val INTERFACE_USER_SWITCH_UNIT= "/edu/weixin/switchUnit" //切换角色
const val INTERFACE_COMMON_LOGIN_BY_TOKEN= "/login/user2/getUserLoginInfo" // 通过token登陆
const val INTERFACE_GET_COMMON_YUN_AVATAR= "/edu/activeApi/getYkjHeadPortrait" //根据登录人获取云空间头像

const val INTERFACE_REFRESH_TOKEN = "/login/user2/refreshToken"// 刷新token
const val INTERFACE_GET_ACCESS_TOKEN= "/rights/weixin/getAccessTokenByAppId" // 通过app_id获取access_token
const val INTERFACE_GET_MINI_CODE= "/parent/mini/getMiniCode" // 获取小程序二维码

const val INTERFACE_GENERATE_WX_QR_TICKET= "/login/wechat/generateQrTicket" // 获取微信带参数二维码的ticket
const val INTERFACE_WX_DO_LOGIN_QUERY= "/edu/user/common/doLoginQuery" // 微信登录的轮询

/**
* 学生请假
*/
const val INTERFACE_GET_STU_LEAVE_LIST= "/edu/attendance/teacher/listStudentLeaveRequest"//获取学生请假列表
const val INTERFACE_GET_STU_LEAVE_INFO_DETAIL= "/edu/attendance/getStudentLeaveRequestDetail" //获取学生的请假信息详情
const val INTERFACE_GET_TEACHER_INFO= "/rights/teacherWork/getTeacherByUserId"//获取人员信息
const val INTERFACE_STUDENT_GET_SHOW_BOX_LIST_OLD= "/edu/attendance/student/getStudentLeaveIds" //获取需要弹出的数据
const val INTERFACE_STUDENT_GET_SHOW_BOX_LIST= "/edu/attendance/student/getStudentLeaveIdsV2" //获取需要弹出的数据
const val INTERFACE_STUDENT_POST_LEAVE_VACATION= "/edu/attendance/student/studentLeaveVacation"//人工销假操作
/**
* 学籍异动
*/

const val INTERFACE_STUDENT_GET_CHANGE_LIST= "/edu/attendance/teacher/listStudentStatusChange"//学籍异动列表
const val INTERFACE_STUDENT_GET_CHANGE_DETAIL= "/edu/attendance/getStudentStatusChangeDetail"//学籍异动详情
/**
* 访客管理
*/
const val INTERFACE_ACCESS_CONTROL_GET_FACE_LIST= "/parent/entranceGuard/getEntranceGuardFaceList" // 获取访客人脸信息列表
const val INTERFACE_ACCESS_CONTROL_GET_FACE_INFO_DETAIL= "/parent/entranceGuard/getEntranceGuardFaceById" // 访客信息

/**
* 电子班牌
*/
const val INTERFACE_CLASS_BRAND_CLASS_INFO = "/edu/electronicClassBoard/getClassInfo" //班级信息
const val INTERFACE_CLASS_BRAND_TEA_INFO = "/edu/electronicClassBoard/getTeacherInfo" //老师列表
const val INTERFACE_CLASS_BRAND_IMAGE_INFO = "/edu/electronicClassBoard/getClassStyle" //班级风采
const val INTERFACE_CLASS_BRAND_ACTIVE_INFO = "/edu/electronicClassBoard/getClassDynamics" //班级动态
const val INTERFACE_CLASS_BRAND_TIME_TABLE_INFO = "/edu/electronicClassBoard/getTodayClassSchedule" //今日课表
const val INTERFACE_GET_VOTE_TEA_CLASS= "/edu/vote/getMyClassList" //班主任获取自己的班级
}

+ 428
- 0
app/src/main/java/com/yzx/ebrand/fragment/ChangeFragment.kt 查看文件

@@ -0,0 +1,428 @@
package com.yzx.ebrand.fragment

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.*
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton
import com.yzx.ebrand.R
import com.yzx.ebrand.adapter.ChangeListAdapter
import com.yzx.ebrand.fragment.base.BaseFragment
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.ChangePresenter
import com.yzx.ebrand.presenter.ChangeView
import com.yzx.ebrand.utils.FileUploadCallBack
import com.yzx.ebrand.widget.BaseDialog
import kotlinx.android.synthetic.main.fragment_change.*
import kotlinx.android.synthetic.main.layout_loading.view.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.jetbrains.anko.support.v4.ctx
import org.jetbrains.anko.support.v4.toast
import org.jetbrains.anko.textColor


class ChangeFragment : BaseFragment<ChangePresenter>(), ChangeView,
NetworkUtils.OnNetworkStatusChangedListener, FileUploadCallBack {

companion object {

val CAMER_REQUEST_CODE = 0x01

@JvmStatic
fun getNewInstance() =
ChangeFragment()
}

private val mAdapter: ChangeListAdapter by lazy {
val list = mutableListOf<StuChange>()
ChangeListAdapter(list)
}

private var mPager = Pager()
var list = mutableListOf<StuChange>()
private val statusBtnList = mutableListOf<QMUIRoundButton>()
var keyword: String = ""
var status: String = ""
private var isLoading = false
private val mShowList = mutableListOf<StuChange>()
private val mShowDialogList = mutableListOf<BaseDialog>()
private var isRefresh = false

private val refreshRun = Runnable {
refreshData()
}

override val inflateId: Int
get() = R.layout.fragment_change

override fun initView() {
NetworkUtils.registerNetworkStatusChangedListener(this)
recyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = mAdapter

preTxtBtn.setOnClickListener { pre() }
nextTxtBtn.setOnClickListener { next() }
allBtn.setOnClickListener { changeStatus(0) }
status1Btn.setOnClickListener { changeStatus(1) }
status2Btn.setOnClickListener { changeStatus(2) }
status3Btn.setOnClickListener { changeStatus(3) }
statusBtnList.add(allBtn)
statusBtnList.add(status1Btn)
statusBtnList.add(status2Btn)
statusBtnList.add(status3Btn)
keywordInput.setOnKeyListener { _, keyCode, _ ->
if (!isLoading) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
keyword = keywordInput.text.toString()
initData()
KeyboardUtils.hideSoftInput(keywordInput)
}
}
false
}
clearBtn.setOnClickListener {
keyword = ""
keywordInput.setText("")
KeyboardUtils.hideSoftInput(keywordInput)
initData()
}
var lastClickTime = TimeUtils.getNowMills()
mAdapter.setOnItemClickListener { adapter, view, position ->
val curr = TimeUtils.getNowMills()
if(curr - lastClickTime > 500){
lastClickTime = curr
mPresenter?.getDetail(mAdapter.getItem(position).id)
}
}

mAdapter.setOnItemChildClickListener { adapter, view, position ->
LogUtils.d("setOnItemChildClickListener", position)
val curr = TimeUtils.getNowMills()
if(curr - lastClickTime > 500){
lastClickTime = curr
when (view.id) {
R.id.cancelBtn -> {

}
R.id.faceEmpty -> {
mPresenter?.getDetail(mAdapter.getItem(position).id)
}
}
}

}


switchBtn.setOnCheckedChangeListener { buttonView, isChecked ->
SPUtils.getInstance().put("auto_show_change", isChecked)
changeSwitchBtnTxt(isChecked)
EventBus.getDefault().post(AutoSwitchChange(2))
}
val isAutoShowLeave = SPUtils.getInstance().getBoolean("auto_show_change", false)
switchBtn.isChecked = isAutoShowLeave
changeSwitchBtnTxt(isAutoShowLeave)

switchBtnTxt.setOnClickListener {
switchBtn.isChecked = !switchBtn.isChecked
}
keywordInput.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s != null && s.isNotEmpty()) {
clearBtn.visibility = View.VISIBLE
} else {
clearBtn.visibility = View.INVISIBLE
}
}

override fun afterTextChanged(s: Editable?) {

}

})
filterLayout.setOnClickListener {
KeyboardUtils.hideSoftInput(keywordInput)
}
btnRefresh.setOnClickListener {
isRefresh = true
showLayoutLoading()
initData()
}
changeStatusBtn(0)
loadingLayout.setOnClickListener {
//do nothing
}
goPageOne.setOnClickListener {
showLayoutLoading()
initData()
}
}

private fun showLayoutLoading(){
loadingLayout.visibility = View.VISIBLE
}

private fun hideLayoutLoading(){
loadingLayout.visibility = View.GONE
}


private fun changeSwitchBtnTxt(isChecked: Boolean) {
if (isChecked) {
switchBtnTxt.setTextColor(ctx.resources.getColor(R.color.green2))
} else {
switchBtnTxt.setTextColor(ctx.resources.getColor(R.color.black_3))
}
}

@SuppressLint("SetTextI18n")
private fun showLeaveDialog(detail: StuChange) {
EventBus.getDefault().post(detail)
}

private fun changeStatusBtn(idx: Int) {
statusBtnList.forEachIndexed { index, button ->
button.isSelected = index == idx
}
}

private fun changeStatus(status: Int) {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
changeStatusBtn(status)
this.status = if (status == 0) {
""
} else {
"${status}"
}
showLayoutLoading()
initData()
}

override fun initData() {

mPager.page_no = 1
if (NetworkUtils.isConnected()) {
showEmpty(1)
isLoading = true
mPresenter?.getList(mPager.page_no, keyword, status)
} else {
showEmpty(2)
}

}

/**
* type 1 loading 2 neterror 3 empty
*/
private fun showEmpty(type: Int) {
when (type) {
1 -> {
mAdapter.setEmptyView(R.layout.layout_loading)
mAdapter.emptyLayout?.apply {
this.QMUIEmptyView.setLoadingShowing(true)
this.QMUIEmptyView.setTitleText("数据加载中")
}
}
2 -> {
mAdapter.setEmptyView(R.layout.layout_loading)
mAdapter.emptyLayout?.apply {
this.QMUIEmptyView.show(false, null, "网络连接异常,请检查", "去设置") {
NetworkUtils.openWirelessSettings()
}
}
}
3 -> {
mAdapter.setEmptyView(R.layout.layout_empty)
}
}

}

private fun refreshData() {
if (isLoading) {
return
}
isLoading = true
mPresenter?.getList(mPager.page_no, keyword, status)
}

private fun pre() {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
if (mPager.page_no <= 1) {
} else {
isLoading = true
showLayoutLoading()
mPresenter?.getList(mPager.page_no - 1, keyword, status)
}
}

private fun next() {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
if (mPager.page_no >= mPager.total_pages) {
} else {
isLoading = true
showLayoutLoading()
mPresenter?.getList(mPager.page_no + 1, keyword, status)
}
}

override fun initPresenter(): ChangePresenter = ChangePresenter(this)

@SuppressLint("SetTextI18n")
override fun onListSuccess(list: MutableList<StuChange>, pager: Pager) {
pageTv?.apply {
if(isRefresh){
toast("刷新成功!")
isRefresh = false
}
mAdapter.setList(list)
mPager = pager
pageTv.text = "${pager.page_no} / ${pager.total_pages}"
totalTv.text = "共${pager.total_count}条"

val disabledColor = Color.parseColor("#666666")
val color = Color.parseColor("#3ca0e9")
if (pager.page_no <= 1) {
preTxtBtn.textColor = disabledColor
goPageOne.visibility = View.GONE
} else {
preTxtBtn.textColor = resources.getColor(R.color.s_app_color_blue)
goPageOne.visibility = View.VISIBLE
}

if (pager.page_no >= pager.total_pages) {
nextTxtBtn.textColor = disabledColor
} else {
nextTxtBtn.textColor = resources.getColor(R.color.s_app_color_blue)
}
isLoading = false
showEmpty(3)
hideLayoutLoading()
pageTv.postDelayed({
refreshData()
}, 30 * 1000)
}
}

override fun onStop() {
pageTv.removeCallbacks(refreshRun)
super.onStop()
EventBus.getDefault().unregister(this)
}


override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}

override fun onListError(error: String) {
isLoading = false
if(isRefresh){
toast("刷新失败,请重试!")
isRefresh = false
}
hideLayoutLoading()
showEmpty(3)
}

override fun onDetailSuccess(detail: StuChange) {
pageTv?.apply {
val item = mShowList.find { it.id == detail.id }
if (item != null) {
//替换新的数据
val index = mShowList.indexOf(item)
mShowList[index] = detail

//移除原本的dialog
val dialogIndex = mShowDialogList.indexOfFirst { it.getLeaveId() == item.id }
if (dialogIndex > -1) {
mShowDialogList[dialogIndex].hide()
mShowDialogList.removeAt(dialogIndex)
}

} else {
mShowList.add(detail)
}
showLeaveDialog(detail)
}
}

override fun onDetailError(error: String) {

}

override fun onDisconnected() {

}

override fun onConnected(networkType: NetworkUtils.NetworkType?) {
refreshData()
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {


}
super.onActivityResult(requestCode, resultCode, data)
}

override fun onSuccess(identity: String, key: String) {
LogUtils.d(identity, key)

}

override fun onError(msg: String) {
LogUtils.d(msg)


}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: MessageEventAuto) {
val list = event.list.filter { it.type == 1 }.toMutableList()
if (list.isNotEmpty() && switchBtn.isChecked) {
list.forEachIndexed { index, leaveID ->
pageTv.postDelayed({
mPresenter?.getDetail(leaveID.id)
}, 500L * index)
}
}
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageRefreshEvent(event: RefreshTokenEvent) {
refreshData()
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: TimeShow) {
timeView.setTime(event)
}
}


+ 509
- 0
app/src/main/java/com/yzx/ebrand/fragment/ClassBrandFragment.kt 查看文件

@@ -0,0 +1,509 @@
package com.yzx.ebrand.fragment

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import com.blankj.utilcode.util.ActivityUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.TimeUtils
import com.bumptech.glide.Glide
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.wgw.photo.preview.PhotoPreview
import com.yzx.ebrand.R
import com.yzx.ebrand.activity.LoginActivity
import com.yzx.ebrand.fragment.base.BaseFragment
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.ClassBrandPresenter
import com.yzx.ebrand.presenter.ClassBrandView
import com.yzx.ebrand.utils.getImgUrl
import com.yzx.ebrand.utils.hideNavigationBar
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toTime
import com.yzx.ebrand.utils.zhCn
import kotlinx.android.synthetic.main.fragment_class_brand.*
import kotlinx.android.synthetic.main.layout_brand_active_info.*
import kotlinx.android.synthetic.main.layout_brand_class_info.*
import kotlinx.android.synthetic.main.layout_brand_image_info.*
import kotlinx.android.synthetic.main.layout_brand_tea_info.*
import kotlinx.android.synthetic.main.layout_brand_timetable_info.*
import kotlinx.android.synthetic.main.layout_class_active_item.view.*
import kotlinx.android.synthetic.main.layout_class_tea_item.view.*
import kotlinx.android.synthetic.main.layout_time_table_item.view.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.jetbrains.anko.support.v4.act
import org.jetbrains.anko.support.v4.ctx

class ClassBrandFragment : BaseFragment<ClassBrandPresenter>(), ClassBrandView {

companion object {

val CAMER_REQUEST_CODE = 0x01

@JvmStatic
fun getNewInstance() =
ClassBrandFragment()
}

private var headClassList: MutableList<HeadClassInfo> = mutableListOf()
private var imgIndex = 0
private var imgLoopRunnable: Runnable? = null
private var currClass = HeadClassInfo()
private val styleImgList: MutableList<ClassStylePic> = mutableListOf()
private val styleImgUrlList: MutableList<String> = mutableListOf()

private val mClassInfoLoopTime = 10 * 60 * 1000L
private val mClassInfoHandler = Handler(Looper.getMainLooper())
private val mClassInfoRunnable = object : Runnable {
override fun run() {
mClassInfoHandler.removeCallbacks(this)
mClassInfoHandler.postDelayed(this, mClassInfoLoopTime)
getClassInfo()
}
}

private val mTimeHandler = Handler(Looper.getMainLooper())
private val timeRunnable = object : Runnable {
override fun run() {
mTimeHandler.removeCallbacks(this)
mTimeHandler.postDelayed(this, 6000)
loopImg(this@ClassBrandFragment.styleImgList)
}
}

override val inflateId: Int
get() = R.layout.fragment_class_brand

private var clickCount = 0

override fun initView() {
btnRefresh.setOnClickListener {
clickCount++
if (clickCount >= 2) {
clickCount = 0
initData()
}
}
userNameLayout.setOnClickListener {
val tipDialog = QMUIDialog.MessageDialogBuilder(activity)
.setTitle("温馨提示")
.setMessage("是否确定退出?")
.addAction("暂不退出") { dialog, index ->
dialog.dismiss()
}
.addAction("立即退出") { dialog, index ->
dialog.dismiss()
User.clearUserInfo()
LoginActivity.active(act)
activity?.apply {
ActivityUtils.finishActivity(this)
}
}
.create()
tipDialog.show()
tipDialog.hideNavigationBar()
}

styleImg0.setOnClickListener {
LogUtils.d("styleImg0Click", this.imgIndex)
previewImg(0, it)
}
styleImg1.setOnClickListener {
previewImg(1, it)
}
styleImg2.setOnClickListener {
previewImg(2, it)
}
styleImg3.setOnClickListener {
previewImg(3, it)
}

classNameLayout.setOnClickListener {
val builder = QMUIDialog.MenuDialogBuilder(ctx)
headClassList.forEach {
builder.addItem(
"${it.grade_name}${it.class_name}"
) { dialog, which ->
LogUtils.d("itemClick", which)
currClass = headClassList[which]
showLoading("加载中...")
getOtherData()
dialog.dismiss()
classNameTv.text = "${currClass.grade_name}${currClass.class_name}"
SPUtils.getInstance().put("local_class_id", currClass.class_id)
}
}
builder.show()
}
// mViewPager = find(R.id.bottomBannerView)
// mViewPager.setLifecycleRegistry(lifecycle)
// .setAdapter(BannerAdapter())
// .setPageStyle(PageStyle.MULTI_PAGE_SCALE,1f)
// .setInterval(6000)
// .setScrollDuration(500)
// .setRevealWidth(dip(300))
// .setPageMargin(dip(20))
// .create()
}

private fun previewImg(imgIndex: Int, view: View) {
// val url =
// styleImgList[this.imgIndex + imgIndex].identity.getImgUrl(styleImgList[this.imgIndex + imgIndex].picture_id)
val url = view.getTag(R.id.image_src_tag).toString()
LogUtils.d("previewImg", imgIndex)
val photoPreview = PhotoPreview.with(this)
.sources(styleImgUrlList)
.onDismissListener {
if (this.styleImgList.size > 4) {
styleImgBox.postDelayed(imgLoopRunnable, 6000)
}
}
.build()
photoPreview.setDefaultShowPosition(styleImgUrlList.indexOf(url))
photoPreview.show(view)
if (imgLoopRunnable != null && this.styleImgList.size > 4) {
styleImgBox.removeCallbacks(imgLoopRunnable)
}

}

override fun initData() {
PhotoPreview.setGlobalImageLoader { position, source, imageView ->
Glide.with(imageView)
.load(source.toString())
.into(imageView)
}
setClassInfo()
mPresenter?.getHeadClassList()

}

private fun getClassInfo(){
mPresenter?.getClassInfo(currClass.class_id.toString())
LogUtils.d("请求时间",TimeUtils.getNowString())
}

private fun getOtherData() {
mPresenter?.getImageInfo(currClass.class_id.toString())
unitName.postDelayed({
mPresenter?.getTeaList(currClass.class_id.toString())
mPresenter?.getTimeTable(currClass.class_id.toString())
mPresenter?.getActiveInfo(currClass.class_id.toString())
}, 300)
}

override fun onHeadClassSuccess(list: MutableList<HeadClassInfo>) {
if (list.size > 0) {
LogUtils.d("有班级")
val localClassId = SPUtils.getInstance().getInt("local_class_id", 0)
currClass = if (currClass.class_id > 0) {
list.find { it.class_id == currClass.class_id } ?: list[0]
} else if (localClassId > 0) {
list.find { it.class_id == localClassId } ?: list[0]
} else {
list[0]
}

headClassList = list
getOtherData()
mClassInfoHandler.removeCallbacks(mClassInfoRunnable)
getClassInfo()
mClassInfoHandler.postDelayed(mClassInfoRunnable,mClassInfoLoopTime)
classNameTv.text = "${currClass.grade_name}${currClass.class_name}"

classSwIcon.visibility = if (list.size > 1) {
View.VISIBLE
} else {
View.GONE
}
} else {
classSwIcon.visibility = View.GONE
val tipDialog = QMUIDialog.MessageDialogBuilder(activity)
.setTitle("温馨提示")
.setMessage("您没有班主任身份,无法使用电子班牌!")
.addAction("知道了") { dialog, index ->
dialog.dismiss()
User.clearUserInfo()
LoginActivity.active(act)
activity?.apply {
ActivityUtils.finishActivity(this)
}
}
.addAction("立即退出") { dialog, index ->
dialog.dismiss()
User.clearUserInfo()
LoginActivity.active(act)
activity?.apply {
ActivityUtils.finishActivity(this)
}
}
.create()
tipDialog.show()
tipDialog.hideNavigationBar()
}
}

private fun setClassInfo() {
val user = User.getUser();
unitName.text = user.unit_name
loginUserNameTv.text = user.user_name
}


override fun onAvatarSuccess(identity: String, head_portrait: String) {
headImgView?.setSrc(identity, head_portrait)
}

override fun onClassInfoSuccess(info: CBClassInfo) {
classTeaNameTv?.let {
classTeaNameTv.text = info.class_teacher.user_name
classStuCountTv.text = "本班人数:${info.class_student_num}人"
faceCountTv.text = "刷脸入校:${info.brushed_face_num}人"
noFaceCountTv.text = "未刷脸:${info.unbrushed_face_num}人"
leaveCountTv.text = "请假:${info.leave_num}人"

mClassInfoHandler.removeCallbacks(mClassInfoRunnable)
mClassInfoHandler.postDelayed(mClassInfoRunnable,mClassInfoLoopTime)
}
}

override fun onTeaListSuccess(list: MutableList<ClassTeaInfo>) {
classTeaListLL.removeAllViews()
list.forEachIndexed { index, it ->
val itemView =
LayoutInflater.from(activity).inflate(R.layout.layout_class_tea_item, null, false)
if (index % 2 == 0) {
itemView.setBackgroundColor(Color.parseColor("#5682ff"))
} else {
itemView.setBackgroundColor(Color.parseColor("#005682ff"))
}
itemView.teaSubjectNameTv.text = it.subject_name
val userName = if (it.type == 1) {
"${it.user_name}(班主任)"
} else {
it.user_name
}
itemView.teaUserNameTv.text = userName
classTeaListLL.addView(itemView)
}
if (list.size == 0) {
val emptyView =
LayoutInflater.from(activity).inflate(R.layout.layout_class_empty, null, false)
classTeaListLL.addView(emptyView)
}
}

override fun onTimeTableSuccess(list: MutableList<TimeTable>) {
timeTableLL.removeAllViews()
list.forEachIndexed { index, it ->
val itemView =
LayoutInflater.from(activity).inflate(R.layout.layout_time_table_item, null, false)
if (index % 2 == 0) {
itemView.setBackgroundColor(Color.parseColor("#33ffffff"))
} else {
itemView.setBackgroundColor(Color.parseColor("#00ffffff"))
}
itemView.lessonNoTv.text = it.lesson_name
itemView.lessonNameTv.text = it.subject_name
timeTableLL.addView(itemView)
}
if (list.size == 0) {
val emptyView =
LayoutInflater.from(activity).inflate(R.layout.layout_class_empty, null, false)
timeTableLL.addView(emptyView)
}
}

private fun previewActiveImg(item: ClassActiveInfo, view: View) {
val list = item.getImgUrls()
if (list.size <= 0) {
this.showDialogToast("暂无可查看照片", icon = QMUITipDialog.Builder.ICON_TYPE_FAIL)
return
}
val photoPreview = PhotoPreview.with(this)
.sources(list)
.onDismissListener {

}
.build()
photoPreview.show(view)
}

private val mActiveList = mutableListOf<ClassActiveInfo>()
override fun onActiveInfoSuccess(list: MutableList<ClassActiveInfo>) {
classActiveLL.removeAllViews()
mActiveList.clear()
mActiveList.addAll(list)
list.forEachIndexed { index, it ->
val itemView =
LayoutInflater.from(activity)
.inflate(R.layout.layout_class_active_item, null, false)
itemView.activeContentTv.text = it.getNewContent()
itemView.addTimeTv.text = it.add_time.toTime()
itemView.addUserTv.text = it.user_name
itemView.setTag(R.id.row_index_key, index)
itemView.setOnClickListener { item ->
previewActiveImg(it, item)
}
classActiveLL.addView(itemView)
}
if (list.size == 0) {
val emptyView =
LayoutInflater.from(activity).inflate(R.layout.layout_class_empty, null, false)
classActiveLL.addView(emptyView)
}
}

override fun onResume() {
setClassInfo()
super.onResume()
}

override fun onDestroy() {
mTimeHandler.removeCallbacks(timeRunnable)
mClassInfoHandler.removeCallbacks(mClassInfoRunnable)
super.onDestroy()
}

override fun onImageInfoSuccess(list: MutableList<ClassStylePic>) {
hideLoading()
if (list.size > 0) {
imgEmpty.visibility = View.GONE
styleImgBox.visibility = View.VISIBLE

// mViewPager.refreshData(list)
}
this.imgIndex = 0
this.styleImgList.clear()
this.styleImgList.addAll(list)
styleImgUrlList.clear()
list.forEach {
styleImgUrlList.add(it.identity.getImgUrl(it.picture_id))
}
when {
list.size == 0 -> {
imgEmpty.visibility = View.VISIBLE
styleImgBox.visibility = View.GONE
}

list.size == 1 -> {
styleImg0.setSrc(list[0].identity, list[0].picture_id)
styleImg0.visibility = View.VISIBLE
styleImgLL.visibility = View.GONE
styleImg1.visibility = View.GONE
styleImg2.visibility = View.GONE
styleImg3.visibility = View.GONE
}

list.size == 2 -> {
styleImg0.setSrc(list[0].identity, list[0].picture_id)
styleImg1.setSrc(list[1].identity, list[1].picture_id)
styleImg0.visibility = View.VISIBLE
styleImgLL.visibility = View.VISIBLE
styleImg1.visibility = View.VISIBLE
styleImg2.visibility = View.GONE
styleImg3.visibility = View.GONE
}

list.size == 3 -> {
styleImg0.setSrc(list[0].identity, list[0].picture_id)
styleImg1.setSrc(list[1].identity, list[1].picture_id)
styleImg2.setSrc(list[2].identity, list[2].picture_id)
styleImg0.visibility = View.VISIBLE
styleImgLL.visibility = View.VISIBLE
styleImg1.visibility = View.VISIBLE
styleImg2.visibility = View.VISIBLE
styleImg3.visibility = View.GONE
}

list.size >= 4 -> {
styleImg0.setSrc(list[0].identity, list[0].picture_id)
styleImg1.setSrc(list[1].identity, list[1].picture_id)
styleImg2.setSrc(list[2].identity, list[2].picture_id)
styleImg3.setSrc(list[3].identity, list[3].picture_id)
styleImg0.visibility = View.VISIBLE
styleImgLL.visibility = View.VISIBLE
styleImg1.visibility = View.VISIBLE
styleImg2.visibility = View.VISIBLE
styleImg3.visibility = View.VISIBLE
}
}

if (list.size > 4) {
this.imgIndex = 4
// styleImgBox.removeCallbacks(null)
// this.loopImg(list)
mTimeHandler.removeCallbacks(timeRunnable)
mTimeHandler.postDelayed(timeRunnable,6000)
}
}

private fun groupingList() {
val topList = mutableListOf<ClassStylePic>()
val bottomList = mutableListOf<ClassStylePic>()
styleImgList.forEachIndexed { index, classStylePic ->
if (index % 4 == 0) {
topList.add(classStylePic)
} else {
bottomList.add(classStylePic)
}
}
}



private fun loopImg(list: MutableList<ClassStylePic>) {
if (this.imgIndex + 3 > list.size - 1) {
this.imgIndex = list.size - 1 - 3
}
styleImg0?.let {
styleImg0.setSrc(list[this.imgIndex + 0].identity, list[this.imgIndex + 0].picture_id)
styleImg1.setSrc(list[this.imgIndex + 1].identity, list[this.imgIndex + 1].picture_id)
styleImg2.setSrc(list[this.imgIndex + 2].identity, list[this.imgIndex + 2].picture_id)
styleImg3.setSrc(list[this.imgIndex + 3].identity, list[this.imgIndex + 3].picture_id)
this.imgIndex += 4
if (this.imgIndex > list.size - 1) {
this.imgIndex = 0
}
styleImg0.visibility = View.VISIBLE
styleImgLL.visibility = View.VISIBLE
styleImg1.visibility = View.VISIBLE
styleImg2.visibility = View.VISIBLE
styleImg3.visibility = View.VISIBLE
}

}

override fun initPresenter(): ClassBrandPresenter = ClassBrandPresenter(this)

override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}


override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}

//接收消息
@SuppressLint("SetTextI18n")
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: TimeShow) {
// 2023年7月31日17:58:37 星期一
val time =
TimeUtils.getNowString(TimeUtils.getSafeDateFormat("yyyy年MM月dd日 HH:mm:ss").zhCn())
timeView.text = "$time ${event.week}"

if (event.min == "30") {
this.getOtherData()
}
}
}

+ 557
- 0
app/src/main/java/com/yzx/ebrand/fragment/HomeFragment.kt 查看文件

@@ -0,0 +1,557 @@
package com.yzx.ebrand.fragment

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.View
import android.widget.EditText
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.*
import com.huantansheng.easyphotos.EasyPhotos
import com.huantansheng.easyphotos.models.album.entity.Photo
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton
import com.yzx.ebrand.R
import com.yzx.ebrand.adapter.HomeListAdapter
import com.yzx.ebrand.fragment.base.BaseFragment
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.HomePresenter
import com.yzx.ebrand.presenter.HomeView
import com.yzx.ebrand.utils.*
import com.yzx.ebrand.widget.BaseDialog
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.android.synthetic.main.layout_loading.view.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.jetbrains.anko.find
import org.jetbrains.anko.support.v4.act
import org.jetbrains.anko.support.v4.ctx
import org.jetbrains.anko.support.v4.toast
import org.jetbrains.anko.textColor


class HomeFragment : BaseFragment<HomePresenter>(), HomeView,
NetworkUtils.OnNetworkStatusChangedListener, FileUploadCallBack {

companion object {

val CAMER_REQUEST_CODE = 0x01

@JvmStatic
fun getNewInstance() =
HomeFragment()
}

private val mAdapter: HomeListAdapter by lazy {
val list = mutableListOf<StuLeave>()
HomeListAdapter(list)
}

private var mPager = Pager()
var list = mutableListOf<StuLeave>()
private val statusBtnList = mutableListOf<QMUIRoundButton>()
var keyword: String = ""
var status: String = ""
private var isLoading = false
private val mShowList = mutableListOf<StuLeave>()
private val mShowDialogList = mutableListOf<BaseDialog>()
private var mCancelItem: StuLeave? = null
private var mCancelFaceImg: ImageView? = null
private var mDialogVacation: BaseDialog? = null
private val mVacation = Vacation()
private val mVacationAttachment = Attachment("", "", "")
private var isRefresh = false

private val refreshRun = Runnable {
refreshData()
}

override val inflateId: Int
get() = R.layout.fragment_home

override fun initView() {
NetworkUtils.registerNetworkStatusChangedListener(this)
recyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = mAdapter

preTxtBtn.setOnClickListener { pre() }
nextTxtBtn.setOnClickListener { next() }
allBtn.setOnClickListener { changeStatus(0) }
status1Btn.setOnClickListener { changeStatus(1) }
status2Btn.setOnClickListener { changeStatus(2) }
status3Btn.setOnClickListener { changeStatus(3) }
status4Btn.setOnClickListener { changeStatus(4) }
status5Btn.setOnClickListener { changeStatus(5) }
statusBtnList.add(allBtn)
statusBtnList.add(status1Btn)
statusBtnList.add(status2Btn)
statusBtnList.add(status3Btn)
statusBtnList.add(status4Btn)
statusBtnList.add(status5Btn)
keywordInput.setOnKeyListener { _, keyCode, _ ->
if (!isLoading) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
keyword = keywordInput.text.toString()
initData()
KeyboardUtils.hideSoftInput(keywordInput)
}
}
false
}
clearBtn.setOnClickListener {
keyword = ""
keywordInput.setText("")
KeyboardUtils.hideSoftInput(keywordInput)
initData()
}
var lastClickTime = TimeUtils.getNowMills()
mAdapter.setOnItemClickListener { adapter, view, position ->
val curr = TimeUtils.getNowMills()
if(curr - lastClickTime > 500){
lastClickTime = curr
LogUtils.d("获取详情开始",TimeUtils.getNowMills(),mAdapter.getItem(position).id)
showLayoutLoading()
mPresenter?.getDetail(mAdapter.getItem(position).id)
}
}

mAdapter.setOnItemChildClickListener { adapter, view, position ->
LogUtils.d("setOnItemChildClickListener", position)
val curr = TimeUtils.getNowMills()
if(curr - lastClickTime > 500){
lastClickTime = curr
when (view.id) {
R.id.cancelBtn -> {
mCancelItem = mAdapter.getItem(position)
showCancelDialog()
}
R.id.faceEmpty -> {
showLayoutLoading()
mPresenter?.getDetail(mAdapter.getItem(position).id)
}
}
}
}


switchBtn.setOnCheckedChangeListener { buttonView, isChecked ->
SPUtils.getInstance().put("auto_show_leave", isChecked)
changeSwitchBtnTxt(isChecked)
EventBus.getDefault().post(AutoSwitchChange(1))
}
val isAutoShowLeave = SPUtils.getInstance().getBoolean("auto_show_leave", false)
switchBtn.isChecked = isAutoShowLeave
changeSwitchBtnTxt(isAutoShowLeave)

switchBtnTxt.setOnClickListener {
switchBtn.isChecked = !switchBtn.isChecked

EventBus.getDefault().post(AutoSwitchChange(1))
}
keywordInput.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s != null && s.isNotEmpty()) {
clearBtn.visibility = View.VISIBLE
} else {
clearBtn.visibility = View.INVISIBLE
}
}

override fun afterTextChanged(s: Editable?) {

}

})
filterLayout.setOnClickListener {
KeyboardUtils.hideSoftInput(keywordInput)
}

btnRefresh.setOnClickListener {
isRefresh = true
showLayoutLoading()
initData()
}
changeStatusBtn(0)
loadingLayout.setOnClickListener {
//do nothing
}
goPageOne.setOnClickListener {
showLayoutLoading()
initData()
}
}
private fun showLayoutLoading(){
loadingLayout.visibility = View.VISIBLE
}
private fun hideLayoutLoading(){
loadingLayout.visibility = View.GONE
}

@SuppressLint("SetTextI18n")
private fun showCancelDialog() {
val dialogVacation = BaseDialog(act, R.style.BaseDialog, R.layout.dialog_vacation)
mCancelItem?.apply {
mVacation.id = id
mVacation.vacation_type = 2
mVacation.vacation_attachment = ""
mVacation.vacation_remark = "电子屏人工销假"
mVacationAttachment.clear()
dialogVacation.find<TextView>(R.id.leave_student_name).text = leave_student_name
dialogVacation.find<TextView>(R.id.class_name).text = "${grade_name}${class_name}"
dialogVacation.find<TextView>(R.id.add_time).text =
"${start_time.toTime()} - ${end_time.toTime()}"
val nowTime = (TimeUtils.getNowMills() / 1000).toInt()
dialogVacation.find<TextView>(R.id.vacation_time).text = nowTime.toTime()
mVacation.vacation_time = nowTime.toLong()
dialogVacation.find<EditText>(R.id.vacation_remark).setText(mVacation.vacation_remark)
dialogVacation.find<View>(R.id.cameraBtn).setOnClickListener { onCameraBtnClick() }
mCancelFaceImg = dialogVacation.find<ImageView>(R.id.face_img)
dialogVacation.find<View>(R.id.submitBtn).setOnClickListener {
postVacation()
}
dialogVacation.find<View>(R.id.closeBtn).setOnClickListener {
dialogVacation.dismiss()
}
}
//处理弹窗显示
dialogVacation.show()
dialogVacation.hideNavigationBar()
mDialogVacation = dialogVacation
}

private fun postVacation() {
if (mVacationAttachment.id.isNotEmpty()) {
mVacation.vacation_attachment = GsonUtils.toJson(mutableListOf(mVacationAttachment))
}
showLoading("销假中")
mPresenter?.postVacation(mVacation)
}

private fun onCameraBtnClick() {
val isGranted = PermissionUtils.isGranted(Manifest.permission.CAMERA)
if (!isGranted) {
PermissionUtils.permission(Manifest.permission.CAMERA)
.callback { isAllGranted, granted, deniedForever, denied ->
if (!isAllGranted) {
val tipDialog = QMUIDialog.MessageDialogBuilder(activity)
.setTitle("温馨提示")
.setMessage("拍照权限被拒绝,请开启权限后重试")
.addAction("取消") { dialog, index ->
dialog.dismiss()
}
.addAction("确定") { dialog, index ->
dialog.dismiss()
PermissionUtils.launchAppDetailsSettings()
}
.create()
tipDialog.show()
tipDialog.hideNavigationBar()
}
}
.request()
} else {
openCamera()
}
}

private fun openCamera() {
EasyPhotos.createCamera(this, true)
.setFileProviderAuthority("${activity?.packageName}.fileProvider")
.start(CAMER_REQUEST_CODE)//也可以选择链式调用写法
}


private fun changeSwitchBtnTxt(isChecked: Boolean) {
if (isChecked) {
switchBtnTxt.setTextColor(ctx.resources.getColor(R.color.green2))
} else {
switchBtnTxt.setTextColor(ctx.resources.getColor(R.color.black_3))
}
}

@SuppressLint("SetTextI18n")
private fun showLeaveDialog(detail: StuLeave) {
EventBus.getDefault().post(detail)
}

private fun changeStatusBtn(idx: Int) {
statusBtnList.forEachIndexed { index, button ->
button.isSelected = index == idx
}
}

private fun changeStatus(status: Int) {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
changeStatusBtn(status)
this.status = if (status == 0) {
""
} else {
"${status}"
}
showLayoutLoading()
initData()
}

override fun initData() {

mPager.page_no = 1
if (NetworkUtils.isConnected()) {
showEmpty(1)
isLoading = true
mPresenter?.getLeaveList(mPager.page_no, keyword, status)
} else {
showEmpty(2)
}

}

/**
* type 1 loading 2 neterror 3 empty
*/
private fun showEmpty(type: Int) {
when (type) {
1 -> {
mAdapter.setEmptyView(R.layout.layout_loading)
mAdapter.emptyLayout?.apply {
this.QMUIEmptyView.setLoadingShowing(true)
this.QMUIEmptyView.setTitleText("数据加载中")
}
}
2 -> {
mAdapter.setEmptyView(R.layout.layout_loading)
mAdapter.emptyLayout?.apply {
this.QMUIEmptyView.show(false, null, "网络连接异常,请检查", "去设置") {
NetworkUtils.openWirelessSettings()
}
}
}
3 -> {
mAdapter.setEmptyView(R.layout.layout_empty)
}
}

}

private fun refreshData() {
if (isLoading) {
return
}
isLoading = true
mPresenter?.getLeaveList(mPager.page_no, keyword, status)
}

private fun pre() {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
if (mPager.page_no <= 1) {
} else {
isLoading = true
showLayoutLoading()
mPresenter?.getLeaveList(mPager.page_no - 1, keyword, status)
}
}

private fun next() {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
if (mPager.page_no >= mPager.total_pages) {
} else {
isLoading = true
showLayoutLoading()
mPresenter?.getLeaveList(mPager.page_no + 1, keyword, status)
}
}

override fun initPresenter(): HomePresenter = HomePresenter(this)

@SuppressLint("SetTextI18n")
override fun onLeaveListSuccess(list: MutableList<StuLeave>, pager: Pager) {
pageTv?.apply {
if(isRefresh){
toast("刷新成功!")
isRefresh = false
}
mAdapter.setList(list)
mPager = pager
pageTv.text = "${pager.page_no} / ${pager.total_pages}"
totalTv.text = "共${pager.total_count}条"

val disabledColor = Color.parseColor("#666666")
val color = Color.parseColor("#3ca0e9")
if (pager.page_no <= 1) {
preTxtBtn.textColor = disabledColor
goPageOne.visibility = View.GONE
} else {
preTxtBtn.textColor = resources.getColor(R.color.s_app_color_blue)
goPageOne.visibility = View.VISIBLE
}

if (pager.page_no >= pager.total_pages) {
nextTxtBtn.textColor = disabledColor
} else {
nextTxtBtn.textColor = resources.getColor(R.color.s_app_color_blue)
}

isLoading = false
showEmpty(3)
hideLayoutLoading()
pageTv.postDelayed({
refreshData()
}, 30 * 1000)
}
}

override fun onStop() {
pageTv.removeCallbacks(refreshRun)
super.onStop()
EventBus.getDefault().unregister(this)
}

override fun onLeaveListError(error: String) {
isLoading = false
hideLayoutLoading()
if(isRefresh){
toast("刷新失败,请重试!")
isRefresh = false
}
showEmpty(3)
}

override fun onLeaveDetailSuccess(detail: StuLeave) {
pageTv?.apply {
val item = mShowList.find { it.id == detail.id }
if (item != null) {
//替换新的数据
val index = mShowList.indexOf(item)
mShowList[index] = detail

//移除原本的dialog
val dialogIndex = mShowDialogList.indexOfFirst { it.getLeaveId() == item.id }
if (dialogIndex > -1) {
mShowDialogList[dialogIndex].hide()
mShowDialogList.removeAt(dialogIndex)
}

} else {
mShowList.add(detail)
}
LogUtils.d("获取详情结束",TimeUtils.getNowMills(),detail.id)
hideLayoutLoading()
showLeaveDialog(detail)
}
}

override fun onLeaveDetailError(error: String) {
hideLayoutLoading()
}

override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: MessageEventAuto) {
val list = event.list.filter { it.type == 0 }.toMutableList()
if (list.isNotEmpty() && switchBtn.isChecked) {
onLeaveIDsSuccess(list)
}
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageRefreshEvent(event: RefreshTokenEvent) {
refreshData()
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: TimeShow) {
timeView.setTime(event)
}

override fun onLeaveIDsSuccess(list: MutableList<LeaveID>) {

list.forEachIndexed { index, leaveID ->
pageTv.postDelayed({
mPresenter?.getDetail(leaveID.id)
}, 500L * index)
}
}

override fun postVacationSuccess(msg: String) {
showDialogToast(msg, 2000L)
hideLoading()
mDialogVacation?.apply {
dismiss()
refreshData()
}
}

override fun postVacationError(msg: String) {
hideLoading()
showDialogToast(msg, 2000L, QMUITipDialog.Builder.ICON_TYPE_FAIL)
}

override fun onDisconnected() {

}

override fun onConnected(networkType: NetworkUtils.NetworkType?) {
refreshData()
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == CAMER_REQUEST_CODE) {
val photos = data?.getParcelableArrayListExtra<Photo>(EasyPhotos.RESULT_PHOTOS)
LogUtils.d("photos", photos)
photos?.apply {
if (this.size > 0) {
mVacationAttachment.name = this[0].name
FileUpload.upload(this[0].path, this@HomeFragment)
}
}

}

}
super.onActivityResult(requestCode, resultCode, data)
}

override fun onSuccess(identity: String, key: String) {
LogUtils.d(identity, key)
mCancelFaceImg?.setSrc(identity, key)
mVacationAttachment.identity = identity
mVacationAttachment.id = key
}

override fun onError(msg: String) {
LogUtils.d(msg)
}
}


+ 174
- 0
app/src/main/java/com/yzx/ebrand/fragment/MyFragment.kt 查看文件

@@ -0,0 +1,174 @@
package com.yzx.ebrand.fragment

import android.text.InputType
import com.blankj.utilcode.util.KeyboardUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.ScreenUtils
import com.qmuiteam.qmui.widget.dialog.QMUIDialog
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.yzx.ebrand.R
import com.yzx.ebrand.activity.WebActivity
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.fragment.base.BaseFragment
import com.yzx.ebrand.model.TeacherInfo
import com.yzx.ebrand.model.TimeShow
import com.yzx.ebrand.model.User
import com.yzx.ebrand.presenter.MyPresenter
import com.yzx.ebrand.presenter.MyView
import com.yzx.ebrand.utils.hideNavigationBar
import kotlinx.android.synthetic.main.fragment_my.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import kotlin.system.exitProcess

class MyFragment : BaseFragment<MyPresenter>(), MyView {

companion object {

@JvmStatic
fun getNewInstance() =
MyFragment()
}

private var count = 0
private val run = Runnable {
count = 0
}

override val inflateId: Int
get() = R.layout.fragment_my

override fun initView() {
sysExitBtn.setOnClickListener {
count++
sysExitBtn.removeCallbacks(run)
sysExitBtn.postDelayed(run, 1000)
if (count >= 5) {
showExitDialog()
}
}
}

private fun showExitDialog() {
val builder = QMUIDialog.EditTextDialogBuilder(activity)

builder.setPlaceholder("输入密码")
.setTitle("请输入密码")
.setInputType(InputType.TYPE_NUMBER_VARIATION_PASSWORD or InputType.TYPE_CLASS_NUMBER)
.addAction(
"取消"
) { dialog, index ->
KeyboardUtils.hideSoftInput(builder.editText)
dialog?.dismiss()
}
.addAction(
"确定"
) { dialog, index ->
val text = builder.editText.text
LogUtils.d(text)
LogUtils.d("112233".equals(text))
if ("112233" == text.toString()) {
activity?.finish()
exitProcess(0)
} else {
// ToastUtils.showShort("密码不正确")
showPwdErrorTip()
}
}
.setCancelable(false)
.setCanceledOnTouchOutside(false)
val dialog = builder.show()

dialog.hideNavigationBar()
}

private fun showPwdErrorTip() {
val tipDialog = QMUITipDialog.Builder(activity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_FAIL)
.setTipWord("密码错误")
.create()
tipDialog.show()
tipDialog.hideNavigationBar()
sysExitBtn.postDelayed({
tipDialog.dismiss()
}, 1500)
}

override fun initData() {

density.text =
"density:${ScreenUtils.getScreenDensity()},dpi:${ScreenUtils.getScreenDensityDpi()}"

logoutBtn.setOnClickListener {
activity?.apply {
User.clearUserInfo()
WebActivity.active(this, "${Config.OA_URL}/login?logout=1")
finish()
}
}
}

override fun onResume() {
super.onResume()
mPresenter?.getTeacherInfo(User.getUser().user_id)
}

override fun initPresenter(): MyPresenter = MyPresenter(this)
override fun onUserInfoSuccess(info: TeacherInfo) {
userName.text = info.teacher_name
sex.text = when (info.sex) {
1 -> "男"
2 -> "女"
else -> "--"
}
phone.text = info.phone
idCard.text = info.card_no

if (info.teacherUnits.isNotEmpty()) {
val unit = info.teacherUnits[0]
if (unit.teacherUnitGroups.isNotEmpty()) {
val group = unit.teacherUnitGroups[0]
unitName.text = unit.unit_name
groupName.text = group.group_name
jobType.text = if (group.job_type_name.isNotEmpty()) {
group.job_type_name
} else {
"-"
}
isLeader.text = if (group.is_leader == 0) {
"是"
} else {
"否"
}
jobName.text = group.job_name
}


}

}

override fun onUserInfoError(error: String) {

}


override fun onStop() {
super.onStop()
EventBus.getDefault().unregister(this)
}


override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: TimeShow) {
timeView.setTime(event)
}

}

+ 449
- 0
app/src/main/java/com/yzx/ebrand/fragment/VisitorFragment.kt 查看文件

@@ -0,0 +1,449 @@
package com.yzx.ebrand.fragment

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Color
import android.text.Editable
import android.text.TextWatcher
import android.view.KeyEvent
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.*
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton
import com.yzx.ebrand.R
import com.yzx.ebrand.adapter.VisitorListAdapter
import com.yzx.ebrand.fragment.base.BaseFragment
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.VisitorPresenter
import com.yzx.ebrand.presenter.VisitorView
import com.yzx.ebrand.utils.FileUploadCallBack
import com.yzx.ebrand.widget.BaseDialog
import kotlinx.android.synthetic.main.fragment_visitor.*
import kotlinx.android.synthetic.main.layout_loading.view.*
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.jetbrains.anko.support.v4.ctx
import org.jetbrains.anko.support.v4.toast
import org.jetbrains.anko.textColor


class VisitorFragment : BaseFragment<VisitorPresenter>(), VisitorView,
NetworkUtils.OnNetworkStatusChangedListener, FileUploadCallBack {

companion object {

val CAMER_REQUEST_CODE = 0x01

@JvmStatic
fun getNewInstance() =
VisitorFragment()
}

private val mAdapter: VisitorListAdapter by lazy {
val list = mutableListOf<Visitor>()
VisitorListAdapter(list)
}

private var mPager = Pager()
var list = mutableListOf<Visitor>()
private val statusBtnList = mutableListOf<QMUIRoundButton>()
var keyword: String = ""
var status: String = "10"
private var isLoading = false
private val mShowList = mutableListOf<Visitor>()
private val mShowDialogList = mutableListOf<BaseDialog>()
private var isRefresh = false
private var mQrCode: QrCode? = null

private val refreshRun = Runnable {
refreshData()
}

override val inflateId: Int
get() = R.layout.fragment_visitor

override fun initView() {
NetworkUtils.registerNetworkStatusChangedListener(this)
recyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = mAdapter

preTxtBtn.setOnClickListener { pre() }
nextTxtBtn.setOnClickListener { next() }
allBtn.setOnClickListener { changeStatus(10, 0) }
status1Btn.setOnClickListener { changeStatus(0, 1) }
status2Btn.setOnClickListener { changeStatus(1, 2) }
status3Btn.setOnClickListener { changeStatus(2, 3) }
status4Btn.setOnClickListener { changeStatus(-1, 4) }
statusBtnList.add(allBtn)
statusBtnList.add(status1Btn)
statusBtnList.add(status2Btn)
statusBtnList.add(status3Btn)
statusBtnList.add(status4Btn)
keywordInput.setOnKeyListener { _, keyCode, _ ->
if (!isLoading) {
if (keyCode == KeyEvent.KEYCODE_ENTER) {
keyword = keywordInput.text.toString()
initData()
KeyboardUtils.hideSoftInput(keywordInput)
}
}
false
}
clearBtn.setOnClickListener {
keyword = ""
keywordInput.setText("")
KeyboardUtils.hideSoftInput(keywordInput)
showLayoutLoading()
initData()
}
var lastClickTime = TimeUtils.getNowMills()
mAdapter.setOnItemClickListener { adapter, view, position ->
val curr = TimeUtils.getNowMills()
if (curr - lastClickTime > 500) {
lastClickTime = curr
mPresenter?.getDetail(mAdapter.getItem(position).id)
}
}

mAdapter.setOnItemChildClickListener { adapter, view, position ->
LogUtils.d("setOnItemChildClickListener", position)
val curr = TimeUtils.getNowMills()
if (curr - lastClickTime > 500) {
lastClickTime = curr
when (view.id) {
R.id.faceEmpty, R.id.nucleinEmpty, R.id.tripCodeEmpty, R.id.healthCodeEmpty -> {
mPresenter?.getDetail(mAdapter.getItem(position).id)
}
}
}

}
btnRefresh.setOnClickListener {
isRefresh = true
showLayoutLoading()
initData()
}


switchBtn.setOnCheckedChangeListener { buttonView, isChecked ->
SPUtils.getInstance().put("auto_show_visitor", isChecked)
changeSwitchBtnTxt(isChecked)
EventBus.getDefault().post(AutoSwitchChange(2))
}
val isAutoShowLeave = SPUtils.getInstance().getBoolean("auto_show_visitor", false)
switchBtn.isChecked = isAutoShowLeave
changeSwitchBtnTxt(isAutoShowLeave)

switchBtnTxt.setOnClickListener {
switchBtn.isChecked = !switchBtn.isChecked
}

keywordInput.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

}

override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
if (s != null && s.isNotEmpty()) {
clearBtn.visibility = View.VISIBLE
} else {
clearBtn.visibility = View.INVISIBLE
}
}

override fun afterTextChanged(s: Editable?) {

}

})
filterLayout.setOnClickListener {
KeyboardUtils.hideSoftInput(keywordInput)
}
codeBtn.setOnClickListener {
showVisitorQRCode()
}
changeStatusBtn(0)
loadingLayout.setOnClickListener {
//do nothing
}
goPageOne.setOnClickListener {
showLayoutLoading()
initData()
}
}

private fun showLayoutLoading(){
loadingLayout.visibility = View.VISIBLE
}

private fun hideLayoutLoading(){
loadingLayout.visibility = View.GONE
}

private fun showVisitorQRCode() {
if (mQrCode != null) {
mQrCode?.apply {
EventBus.getDefault().post(ViewImage(1, identity, key))
}
} else {
mPresenter?.getQrcodeWithAccessToken()
}
}


private fun changeSwitchBtnTxt(isChecked: Boolean) {
if (isChecked) {
switchBtnTxt.setTextColor(ctx.resources.getColor(R.color.green2))
} else {
switchBtnTxt.setTextColor(ctx.resources.getColor(R.color.black_3))
}
}

@SuppressLint("SetTextI18n")
private fun showLeaveDialog(detail: Visitor) {
EventBus.getDefault().post(detail)
}

private fun changeStatusBtn(idx: Int) {
statusBtnList.forEachIndexed { index, button ->
button.isSelected = index == idx
}
}

private fun changeStatus(status: Int, index: Int) {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
showLayoutLoading()
changeStatusBtn(index)
this.status = "${status}"
initData()
}

override fun initData() {

mPager.page_no = 1
if (NetworkUtils.isConnected()) {
showEmpty(1)
isLoading = true
mPresenter?.getList(mPager.page_no, keyword, status)
} else {
showEmpty(2)
}

}

/**
* type 1 loading 2 neterror 3 empty
*/
private fun showEmpty(type: Int) {
when (type) {
1 -> {
mAdapter.setEmptyView(R.layout.layout_loading)
mAdapter.emptyLayout?.apply {
this.QMUIEmptyView.setLoadingShowing(true)
this.QMUIEmptyView.setTitleText("数据加载中")
}
}
2 -> {
mAdapter.setEmptyView(R.layout.layout_loading)
mAdapter.emptyLayout?.apply {
this.QMUIEmptyView.show(false, null, "网络连接异常,请检查", "去设置") {
NetworkUtils.openWirelessSettings()
}
}
}
3 -> {
mAdapter.setEmptyView(R.layout.layout_empty)
}
}

}

private fun refreshData() {
if (isLoading) {
return
}
isLoading = true
mPresenter?.getList(mPager.page_no, keyword, status)
}

private fun pre() {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
if (mPager.page_no <= 1) {
} else {
isLoading = true
hideLayoutLoading()
mPresenter?.getList(mPager.page_no - 1, keyword, status)
}
}

private fun next() {
KeyboardUtils.hideSoftInput(keywordInput)
if (isLoading) {
return
}
if (mPager.page_no >= mPager.total_pages) {
} else {
isLoading = true
hideLayoutLoading()
mPresenter?.getList(mPager.page_no + 1, keyword, status)
}
}

override fun initPresenter(): VisitorPresenter = VisitorPresenter(this)

@SuppressLint("SetTextI18n")
override fun onListSuccess(list: MutableList<Visitor>, pager: Pager) {
pageTv?.apply {
if (isRefresh) {
toast("刷新成功!")
isRefresh = false
}
mAdapter.setList(list)
mPager = pager
pageTv.text = "${pager.page_no} / ${pager.total_pages}"
totalTv.text = "共${pager.total_count}条"

val disabledColor = Color.parseColor("#666666")
val color = Color.parseColor("#3ca0e9")
if (pager.page_no <= 1) {
preTxtBtn.textColor = disabledColor
goPageOne.visibility = View.GONE
} else {
preTxtBtn.textColor = resources.getColor(R.color.s_app_color_blue)
goPageOne.visibility = View.VISIBLE
}

if (pager.page_no >= pager.total_pages) {
nextTxtBtn.textColor = disabledColor
} else {
nextTxtBtn.textColor = resources.getColor(R.color.s_app_color_blue)
}
isLoading = false
showEmpty(3)
hideLayoutLoading()
pageTv.postDelayed({
refreshData()
}, 30 * 1000)
}
}

override fun onStop() {
pageTv.removeCallbacks(refreshRun)
super.onStop()
EventBus.getDefault().unregister(this)
}


override fun onStart() {
super.onStart()
EventBus.getDefault().register(this)
}

override fun onListError(error: String) {
isLoading = false
if (isRefresh) {
toast("刷新失败,请重试!")
isRefresh = false
}
hideLayoutLoading()
showEmpty(3)
}

override fun onDetailSuccess(detail: Visitor) {
pageTv?.apply {
val item = mShowList.find { it.id == detail.id }
if (item != null) {
//替换新的数据
val index = mShowList.indexOf(item)
mShowList[index] = detail

//移除原本的dialog
val dialogIndex = mShowDialogList.indexOfFirst { it.getLeaveId() == item.id }
if (dialogIndex > -1) {
mShowDialogList[dialogIndex].hide()
mShowDialogList.removeAt(dialogIndex)
}

} else {
mShowList.add(detail)
}
showLeaveDialog(detail)
}
}

override fun onDetailError(error: String) {

}

override fun onDisconnected() {

}

override fun onConnected(networkType: NetworkUtils.NetworkType?) {
refreshData()
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK) {


}
super.onActivityResult(requestCode, resultCode, data)
}

override fun onSuccess(identity: String, key: String) {
LogUtils.d(identity, key)

}

override fun onError(msg: String) {
LogUtils.d(msg)


}

override fun onQrCodeSuccess(qrCode: QrCode) {
LogUtils.d(qrCode)
mQrCode = qrCode
EventBus.getDefault().post(ViewImage(1, qrCode.identity, qrCode.key))
}

override fun onQrCodeError(error: String) {
toast("二维码获取失败,请重试!")
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: MessageEventAuto) {
val list = event.list.filter { it.type == 1 }.toMutableList()
if (list.isNotEmpty() && switchBtn.isChecked) {
list.forEachIndexed { index, leaveID ->
pageTv.postDelayed({
mPresenter?.getDetail(leaveID.id)
}, 500L * index)
}
}
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageRefreshEvent(event: RefreshTokenEvent) {
refreshData()
}

//接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(event: TimeShow) {
timeView.setTime(event)
}
}


+ 105
- 0
app/src/main/java/com/yzx/ebrand/fragment/base/BaseFragment.kt 查看文件

@@ -0,0 +1,105 @@
package com.yzx.ebrand.fragment.base


import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.utils.hideNavigationBar

/**
* fragment 基类
*/
abstract class BaseFragment<out P : BasePresenter<*>> : Fragment() {

/**
* 当前页面需要加载的layoutId,等价setContentView
*/
abstract val inflateId: Int

private var mLoadingDialog: QMUITipDialog? = null

/**
* 初始化视图操作在这里执行,执行时机为onCreate之后
*/
abstract fun initView(): Unit

/**
* 数据初始化在这里执行,执行时机为initView之后
*/
abstract fun initData(): Unit

//kotlin 懒加载,在第一次使用Presenter时初始化,这种设计是针对一个View只针对一个Presenter。
//多个Presenter的情况此处不应该使用泛型
protected val mPresenter: P? by lazy { initPresenter() }

abstract fun initPresenter(): P?


override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(inflateId, null)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

initView()
initData()
}

override fun onStart() {
super.onStart()

}

override fun onStop() {
super.onStop()

}


override fun onDestroy() {
super.onDestroy()
}

fun showDialogToast(
msg: String,
duration: Long = 1500,
@QMUITipDialog.Builder.IconType icon: Int = QMUITipDialog.Builder.ICON_TYPE_SUCCESS
) {
val tipDialog = QMUITipDialog.Builder(activity)
.setIconType(icon)
.setTipWord(msg)
.create()
tipDialog.show()
tipDialog.hideNavigationBar()
view?.postDelayed({
tipDialog.dismiss()
}, duration)
}

fun showLoading(msg: String = "加载中...") {
mLoadingDialog = QMUITipDialog.Builder(activity)
.setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
.setTipWord(msg)
.create()
mLoadingDialog?.apply {
show()
}
}

fun hideLoading() {
mLoadingDialog?.apply {
if (isShowing) {
dismiss()
}
}
}
}

+ 16
- 0
app/src/main/java/com/yzx/ebrand/model/BaseBean.kt 查看文件

@@ -0,0 +1,16 @@
package com.yzx.ebrand.model

data class BaseBean<T>(
var code: Int,
var msg: String,
val data: T,
val list: MutableList<T>,
val pager:Pager = Pager()
)

data class Pager(
var page_no:Int = 1,
val page_size:Int = 0,
val total_pages:Int = 0,
val total_count:Int = 0
)

+ 24
- 0
app/src/main/java/com/yzx/ebrand/model/Book.kt 查看文件

@@ -0,0 +1,24 @@
package com.yzx.ebrand.model

class Book {
var book_name:String = ""
var file_type:String = ""
var book_file_identity:String = ""
var book_file_id:String = ""
var author:String = ""
var read_requires:String = ""
var read_progress:Float = 0f
var volumes:MutableList<Volumes> = mutableListOf()
}

class Volumes{
var id:String = ""
var title:String = ""
var sections:MutableList<Sections> = mutableListOf()
}

class Sections{
var id:String = ""
var title:String = ""
var content:String = ""
}

+ 75
- 0
app/src/main/java/com/yzx/ebrand/model/CBClassInfo.kt 查看文件

@@ -0,0 +1,75 @@
package com.yzx.ebrand.model

import com.yzx.ebrand.utils.getImgUrl
import java.net.URLDecoder

data class CBClassInfo(
val brushed_face_num: Int = 0,
val class_student_num: Int = 0,
val class_teacher: ClassTeacher = ClassTeacher(),
val leave_num: Int = 0,
val unbrushed_face_num: Int = 0,
val user_photo: UserPhoto = UserPhoto()
)

data class ClassTeacher(
val user_id: Int = 0,
val user_name: String = ""
)

data class UserPhoto(
val head_portrait: String = "",
val identity: String = ""
)

data class ClassTeaInfo(
val subject_name: String = "",
val subject_id: String = "",
val user_name: String = "",
val user_id: String = "",
val type: Int = 0,
)

data class TimeTable(
val lesson_no: Int = 0,
val lesson_name: String = "",
val subject_id: String = "",
val subject_name: String = "",
)

data class ClassActiveInfo(
val add_time: Int = 0,
val user_name: String = "",
val content: String = "",
val attachments: MutableList<ActiveAttachment> = mutableListOf(),
){
fun getNewContent():String{
return URLDecoder.decode(content,"UTF-8")
}

fun getImgUrls():MutableList<String>{
val list = mutableListOf<String>()
attachments.forEach {
if (it.file_id?.isNotEmpty())
list.add(it.file_identity.getImgUrl(it.file_id))
}
return list
}
}

data class ActiveAttachment(
val file_id: String = "",
val file_identity: String = "",
)

data class ClassStylePic(
val identity: String = "",
val picture_id: String = "",
)

data class HeadClassInfo(
val class_id: Int = 0,
val class_name: String = "",
val grade_id: Int = 0,
val grade_name: String = "",
)

+ 7
- 0
app/src/main/java/com/yzx/ebrand/model/HomeItem.kt 查看文件

@@ -0,0 +1,7 @@
package com.yzx.ebrand.model

class HomeItem (
var title:String,
var img:Int,
var url:String = ""
)

+ 39
- 0
app/src/main/java/com/yzx/ebrand/model/MessageEvent.kt 查看文件

@@ -0,0 +1,39 @@
package com.yzx.ebrand.model

import com.blankj.utilcode.util.TimeUtils
import com.yzx.ebrand.utils.zhCn

data class MessageEventAuto(
var list: MutableList<LeaveID>,
val type: Int = 0
)

data class AutoSwitchChange(val type: Int)

data class RefreshTokenEvent(val token: String)


data class TimeShow(
var year: String = "",
var month: String = "",
var day: String = "",
var hour: String = "",
var min: String = "",
var sec: String = "",
var week: String = ""
) {
fun getNowObj(): TimeShow {
//yyyy-MM-dd HH:mm:ss
year = TimeUtils.getNowString(TimeUtils.getSafeDateFormat("yyyy").zhCn())
month = TimeUtils.getNowString(TimeUtils.getSafeDateFormat("MM").zhCn())
day = TimeUtils.getNowString(TimeUtils.getSafeDateFormat("dd").zhCn())
hour = TimeUtils.getNowString(TimeUtils.getSafeDateFormat("HH").zhCn())
min = TimeUtils.getNowString(TimeUtils.getSafeDateFormat("mm").zhCn())
sec = TimeUtils.getNowString(TimeUtils.getSafeDateFormat("ss").zhCn())
week = TimeUtils.getChineseWeek(System.currentTimeMillis()).replace("周", "星期")
return this
}

}

data class UserLoginEvent(val isLogin: Boolean = true)

+ 7
- 0
app/src/main/java/com/yzx/ebrand/model/Note.kt 查看文件

@@ -0,0 +1,7 @@
package com.yzx.ebrand.model

class Note {
var key:String = ""
var identity:String = ""
var BGid:Int = 0
}

+ 8
- 0
app/src/main/java/com/yzx/ebrand/model/QrCode.kt 查看文件

@@ -0,0 +1,8 @@
package com.yzx.ebrand.model
data class QrCode(
val identity: String = "",
val key: String = ""
)
data class AccessToken(
val access_token: String = ""
)

+ 5
- 0
app/src/main/java/com/yzx/ebrand/model/ReToken.kt 查看文件

@@ -0,0 +1,5 @@
package com.yzx.ebrand.model

class ReToken (
val token:String
)

+ 209
- 0
app/src/main/java/com/yzx/ebrand/model/StuChange.kt 查看文件

@@ -0,0 +1,209 @@
package com.yzx.ebrand.model

import com.yzx.ebrand.config.Config

data class StuChangeType(
val id: Int = 0,
val label: String = "",
val shortLabel: String = ""
) {
fun getShortLabelVal(): String {
if (shortLabel.isNotEmpty()) {
return shortLabel
}
return label
}
}

data class StuChange(
val activities: List<ChangeActivity> = mutableListOf(),
val add_time: Int = 0,
val add_user_id: Int = 0,
val add_user_name: String = "",
val attachment: String = "",
val attachments: List<Any> = listOf(),
val can_reviewed: Int = 0,
val class_id: Int = 0,
val class_name: String = "",
val end_time: Int = 0,
val face_identity: String = "",
val face_key: String = "",
val grade_id: Int = 0,
val grade_name: String = "",
val headteacher_id: Int = 0,
val id: Int = 0,
val is_cancel_change: Int = 0,
val is_delete: Int = 0,
val is_resume_school: Int = 0,
val new_todo_list_id: Int = 0,
val school_id: Int = 0,
val school_name: String = "",
val sign_identity: String = "",
val sign_key: String = "",
val start_time: Int = 0,
val status: Int = 0,
val status_change_reason: String = "",
val status_change_student_id: Int = 0,
val status_change_student_name: String = "",
val status_change_type: Int = 0,
val status_change_type_name: String = "",
val sub_status: Int = 0,
val target_class_id: Int = 0,
val target_class_name: String = "",
val target_grade_id: Int = 0,
val target_grade_name: String = "",
val target_headteacher_id: Int = 0,
val target_school_id: Int = 0,
val target_school_name: String = "",
val target_status: Int = 0,
val todo_list_id: Int = 0,
val type: Int = 0
) {
fun getStatusImg(): String {
return when {
getSubStatusName().isNotEmpty() -> {
"https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/statuschange/${getSubStatusIcon()}.png"
}
status == 1 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/stutakeleave_wait.png"
status == 2 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/stutakeleave_pass.png"
status == 3 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/stutakeleave_nopass.png"
else -> ""
}
}

fun getSubStatusIcon(
changeType: Int = status_change_type,
subStatus: Int = sub_status
): String {
if (is_resume_school == 1) {
return "resume_school"
}
return when (subStatus) {
0 -> "change0"
else -> {
"${changeType}_${subStatus}"
}
}
}

fun getSubStatusName(
changeType: Int = status_change_type,
subStatus: Int = sub_status
): String {
if (status != 2) {
return ""
}
if (is_resume_school == 1) {
return "恢复上学"
}
//其他type 无子状态
when (changeType) {
Config.STU_CHANGE_STATUS_LEAVE_SCHOOL -> {
return when (subStatus) {
0 -> {
"未开始"
}
1 -> {
"休学中"
}
else -> {
"休学结束"
}
}
}
Config.STU_CHANGE_STATUS_OUT_SCHOOL -> {
return when (subStatus) {
0 -> {
"未开始"
}
else -> {
"已退学"
}
}
}
Config.STU_CHANGE_STATUS_INTROSPECTION -> {
return when (subStatus) {
0 -> {
"未开始"
}
1 -> {
"反省中"
}
else -> {
"反省结束"
}
}
}
Config.STU_CHANGE_STATUS_INTERNSHIP -> {
return when (subStatus) {
0 -> {
"未开始"
}
1 -> {
"实习中"
}
else -> {
"实习结束"
}
}
}
Config.STU_CHANGE_STATUS_DROP_OUT -> {
return when (subStatus) {
0 -> {
"未开始"
}
else -> {
"已辍学"
}
}
}
Config.STU_CHANGE_STATUS_TRANSFER_OUT -> {
return when (subStatus) {
0 -> {
"未开始"
}
else -> {
"已转出"
}
}
}
}
return ""
}

fun getStep(): List<ChangeActivity> {
return activities.reversed()
}

}

data class ChangeActivity(
val activity_name: String = "",
val add_time: Int = 0,
val add_user_id: Int = 0,
val add_user_name: String = "",
val add_user_type: Int = 0,
val approval_comments: String = "",
val approval_status: Int = 0,
val approve_node: Int = 0,
val approve_sort: Int = 0,
val approve_user_type: Int = 0,
val approve_way: Int = 0,
val id: Int = 0,
val is_approve: Int = 0,
val is_auto_pass: Int = 0,
val related_id: Int = 0,
val relation_id: Int = 0,
val report_end_date: Int = 0,
val report_start_date: Int = 0,
val role_type: Int = 0,
val school_name: String = "",
val sign_identity: String = "",
val sign_key: String? = "",
val status: Int = 0,
val sub_type: String = "",
val type: Int = 0,
val unit_id: Int = 0,
val unit_name: String = "",
val vacation_type: Int = 0
)

+ 199
- 0
app/src/main/java/com/yzx/ebrand/model/StuLeave.kt 查看文件

@@ -0,0 +1,199 @@
package com.yzx.ebrand.model

import android.os.Parcelable
import com.yzx.ebrand.utils.durationStr
import kotlinx.android.parcel.Parcelize

@Parcelize
data class StuLeave(
val activities: MutableList<LeaveActivity> = mutableListOf(),
val add_time: Int = 0,
val add_user_id: Int = 0,
val add_user_name: String = "",
val add_user_type: Int = 0,
val approve_time: Int = 0,
val can_reviewed: Int = 0,
val class_id: Int = 0,
val class_name: String = "",
val copy_recipients: String = "",
val end_time: Int = 0,
val entry_flag: Int = 0,
val face_identity: String = "",
val face_key: String = "",
val ftime: Int = 0,
val grade_id: Int = 0,
val grade_name: String = "",
val headteacher_id: Int = 0,
val id: Int = 0,
val is_cancel_leave: Int = 0,
val leave_request_reason: String = "",
val leave_request_type: Int = 0,
val leave_request_type_name: String = "",
val leave_student_id: Int = 0,
val leave_student_name: String = "",
val relation_id: Int = 0,
val school_id: Int = 0,
val school_name: String = "",
val start_time: Int = 0,
val status: Int = 0,
val todo_list_id: Int = 0,
val todo_status: Int = 0
) : Parcelable {

fun getStep(): MutableList<LeaveActivity> {
val logList = mutableListOf<LeaveActivity>()
for (item in activities) {
if (item.child.isNotEmpty()) {
for (it in item.child) {
it.activity_name = when (it.approve_user_type) {
0 -> "领导审批"
1 -> "自选"
2 -> if (it.role_type == 3) {
"班主任审批"
} else {
"任课老师审批"
}
3 -> "专业部领导审批"
4 -> "值班领导审批"
else -> "领导审批"
}
}
val approvedList = item.child.filter {
return@filter it.approval_status > 1
}
if (approvedList.isNotEmpty()) {
if (item.approve_way == 2) {
logList.addAll(approvedList)
} else {
logList.addAll(item.child)
}
} else {
item.activity_name = when (item.approve_user_type) {
0 -> "领导审批"
1 -> "自选"
2 -> if (item.role_type == 3) {
"班主任审批"
} else {
"任课老师审批"
}
3 -> "专业部领导审批"
4 -> "值班领导审批"
else -> "领导审批"
}
if (item.child.size > 1) {
item.activity_name += when (item.approve_way) {
0 -> "(依次审批)"
1 -> "(会签)"
2 -> "(或签)"
else -> ""
}
}
item.add_user_name = item.child.map {
return@map it.add_user_name
}.joinToString(separator = "、")

item.approval_status = 1
item.is_approve = 1
logList.add(item)
}
} else if (item.is_approve == 0) { //提交人
if (item.activity_name.contains("并直接通过") || item.is_auto_pass == 1) {
item.activity_name = "提交申请(直接通过)"
} else {
item.activity_name = "提交申请"
}
if (item.add_user_type == 0) {
item.add_user_type_name = "老师"
} else if (item.add_user_type == 1) {
item.add_user_type_name = "学生家长"
}
logList.add(item)
} else if (item.is_approve == 2) { //学生返校销假
if (item.vacation_type == 2) { //销假/返校类型(1自动销假 2老师操作销假)
val remark = item.approval_comments
item.approval_comments = "人工销假,销假操作人:${item.add_user_name}。"
if (item.add_time > end_time) { //超时
item.approval_comments += "超出请假时长:${(item.add_time - end_time).durationStr()}。"
item.color = "#ff4040"
}
if (remark.isNotEmpty()) {
item.approval_comments += "备注:${remark}"
}
} else if (item.vacation_type == 1) {
item.approval_comments = "刷脸进校,自动销假。"
if (item.add_time > end_time) { //超时
item.approval_comments += "超出请假时长:${(item.add_time - end_time).durationStr()}。"
item.color = "#ff4040"
}
}else if(item.vacation_type == 3){
item.approval_comments = "系统自动销假。"
}
logList.add(item)
}
}

return logList
}
}

@Parcelize
data class LeaveID(var id: Int,var type:Int) : Parcelable
@Parcelize
data class LeaveActivity(
var activity_name: String = "",
var add_time: Int = 0,
var add_user_id: Int = 0,
var add_user_name: String = "",
var add_user_type: Int = 0,
var approval_comments: String = "",
var approval_status: Int = 0,
var approve_node: Int = 0,
var approve_sort: Int = 0,
var approve_user_type: Int = 0,
var approve_way: Int = 0,
var child: MutableList<LeaveActivity> = mutableListOf(),
var id: Int = 0,
var is_approve: Int = 0,
var related_id: Int = 0,
var relation_id: Int = 0,
var report_end_date: Int = 0,
var report_start_date: Int = 0,
var role_type: Int = 0,
var school_name: String = "",
var sign_identity: String = "",
var sign_key: String = "",
var status: Int = 0,
var sub_type: Int = 0,
var type: Int = 0,
var unit_id: Int = 0,
var unit_name: String = "",
var add_user_type_name: String = "",
var is_auto_pass: Int = 0,
var vacation_type: Int = 0,
var color: String = "",
val face_infos: MutableList<FaceInfo> = mutableListOf()
) : Parcelable {
fun getInImg(): FaceInfo? {
val imgList = face_infos.filter { it.isImg() }
if (imgList.isNotEmpty()) {
return imgList[0]
}
return null
}
}
@Parcelize
data class FaceInfo(
var attachment_name: String = "",
var attachment_id: String = "",
var identity: String = ""
) : Parcelable {
fun isImg(): Boolean {
if (attachment_name.isNullOrBlank()) {
return false
}
if (attachment_name.endsWith(".jpg", true) || attachment_name.endsWith(".png", true)) {
return true
}
return false
}
}

+ 21
- 0
app/src/main/java/com/yzx/ebrand/model/TabEntity.kt 查看文件

@@ -0,0 +1,21 @@
package com.yzx.ebrand.model

import com.flyco.tablayout.listener.CustomTabEntity

data class TabEntity(var title: String,
var selectedIcon: Int,
var unSelectedIcon: Int) :
CustomTabEntity {
override fun getTabTitle(): String {
return title
}

override fun getTabSelectedIcon(): Int {
return selectedIcon
}

override fun getTabUnselectedIcon(): Int {
return unSelectedIcon
}

}

+ 102
- 0
app/src/main/java/com/yzx/ebrand/model/TeacherInfo.kt 查看文件

@@ -0,0 +1,102 @@
package com.yzx.ebrand.model

data class TeacherInfo(
val academic_degree: Int = 0,
val academic_degree_describe: String = "",
val add_time: Int = 0,
val age: Int = 0,
val audit_remark: String = "",
val audit_status: Int = 0,
val audit_user_id: Int = 0,
val audit_user_name: String = "",
val birth_place: String = "",
val birth_place_json: String = "",
val birthday: String = "",
val card_no: String = "",
val card_no_type: Int = 0,
val degree_id: Int = 0,
val editing_time: Int = 0,
val face_add_time: Int = 0,
val face_identity: String = "",
val face_key: String = "",
val first_part: Int = 0,
val first_part_describe: Int = 0,
val first_part_time: Int = 0,
val head_portrait: String = "",
val is_commit: Int = 0,
val is_remind_commit: Int = 0,
val is_retire_time: Int = 0,
val is_show_btn: Int = 0,
val is_syn: Int = 0,
val marry_status_id: Int = 0,
val nation: Int = 0,
val native_place: String = "",
val native_place_json: String = "",
val nick_name: String = "",
val not_incumbency_time: Int = 0,
val people_identity: Int = 0,
val people_source_describe: Int = 0,
val people_source_type: Int = 0,
val people_type: Int = 0,
val phone: String = "",
val professional: String = "",
val retire_remark: String = "",
val retire_time: Long = 0,
val salary_unit_id: Int = 0,
val school_id: Int = 0,
val second_part: Int = 0,
val second_part_describe: Int = 0,
val second_part_time: Int = 0,
val sex: Int = 0,
val status: Int = 0,
val teach_curriculum: String = "",
val teach_interval_time: Int = 0,
val teach_period: Int = 0,
val teach_start_time: String = "",
val teach_years: Int = 0,
val teacherUnits: List<TeacherUnit> = listOf(),
val teacher_id: Int = 0,
val teacher_name: String = "",
val teacher_school_status: Int = 0,
val urgent_phone: String = "",
val user_id: Int = 0,
val user_type: Int = 0,
val work_interval_time: Int = 0,
val work_start_time: String = "",
val work_years: Int = 0
)

data class TeacherUnit(
val add_time: Int = 0,
val id: Int = 0,
val into_unit_time: Int = 0,
val is_salary_unit: Int = 0,
val post_level: Int = 0,
val post_level_name: String = "",
val status: Int = 0,
val teacherUnitGroups: List<TeacherUnitGroup> = listOf(),
val title: Int = 0,
val title_name: String = "",
val unit_id: Int = 0,
val unit_main: Int = 0,
val unit_main_describe: Int = 0,
val unit_main_type: Int = 0,
val unit_name: String = "",
val user_id: Int = 0
)

data class TeacherUnitGroup(
val add_time: Int = 0,
val group_id: Int = 0,
val group_ids: String = "",
val group_name: String = "",
val id: Int = 0,
val is_leader: Int = 0,
val job_name: String = "",
val job_name_id: Int = 0,
val job_status: Int = 0,
val job_type: Int = 0,
val job_type_name: String = "",
val status: Int = 0,
val teacher_unit_id: Int = 0
)

+ 13
- 0
app/src/main/java/com/yzx/ebrand/model/UploadBean.kt 查看文件

@@ -0,0 +1,13 @@
package com.yzx.ebrand.model

class UploadBean {
var code:Int = 0
var msg:String = ""
var content:UploadContent = UploadContent()
}

class UploadContent{
var identity:String = ""
var key:String = ""
var file_size:String = ""
}

+ 105
- 0
app/src/main/java/com/yzx/ebrand/model/User.kt 查看文件

@@ -0,0 +1,105 @@
package com.yzx.ebrand.model

import com.blankj.utilcode.util.SPUtils
import com.blankj.utilcode.util.TimeUtils

class BaseUser(var token: String,
var type:Int,
var role:String,
var user_id:Int,
var unit_id:Int,
var school_id:Int,
var unit_name:String,
var school_name:String,
var direct_login:Int,
var tmp_token:String,
var phone:String,
)

class UserAvatar(val identity:String,val head_portrait:String)

class WxQrTicket(val ticket:String)

class User(
var user_name: String,
var user_id: Int,
var account_type: Int,
var role: String,
var token: String,
var school_id: Int,
var phone: String,
var ticket: String,
var loginTime: Long,
var unit_name:String,
var school_name:String,
) {
fun save() {
val sp = SPUtils.getInstance()
sp.put("user_name", user_name)
sp.put("user_id", user_id)
sp.put("token", token)
sp.put("school_id", school_id)
sp.put("phone", phone)
sp.put("ticket", ticket)
sp.put("account_type", account_type)
sp.put("role", role)
sp.put("loginTime", TimeUtils.getNowMills())
sp.put("unit_name", if (unit_name.isNullOrBlank()){school_name}else{unit_name})
}

companion object {
fun getUser(): User {
val sp = SPUtils.getInstance()
return User(
sp.getString("user_name", ""),
sp.getInt("user_id", 0),
sp.getInt("account_type", 0),
sp.getString("role", ""),
sp.getString("token", ""),
sp.getInt("school_id", 0),
sp.getString("phone", ""),
sp.getString("ticket", ""),
sp.getLong("loginTime", 0),
sp.getString("unit_name", ""),
sp.getString("unit_name", ""),
)
}

fun isLogin(): Boolean {
val now = TimeUtils.getNowMills()
val user = getUser()
if (user.token.isNullOrBlank()) {
return false
}
if (now - user.loginTime > 24 * 60 * 60 * 1000) {
return false
}
return true
}

fun getUnitCount(): Int = SPUtils.getInstance().getInt("unit_count", 1)

fun saveUnitCount(count: Int) {
SPUtils.getInstance().put("unit_count", count);
}

fun saveLastLoginTime(time:Long){
val sp = SPUtils.getInstance()
sp.put("loginTime", time)
}

fun clearUserInfo() {
val sp = SPUtils.getInstance()
sp.remove("user_name")
sp.remove("user_id")
sp.remove("account_type")
sp.remove("role")
sp.remove("token")
sp.remove("school_id")
sp.remove("phone")
sp.remove("ticket")
sp.remove("loginTime")
sp.remove("unit_name")
}
}
}

+ 21
- 0
app/src/main/java/com/yzx/ebrand/model/Vacation.kt 查看文件

@@ -0,0 +1,21 @@
package com.yzx.ebrand.model

data class Vacation(
var vacation_time: Long = 0,
var vacation_type: Int = 2,
var vacation_remark: String = "",
var vacation_attachment: String = "",
var id: Int = 0
)

data class Attachment(
var name: String,
var id: String,
var identity: String
){
fun clear(){
name =""
id =""
identity =""
}
}

+ 11
- 0
app/src/main/java/com/yzx/ebrand/model/Version.kt 查看文件

@@ -0,0 +1,11 @@
package com.yzx.ebrand.model

class Version {
var version: String = ""
var version_code: Int = 0
var id: Int = 0
var type: Int = 0
var explain: String = ""
var app_src: String = ""
var status: Int = 0
}

+ 7
- 0
app/src/main/java/com/yzx/ebrand/model/ViewImage.kt 查看文件

@@ -0,0 +1,7 @@
package com.yzx.ebrand.model

data class ViewImage(
val id: Int = 0,
val identity: String = "",
val key: String = ""
)

+ 113
- 0
app/src/main/java/com/yzx/ebrand/model/Visitor.kt 查看文件

@@ -0,0 +1,113 @@
package com.yzx.ebrand.model

import kotlin.math.abs

data class Visitor(
val add_time: Int = 0,
val auditRecordOuts: MutableList<AuditRecordOut> = mutableListOf(),
val audit_status: Int = 0,
val car_in_time: Int = 0,
val car_out_time: Int = 0,
val card_no: String = "",
val end_time: Int = 0,
val face_identity: String = "",
val face_key: String = "",
val health_code_identity: String = "",
val health_code_key: String = "",
val health_code_status: Int = -1,
val history_num: Int = 0,
val id: Int = 0,
val in_out_num: Int = 0,
val is_drive: Int = 0,
val license_plate: String = "",
val positionNums: List<Any> = mutableListOf(),
val position_id: Int = 0,
val reception_user: String = "",
val reception_user_id: Int = 0,
val start_time: Int = 0,
val trip_code_identity: String = "",
val trip_code_key: String = "",
val user_id: Int = 0,
val user_name: String = "",
val user_phone: String = "",
val user_type: Int = 0,
val visit_reason: String = "",
val nuclein_file_key: String = "",
val nuclein_file_identity: String = "",
val nuclein_time: Int = 0,
val nuclein_result: Int = 0
) {
fun getStatusImg(): String {
return when (audit_status) {
0 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/v_status_0.png"
1 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/v_status_1.png"
2 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/v_status_2.png"
-1 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/v_status_-1.png"
else -> "--"
}
}

fun getStep(): MutableList<AuditRecordOut> {
val list = mutableListOf<AuditRecordOut>()
list.add(AuditRecordOut(add_time = add_time, typeTxt = "发起申请"))
auditRecordOuts.forEach {
list.add(it.getCopyItem())
}
return list
}

fun getNucleinStatusObj(): NucleinStatusObj {
val time = abs(add_time - nuclein_time)
val nucleinResultName = if (nuclein_result == 2) {
"阳性"
} else {
"阴性"
}
var name = ""
var color = "#5DAD64"
when {
time < 24 * 60 * 60 -> {
name = "省内24小时:${nucleinResultName}"
color = "#5DAD64";
}
time < 48 * 60 * 60 -> {
name = "省内48小时:${nucleinResultName}"
color = "#3c7ef6";
}
time < 72 * 60 * 60 -> {
name = "省内72小时:${nucleinResultName}"
color = "#62D5FF";
}
else -> {
name = "省内72小时以上:${nucleinResultName}"
color = "#999999";
}
}
if (nuclein_result == 2) {
color = "#ff4040"
}
return NucleinStatusObj(name, color)
}
}

data class NucleinStatusObj(val nuclein_name: String = "",
val nuclein_color: String = "#333333")
data class AuditRecordOut(
val add_time: Int = 0,
val audit_remark: String = "",
val audit_status: Int = 0,
val audit_user_name: String = "",
val typeTxt: String = "",
val id: Int = 0
) {
fun getTitle(): String {
if (typeTxt.isNotEmpty()) {
return typeTxt
}
return "接待人审批"
}

fun getCopyItem(): AuditRecordOut {
return AuditRecordOut(add_time, audit_remark, audit_status, audit_user_name, typeTxt, id)
}
}

+ 25
- 0
app/src/main/java/com/yzx/ebrand/model/YzxClientInfo.kt 查看文件

@@ -0,0 +1,25 @@
package com.yzx.ebrand.model

import com.blankj.utilcode.util.TimeUtils

class YzxClientInfo {
var type: Int = 0
var user_id: String = ""
var unit_id: String = ""
var token: String = ""
var service_timestamp: Long = 0
var data: MsgStu = MsgStu()
}

data class MsgStu(val unit_id: Int = 0, val student_id: Int = 0)


data class YzxHeart(
val type: Int = 70,
val msg: String = "heart",
val timestamp: String = ""
) {
fun getYzxHeader(): YzxHeart {
return YzxHeart(timestamp = TimeUtils.getNowString())
}
}

+ 77
- 0
app/src/main/java/com/yzx/ebrand/presenter/ChangePresenter.kt 查看文件

@@ -0,0 +1,77 @@
package com.yzx.ebrand.presenter

import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.base.*
import com.yzx.ebrand.config.YzxInterface

class ChangePresenter(view: ChangeView) : BasePresenter<ChangeView>(view) {


fun getList(pageNo: Int, keyword: String, status: String) {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_STUDENT_GET_CHANGE_LIST}"
OkGo.post<YzxResponse<StuChange>>(url)
.tag(this)
.params("keyword", keyword)
.params("status", status)
.params("page_size", 6)
.params("page_no", pageNo)
.execute(object : JsonCallBack<YzxResponse<StuChange>>() {


override fun onSuccess(response: Response<YzxResponse<StuChange>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onListSuccess(response.body().list, response.body().pager)
}
}

override fun onError(response: Response<YzxResponse<StuChange>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onListError(response?.body()?.msg ?: "")
}
})
}
fun getDetail(id: Int) {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_STUDENT_GET_CHANGE_DETAIL}"
OkGo.post<YzxResponse<StuChange>>(url)
.tag(this)
.params("id", id)
.execute(object : JsonCallBack<YzxResponse<StuChange>>() {


override fun onSuccess(response: Response<YzxResponse<StuChange>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onDetailSuccess(response.body().data)
}
}

override fun onError(response: Response<YzxResponse<StuChange>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onDetailError(response?.body()?.msg ?: "")
}
})
}


}

interface ChangeView : IView {
fun onListSuccess(list: MutableList<StuChange>, pager: Pager)
fun onListError(error: String)
fun onDetailSuccess(detail: StuChange)
fun onDetailError(error: String)
}

+ 176
- 0
app/src/main/java/com/yzx/ebrand/presenter/ClassBrandPresenter.kt 查看文件

@@ -0,0 +1,176 @@
package com.yzx.ebrand.presenter

import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.config.YzxInterface
import com.yzx.ebrand.model.CBClassInfo
import com.yzx.ebrand.model.ClassActiveInfo
import com.yzx.ebrand.model.ClassStylePic
import com.yzx.ebrand.model.ClassTeaInfo
import com.yzx.ebrand.model.HeadClassInfo
import com.yzx.ebrand.model.TimeTable
import com.yzx.ebrand.model.User
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.presenter.base.IView
import com.yzx.ebrand.presenter.base.JsonCallBack
import com.yzx.ebrand.presenter.base.YzxResponse

class ClassBrandPresenter(view: ClassBrandView) : BasePresenter<ClassBrandView>(view) {
fun getHeadClassList(){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_GET_VOTE_TEA_CLASS}"
OkGo.post<YzxResponse<HeadClassInfo>>(url)
.tag(this)
.execute(object : JsonCallBack<YzxResponse<HeadClassInfo>>() {

override fun onSuccess(response: Response<YzxResponse<HeadClassInfo>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onHeadClassSuccess(response.body().list)
}
}

override fun onError(response: Response<YzxResponse<HeadClassInfo>>?) {
super.onError(response)
LogUtils.d(response)
}
})
}
fun getClassInfo(class_id:String){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_CLASS_BRAND_CLASS_INFO}"
OkGo.post<YzxResponse<CBClassInfo>>(url)
.tag(this)
.params("class_id", class_id)
.execute(object : JsonCallBack<YzxResponse<CBClassInfo>>() {

override fun onSuccess(response: Response<YzxResponse<CBClassInfo>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
val info = response.body().data
mView?.onAvatarSuccess(info.user_photo.identity,info.user_photo.head_portrait)
mView?.onClassInfoSuccess(response.body().data)
}
}

override fun onError(response: Response<YzxResponse<CBClassInfo>>?) {
super.onError(response)
LogUtils.d(response)
// mView?.onListError(response?.body()?.msg ?: "")
}
})
}

fun getTeaList(class_id: String){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_CLASS_BRAND_TEA_INFO}"
OkGo.post<YzxResponse<ClassTeaInfo>>(url)
.tag(this)
.params("class_id", class_id)
.execute(object : JsonCallBack<YzxResponse<ClassTeaInfo>>() {

override fun onSuccess(response: Response<YzxResponse<ClassTeaInfo>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onTeaListSuccess(response.body().list)
}
}

override fun onError(response: Response<YzxResponse<ClassTeaInfo>>?) {
super.onError(response)
LogUtils.d(response)
// mView?.onListError(response?.body()?.msg ?: "")
}
})
}

fun getTimeTable(class_id: String){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_CLASS_BRAND_TIME_TABLE_INFO}"
OkGo.post<YzxResponse<TimeTable>>(url)
.tag(this)
.params("class_id", class_id)
.execute(object : JsonCallBack<YzxResponse<TimeTable>>() {

override fun onSuccess(response: Response<YzxResponse<TimeTable>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onTimeTableSuccess(response.body().list)
}
}

override fun onError(response: Response<YzxResponse<TimeTable>>?) {
super.onError(response)
LogUtils.d(response)
}
})
}

fun getActiveInfo(class_id:String){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_CLASS_BRAND_ACTIVE_INFO}"
OkGo.post<YzxResponse<ClassActiveInfo>>(url)
.tag(this)
.params("class_id", class_id)
.execute(object : JsonCallBack<YzxResponse<ClassActiveInfo>>() {

override fun onSuccess(response: Response<YzxResponse<ClassActiveInfo>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onActiveInfoSuccess(response.body().list)
}
}

override fun onError(response: Response<YzxResponse<ClassActiveInfo>>?) {
super.onError(response)
LogUtils.d(response)
}
})
}

fun getImageInfo(class_id: String){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_CLASS_BRAND_IMAGE_INFO}"
OkGo.post<YzxResponse<ClassStylePic>>(url)
.tag(this)
.params("class_id", class_id)
.execute(object : JsonCallBack<YzxResponse<ClassStylePic>>() {

override fun onSuccess(response: Response<YzxResponse<ClassStylePic>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onImageInfoSuccess(response.body().list)
}
}

override fun onError(response: Response<YzxResponse<ClassStylePic>>?) {
super.onError(response)
LogUtils.d(response)
}
})
}
}

interface ClassBrandView : IView {
fun onHeadClassSuccess(list:MutableList<HeadClassInfo>)
fun onAvatarSuccess(identity:String,head_portrait:String)
fun onClassInfoSuccess(info: CBClassInfo)
fun onTeaListSuccess(list:MutableList<ClassTeaInfo>)
fun onTimeTableSuccess(list:MutableList<TimeTable>)
fun onActiveInfoSuccess(list:MutableList<ClassActiveInfo>)
fun onImageInfoSuccess(list: MutableList<ClassStylePic>)
}

+ 131
- 0
app/src/main/java/com/yzx/ebrand/presenter/HomePresenter.kt 查看文件

@@ -0,0 +1,131 @@
package com.yzx.ebrand.presenter

import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.base.*
import com.yzx.ebrand.config.YzxInterface

class HomePresenter(view: HomeView) : BasePresenter<HomeView>(view) {


fun getLeaveList(pageNo: Int, keyword: String, status: String) {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_GET_STU_LEAVE_LIST}"
OkGo.post<YzxResponse<StuLeave>>(url)
.tag(this)
.params("keyword", keyword)
.params("status", status)
.params("page_size", 6)
.params("page_no", pageNo)
.execute(object : JsonCallBack<YzxResponse<StuLeave>>() {


override fun onSuccess(response: Response<YzxResponse<StuLeave>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onLeaveListSuccess(response.body().list, response.body().pager)
}
}

override fun onError(response: Response<YzxResponse<StuLeave>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLeaveListError(response?.body()?.msg ?: "")
}
})
}
fun getLeaveShowIds() {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_STUDENT_GET_SHOW_BOX_LIST}"
OkGo.post<YzxResponse<LeaveID>>(url)
.tag(this)
.execute(object : JsonCallBack<YzxResponse<LeaveID>>() {
override fun onSuccess(response: Response<YzxResponse<LeaveID>>?) {
if (response?.isSuccessful == true) {
mView?.onLeaveIDsSuccess(response.body().list)
LogUtils.d("getLeaveShowIds",response.body().list)
}
}

override fun onError(response: Response<YzxResponse<LeaveID>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLeaveListError(response?.body()?.msg ?: "")
}
})
}

fun getDetail(id: Int) {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_GET_STU_LEAVE_INFO_DETAIL}"
OkGo.post<YzxResponse<StuLeave>>(url)
.tag(this)
.params("id", id)
.execute(object : JsonCallBack<YzxResponse<StuLeave>>() {


override fun onSuccess(response: Response<YzxResponse<StuLeave>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onLeaveDetailSuccess(response.body().data)
}
}

override fun onError(response: Response<YzxResponse<StuLeave>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLeaveDetailError(response?.body()?.msg ?: "")
}
})
}

fun postVacation(data:Vacation){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_STUDENT_POST_LEAVE_VACATION}"
OkGo.post<SimpleResponse>(url)
.tag(this)
.params("id", data.id)
.params("vacation_type", data.vacation_type)
.params("vacation_time", data.vacation_time)
.params("vacation_remark", data.vacation_remark)
.params("vacation_attachment", data.vacation_attachment)
.execute(object : JsonCallBack<SimpleResponse>() {


override fun onSuccess(response: Response<SimpleResponse>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.postVacationSuccess("销假成功!")
}
}

override fun onError(response: Response<SimpleResponse>?) {
super.onError(response)
LogUtils.d(response)
mView?.postVacationError(response?.body()?.msg ?: "销假失败,请重试!")
}
})
}

}

interface HomeView : IView {
fun onLeaveListSuccess(list: MutableList<StuLeave>, pager: Pager)
fun onLeaveListError(error: String)
fun onLeaveDetailSuccess(detail: StuLeave)
fun onLeaveDetailError(error: String)
fun onLeaveIDsSuccess(list: MutableList<LeaveID>)
fun postVacationSuccess(msg: String)
fun postVacationError(msg: String)
}

+ 207
- 0
app/src/main/java/com/yzx/ebrand/presenter/LoginPresenter.kt 查看文件

@@ -0,0 +1,207 @@
package com.yzx.ebrand.presenter

import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.config.YzxInterface
import com.yzx.ebrand.model.BaseUser
import com.yzx.ebrand.model.User
import com.yzx.ebrand.model.WxQrTicket
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.presenter.base.IView
import com.yzx.ebrand.presenter.base.JsonCallBack
import com.yzx.ebrand.presenter.base.YzxResponse

class LoginPresenter(view: LoginView) : BasePresenter<LoginView>(view) {
fun login(phone: String, psw: String) {
val url = Config.BASE_URL + YzxInterface.INTERFACE_LOGIN_ALL
OkGo.post<YzxResponse<BaseUser>>(url)
.tag(this)
.params("phone", phone)
.params("password", psw)
.params("original_password", psw)
.execute(object : JsonCallBack<YzxResponse<BaseUser>>() {
override fun onSuccess(response: Response<YzxResponse<BaseUser>>?) {
if (response?.isSuccessful == true) {
mView?.onLoginSuccess(response.body().data, response.body().list)
LogUtils.d("login", response.body().list)
}
}

override fun onError(response: Response<YzxResponse<BaseUser>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLoginError(response?.body()?.msg ?: "")
}
})
}

fun switchUser(token: String, user_id: Int, unit_id: Int) {
val url = Config.BASE_URL + YzxInterface.INTERFACE_USER_SWITCH
OkGo.post<YzxResponse<User>>(url)
.tag(this)
.params("token", token)
.params("user_id", user_id)
.params("unit_id", unit_id)
.params("type", 0)
.execute(object : JsonCallBack<YzxResponse<User>>() {
override fun onSuccess(response: Response<YzxResponse<User>>?) {
if (response?.isSuccessful == true) {
response.body().data.save()
getUserLoginInfo(response.body().data.token)
}
}

override fun onError(response: Response<YzxResponse<User>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLoginError(response?.body()?.msg ?: "")
}
})
}

fun switchUnit(user_id: Int, school_id: Int, tmp_token: String) {
val url = Config.BASE_URL + YzxInterface.INTERFACE_USER_SWITCH_UNIT
OkGo.post<YzxResponse<User>>(url)
.tag(this)
.params("school_id", school_id)
.params("user_id", user_id)
.params("tmp_token", tmp_token)
.params("client_id", 201)
.params("type", 0)
.execute(object : JsonCallBack<YzxResponse<User>>() {
override fun onSuccess(response: Response<YzxResponse<User>>?) {
if (response?.isSuccessful == true) {
getUserLoginInfo(response.body().data.token)
}
}

override fun onError(response: Response<YzxResponse<User>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLoginError(response?.body()?.msg ?: "")
}
})
}

fun getUserLoginInfo(token: String) {
val url = Config.BASE_URL + YzxInterface.INTERFACE_COMMON_LOGIN_BY_TOKEN
OkGo.post<YzxResponse<User>>(url)
.tag(this)
.params("token", token)
.execute(object : JsonCallBack<YzxResponse<User>>() {
override fun onSuccess(response: Response<YzxResponse<User>>?) {
if (response?.isSuccessful == true) {
response.body().data.save()
mView?.onUserInfoSuccess(response.body().data)
}
}

override fun onError(response: Response<YzxResponse<User>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLoginError(response?.body()?.msg ?: "")
}
})
}

fun getUserRoleInfoByPhone(phone: String, temp_token: String = "") {
val url = Config.BASE_URL + YzxInterface.INTERFACE_USER_ROLE_LIST_BY_PHONE
OkGo.post<YzxResponse<BaseUser>>(url)
.tag(this)
.params("phone", phone)
.execute(object : JsonCallBack<YzxResponse<BaseUser>>() {
override fun onSuccess(response: Response<YzxResponse<BaseUser>>?) {
if (response?.isSuccessful == true) {
val teaList = response.body().list.filter { return@filter it.role.toInt() == 0 }
.toMutableList()
teaList.forEach {
it.unit_name = it.school_name
it.unit_id = it.school_id
}
mView?.onUserListSuccess(teaList, temp_token)
}
}

override fun onError(response: Response<YzxResponse<BaseUser>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLoginError(response?.body()?.msg ?: "")
}
})
}

fun getUserRoleList(token: String) {
val url = Config.BASE_URL + YzxInterface.INTERFACE_USER_ROLE_LIST
OkGo.post<YzxResponse<BaseUser>>(url)
.tag(this)
.params("token", token)
.execute(object : JsonCallBack<YzxResponse<BaseUser>>() {
override fun onSuccess(response: Response<YzxResponse<BaseUser>>?) {
if (response?.isSuccessful == true) {
val teaList = response.body().list.filter { return@filter it.type == 0 }
.toMutableList()
mView?.onUserListSuccess(teaList, token)
}
}

override fun onError(response: Response<YzxResponse<BaseUser>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLoginError(response?.body()?.msg ?: "")
}
})
}

fun getWXQrCode() {
val url = Config.BASE_URL + YzxInterface.INTERFACE_GENERATE_WX_QR_TICKET
OkGo.post<YzxResponse<WxQrTicket>>(url)
.tag(this)
.params("mp_id", 4)
.execute(object : JsonCallBack<YzxResponse<WxQrTicket>>() {
override fun onSuccess(response: Response<YzxResponse<WxQrTicket>>?) {
if (response?.isSuccessful == true) {
val url =
"https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=${response.body().data.ticket}"
mView?.onWxQrCodeSuccess(url, response.body().data.ticket)
}
}

override fun onError(response: Response<YzxResponse<WxQrTicket>>?) {
super.onError(response)
LogUtils.d(response)
}
})
}

fun loginQuery(ticket: String) {
val url = Config.BASE_URL + YzxInterface.INTERFACE_WX_DO_LOGIN_QUERY

OkGo.post<YzxResponse<BaseUser>>(url)
.tag(this)
.params("ticket", ticket)
.execute(object : JsonCallBack<YzxResponse<BaseUser>>() {
override fun onSuccess(response: Response<YzxResponse<BaseUser>>?) {
if (response?.isSuccessful == true) {
val res = response.body()
mView?.onLoginQuerySuccess(res.data, res.code)
}
}

override fun onError(response: Response<YzxResponse<BaseUser>>?) {
super.onError(response)
LogUtils.d(response)
}
})
}
}

interface LoginView : IView {
fun onLoginSuccess(user: BaseUser, list: MutableList<BaseUser>)
fun onLoginError(msg: String)
fun onUserInfoSuccess(user: User)
fun onUserListSuccess(list: MutableList<BaseUser>, token: String)
fun onWxQrCodeSuccess(imgUrl: String, ticket: String)
fun onLoginQuerySuccess(user: BaseUser, code: Int)
}

+ 48
- 0
app/src/main/java/com/yzx/ebrand/presenter/MainPresenter.kt 查看文件

@@ -0,0 +1,48 @@
package com.yzx.ebrand.presenter

import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.config.YzxInterface
import com.yzx.ebrand.model.LeaveID
import com.yzx.ebrand.model.User
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.presenter.base.IView
import com.yzx.ebrand.presenter.base.JsonCallBack
import com.yzx.ebrand.presenter.base.YzxResponse

class MainPresenter(view: MainView) : BasePresenter<MainView>(view) {


fun getLeaveShowIds(student_id: String = "") {
if (User.getUser().token.isEmpty()) {
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_STUDENT_GET_SHOW_BOX_LIST}"
OkGo.post<YzxResponse<LeaveID>>(url)
.tag(this)
.params("student_id", student_id)
.execute(object : JsonCallBack<YzxResponse<LeaveID>>() {
override fun onSuccess(response: Response<YzxResponse<LeaveID>>?) {
if (response?.isSuccessful == true) {
mView?.onLeaveIDsSuccess(response.body().list)
LogUtils.d("getLeaveShowIds", response.body().list)
}
}

override fun onError(response: Response<YzxResponse<LeaveID>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onLeaveIDsError()
}
})
}


}

interface MainView : IView {
fun onLeaveIDsSuccess(list: MutableList<LeaveID>)
fun onLeaveIDsError()
}

+ 51
- 0
app/src/main/java/com/yzx/ebrand/presenter/MyPresenter.kt 查看文件

@@ -0,0 +1,51 @@
package com.yzx.ebrand.presenter

import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.model.TeacherInfo
import com.yzx.ebrand.model.User
import com.yzx.ebrand.config.YzxInterface
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.presenter.base.IView
import com.yzx.ebrand.presenter.base.JsonCallBack
import com.yzx.ebrand.presenter.base.YzxResponse

class MyPresenter(view: MyView) : BasePresenter<MyView>(view) {


fun getTeacherInfo(user_id: Int) {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_GET_TEACHER_INFO}"
OkGo.post<YzxResponse<TeacherInfo>>(url)
.tag(this)
.params("user_id", user_id)
.execute(object : JsonCallBack<YzxResponse<TeacherInfo>>() {

override fun onSuccess(response: Response<YzxResponse<TeacherInfo>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onUserInfoSuccess(response.body().data)
}
}

override fun onError(response: Response<YzxResponse<TeacherInfo>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onUserInfoError(response?.body()?.msg ?: "")
}
})
}




}

interface MyView : IView {
fun onUserInfoSuccess(info: TeacherInfo)
fun onUserInfoError(error:String)
}

+ 140
- 0
app/src/main/java/com/yzx/ebrand/presenter/VisitorPresenter.kt 查看文件

@@ -0,0 +1,140 @@
package com.yzx.ebrand.presenter

import com.blankj.utilcode.util.LogUtils
import com.lzy.okgo.OkGo
import com.lzy.okgo.model.Response
import com.yzx.ebrand.config.Config
import com.yzx.ebrand.config.YzxInterface
import com.yzx.ebrand.model.*
import com.yzx.ebrand.presenter.base.BasePresenter
import com.yzx.ebrand.presenter.base.IView
import com.yzx.ebrand.presenter.base.JsonCallBack
import com.yzx.ebrand.presenter.base.YzxResponse

class VisitorPresenter(view: VisitorView) : BasePresenter<VisitorView>(view) {


fun getList(pageNo: Int, keyword: String, status: String) {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_ACCESS_CONTROL_GET_FACE_LIST}"
OkGo.post<YzxResponse<Visitor>>(url)
.tag(this)
.params("keyword", keyword)
.params("audit_status", status)
.params("user_type", 3)
.params("page_size", 6)
.params("page_no", pageNo)
.execute(object : JsonCallBack<YzxResponse<Visitor>>() {


override fun onSuccess(response: Response<YzxResponse<Visitor>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onListSuccess(response.body().list, response.body().pager)
}
}

override fun onError(response: Response<YzxResponse<Visitor>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onListError(response?.body()?.msg ?: "")
}
})
}
fun getDetail(id: Int) {
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_ACCESS_CONTROL_GET_FACE_INFO_DETAIL}"
OkGo.post<YzxResponse<Visitor>>(url)
.tag(this)
.params("id", id)
.params("user_type", 3)
.execute(object : JsonCallBack<YzxResponse<Visitor>>() {


override fun onSuccess(response: Response<YzxResponse<Visitor>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onDetailSuccess(response.body().data)
}
}

override fun onError(response: Response<YzxResponse<Visitor>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onDetailError(response?.body()?.msg ?: "")
}
})
}


fun getQrcodeWithAccessToken(){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_GET_ACCESS_TOKEN}"
OkGo.post<YzxResponse<AccessToken>>(url)
.tag(this)
.params("app_id", Config.MP_APPID)
.execute(object : JsonCallBack<YzxResponse<AccessToken>>() {


override fun onSuccess(response: Response<YzxResponse<AccessToken>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
getQrCode(response.body().data.access_token)
}
}

override fun onError(response: Response<YzxResponse<AccessToken>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onQrCodeError(response?.body()?.msg ?: "")
}
})
}

fun getQrCode(accessToken:String){
if(User.getUser().token.isEmpty()){
return
}
val url = "${Config.BASE_URL}${YzxInterface.INTERFACE_GET_MINI_CODE}"
val unitId = User.getUser().school_id
OkGo.post<YzxResponse<QrCode>>(url)
.tag(this)
.params("page_url", "pages/accesscontrol/apply/index")
.params("scene", "_${unitId}")
.params("access_token", accessToken)
.execute(object : JsonCallBack<YzxResponse<QrCode>>() {


override fun onSuccess(response: Response<YzxResponse<QrCode>>?) {
LogUtils.d(response)
if (response?.isSuccessful == true) {
mView?.onQrCodeSuccess(response.body().data)
}
}

override fun onError(response: Response<YzxResponse<QrCode>>?) {
super.onError(response)
LogUtils.d(response)
mView?.onQrCodeError(response?.body()?.msg ?: "")
}
})
}


}

interface VisitorView : IView {
fun onListSuccess(list: MutableList<Visitor>, pager: Pager)
fun onListError(error: String)
fun onDetailSuccess(detail: Visitor)
fun onDetailError(error: String)
fun onQrCodeSuccess(qrCode: QrCode)
fun onQrCodeError(error: String)
}

+ 19
- 0
app/src/main/java/com/yzx/ebrand/presenter/base/BasePresenter.kt 查看文件

@@ -0,0 +1,19 @@
package com.yzx.ebrand.presenter.base

/**
* 类名:BasePresenter
* 作者:Yun.Lei
* 功能:
* 创建日期:2018-07-13 10:40
* 修改人:
* 修改时间:
* 修改备注:
*/
abstract class BasePresenter<T : IView>(view: T) {
protected var mView: T? = view

fun onDestroy() {
mView = null
}

}

+ 50
- 0
app/src/main/java/com/yzx/ebrand/presenter/base/Convert.java 查看文件

@@ -0,0 +1,50 @@
package com.yzx.ebrand.presenter.base;

import com.google.gson.Gson;
import com.google.gson.JsonIOException;
import com.google.gson.JsonSyntaxException;
import com.google.gson.stream.JsonReader;

import java.io.Reader;
import java.lang.reflect.Type;

public class Convert {

private static Gson create() {
return GsonHolder.gson;
}

private static class GsonHolder {
private static Gson gson = new Gson();
}

public static <T> T fromJson(String json, Class<T> type) throws JsonIOException, JsonSyntaxException {
return create().fromJson(json, type);
}

public static <T> T fromJson(String json, Type type) {
return create().fromJson(json, type);
}

public static <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
return create().fromJson(reader, typeOfT);
}

public static <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
return create().fromJson(json, classOfT);
}

public static <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
return create().fromJson(json, typeOfT);
}

public static String toJson(Object src) {
return create().toJson(src);
}

public static String toJson(Object src, Type typeOfSrc) {
return create().toJson(src, typeOfSrc);
}


}

+ 12
- 0
app/src/main/java/com/yzx/ebrand/presenter/base/IView.kt 查看文件

@@ -0,0 +1,12 @@
package com.yzx.ebrand.presenter.base

/**
* 类名:IView
* 作者:Yun.Lei
* 功能:
* 创建日期:2018-07-13 10:39
* 修改人:
* 修改时间:
* 修改备注:
*/
interface IView

+ 193
- 0
app/src/main/java/com/yzx/ebrand/presenter/base/JsonCallBack.java 查看文件

@@ -0,0 +1,193 @@
package com.yzx.ebrand.presenter.base;

import android.content.Intent;

import com.blankj.utilcode.util.ActivityUtils;
import com.blankj.utilcode.util.LogUtils;
import com.google.gson.stream.JsonReader;
import com.lzy.okgo.callback.AbsCallback;
import com.lzy.okgo.model.HttpHeaders;
import com.lzy.okgo.request.base.Request;
import com.yzx.ebrand.App;
import com.yzx.ebrand.MainActivity;
import com.yzx.ebrand.activity.LoginActivity;
import com.yzx.ebrand.config.RefreshToken;
import com.yzx.ebrand.model.User;
import com.yzx.ebrand.utils.Monitor;

import org.json.JSONArray;
import org.json.JSONObject;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Date;

import okhttp3.Response;
import okhttp3.ResponseBody;

public abstract class JsonCallBack<T> extends AbsCallback<T> {

private Type type;
private Class<T> clazz;
private StringBuilder sb = new StringBuilder();

public JsonCallBack() {

}

public JsonCallBack(Type type) {
this.type = type;
}

public JsonCallBack(Class<T> clazz) {
this.clazz = clazz;
}

@Override
public void onStart(Request<T, ? extends Request> request) {
super.onStart(request);
User user = User.Companion.getUser();
HttpHeaders headers = new HttpHeaders();
headers.put("phone", user.getPhone());
headers.put("token", user.getToken());
// headers.put("phone","18780170404");
// headers.put("token","11c73fb160bd715654736e7196dc1b57");
request.headers(headers);

sb.append("url:").append(request.getUrl()).append("\n");
sb.append("headers:").append(request.getHeaders().toString()).append("\n");
sb.append("params:").append(request.getParams().toString()).append("\n");
}

@Override
public T convertResponse(Response response) throws Throwable {

if (type == null) {
if (clazz == null) {
// 如果没有通过构造函数传进来,就自动解析父类泛型的真实类型(有局限性,继承后就无法解析到)
Type genType = getClass().getGenericSuperclass();
type = ((ParameterizedType) genType).getActualTypeArguments()[0];
} else {
return parseClass(response, clazz);
}
}

if (type instanceof ParameterizedType) {
return parseParameterizedType(response, (ParameterizedType) type);
} else if (type instanceof Class) {
return parseClass(response, (Class<?>) type);
} else {
return parseType(response, type);
}
}

private T parseClass(Response response, Class<?> rawType) throws Exception {
if (rawType == null) return null;
ResponseBody body = response.body();
if (body == null) return null;
JsonReader jsonReader = new JsonReader(body.charStream());

if (rawType == String.class) {
//noinspection unchecked
return (T) body.string();
} else if (rawType == JSONObject.class) {
//noinspection unchecked
return (T) new JSONObject(body.string());
} else if (rawType == JSONArray.class) {
//noinspection unchecked
return (T) new JSONArray(body.string());
} else {
T t = Convert.fromJson(jsonReader, rawType);
response.close();
return t;
}
}

private T parseType(Response response, Type type) throws Exception {
if (type == null) return null;
ResponseBody body = response.body();
if (body == null) return null;
JsonReader jsonReader = new JsonReader(body.charStream());

// 泛型格式如下: new JsonCallback<任意JavaBean>(this)
T t = Convert.fromJson(jsonReader, type);
response.close();
return t;
}

private T parseParameterizedType(Response response, ParameterizedType type) throws Exception {
if (type == null) return null;
ResponseBody body = response.body();
if (body == null) return null;
JsonReader jsonReader = new JsonReader(body.charStream());

Type rawType = type.getRawType(); // 泛型的实际类型
Type typeArgument = type.getActualTypeArguments()[0]; // 泛型的参数
if (rawType != YzxResponse.class) {
// 泛型格式如下: new JsonCallback<外层BaseBean<内层JavaBean>>(this)
T t = Convert.fromJson(jsonReader, type);
response.close();
return t;
} else {
if (typeArgument == Void.class) {
// 泛型格式如下: new JsonCallback<YzxResponse<Void>>(this)
SimpleResponse simpleResponse = Convert.fromJson(jsonReader, SimpleResponse.class);
response.close();
//noinspection unchecked
return (T) simpleResponse.toYzxResponse();
} else {
// 泛型格式如下: new JsonCallback<YzxResponse<内层JavaBean>>(this)
YzxResponse yzxResponse = Convert.fromJson(jsonReader, type);
response.close();
int code = yzxResponse.code;
// 一般来说服务器会和客户端约定一个数表示成功,如200,其余的表示失败,如400,300等,这里根据实际情况罗列并抛出
if (code == 0 || code == 451 || code == 452 || code == 453) {
//noinspection unchecked
return (T) yzxResponse;
} else if (code == 406) {
long currTime = new Date().getTime();
User.Companion.saveLastLoginTime(currTime - 24*60*60*1000L);
RefreshToken.INSTANCE.refresh(new RefreshToken.RefreshCallback() {
@Override
public void onSuccess() {
LogUtils.d("onSuccess");
Intent intent = new Intent(App.Companion.getContext(),MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ActivityUtils.finishActivity(MainActivity.class);
ActivityUtils.startActivity(intent);
}

@Override
public void onError() {
LogUtils.d("onError");
User.Companion.clearUserInfo();
Intent intent = new Intent(App.Companion.getContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// intent.putExtra("link", Config.INSTANCE.getOA_URL()+"/login?logout=1");
ActivityUtils.startActivity(intent);
ActivityUtils.finishActivity(MainActivity.class);
}
});
throw new IllegalStateException("错误代码:" + code + ",错误信息:" + yzxResponse.msg);
} else {
// 直接将服务端的错误信息抛出,onError中可以获取
throw new IllegalStateException("错误代码:" + code + ",错误信息:" + yzxResponse.msg);
}
}
}
}

@Override
public void onError(com.lzy.okgo.model.Response<T> response) {
super.onError(response);
String msg = response.getException().getMessage();
if(msg==null){
msg = "";
}
//登录相关信息不上报
if(!msg.contains("错误代码:406") && !msg.contains("token信息不存在!")){
sb.append("异常信息:").append(msg);
Monitor.INSTANCE.postNetError(sb);
}
}
}

+ 20
- 0
app/src/main/java/com/yzx/ebrand/presenter/base/SimpleResponse.java 查看文件

@@ -0,0 +1,20 @@
package com.yzx.ebrand.presenter.base;


import java.io.Serializable;

public class SimpleResponse implements Serializable {

private static final long serialVersionUID = -1477609349345966116L;

public int code;
public String msg;

public YzxResponse toYzxResponse() {
YzxResponse lzyResponse = new YzxResponse();
lzyResponse.code = code;
lzyResponse.msg = msg;
return lzyResponse;
}
}


+ 27
- 0
app/src/main/java/com/yzx/ebrand/presenter/base/YzxListResponse.java 查看文件

@@ -0,0 +1,27 @@
package com.yzx.ebrand.presenter.base;


import com.yzx.ebrand.model.Pager;

import java.io.Serializable;
import java.util.ArrayList;

public class YzxListResponse<T> implements Serializable {

private static final long serialVersionUID = 5213230387175987834L;

public int code = -1;
public String msg;
public ArrayList<T> list;
public Pager pager;

@Override
public String toString() {
return "YzxResponse{\n" +//
"\tcode=" + code + "\n" +//
"\tmsg='" + msg + "\'\n" +//
"\tlist=" + list + "\n" +//
"\tpager=" + pager + "\n" +//
'}';
}
}

+ 30
- 0
app/src/main/java/com/yzx/ebrand/presenter/base/YzxResponse.java 查看文件

@@ -0,0 +1,30 @@
package com.yzx.ebrand.presenter.base;



import com.yzx.ebrand.model.Pager;

import java.io.Serializable;
import java.util.ArrayList;

public class YzxResponse<T> implements Serializable {

private static final long serialVersionUID = 5213230387175987834L;

public int code = -1;
public String msg;
public T data;
public ArrayList<T> list;
public Pager pager;

@Override
public String toString() {
return "YzxResponse{\n" +//
"\tcode=" + code + "\n" +//
"\tmsg='" + msg + "\'\n" +//
"\tdata=" + data + "\n" +//
"\tlist=" + list + "\n" +//
"\tpager=" + pager + "\n" +//
'}';
}
}

+ 21
- 0
app/src/main/java/com/yzx/ebrand/receiver/BootReceiver.kt 查看文件

@@ -0,0 +1,21 @@
package com.yzx.ebrand.receiver

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import com.yzx.ebrand.MainActivity




class BootReceiver :BroadcastReceiver(){
override fun onReceive(context: Context?, intent: Intent?) {
intent?.apply {
if (action.equals("android.intent.action.BOOT_COMPLETED")) {
val i = Intent(context, MainActivity::class.java)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context?.startActivity(i)
}
}
}
}

+ 49
- 0
app/src/main/java/com/yzx/ebrand/utils/FileUpload.kt 查看文件

@@ -0,0 +1,49 @@
package com.yzx.ebrand.utils

import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.Response
import com.yzx.ebrand.model.User
import com.yzx.ebrand.config.YzxInterface
import org.json.JSONObject
import java.io.File

object FileUpload {

fun upload(path: String, callBack: FileUploadCallBack) {
val user = User.getUser()
OkGo.post<String>(YzxInterface.FILE_UPLOAD_URL)
.tag(this)
.params("token", user.token)
.params("user", user.user_id)
.params("file", File(path))
.execute(object : StringCallback() {
override fun onSuccess(response: Response<String>) {
try {
val noteJson = response.body()
val noteJsonObject = JSONObject(noteJson)
val noteContent = noteJsonObject.optString("content")
val noteContentObject = JSONObject(noteContent)
val noteKey = noteContentObject.optString("key")
val noteIdentity = noteContentObject.optString("identity")
callBack.onSuccess(noteIdentity, noteKey)
} catch (e: Exception) {
}
}

override fun onError(response: Response<String>) {
super.onError(response)
callBack.onError("上传失败")
}

override fun onFinish() {
super.onFinish()
}
})
}
}

interface FileUploadCallBack {
fun onSuccess(identity: String, key: String)
fun onError(msg: String)
}

+ 117
- 0
app/src/main/java/com/yzx/ebrand/utils/KotlinX.kt 查看文件

@@ -0,0 +1,117 @@
package com.yzx.ebrand.utils

import android.app.Dialog
import android.view.View
import android.widget.ImageView
import com.blankj.utilcode.util.TimeUtils
import com.bumptech.glide.Glide
import com.yzx.ebrand.R
import java.text.SimpleDateFormat
import java.util.TimeZone

fun ImageView.setSrc(identity: String, key: String) {
val url = "https://${identity.ifEmpty { "filea" }}.oa.qbjjyyun.net/edufile/imageView?uniqueKey=${key}"
Glide.with(this)
.load(url)
.placeholder(R.color.gray_1)
.into(this)
this.setTag(R.id.image_src_tag,url)
}

fun String.getImgUrl(key: String):String{
return "https://${this.ifEmpty { "filea" }}.oa.qbjjyyun.net/edufile/imageView?uniqueKey=${key}"
}

fun ImageView.setSrc(url: String) {
Glide.with(this)
.load(url)
.placeholder(R.color.gray_1)
.into(this)
}

fun Int.toTime(format:String = "yyyy-MM-dd HH:mm"): String {
val format = TimeUtils.getSafeDateFormat(format)
format.timeZone = TimeZone.getTimeZone("GMT+8:00")
return TimeUtils.millis2String(this * 1000L, format)
}

fun Int.toDay(): String {
return toTime("yyyy-MM-dd")
}

fun Int.durationStr(): String {
val value = this
if (value <= 60) {
return "${value}秒"
} else if (value > 60 && value <= 60 * 60) {
var min = value / 60
if (min == 60) {
return "1小时"
}
return "${min}分钟"
} else if (value > 60 * 60 && value <= 24 * 60 * 60) {
var hour = value / 3600.0

if (hour >= 23.5f && hour <25f) {
return "1天"
}

return "${hour.toInt()}小时"
} else {
var day = value / (24 * 60 * 60)
var sub = value % (24 * 60 * 60);
var hour = sub / 3600f
if (hour >= 23.5f || hour <25f) {
return "${day + 1}天"
}
if (hour < 1) {
return "${day}天"
}
return "${day}天${hour.toInt()}小时"
}
}

fun Dialog.hideNavigationBar(){
val window = this.window
window?.apply {
val uiOptions = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
window.decorView.systemUiVisibility = uiOptions
window.decorView.setOnSystemUiVisibilityChangeListener {
window.decorView.systemUiVisibility = uiOptions
}
}
}

fun SimpleDateFormat.zhCn():SimpleDateFormat{
timeZone = TimeZone.getTimeZone("GMT+8:00")
return this
}

























+ 130
- 0
app/src/main/java/com/yzx/ebrand/utils/Monitor.kt 查看文件

@@ -0,0 +1,130 @@
package com.yzx.ebrand.utils

import android.os.Build
import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.SPUtils
import com.google.gson.Gson
import com.lzy.okgo.OkGo
import com.lzy.okgo.callback.StringCallback
import com.lzy.okgo.model.HttpHeaders
import com.lzy.okgo.model.Response
import com.yzx.ebrand.model.User
import java.text.SimpleDateFormat
import java.util.*


object Monitor {
val DT_URL =
"https://oapi.dingtalk.com/robot/send?access_token=886b2c609ddbcc1c8ff80abfd847e9c192bbde80815721204799b0b300cd7418"

fun postDingTalkMsg() {
val monitorText = SPUtils.getInstance().getString("crashData")
if (!monitorText.isBlank()) {
val monitor = MonitorInfo("text", MonitorText(monitorText))
val headers = HttpHeaders()
val json = Gson().toJson(monitor)
headers.put("content-type", "application/json")
OkGo.post<String>(DT_URL)
.tag("")
.headers(headers)
.upJson(json)
.execute(object : StringCallback() {
override fun onSuccess(response: Response<String>?) {
LogUtils.d(json)
LogUtils.d(response)
SPUtils.getInstance().remove("crashData")
}

override fun onError(response: Response<String>?) {
super.onError(response)
LogUtils.d(response)
Thread {
Thread.sleep(3000)
postDingTalkMsg()
}
}
})
}

}

fun saveErrorInfo(
crashType: Int,
errorType: String?,
errorMessage: String?,
errorStack: String?
) {
val monitorText = "crashType:${crashType}\n" +
"errorType:${errorType}\n" +
"errorMessage:${errorMessage}\n" +
"errorStack:\n${errorStack}"
val stringBuffer = StringBuffer()
stringBuffer.append("电子屏异常上报:").append("\n")
stringBuffer.append("系统信息:").append(AppUtils.getAppInfo().versionName).append("\n")
val user = User.getUser()
if (user.user_id > 0) {
stringBuffer.append("用户信息:").append("\n")
.append("user_name:${user.user_name}").append("\n")
.append("user_id:${user.user_id}").append("\n")
.append("phone:${user.phone}").append("\n")
.append("token:${user.token}").append("\n")
}
stringBuffer.append("崩溃时间:")
.append(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date()))
.append("\n")
stringBuffer.append("手机系统:").append(Build.VERSION.RELEASE).append("\n")
stringBuffer.append("手机型号:").append(Build.MODEL).append("\n")
stringBuffer.append("崩溃信息:").append("\n").append(monitorText)
SPUtils.getInstance().put("crashData", stringBuffer.toString())
}

fun postNetError(errorInfo:StringBuilder){
val stringBuffer = StringBuffer()
stringBuffer.append("电子屏异常上报:").append("\n")
stringBuffer.append("异常类型:").append("接口异常").append("\n")
stringBuffer.append("系统信息:").append(AppUtils.getAppInfo().versionName).append("\n")
val user = User.getUser()
if (user.user_id > 0) {
stringBuffer.append("用户信息:").append("\n")
.append("user_name:${user.user_name}").append("\n")
.append("user_id:${user.user_id}").append("\n")
.append("phone:${user.phone}").append("\n")
.append("token:${user.token}").append("\n")
}
stringBuffer.append("请求时间:")
.append(SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date()))
.append("\n")
stringBuffer.append("手机系统:").append(Build.VERSION.RELEASE).append("\n")
stringBuffer.append("手机型号:").append(Build.MODEL).append("\n")
stringBuffer.append(errorInfo)
val monitor = MonitorInfo("text", MonitorText(stringBuffer.toString()))
val headers = HttpHeaders()
val json = Gson().toJson(monitor)
headers.put("content-type", "application/json")
OkGo.post<String>(DT_URL)
.tag("")
.headers(headers)
.upJson(json)
.execute(object : StringCallback() {
override fun onSuccess(response: Response<String>?) {
LogUtils.d(json)
LogUtils.d(response)
}

override fun onError(response: Response<String>?) {
super.onError(response)
LogUtils.d(response)

}
})
}
}

class MonitorInfo(
val msgtype: String = "text",
val text: MonitorText = MonitorText("电子屏异常上报")
)

class MonitorText(val content: String = "")


+ 15
- 0
app/src/main/java/com/yzx/ebrand/utils/YzxFileProvider.kt 查看文件

@@ -0,0 +1,15 @@
package com.yzx.ebrand.utils

import androidx.core.content.FileProvider


/**
* 类名:YzxFileProvider
* 作者:Yun.Lei
* 功能:
* 创建日期:2020年5月6日14:09:27
* 修改人:
* 修改时间:
* 修改备注:
*/
class YzxFileProvider: FileProvider()

+ 39
- 0
app/src/main/java/com/yzx/ebrand/widget/BaseDialog.kt 查看文件

@@ -0,0 +1,39 @@
package com.yzx.ebrand.widget

import android.app.Dialog
import android.content.Context
import android.view.Window
import com.yzx.ebrand.utils.hideNavigationBar

class BaseDialog(context: Context, themeResId: Int, res: Int) : Dialog(context, themeResId) {
private var res: Int = 0
private var leaveId:Int = 0
var showed = false

init {
hideNavigationBar()
requestWindowFeature(Window.FEATURE_NO_TITLE)
setContentView(res)
this.res = res
setCanceledOnTouchOutside(false)
setCancelable(false)
}

fun setLeaveId(id:Int){
leaveId = id
}

fun getLeaveId():Int{
return leaveId
}

override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus)
hideNavigationBar()
}

override fun show() {
hideNavigationBar()
super.show()
}
}

+ 122
- 0
app/src/main/java/com/yzx/ebrand/widget/ChangeDialog.kt 查看文件

@@ -0,0 +1,122 @@
package com.yzx.ebrand.widget

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.yzx.ebrand.R
import com.yzx.ebrand.adapter.ChangeDialogStepAdapter
import com.yzx.ebrand.model.StuChange
import com.yzx.ebrand.model.ViewImage
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toDay
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.find
import org.jetbrains.anko.textColor

/**
* 展示学生请假
*/
class ChangeDialog(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) :
ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {

val adapter: ChangeDialogStepAdapter by lazy {
ChangeDialogStepAdapter(mutableListOf())
}
var onCloseClick: (view:View) -> Unit = {}

init {
val view = LayoutInflater.from(context).inflate(R.layout.dialog_change, null)
val layoutParams = LayoutParams(0, LayoutParams.WRAP_CONTENT)
layoutParams.matchConstraintPercentWidth = 0.8f
layoutParams.topToTop = LayoutParams.PARENT_ID
layoutParams.startToStart = LayoutParams.PARENT_ID
layoutParams.endToEnd = LayoutParams.PARENT_ID
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
view.layoutParams = layoutParams
addView(view)
background = ContextCompat.getDrawable(context, R.color.dialog_bg)
setOnClickListener { } //阻止事件冒泡
}

@SuppressLint("SetTextI18n")
fun setData(detail: StuChange) {
//处理弹窗显示
find<TextView>(R.id.leave_student_name).text = detail.status_change_student_name
if (detail.face_key.isNotEmpty()) {
val img = find<ImageView>(R.id.face_img)
img.setSrc(detail.face_identity, detail.face_key)
img.visibility = View.VISIBLE
find<View>(R.id.face_empty).visibility = View.GONE
} else {
find<View>(R.id.face_empty).visibility = View.VISIBLE
find<View>(R.id.face_img).visibility = View.GONE
}
find<ImageView>(R.id.face_img).setOnClickListener {
EventBus.getDefault().post(ViewImage(detail.id,detail.face_identity,detail.face_key))
}
find<TextView>(R.id.class_name).text = "${detail.grade_name}${detail.class_name}"
find<TextView>(R.id.leave_request_type_name).text = detail.status_change_type_name
find<TextView>(R.id.statusName).text = when (detail.status) {
1 -> "待处理"
2 -> "已确认"
3 -> "已拒绝"
else -> "--"
}
find<TextView>(R.id.statusName).textColor = when (detail.status) {
1 -> Color.parseColor("#333333")
2 -> Color.parseColor("#3c7ef6")
3 -> Color.parseColor("#ff4040")
else -> Color.parseColor("#333333")
}
if (detail.getSubStatusName().isNotEmpty()) {
find<TextView>(R.id.subStatusName).text = "(${detail.getSubStatusName()})"
find<TextView>(R.id.subStatusName).textColor = when (detail.sub_status) {
0, 2 -> Color.parseColor("#ff4040")
1, 3 -> Color.parseColor("#07c160")
else -> Color.parseColor("#333333")
}
} else {
find<TextView>(R.id.subStatusName).text = ""
}
var time = "--"
if (detail.start_time > 0) {
time = detail.start_time.toDay()
}
if (detail.end_time > 0) {
time = "$time -- ${detail.end_time.toDay()}"
}
find<TextView>(R.id.add_time).text = time
if(detail.status_change_reason.isNotEmpty()){
find<View>(R.id.remarkLayout).visibility = View.VISIBLE
find<TextView>(R.id.leave_request_reason).text = detail.status_change_reason
}else{
find<View>(R.id.remarkLayout).visibility = View.GONE
}
find<ImageView>(R.id.statusImg).setSrc(detail.getStatusImg())

find<RecyclerView>(R.id.stepRecycler)
val recyclerView = find<RecyclerView>(R.id.stepRecycler)
recyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = adapter
adapter.setList(detail.getStep())

find<View>(R.id.closeBtn).setOnClickListener {
onCloseClick(this)
}
}
}

+ 100
- 0
app/src/main/java/com/yzx/ebrand/widget/LeaveDialog.kt 查看文件

@@ -0,0 +1,100 @@
package com.yzx.ebrand.widget

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.yzx.ebrand.R
import com.yzx.ebrand.adapter.HomeDialogStepAdapter
import com.yzx.ebrand.model.StuLeave
import com.yzx.ebrand.model.ViewImage
import com.yzx.ebrand.utils.durationStr
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.dialog_leave.view.*
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.find

/**
* 展示学生请假
*/
class LeaveDialog(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) :
ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {

val adapter: HomeDialogStepAdapter by lazy {
HomeDialogStepAdapter(mutableListOf())
}
var onCloseClick: (view:View) -> Unit = {}

init {
val view = LayoutInflater.from(context).inflate(R.layout.dialog_leave, null)
val layoutParams = LayoutParams(0, LayoutParams.WRAP_CONTENT)
layoutParams.matchConstraintPercentWidth = 0.8f
layoutParams.topToTop = LayoutParams.PARENT_ID
layoutParams.startToStart = LayoutParams.PARENT_ID
layoutParams.endToEnd = LayoutParams.PARENT_ID
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
view.layoutParams = layoutParams
addView(view)
background = ContextCompat.getDrawable(context, R.color.dialog_bg)
setOnClickListener { } //阻止事件冒泡
}

@SuppressLint("SetTextI18n")
fun setData(detail: StuLeave) {
leave_student_name.text = detail.leave_student_name
if (detail.face_key.isNotEmpty()) {
val img = find<ImageView>(R.id.face_img)
img.setSrc(detail.face_identity, detail.face_key)
img.visibility = View.VISIBLE
find<View>(R.id.face_empty).visibility = View.GONE
} else {
find<View>(R.id.face_empty).visibility = View.VISIBLE
find<View>(R.id.face_img).visibility = View.GONE
}
find<ImageView>(R.id.face_img).setOnClickListener {
EventBus.getDefault().post(ViewImage(detail.id,detail.face_identity,detail.face_key))
}
find<TextView>(R.id.class_name).text = "${detail.grade_name}${detail.class_name}"
find<TextView>(R.id.leave_request_type_name).text = detail.leave_request_type_name
find<TextView>(R.id.leave_duration_str).text =
(detail.end_time - detail.start_time).durationStr()
find<TextView>(R.id.add_time).text =
"${detail.start_time.toTime()} - ${detail.end_time.toTime()}"
find<TextView>(R.id.leave_request_reason).text = detail.leave_request_reason
find<ImageView>(R.id.statusImg).setSrc(
when (detail.status) {
1 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/stutakeleave_wait.png"
2 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/stutakeleave_pass.png"
3 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/stutakeleave_nopass.png"
4 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/cancellation.png"
5 -> "https://oa-edu-1259243469.cos.ap-chengdu.myqcloud.com/public/mini/cancellation_overtime.png"
else -> ""
}
)

find<RecyclerView>(R.id.stepRecycler)
val recyclerView = find<RecyclerView>(R.id.stepRecycler)
val layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.layoutManager = layoutManager

recyclerView.adapter = adapter
adapter.setList(detail.getStep())
recyclerView.scrollToPosition(adapter.itemCount - 1)
find<View>(R.id.closeBtn).setOnClickListener {
onCloseClick(this)
}
}
}

+ 28
- 0
app/src/main/java/com/yzx/ebrand/widget/TimeView.kt 查看文件

@@ -0,0 +1,28 @@
package com.yzx.ebrand.widget

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.yzx.ebrand.R
import com.yzx.ebrand.model.TimeShow
import kotlinx.android.synthetic.main.view_time.view.*

class TimeView(context: Context, attrs: AttributeSet) :
FrameLayout(context, attrs) {

init {
val view = LayoutInflater.from(context).inflate(R.layout.view_time, null)
addView(view)
}

@SuppressLint("SetTextI18n")
fun setTime(timeShow: TimeShow) {
hour.text = timeShow.hour
min.text = timeShow.min
sec.text = timeShow.sec
week.text = timeShow.week
year.text = "${timeShow.year}年${timeShow.month}月${timeShow.day}日"
}
}

+ 56
- 0
app/src/main/java/com/yzx/ebrand/widget/ViewImageDialog.kt 查看文件

@@ -0,0 +1,56 @@
package com.yzx.ebrand.widget

import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.yzx.ebrand.R
import com.yzx.ebrand.model.ViewImage
import com.yzx.ebrand.utils.setSrc
import kotlinx.android.synthetic.main.dialog_view_img.view.*
import org.jetbrains.anko.find

/**
* 展示大图
*/
class ViewImageDialog(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) :
ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {

var onCloseClick: (view: View) -> Unit = {}
init {
val view = LayoutInflater.from(context).inflate(R.layout.dialog_view_img, null)
val layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
layoutParams.matchConstraintPercentWidth = 0.8f
layoutParams.topToTop = LayoutParams.PARENT_ID
layoutParams.startToStart = LayoutParams.PARENT_ID
layoutParams.endToEnd = LayoutParams.PARENT_ID
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
view.layoutParams = layoutParams
addView(view)
background = ContextCompat.getDrawable(context, R.color.dialog_bg)
setOnClickListener { } //阻止事件冒泡


}

@SuppressLint("SetTextI18n")
fun setData(viewImg: ViewImage) {
// photo_view.setSrc(viewImg.identity,viewImg.key)
// photo_view.setImageResource(R.mipmap.empty)
val img = find<ImageView>(R.id.photo_view)
img.setSrc(viewImg.identity,viewImg.key)
// img.setSrc("https://fileb.oa.qbjjyyun.net/edufile/imageView?uniqueKey=125a4c591c91fbb9f186da8e54cd31aa")
photo_view.setOnClickListener {
onCloseClick(this)
}
}
}

+ 190
- 0
app/src/main/java/com/yzx/ebrand/widget/VisitorDialog.kt 查看文件

@@ -0,0 +1,190 @@
package com.yzx.ebrand.widget

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.yzx.ebrand.R
import com.yzx.ebrand.adapter.VisitorDialogStepAdapter
import com.yzx.ebrand.model.ViewImage
import com.yzx.ebrand.model.Visitor
import com.yzx.ebrand.utils.setSrc
import com.yzx.ebrand.utils.toDay
import com.yzx.ebrand.utils.toTime
import kotlinx.android.synthetic.main.dialog_visitor.view.*
import org.greenrobot.eventbus.EventBus
import org.jetbrains.anko.find
import org.jetbrains.anko.textColor

/**
* 展示访客信息
*/
class VisitorDialog(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
defStyleRes: Int = 0
) :
ConstraintLayout(context, attrs, defStyleAttr, defStyleRes) {

val adapter: VisitorDialogStepAdapter by lazy {
VisitorDialogStepAdapter(mutableListOf())
}
var onCloseClick: (view: View) -> Unit = {}

init {
val view = LayoutInflater.from(context).inflate(R.layout.dialog_visitor, null)
val layoutParams = LayoutParams(0, LayoutParams.WRAP_CONTENT)
layoutParams.matchConstraintPercentWidth = 0.8f
layoutParams.topToTop = LayoutParams.PARENT_ID
layoutParams.startToStart = LayoutParams.PARENT_ID
layoutParams.endToEnd = LayoutParams.PARENT_ID
layoutParams.bottomToBottom = LayoutParams.PARENT_ID
view.layoutParams = layoutParams
addView(view)
background = ContextCompat.getDrawable(context, R.color.dialog_bg)
setOnClickListener { } //阻止事件冒泡
}

@SuppressLint("SetTextI18n", "Range")
fun setData(detail: Visitor) {
//处理弹窗显示
find<TextView>(R.id.userName).text = "${detail.user_name} ${detail.user_phone}"
find<TextView>(R.id.id_card_num).text = "${detail.card_no}"
if (detail.face_key.isNotEmpty()) {
val img = find<ImageView>(R.id.face_img)
img.setSrc(detail.face_identity, detail.face_key)
img.visibility = View.VISIBLE
find<View>(R.id.face_empty).visibility = View.GONE
} else {
find<View>(R.id.face_empty).visibility = View.VISIBLE
find<View>(R.id.face_img).visibility = View.GONE
}
find<ImageView>(R.id.face_img).setOnClickListener {
EventBus.getDefault().post(ViewImage(detail.id, detail.face_identity, detail.face_key))
}
when {
detail.health_code_status >= 0 -> {
healthCodeStatusLayout.visibility = VISIBLE
health_empty.visibility = GONE
health_img.visibility = GONE
when (detail.health_code_status) {
0 -> {
healthCodeStatus.text = "状态:绿码"
healthCodeStatus.textColor = Color.parseColor("#5DAD64")
}
1 -> {
healthCodeStatus.text = "状态:黄码"
healthCodeStatus.textColor = Color.parseColor("#FCCF13")
}
10 -> {
healthCodeStatus.text = "状态:红码"
healthCodeStatus.textColor = Color.parseColor("#FC0416")
}
}
}
detail.health_code_key.isNotEmpty() -> {
healthCodeStatusLayout.visibility = GONE
val img = find<ImageView>(R.id.health_img)
img.setSrc(detail.health_code_identity, detail.health_code_key)
img.visibility = View.VISIBLE
find<View>(R.id.health_empty).visibility = View.GONE
}
else -> {
healthCodeStatusLayout.visibility = GONE
find<View>(R.id.health_empty).visibility = View.VISIBLE
find<View>(R.id.health_img).visibility = View.GONE
}
}
find<ImageView>(R.id.health_img).setOnClickListener {
EventBus.getDefault()
.post(ViewImage(detail.id, detail.health_code_identity, detail.health_code_key))
}
if (detail.trip_code_key.isNotEmpty()) {
val img = find<ImageView>(R.id.trip_img)
img.setSrc(detail.trip_code_identity, detail.trip_code_key)
img.visibility = View.VISIBLE
find<View>(R.id.trip_empty).visibility = View.GONE
} else {
find<View>(R.id.trip_empty).visibility = View.VISIBLE
find<View>(R.id.trip_img).visibility = View.GONE
}
if(detail.nuclein_file_key.isNullOrBlank()){
nuclein_img.visibility = View.GONE
nuclein_empty.visibility = View.VISIBLE
}else{
nuclein_img.visibility = View.VISIBLE
nuclein_empty.visibility = View.GONE
nuclein_img.setSrc(detail.nuclein_file_identity, detail.nuclein_file_key)
}
if(detail.nuclein_time>0){
nucleinStatusLayout.visibility = VISIBLE
nucleinStatus.text = detail.getNucleinStatusObj().nuclein_name
nucleinStatus.setTextColor(Color.parseColor(detail.getNucleinStatusObj().nuclein_color))
}else{
nucleinStatusLayout.visibility = GONE
}
find<ImageView>(R.id.trip_img).setOnClickListener {
EventBus.getDefault()
.post(ViewImage(detail.id, detail.trip_code_identity, detail.trip_code_key))
}
find<ImageView>(R.id.nuclein_img).setOnClickListener {
EventBus.getDefault()
.post(ViewImage(detail.id, detail.nuclein_file_identity, detail.nuclein_file_key))
}
find<TextView>(R.id.reception_user).text = "${detail.reception_user}"
find<TextView>(R.id.visit_reason).text = "${detail.visit_reason}"
find<TextView>(R.id.is_drive).text = when (detail.is_drive) {
1 -> "是"
0 -> "否"
else -> "--"
}
if (detail.is_drive == 1) {
find<View>(R.id.carLayout).visibility = View.VISIBLE
find<View>(R.id.doorLayout).visibility = View.GONE
find<TextView>(R.id.license_plate).text = "${detail.license_plate}"
find<TextView>(R.id.car_in_time).text =
"${detail.car_in_time.toTime()} - ${detail.car_out_time.toTime()}"
} else {
find<View>(R.id.carLayout).visibility = View.GONE
find<View>(R.id.doorLayout).visibility = View.VISIBLE
find<TextView>(R.id.audit_status_str).text = when (detail.audit_status) {
0 -> "待审核"
1 -> "可通行"
2 -> "审核拒绝"
-1 -> "已失效"
else -> "--"
}
find<TextView>(R.id.audit_status_str).textColor = when (detail.audit_status) {
0 -> Color.parseColor("#333333")
1 -> Color.parseColor("#3c7ef6")
2 -> Color.parseColor("#ff4040")
-1 -> Color.parseColor("#999999")
else -> Color.parseColor("#333333")
}
find<TextView>(R.id.start_time).text =
"${detail.start_time.toDay()} - ${detail.end_time.toDay()} 可进出${detail.in_out_num}次"
}

find<ImageView>(R.id.statusImg).setSrc(detail.getStatusImg())

find<RecyclerView>(R.id.stepRecycler)
val recyclerView = find<RecyclerView>(R.id.stepRecycler)
recyclerView.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
recyclerView.adapter = adapter
adapter.setList(detail.getStep())

find<View>(R.id.closeBtn).setOnClickListener {
onCloseClick(this)
}
}
}

+ 26
- 0
app/src/main/java/com/yzx/ebrand/widget/YzxPDFViewPager.kt 查看文件

@@ -0,0 +1,26 @@
package com.yzx.ebrand.widget

import android.content.Context
import android.view.MotionEvent
import es.voghdev.pdfviewpager.library.PDFViewPager

class YzxPDFViewPager(context:Context,path:String):PDFViewPager(context,path){


override fun setCurrentItem(item: Int, smoothScroll: Boolean) {
super.setCurrentItem(item, false)
}

override fun setCurrentItem(item: Int) {
super.setCurrentItem(item,false)
}

override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
return false
}

override fun onTouchEvent(ev: MotionEvent?): Boolean {
return false
}

}

+ 8
- 0
app/src/main/res/anim/rotate_0_to_180.xml 查看文件

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate android:fromDegrees="0"
android:toDegrees="180"
android:pivotX="50%"
android:pivotY="50%"
android:duration="300"/>
</set>

+ 8
- 0
app/src/main/res/anim/rotate_180_to_360.xml 查看文件

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300">
<rotate android:fromDegrees="180"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"/>
</set>

+ 7
- 0
app/src/main/res/anim/slide_bottom_in.xml 查看文件

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="100%"
android:toYDelta="0"
android:duration="400"/>
</set>

+ 7
- 0
app/src/main/res/anim/slide_bottom_out.xml 查看文件

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromYDelta="0"
android:toYDelta="100%"
android:duration="400"/>
</set>

+ 6
- 0
app/src/main/res/anim/slide_left_in.xml 查看文件

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%p"
android:toXDelta="0"
android:duration="500"/>
</set>

部分文件因文件數量過多而無法顯示

Loading…
取消
儲存