├── .gitignore
├── .idea
├── .name
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── dictionaries
│ └── Administrator.xml
├── gradle.xml
├── misc.xml
├── render.experimental.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── we
│ │ └── zxlite
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── we
│ │ │ └── zxlite
│ │ │ ├── GlideModule.kt
│ │ │ ├── activity
│ │ │ ├── AnalyzeActivity.kt
│ │ │ ├── BaseActivity.kt
│ │ │ ├── GuessActivity.kt
│ │ │ ├── InitActivity.kt
│ │ │ ├── LoginActivity.kt
│ │ │ ├── MainActivity.kt
│ │ │ ├── PaperActivity.kt
│ │ │ ├── RegisterActivity.kt
│ │ │ └── ReportActivity.kt
│ │ │ ├── adapter
│ │ │ ├── AnalyzeListAdapter.kt
│ │ │ ├── AnalyzePageAdapter.kt
│ │ │ ├── ExamListAdapter.kt
│ │ │ ├── GuessItemAdapter.kt
│ │ │ ├── ReportItemAdapter.kt
│ │ │ └── ReportPageAdapter.kt
│ │ │ ├── bean
│ │ │ ├── AnalyzeListBean.kt
│ │ │ ├── AnalyzePageBean.kt
│ │ │ ├── ReportListBean.kt
│ │ │ ├── ReportPageBean.kt
│ │ │ └── UserConfigBean.kt
│ │ │ ├── dialog
│ │ │ ├── AboutDialog.kt
│ │ │ ├── AccountDialog.kt
│ │ │ ├── BaseAlertDialog.kt
│ │ │ ├── BaseSheetDialog.kt
│ │ │ ├── BindDialog.kt
│ │ │ ├── ModifyDialog.kt
│ │ │ └── SelectFriendsDialog.kt
│ │ │ ├── utils
│ │ │ ├── BaseUtils.kt
│ │ │ ├── GetterUtils.kt
│ │ │ ├── HttpUtils.kt
│ │ │ ├── SqlUtils.kt
│ │ │ └── UserUtils.kt
│ │ │ └── view
│ │ │ ├── ProgressBar.kt
│ │ │ ├── ScoreChart.kt
│ │ │ └── ShadowView.kt
│ └── res
│ │ ├── drawable
│ │ ├── edit_line.xml
│ │ ├── ic_arrow.xml
│ │ ├── ic_arrow_back.xml
│ │ ├── ic_launcher.xml
│ │ ├── ic_launcher_foreground.xml
│ │ ├── nav_text_color.xml
│ │ ├── shadow_btm.xml
│ │ └── shadow_top.xml
│ │ ├── layout
│ │ ├── activity_analyze.xml
│ │ ├── activity_guess.xml
│ │ ├── activity_init.xml
│ │ ├── activity_login.xml
│ │ ├── activity_main.xml
│ │ ├── activity_paper.xml
│ │ ├── activity_register.xml
│ │ ├── activity_report.xml
│ │ ├── dialog_about.xml
│ │ ├── dialog_bind.xml
│ │ ├── dialog_modify.xml
│ │ ├── fragment_analyze.xml
│ │ ├── fragment_report.xml
│ │ ├── fragment_report_general.xml
│ │ ├── header_main.xml
│ │ ├── item_analyze.xml
│ │ ├── item_general.xml
│ │ ├── item_guess.xml
│ │ ├── item_report.xml
│ │ └── item_tab.xml
│ │ ├── menu
│ │ ├── menu_main.xml
│ │ └── menu_report.xml
│ │ ├── mipmap-anydpi-v26
│ │ ├── ic_launcher.xml
│ │ └── ic_launcher_round.xml
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ └── values
│ │ ├── attrs.xml
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── we
│ └── zxlite
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | 智学网
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | xmlns:android
20 |
21 | ^$
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | xmlns:.*
31 |
32 | ^$
33 |
34 |
35 | BY_NAME
36 |
37 |
38 |
39 |
40 |
41 |
42 | .*:id
43 |
44 | http://schemas.android.com/apk/res/android
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | .*:name
54 |
55 | http://schemas.android.com/apk/res/android
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | name
65 |
66 | ^$
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | style
76 |
77 | ^$
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | .*
87 |
88 | ^$
89 |
90 |
91 | BY_NAME
92 |
93 |
94 |
95 |
96 |
97 |
98 | .*
99 |
100 | http://schemas.android.com/apk/res/android
101 |
102 |
103 | ANDROID_ATTRIBUTE_ORDER
104 |
105 |
106 |
107 |
108 |
109 |
110 | .*
111 |
112 | .*
113 |
114 |
115 | BY_NAME
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/dictionaries/Administrator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | authbizcode
5 | authguid
6 | authtimestamp
7 | authtoken
8 | choo
9 | dandroid
10 | dapp
11 | disp
12 | dtos
13 | fcgi
14 | ffrom
15 | iflytek
16 | knowledges
17 | mqqopensdkapi
18 | passwd
19 | pressenter
20 | recyclerview
21 | zxlite
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/render.experimental.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 智学网Lite
2 | ### 更新日志
3 | * 优化登录失败逻辑
4 | * 修复阴影显示问题
5 | * 新增题目解析
6 | * 新增全科显示
7 | * 新增好友伴学
8 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | apply plugin: 'kotlin-android'
4 |
5 | apply plugin: 'kotlin-kapt'
6 |
7 | apply plugin: 'kotlin-android-extensions'
8 |
9 | android {
10 | compileSdkVersion 29
11 | buildToolsVersion "29.0.2"
12 | defaultConfig {
13 | applicationId "we.zxlite"
14 | minSdkVersion 15
15 | targetSdkVersion 29
16 | versionCode 1
17 | versionName "1.0"
18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
19 | }
20 | buildTypes {
21 | release {
22 | minifyEnabled true
23 | zipAlignEnabled true
24 | shrinkResources true
25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 | }
29 |
30 | dependencies {
31 | implementation fileTree(dir: 'libs', include: ['*.jar'])
32 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
33 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinx_version"
34 | implementation "org.jetbrains.anko:anko-sqlite:$anko_version"
35 | implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'
36 | implementation 'com.github.bumptech.glide:glide:4.9.0'
37 | implementation 'com.google.android.material:material:1.2.0-alpha01'
38 | implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03'
39 | implementation 'androidx.appcompat:appcompat:1.1.0'
40 | implementation 'androidx.core:core-ktx:1.1.0'
41 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
42 | testImplementation 'junit:junit:4.12'
43 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
44 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
45 | kapt 'com.github.bumptech.glide:compiler:4.9.0'
46 | }
47 |
48 | repositories {
49 | maven { url 'https://jitpack.io' }
50 | }
51 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/we/zxlite/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite
2 |
3 | import androidx.test.platform.app.InstrumentationRegistry
4 | import androidx.test.ext.junit.runners.AndroidJUnit4
5 |
6 | import org.junit.Test
7 | import org.junit.runner.RunWith
8 |
9 | import org.junit.Assert.*
10 |
11 | /**
12 | * Instrumented test, which will execute on an Android device.
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | @RunWith(AndroidJUnit4::class)
17 | class ExampleInstrumentedTest {
18 | @Test
19 | fun useAppContext() {
20 | // Context of the app under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("we.zxlite", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
14 |
17 |
20 |
23 |
26 |
29 |
32 |
35 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/GlideModule.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite
2 |
3 | import android.content.Context
4 | import android.graphics.drawable.Drawable
5 | import com.bumptech.glide.GlideBuilder
6 | import com.bumptech.glide.annotation.GlideModule
7 | import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade
8 | import com.bumptech.glide.module.AppGlideModule
9 |
10 | @GlideModule
11 | class GlideModule : AppGlideModule() {
12 | override fun applyOptions(ctx: Context, builder: GlideBuilder) {
13 | super.applyOptions(ctx, builder)
14 | builder.setDefaultTransitionOptions(Drawable::class.java, withCrossFade()) //增加渐变动画
15 | }
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/AnalyzeActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.graphics.Color.RED
4 | import android.os.Bundle
5 | import android.view.View
6 | import android.widget.TextView
7 | import com.google.android.material.tabs.TabLayoutMediator
8 | import com.google.android.material.tabs.TabLayoutMediator.TabConfigurationStrategy
9 | import kotlinx.android.synthetic.main.activity_analyze.*
10 | import kotlinx.coroutines.Dispatchers.Main
11 | import kotlinx.coroutines.launch
12 | import kotlinx.coroutines.withContext
13 | import org.jetbrains.anko.toast
14 | import org.json.JSONObject
15 | import we.zxlite.R
16 | import we.zxlite.adapter.AnalyzePageAdapter
17 | import we.zxlite.bean.AnalyzePageBean
18 | import we.zxlite.utils.BaseUtils.color
19 | import we.zxlite.utils.HttpUtils.Error
20 | import we.zxlite.utils.HttpUtils.Type.JsonObject
21 | import we.zxlite.utils.HttpUtils.api
22 | import kotlin.Comparator
23 | import kotlin.collections.ArrayList
24 |
25 | class AnalyzeActivity : BaseActivity() {
26 |
27 | companion object {
28 | //解析URL
29 | private const val ANALYZE_URL =
30 | "https://www.zhixue.com/zhixuebao/report/getPaperAnalysis"
31 | //原卷id
32 | private const val PAPER_ID = "paperId"
33 | // 类型主题分析
34 | private const val TYPE_TOPIC = "typeTopicAnalysis"
35 | //主题分析
36 | private const val TYPE_DTOS = "topicAnalysisDTOs"
37 | //题号
38 | private const val DIS_TITLE_NUMBER = "disTitleNumber"
39 | //答案类型
40 | private const val ANSWER_TYPE = "answerType"
41 | //答案Html
42 | private const val ANALYSIS_HTML = "analysisHtml"
43 | //答案Html
44 | private const val ANSWER_HTML = "answerHtml"
45 | //题头
46 | private const val TOPIC_NUMBER = "topicNumber"
47 | //主题id
48 | private const val TOPIC_ID = "topicId"
49 | //主题id
50 | private const val TOPIC_SET_ID = "topicSetId"
51 | //主题分数
52 | private const val TOPIC_SCORE_DTOS = "topicScoreDTOs"
53 | //标准答案
54 | private const val STANDARD_ANSWER = "standardAnswer"
55 | //用户答案
56 | private const val USER_ANSWER = "userAnswer"
57 | //用户答案
58 | private const val USER_ANSWERS = "userAnswers"
59 | //图像答案
60 | private const val IMAGE_ANSWER = "imageAnswer"
61 | //标准分数
62 | private const val STANDARD_SCORE = "standardScore"
63 | //分数
64 | private const val SCORE = "score"
65 | //题目
66 | private const val CONTENT_HTML = "contentHtml"
67 | //知识点
68 | private const val KNOWLEDGE_GROUPS = "relatedKnowledgeGroups"
69 | }
70 |
71 | //解析页列表
72 | private val analyzePageList = ArrayList()
73 | //解析参数
74 | private val analyzeParams get() = "?paperId=${intent.getStringExtra(PAPER_ID)}"
75 |
76 | override fun onCreate(savedInstanceState: Bundle?) {
77 | super.onCreate(savedInstanceState)
78 | setContentView(R.layout.activity_analyze)
79 | loadAnalyze()
80 | }
81 |
82 | override fun initView() {
83 | setSupportActionBar(analyzeBar)
84 | analyzeBar.setNavigationOnClickListener { onBackPressed() }
85 | analyzePager.adapter = AnalyzePageAdapter(analyzePageList)
86 | analyzePager.offscreenPageLimit = 3
87 | TabLayoutMediator(analyzeTab, analyzePager, TabConfigurationStrategy { tab, position ->
88 | val tabView = View.inflate(this, R.layout.item_tab, null) as TextView
89 | tabView.text = analyzePageList[position].disTitleNumber
90 | when {
91 | analyzePageList[position].score == analyzePageList[position].standardScore ->
92 | tab.tag = 0
93 | analyzePageList[position].score == 0.0 -> {
94 | tab.tag = 1
95 | tabView.setTextColor(RED)
96 | }
97 | else -> {
98 | tab.tag = 2
99 | tabView.setTextColor(color(R.color.colorDeepYellow))
100 | }
101 | }
102 | tab.customView = tabView
103 | }).attach()
104 | }
105 |
106 | private fun loadAnalyze() {
107 | launch {
108 | api(ANALYZE_URL + analyzeParams, null, true, JsonObject).let {
109 | if (it is JSONObject) {
110 | val topicAnalysis = it.optJSONArray(TYPE_TOPIC)
111 | for (i in 0 until topicAnalysis!!.length()) {
112 | val topicDTOs =
113 | topicAnalysis.optJSONObject(i).optJSONArray(TYPE_DTOS)
114 | for (dto in 0 until topicDTOs!!.length()) {
115 | val topic = topicDTOs.optJSONObject(dto)
116 | analyzePageList.add(
117 | AnalyzePageBean(
118 | disTitleNumber = topic.optString(DIS_TITLE_NUMBER),
119 | topicNumber = topic.optInt(TOPIC_NUMBER),
120 | topicScoreDTOs = topic.optString(TOPIC_SCORE_DTOS),
121 | topicId = topic.optString(TOPIC_ID),
122 | topicSetId = topic.optString(TOPIC_SET_ID),
123 | analysisHtml = topic.optString(ANALYSIS_HTML),
124 | contentHtml = topic.optString(CONTENT_HTML),
125 | answerType = topic.optString(ANSWER_TYPE),
126 | answerHtml = topic.optString(ANSWER_HTML),
127 | standardAnswer = topic.optString(STANDARD_ANSWER),
128 | standardScore = topic.optDouble(STANDARD_SCORE),
129 | score = topic.optDouble(SCORE),
130 | userAnswer = topic.optString(USER_ANSWER),
131 | userAnswers = topic.optString(USER_ANSWERS),
132 | imageAnswers = topic.optString(IMAGE_ANSWER),
133 | relatedKnowledgeGroups = topic.optString(KNOWLEDGE_GROUPS)
134 | )
135 | )
136 | }
137 | }
138 | analyzePageList.sortWith(Comparator { o1, o2 ->
139 | if (o1.topicNumber > o2.topicNumber) 1 else -1
140 | })
141 | withContext(Main) {
142 | analyzePager.adapter!!.notifyItemRangeInserted(0, analyzePageList.size)
143 | }
144 | } else toast((it as Error).message)
145 | }
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.os.Build.VERSION.SDK_INT
4 | import android.os.Build.VERSION_CODES.LOLLIPOP
5 | import android.os.Build.VERSION_CODES.M
6 | import android.os.Bundle
7 | import android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
8 | import android.view.Window
9 | import androidx.appcompat.app.AppCompatActivity
10 | import kotlinx.coroutines.CoroutineScope
11 | import kotlinx.coroutines.MainScope
12 | import kotlinx.coroutines.cancel
13 | import we.zxlite.R
14 | import we.zxlite.utils.BaseUtils.color
15 |
16 | abstract class BaseActivity : AppCompatActivity(), CoroutineScope by MainScope() {
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | window.initStatusBar()
21 | }
22 |
23 | override fun setContentView(layoutResID: Int) {
24 | super.setContentView(layoutResID)
25 | initView()
26 | }
27 |
28 | override fun onDestroy() {
29 | super.onDestroy()
30 | cancel()
31 | }
32 |
33 | /** 初始化状态栏
34 | * Android 6.0 白底黑字状态栏
35 | * Android 5.0 暗色状态栏
36 | */
37 | private fun Window.initStatusBar() {
38 | if (SDK_INT >= M) {
39 | decorView.systemUiVisibility = SYSTEM_UI_FLAG_LIGHT_STATUS_BAR
40 | } else if (SDK_INT >= LOLLIPOP) {
41 | statusBarColor = color(R.color.colorGreyBar)
42 | }
43 | }
44 |
45 | /** 初始化界面 */
46 | abstract fun initView()
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/GuessActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.os.Bundle
4 | import kotlinx.android.synthetic.main.activity_guess.*
5 | import kotlinx.coroutines.Dispatchers.Main
6 | import kotlinx.coroutines.launch
7 | import kotlinx.coroutines.withContext
8 | import org.jetbrains.anko.toast
9 | import org.json.JSONArray
10 | import org.json.JSONObject
11 | import we.zxlite.R
12 | import we.zxlite.adapter.GuessItemAdapter
13 | import we.zxlite.dialog.SelectFriendsDialog
14 | import we.zxlite.utils.BaseUtils.EMPTY_STR
15 | import we.zxlite.utils.HttpUtils.Error
16 | import we.zxlite.utils.HttpUtils.Type.JsonObject
17 | import we.zxlite.utils.HttpUtils.Type.JsonArray
18 | import we.zxlite.utils.HttpUtils.api
19 | import we.zxlite.utils.UserUtils.cfg
20 |
21 | class GuessActivity : BaseActivity() {
22 |
23 | companion object {
24 | //获取好友
25 | private const val FRIENDS_URL = "https://app.zhixue.com/study/social/t/getFriends?"
26 | //获取分数
27 | private const val GUESS_URL = "https://app.zhixue.com/study/social/getGuessScore"
28 | //获取班级
29 | private const val GRADE_URL = "https://www.zhixue.com/zhixuebao/studentPK/getClazzByGradeId"
30 | //获取同学
31 | private const val CLAZZ_URL =
32 | "https://www.zhixue.com/zhixuebao/studentPK/getStudentByClazzId"
33 |
34 | private const val SUBJECT_LIST = "subjectList"
35 | private const val SUBJECT_CODE = "subjectCode"
36 | private const val STUDENT_PK_DTOS = "studentPKDTOs"
37 | private const val EXAM_ID = "examId"
38 | private const val FRIENDS = "friends"
39 | private const val USER_NAME = "userName"
40 | private const val USER_ID = "userId"
41 | private const val NAME_LIST = "nameList"
42 | private const val IS_SELF = "isSelf"
43 | private const val CLAZZ_ID = "clazzId"
44 | private const val STUDENT_ID = "studentId"
45 | private const val STUDENT_NAME = "studentName"
46 | }
47 |
48 | private var friendsId = mutableListOf()
49 | private var friendsName = mutableListOf()
50 |
51 | private var mList = mutableMapOf()
52 | private var fList = mutableMapOf()
53 |
54 | override fun onCreate(savedInstanceState: Bundle?) {
55 | super.onCreate(savedInstanceState)
56 | setContentView(R.layout.activity_guess)
57 | loadFriends()
58 | }
59 |
60 | override fun initView() {
61 | setSupportActionBar(guessBar)
62 | guessBar.setNavigationOnClickListener { onBackPressed() }
63 | guessRecycler.adapter = GuessItemAdapter(mList, fList)
64 | guessSelect.setOnClickListener {
65 | if (friendsId.isNotEmpty() && friendsName.isNotEmpty()) SelectFriendsDialog { i ->
66 | mList.clear()
67 | fList.clear()
68 | guessSelectText.text = friendsName[i]
69 | guessRecycler.adapter!!.notifyDataSetChanged()
70 | loadScores(i)
71 | }.apply {
72 | arguments = Bundle().apply { putStringArray(NAME_LIST, friendsName.toTypedArray()) }
73 | }.show(supportFragmentManager, EMPTY_STR)
74 | else toast(R.string.noFriends)
75 | }
76 | guessSelect.setOnLongClickListener {
77 | toast(R.string.toastWait)
78 | launch {
79 | api(GRADE_URL, "token=${cfg.serviceToken}", true, JsonArray).let {
80 | if (it is JSONArray)
81 | for (i in 0 until it.length()) {
82 | val clazz = it.optJSONObject(i)
83 | if (clazz.optBoolean(IS_SELF))
84 | return@let clazz.optString(CLAZZ_ID)
85 | } else null
86 | }?.let {
87 | api(CLAZZ_URL, "clazzId=$it&token=${cfg.serviceToken}", true, JsonArray).run {
88 | if (this is JSONArray) {
89 | friendsId.clear()
90 | friendsName.clear()
91 | for (i in 0 until length()) {
92 | val friends = optJSONObject(i).optJSONArray(FRIENDS)
93 | for (f in 0 until friends!!.length()) {
94 | val friend = friends.optJSONObject(f)
95 | friendsId.add(f, friend.optString(STUDENT_ID))
96 | friendsName.add(f, friend.optString(STUDENT_NAME))
97 | }
98 | }
99 | withContext(Main) {
100 | toast(R.string.addSuccess)
101 | }
102 | }
103 | }
104 | }
105 | }
106 | return@setOnLongClickListener true
107 | }
108 | }
109 |
110 | private fun loadScores(position: Int) {
111 | launch {
112 | val guessParams =
113 | "examId=${intent.getStringExtra(EXAM_ID)}&guessUserId=${friendsId[position]}"
114 | api(GUESS_URL, guessParams, true, JsonObject).let {
115 | if (it is JSONObject) {
116 | val dtos = it.optJSONArray(STUDENT_PK_DTOS)
117 | if (dtos != null) {
118 | val mScores = dtos.optJSONObject(0).optJSONArray(SUBJECT_LIST)
119 | for (i in 0 until mScores!!.length()) {
120 | mList[i] = mScores.optJSONObject(i)
121 | }
122 |
123 | val fScores = dtos.optJSONObject(1).optJSONArray(SUBJECT_LIST)
124 | for (i in 0 until fScores!!.length()) {
125 | val json = fScores.optJSONObject(i)
126 | val code = json.optString(SUBJECT_CODE, "0")
127 | fList[code] = json
128 | }
129 |
130 | withContext(Main) {
131 | guessRecycler.adapter!!.notifyItemRangeInserted(0, mList.size)
132 | }
133 | } else Unit
134 | } else withContext(Main) {
135 | toast((it as Error).message)
136 | }
137 | }
138 | }
139 | }
140 |
141 | private fun loadFriends() {
142 | launch {
143 | api(FRIENDS_URL, null, true, JsonObject).let {
144 | if (it is JSONObject) {
145 | val friendArray = it.optJSONArray(FRIENDS)
146 | for (i in 0 until friendArray!!.length()) {
147 | val friend = friendArray.optJSONObject(i)
148 | friendsId.add(i, friend.optString(USER_ID))
149 | friendsName.add(i, friend.optString(USER_NAME))
150 | }
151 | }
152 | }
153 | }
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/InitActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.os.Bundle
4 | import kotlinx.coroutines.Dispatchers.Main
5 | import kotlinx.coroutines.launch
6 | import kotlinx.coroutines.withContext
7 | import org.jetbrains.anko.startActivity
8 | import we.zxlite.R
9 | import we.zxlite.utils.UserUtils.login
10 | import we.zxlite.utils.UserUtils.updateConfig
11 |
12 | class InitActivity : BaseActivity() {
13 |
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContentView(R.layout.activity_init)
17 | }
18 |
19 | override fun initView() {
20 | launch {
21 | updateConfig()
22 | withContext(Main) {
23 | if (login()) startActivity() else startActivity()
24 | finish()
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/LoginActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.os.Bundle
4 | import android.text.Editable
5 | import android.text.TextWatcher
6 | import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_SHORT
7 | import com.google.android.material.snackbar.Snackbar
8 | import kotlinx.android.synthetic.main.activity_login.*
9 | import kotlinx.coroutines.Dispatchers.Main
10 | import kotlinx.coroutines.launch
11 | import kotlinx.coroutines.withContext
12 | import org.jetbrains.anko.browse
13 | import org.jetbrains.anko.db.replace
14 | import org.jetbrains.anko.db.select
15 | import org.jetbrains.anko.startActivity
16 | import we.zxlite.R
17 | import we.zxlite.utils.BaseUtils.EMPTY_STR
18 | import we.zxlite.utils.BaseUtils.db
19 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_NAME
20 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_VALUE
21 | import we.zxlite.utils.SqlUtils.Helper.Companion.SELECT_USER
22 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_CFG
23 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_RMB
24 | import we.zxlite.utils.UserUtils.login
25 |
26 | class LoginActivity : BaseActivity() {
27 |
28 | companion object {
29 | private const val FORGET_URL =
30 | "http://pass.changyan.com/forget?customConfig=e3ZpZXdfdHlwZTogIkg1IixoaWRkZW5fbW9kdWxlOiAiZm9yZ2V0QWNjb3VudCIsbG9nbzoiemhpeHVlIix0aGVtZToiZ3JlZW4iLGNhbGxiYWNrX3R5cGU6InBvc3RNZXNzYWdlIixsb2dpbl90eXBlOiJtYW51YWwifQ==" //忘记密码
31 | }
32 |
33 | private val logUserName //获取编辑框账号参数
34 | get() = loginUsername.text.toString()
35 |
36 | private val logUserPwd //获取编辑框密码参数
37 | get() = loginPassword.text.toString()
38 |
39 | override fun onCreate(savedInstanceState: Bundle?) {
40 | super.onCreate(savedInstanceState)
41 | setContentView(R.layout.activity_login)
42 | }
43 |
44 | override fun initView() {
45 | loginUsername.addTextChangedListener(object : TextWatcher {
46 | override fun afterTextChanged(s: Editable) {
47 | if (s.length > 6) db.use {
48 | select(TABLE_RMB, ITEM_VALUE)
49 | .whereSimple("$ITEM_NAME = '${logUserName}'")
50 | .exec { if (moveToFirst()) getString(0) else EMPTY_STR }
51 | .let { loginPassword.setText(it) }
52 | }
53 | }
54 |
55 | override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
56 |
57 | override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
58 | })
59 | loginForget.setOnClickListener { browse(FORGET_URL) }
60 | loginReg.setOnClickListener { startActivity() }
61 | loginBtn.setOnClickListener { onLogin() }
62 | db.use {
63 | select(TABLE_CFG, ITEM_VALUE)
64 | .whereSimple("$ITEM_NAME = '$SELECT_USER'")
65 | .exec { if (moveToFirst()) loginUsername.setText(getString(0)) else null }
66 | }
67 | }
68 |
69 | /**检查登录参数
70 | * @param loginName 用户名
71 | * @param loginPwd 用户密码
72 | */
73 | private fun onLogin(loginName: String = logUserName, loginPwd: String = logUserPwd) {
74 | loginBtn.isEnabled = false
75 | launch {
76 | if (login(loginName, loginPwd)) {
77 | db.use {
78 | replace(TABLE_RMB, ITEM_NAME to loginName, ITEM_VALUE to loginPwd)
79 | replace(TABLE_CFG, ITEM_NAME to SELECT_USER, ITEM_VALUE to loginName)
80 | }
81 | withContext(Main) {
82 | startActivity()
83 | finish()
84 | }
85 | } else withContext(Main) {
86 | loginBtn.isEnabled = true
87 | Snackbar.make(loginBtn, R.string.loginFailed, LENGTH_SHORT).show()
88 | }
89 | }
90 | }
91 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.os.Bundle
4 | import android.view.MenuItem
5 | import androidx.appcompat.app.ActionBarDrawerToggle
6 | import com.google.android.material.internal.NavigationMenuView
7 | import com.google.android.material.navigation.NavigationView
8 | import com.google.android.material.snackbar.BaseTransientBottomBar.*
9 | import com.google.android.material.snackbar.Snackbar
10 | import kotlinx.android.synthetic.main.activity_main.*
11 | import kotlinx.android.synthetic.main.header_main.view.*
12 | import org.jetbrains.anko.db.delete
13 | import org.jetbrains.anko.db.replace
14 | import org.jetbrains.anko.db.select
15 | import org.jetbrains.anko.startActivity
16 | import we.zxlite.R
17 | import we.zxlite.dialog.BindDialog
18 | import we.zxlite.dialog.ModifyDialog
19 | import we.zxlite.utils.BaseUtils.EMPTY_STR
20 | import we.zxlite.utils.BaseUtils.db
21 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_NAME
22 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_VALUE
23 | import we.zxlite.utils.SqlUtils.Helper.Companion.REPORT_TYPE
24 | import we.zxlite.utils.SqlUtils.Helper.Companion.SELECT_USER
25 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_CFG
26 | import we.zxlite.utils.UserUtils.cfg
27 | import android.content.Intent
28 | import android.net.Uri
29 | import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
30 | import kotlinx.coroutines.Dispatchers.Main
31 | import kotlinx.coroutines.launch
32 | import kotlinx.coroutines.withContext
33 | import org.jetbrains.anko.email
34 | import org.json.JSONObject
35 | import we.zxlite.adapter.ExamListAdapter
36 | import we.zxlite.adapter.ExamListAdapter.ItemDecoration
37 | import we.zxlite.bean.ReportListBean
38 | import we.zxlite.dialog.AboutDialog
39 | import we.zxlite.dialog.AccountDialog
40 | import we.zxlite.utils.HttpUtils.Error
41 | import we.zxlite.utils.HttpUtils.Type.JsonObject
42 | import we.zxlite.utils.HttpUtils.api
43 |
44 | class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener,
45 | SwipeRefreshLayout.OnRefreshListener {
46 |
47 | companion object {
48 | //考试报告
49 | private const val EXAM_TYPE = "EXAM_TYPE"
50 | //作业报告
51 | private const val HOMEWORK_TYPE = "HOMEWORK_TYPE"
52 | //考试列表
53 | private const val EXAM_INFO_LIST = "examInfoList"
54 | //考试id
55 | private const val EXAM_ID = "examId"
56 | //考试名称
57 | private const val EXAM_NAME = "examName"
58 | //考试时间
59 | private const val CREATE_TIME = "examCreateDateTime"
60 | //考试
61 | private const val EXAM = "exam"
62 | //作业
63 | private const val HOMEWORK = "homework"
64 | //页面列表
65 | private const val LIST_URL = "https://www.zhixue.com/zhixuebao/report/getPageExamList"
66 |
67 | private const val QQ_GROUP =
68 | "mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D668tQMrX050v9ChooYRBaRA137b5YbOb"
69 | }
70 |
71 | //报告类型
72 | private val reportType get() = if (mainNav.checkedItem!!.itemId == R.id.menuReportExam) EXAM else HOMEWORK
73 | //报告列表
74 | private val reportList = ArrayList()
75 | //报告页码
76 | private val reportIndex get() = reportList.size / 10 + 1
77 | //报告参数
78 | private val reportParams get() = "reportType=$reportType&pageIndex=$reportIndex&pageSize=10&actualPosition=0"
79 |
80 | override fun onCreate(savedInstanceState: Bundle?) {
81 | super.onCreate(savedInstanceState)
82 | setContentView(R.layout.activity_main)
83 | loadList()
84 | }
85 |
86 | override fun initView() {
87 | setSupportActionBar(mainBar)
88 | val toggle =
89 | ActionBarDrawerToggle(this, mainDrawer, mainBar, R.string.appName, R.string.appName)
90 | val menuView = mainNav.getChildAt(0) as NavigationMenuView
91 | mainDrawer.addDrawerListener(toggle)
92 | toggle.syncState()
93 | menuView.isVerticalScrollBarEnabled = false
94 | mainNav.getHeaderView(0).headerTitle.text = cfg.curName
95 | db.use {
96 | select(TABLE_CFG, ITEM_VALUE)
97 | .whereSimple("$ITEM_NAME = '$REPORT_TYPE'")
98 | .exec { if (moveToFirst()) getString(0) else EXAM_TYPE }
99 | .let { mainNav.setCheckedItem(if (it == EXAM_TYPE) R.id.menuReportExam else R.id.menuReportHomework) }
100 | }
101 | mainNav.setNavigationItemSelectedListener(this)
102 | mainRefresh.setOnRefreshListener(this)
103 | mainFab.setOnClickListener { if (!mainRefresh.isRefreshing) loadList() }
104 | mainRecycler.addItemDecoration(ItemDecoration())
105 | mainRecycler.adapter = ExamListAdapter(reportList) { examId, examName ->
106 | startActivity(EXAM_ID to examId, EXAM_NAME to examName)
107 | }
108 | }
109 |
110 | override fun onNavigationItemSelected(item: MenuItem): Boolean {
111 | when (item.itemId) {
112 | R.id.menuReportExam -> changeReportType(EXAM_TYPE, item)
113 | R.id.menuReportHomework -> changeReportType(HOMEWORK_TYPE, item)
114 | R.id.menuUpdate -> onUpdate()
115 | R.id.menuLogout -> onLogout()
116 | R.id.menuFeedback -> onFeedback()
117 | R.id.menuSwitchAccount -> AccountDialog().show(supportFragmentManager, EMPTY_STR)
118 | R.id.menuAbout -> AboutDialog().show(supportFragmentManager, EMPTY_STR)
119 | R.id.menuBindMobile -> BindDialog().show(supportFragmentManager, EMPTY_STR)
120 | R.id.menuModifyPwd -> ModifyDialog().show(supportFragmentManager, EMPTY_STR)
121 | else -> Unit
122 | }
123 | return true
124 | }
125 |
126 | override fun onRefresh() {
127 | if (reportList.size == 0) loadList() else mainRefresh.isRefreshing = false
128 | }
129 |
130 | /** 改变报告类型
131 | * @param type 报告类型
132 | * @param item 菜单项
133 | */
134 | private fun changeReportType(type: String, item: MenuItem) {
135 | db.use { replace(TABLE_CFG, ITEM_NAME to REPORT_TYPE, ITEM_VALUE to type) }
136 | mainNav.setCheckedItem(item)
137 | mainFab.hide()
138 | mainDrawer.closeDrawers()
139 | mainRecycler.adapter!!.notifyItemRangeRemoved(0, reportList.size)
140 | reportList.clear()
141 | loadList()
142 | }
143 |
144 | /** 加载报告 */
145 | private fun loadList() {
146 | mainRefresh.isRefreshing = true
147 | launch {
148 | api(LIST_URL, reportParams, true, JsonObject).let {
149 | if (it is JSONObject) {
150 | val listOldSize = reportList.size
151 | val examInfoList = it.optJSONArray(EXAM_INFO_LIST)
152 | for (i in 0 until examInfoList!!.length()) {
153 | val item = examInfoList.optJSONObject(i)
154 | reportList.add(
155 | ReportListBean(
156 | examId = item.optString(EXAM_ID),
157 | examName = item.optString(EXAM_NAME),
158 | examCreateTime = item.optLong(CREATE_TIME)
159 | )
160 | )
161 | }
162 | withContext(Main) {
163 | if (reportList.size % 10 == 0) mainFab.show() else mainFab.hide()
164 | mainRefresh.isRefreshing = false
165 | mainRecycler.adapter!!.notifyItemRangeInserted(
166 | listOldSize,
167 | reportList.size - listOldSize
168 | )
169 | }
170 | } else if (it is Error) withContext(Main) {
171 | mainRefresh.isRefreshing = false
172 | Snackbar.make(mainDrawer, it.message, LENGTH_SHORT).show()
173 | }
174 | }
175 | }
176 | }
177 |
178 | /** 意见反馈 */
179 | private fun onFeedback() {
180 | Snackbar
181 | .make(mainDrawer, R.string.toastFeedback, LENGTH_LONG)
182 | .setAction(R.string.actionConfirm) {
183 | if (!email("mail-westudio@gmail.com", "智学网Lite意见反馈")) {
184 | Snackbar.make(mainDrawer, R.string.invokeMailFailed, LENGTH_SHORT).show()
185 | }
186 | }
187 | .show()
188 | }
189 |
190 | /** 检测更新 */
191 | private fun onUpdate() {
192 | Snackbar
193 | .make(mainDrawer, R.string.toastUpdate, LENGTH_LONG)
194 | .setAction(R.string.actionConfirm) {
195 | try {
196 | startActivity(Intent().apply { data = Uri.parse(QQ_GROUP) })
197 | } catch (e: Exception) {
198 | Snackbar.make(mainDrawer, R.string.invokeQQFailed, LENGTH_SHORT).show()
199 | }
200 | }
201 | .show()
202 | }
203 |
204 | /** 注销登录 */
205 | private fun onLogout() {
206 | Snackbar
207 | .make(mainDrawer, R.string.toastLogout, LENGTH_LONG)
208 | .setAction(R.string.actionConfirm) {
209 | cfg.clean()//清空当前信息
210 | db.use {
211 | delete(TABLE_CFG, "$ITEM_NAME = {$SELECT_USER}", SELECT_USER to SELECT_USER)
212 | }
213 | startActivity()
214 | finish()
215 | }
216 | .show()
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/PaperActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import kotlinx.android.synthetic.main.activity_paper.*
6 | import we.zxlite.R
7 | import we.zxlite.utils.UserUtils.cfg
8 |
9 | class PaperActivity : BaseActivity() {
10 |
11 | companion object {
12 | //原卷
13 | private const val PAPER_URL = "https://www.zhixue.com/studentanswer/index.html"
14 | //原卷id
15 | private const val PAPER_ID = "paperId"
16 | }
17 |
18 | //原卷URL
19 | private val paperUrl get() = "$PAPER_URL?token=${cfg.serviceToken}&paperId=$paperId"
20 | //原卷id
21 | private val paperId get() = intent.getStringExtra(PAPER_ID)
22 |
23 | override fun onCreate(savedInstanceState: Bundle?) {
24 | super.onCreate(savedInstanceState)
25 | setContentView(R.layout.activity_paper)
26 | paperWeb.loadUrl(paperUrl)
27 | }
28 |
29 | @SuppressLint("SetJavaScriptEnabled")
30 | override fun initView() {
31 | setSupportActionBar(paperBar)
32 | paperBar.setNavigationOnClickListener { onBackPressed() }
33 | paperWeb.settings.apply {
34 | setSupportZoom(true)
35 | javaScriptEnabled = true
36 | builtInZoomControls = true
37 | displayZoomControls = false
38 | loadWithOverviewMode = true
39 | useWideViewPort = true
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/RegisterActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.graphics.drawable.ColorDrawable
4 | import android.os.Bundle
5 | import com.bumptech.glide.load.resource.bitmap.CenterCrop
6 | import com.bumptech.glide.load.resource.bitmap.RoundedCorners
7 | import com.google.android.material.snackbar.BaseTransientBottomBar.LENGTH_SHORT
8 | import com.google.android.material.snackbar.Snackbar
9 | import kotlinx.android.synthetic.main.activity_register.*
10 | import kotlinx.coroutines.Dispatchers.Main
11 | import kotlinx.coroutines.launch
12 | import kotlinx.coroutines.withContext
13 | import org.json.JSONObject
14 | import we.zxlite.GlideApp
15 | import we.zxlite.R
16 | import we.zxlite.utils.BaseUtils.EMPTY_STR
17 | import we.zxlite.utils.BaseUtils.color
18 | import we.zxlite.utils.BaseUtils.bitmap
19 | import we.zxlite.utils.BaseUtils.rc4
20 | import we.zxlite.utils.HttpUtils.Error
21 | import we.zxlite.utils.HttpUtils.Type.JsonObject
22 | import we.zxlite.utils.HttpUtils.connApi
23 |
24 | class RegisterActivity : BaseActivity() {
25 |
26 | //获取图像标识
27 | private var sid = EMPTY_STR
28 | //获取图像
29 | private var img = EMPTY_STR
30 | //获取编辑框手机号码
31 | private val regPhone get() = regPhoneNumber.text.toString()
32 | //获取编辑框密码
33 | private val regPwd get() = regPassword.text.toString().rc4
34 | //获取编辑框图形验证码
35 | private val regImage get() = regImgCode.text.toString()
36 | //获取编辑框手机验证码
37 | private val regSms get() = regSmsCode.text.toString()
38 | //短信参数
39 | private val smsParams get() = "checkCode=$regImage&mobile=$regPhone&passwd=$regPwd&sid=$sid"
40 | //注册参数
41 | private val regParams get() = "passwd=$regPwd&role=parent&smsCode=$regSms&sid=$sid"
42 |
43 | companion object {
44 | private const val REG_URL = "https://www.zhixue.com/container/app/reg/register" //注册账号
45 | private const val IMG_URL =
46 | "https://www.zhixue.com/container/app/reg/getImageCode" //获取图像验证码
47 | private const val SMS_URL = "https://www.zhixue.com/container/app/reg/getSmsCode" //获取手机验证码
48 |
49 | private const val IMG = "image"
50 | private const val SID = "sid"
51 | }
52 |
53 | override fun onCreate(savedInstanceState: Bundle?) {
54 | super.onCreate(savedInstanceState)
55 | setContentView(R.layout.activity_register)
56 | loadCode() //加载验证码
57 | }
58 |
59 | override fun initView() {
60 | regImgBtn.setOnClickListener { loadCode() }
61 | regSmsBtn.setOnClickListener { getSms() }
62 | regBtn.setOnClickListener { onReg() }
63 | }
64 |
65 | /**获取图形验证码*/
66 | private fun loadCode() = launch {
67 | connApi(IMG_URL, EMPTY_STR, false, JsonObject).let {
68 | if (it is JSONObject) {
69 | sid = it.optString(SID)
70 | img = it.optString(IMG)
71 | GlideApp
72 | .with(this@RegisterActivity)
73 | .load(img.bitmap)
74 | .transform(CenterCrop(), RoundedCorners(8))
75 | .into(regImg)
76 | } else {
77 | GlideApp
78 | .with(this@RegisterActivity)
79 | .load(ColorDrawable(color(R.color.colorSubTitle)))
80 | .transform(CenterCrop(), RoundedCorners(8))
81 | .into(regImg)
82 | }
83 | }
84 | }
85 |
86 | /** 获取短信验证码 */
87 | private fun getSms() {
88 | if (regPhone.isNotEmpty() && regPwd.isNotEmpty() && regImage.isNotEmpty()) launch {
89 | connApi(SMS_URL, smsParams, false, JsonObject).let {
90 | withContext(Main) {
91 | if (it is JSONObject)
92 | Snackbar.make(regSmsBtn, R.string.smsSuccess, LENGTH_SHORT).show()
93 | else if (it is Error) {
94 | loadCode()
95 | Snackbar.make(regSmsBtn, it.message, LENGTH_SHORT).show()
96 | }
97 | }
98 | }
99 | } else Snackbar.make(regSmsBtn, R.string.valueIncorrect, LENGTH_SHORT).show()
100 | }
101 |
102 | /** 注册账号 */
103 | private fun onReg() {
104 | regBtn.isEnabled = false
105 | launch {
106 | connApi(REG_URL, regParams, false, JsonObject).let {
107 | withContext(Main) {
108 | if (it is JSONObject)
109 | Snackbar.make(regSmsBtn, R.string.regSuccess, Snackbar.LENGTH_INDEFINITE)
110 | .setAction(R.string.actionReturn) { finish() }
111 | .show()
112 | else if (it is Error)
113 | Snackbar.make(regBtn, it.message, LENGTH_SHORT).show()
114 | regBtn.isEnabled = true
115 | }
116 | }
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/activity/ReportActivity.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.activity
2 |
3 | import android.os.Bundle
4 | import android.view.Menu
5 | import android.view.MenuItem
6 | import com.github.mikephil.charting.data.Entry
7 | import com.google.android.material.tabs.TabLayoutMediator
8 | import com.google.android.material.tabs.TabLayoutMediator.TabConfigurationStrategy
9 | import kotlinx.android.synthetic.main.activity_report.*
10 | import kotlinx.coroutines.Dispatchers.Main
11 | import kotlinx.coroutines.launch
12 | import kotlinx.coroutines.withContext
13 | import org.jetbrains.anko.startActivity
14 | import org.jetbrains.anko.toast
15 | import org.json.JSONObject
16 | import we.zxlite.R
17 | import we.zxlite.adapter.ReportPageAdapter
18 | import we.zxlite.bean.ReportPageBean
19 | import we.zxlite.utils.BaseUtils.EMPTY_STR
20 | import we.zxlite.utils.HttpUtils.Error
21 | import we.zxlite.utils.HttpUtils.api
22 | import we.zxlite.utils.HttpUtils.Type.JsonObject
23 |
24 | class ReportActivity : BaseActivity() {
25 |
26 | companion object {
27 | //报告
28 | private const val REPORT_URL = "https://www.zhixue.com/zhixuebao/report/exam/getReportMain"
29 | //表
30 | private const val CHART_URL = "https://www.zhixue.com/zhixuebao/report/paper/getLevelTrend"
31 | //报告列表
32 | private const val PAPER_LIST = "paperList"
33 | //列表
34 | private const val LIST = "list"
35 | //报告id
36 | private const val EXAM_ID = "examId"
37 | //报告名称
38 | private const val EXAM_NAME = "examName"
39 | //标题
40 | private const val TITLE = "title"
41 | //考卷id
42 | private const val PAPER_ID = "paperId"
43 | //考卷名
44 | private const val PAPER_NAME = "paperName"
45 | //总分
46 | private const val STANDARD_SCORE = "standardScore"
47 | //用户得分
48 | private const val USER_SCORE = "userScore"
49 | //学科码
50 | private const val SUBJECT_CODE = "subjectCode"
51 | // 学科名
52 | private const val SUBJECT_NAME = "subjectName"
53 | //数据列表
54 | private const val DATA_LIST = "dataList"
55 | //等级
56 | private const val LEVEL = "level"
57 | //标识
58 | private const val TAG = "tag"
59 | //名称
60 | private const val NAME = "name"
61 | //全科
62 | private const val GENERAL_SUBJECT = "全科"
63 | }
64 |
65 | //报告页列表
66 | private val reportPageList = ArrayList()
67 | //报告id
68 | private val examId get() = intent.getStringExtra(EXAM_ID)
69 | //水平趋势
70 | private val String.levelTrend: Float
71 | get() {
72 | return when (this) {
73 | "A等" -> 8F
74 | "A1" -> 8F
75 | "A2" -> 7.6F
76 | "A3" -> 7.2F
77 | "A4" -> 6.8F
78 | "A5" -> 6.4F
79 | "B等" -> 6F
80 | "B1" -> 6F
81 | "B2" -> 5.6F
82 | "B3" -> 5.2F
83 | "B4" -> 4.8F
84 | "B5" -> 4.4F
85 | "C等" -> 4F
86 | "C1" -> 4F
87 | "C2" -> 3.6F
88 | "C3" -> 3.2F
89 | "C4" -> 2.8F
90 | "C5" -> 2.4F
91 | "D等" -> 2F
92 | "D1" -> 2F
93 | "D2" -> 1.6F
94 | "D3" -> 1.2F
95 | "D4" -> 0.8F
96 | "D5" -> 0.4F
97 | else -> 0.15F
98 | }
99 | }
100 |
101 | override fun onCreate(savedInstanceState: Bundle?) {
102 | super.onCreate(savedInstanceState)
103 | setContentView(R.layout.activity_report)
104 | loadReport()
105 | }
106 |
107 | override fun onCreateOptionsMenu(menu: Menu?): Boolean {
108 | menuInflater.inflate(R.menu.menu_report, menu)
109 | return true
110 | }
111 |
112 | override fun onOptionsItemSelected(item: MenuItem): Boolean {
113 | val selected = reportPageList[reportPager.currentItem].paperId
114 | if (selected.isEmpty() && item.itemId != R.id.menuGuess) {
115 | toast(R.string.showError)
116 | return true
117 | }
118 | when (item.itemId) {
119 | R.id.menuAnalyze -> startActivity(PAPER_ID to selected)
120 | R.id.menuPaper -> startActivity(PAPER_ID to selected)
121 | R.id.menuGuess -> startActivity(EXAM_ID to examId)
122 | }
123 | return true
124 | }
125 |
126 | override fun initView() {
127 | setSupportActionBar(reportBar)
128 | reportBar.setNavigationOnClickListener { onBackPressed() }
129 | reportPager.offscreenPageLimit = 5
130 | reportPager.adapter = ReportPageAdapter(reportPageList) { chart, id ->
131 | launch {
132 | val chartParams = "paperId=$id&pageIndex=1&pageSize=5&examId=$examId"
133 | api(CHART_URL, chartParams, true, JsonObject).let {
134 | if (it is JSONObject) {
135 | val chartList = it.optJSONArray(LIST)
136 | for (i in 0 until chartList!!.length()) {
137 | val entries = ArrayList()
138 | val item = chartList.optJSONObject(i)
139 | val itemName = item.optJSONObject(TAG)!!.optString(NAME)
140 | val dataList = item.optJSONArray(DATA_LIST)
141 | for (data in 0 until dataList!!.length()) {
142 | val levelTrend =
143 | dataList.optJSONObject(data).optString(LEVEL).levelTrend
144 | entries.add(Entry(data * 2f, levelTrend))
145 | }
146 | chart.addLine(itemName, entries, i * 5f)
147 | }
148 | withContext(Main) {
149 | chart.tag = true
150 | chart.legend.setCustom(chart.legendEntries)
151 | chart.notifyDataSetChanged()
152 | chart.invalidate()
153 | }
154 | }
155 | }
156 | }
157 | }
158 | TabLayoutMediator(reportTab, reportPager, TabConfigurationStrategy { tab, position ->
159 | tab.text = reportPageList[position].title
160 | }).attach()
161 | }
162 |
163 | /** 加载报告 */
164 | private fun loadReport() {
165 | launch {
166 | val reportParams = "examId=$examId"
167 | api(REPORT_URL, reportParams, true, JsonObject).let {
168 | if (it is JSONObject) {
169 | val reportList = it.optJSONArray(PAPER_LIST)
170 | var totalStandardScore = 0.00
171 | var totalUserScore = 0.00
172 | for (i in 0 until reportList!!.length()) {
173 | val item = reportList.optJSONObject(i)
174 | if (item.optString(TITLE) != "理综" && item.optString(TITLE) != "文综") {
175 | totalStandardScore += item.optDouble(STANDARD_SCORE)
176 | totalUserScore += item.optDouble(USER_SCORE)
177 | }
178 | reportPageList.add(
179 | ReportPageBean(
180 | title = item.optString(TITLE),
181 | paperId = item.optString(PAPER_ID),
182 | paperName = item.optString(PAPER_NAME),
183 | standardScore = item.optDouble(STANDARD_SCORE),
184 | userScore = item.optDouble(USER_SCORE),
185 | subjectCode = item.optInt(SUBJECT_CODE),
186 | subjectName = item.optString(SUBJECT_NAME)
187 | )
188 | )
189 | }
190 | if (reportList.length() > 1)
191 | reportPageList.add(
192 | 0,
193 | ReportPageBean(
194 | title = GENERAL_SUBJECT,
195 | paperId = EMPTY_STR,
196 | paperName = intent.getStringExtra(EXAM_NAME)!!,
197 | standardScore = totalStandardScore,
198 | userScore = totalUserScore,
199 | subjectCode = -1,
200 | subjectName = EMPTY_STR
201 | )
202 | )
203 | withContext(Main) {
204 | reportPager.adapter!!.notifyItemRangeInserted(0, reportPageList.size)
205 | }
206 | } else withContext(Main) {
207 | toast((it as Error).message)
208 | }
209 | }
210 | }
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/adapter/AnalyzeListAdapter.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.adapter
2 |
3 | import android.text.Html.TagHandler
4 | import android.view.LayoutInflater.from
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import androidx.core.text.HtmlCompat
9 | import androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY
10 | import androidx.recyclerview.widget.RecyclerView
11 | import kotlinx.android.synthetic.main.item_analyze.view.*
12 | import we.zxlite.R
13 | import we.zxlite.bean.AnalyzeListBean
14 | import we.zxlite.utils.GetterUtils.ImageGetter
15 |
16 | class AnalyzeListAdapter(private val analyzeList: ArrayList) :
17 | RecyclerView.Adapter() {
18 |
19 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
20 | ViewHolder(from(parent.context).inflate(R.layout.item_analyze, parent, false))
21 |
22 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
23 | holder.itemTitle.text = analyzeList[position].title
24 | holder.itemContent.text = HtmlCompat.fromHtml(analyzeList[position].content,
25 | FROM_HTML_MODE_LEGACY,
26 | ImageGetter(holder.itemContent),
27 | TagHandler { opening, tag, output, _ ->
28 | if (!opening && tag != null && tag.contentEquals("td")) output.append('\n')
29 | })
30 | }
31 |
32 | override fun getItemCount() = analyzeList.size
33 |
34 | class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
35 | val itemTitle: TextView = itemView.itemTitle
36 | val itemContent: TextView = itemView.itemContent
37 | }
38 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/adapter/AnalyzePageAdapter.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.adapter
2 |
3 | import android.graphics.Rect
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import android.view.LayoutInflater.from
7 | import androidx.recyclerview.widget.RecyclerView
8 | import kotlinx.coroutines.Dispatchers.Main
9 | import kotlinx.coroutines.GlobalScope
10 | import kotlinx.coroutines.launch
11 | import kotlinx.coroutines.withContext
12 | import org.json.JSONArray
13 | import we.zxlite.R
14 | import we.zxlite.bean.AnalyzeListBean
15 | import we.zxlite.bean.AnalyzePageBean
16 |
17 | class AnalyzePageAdapter(private val analyzeList: ArrayList) :
18 | RecyclerView.Adapter() {
19 |
20 | companion object {
21 | private const val TITLE_TOPIC = "题目"
22 | private const val TITLE_MY_SCORE = "我的得分"
23 | private const val TITLE_MY_ANSWER = "我的答案"
24 | private const val TITLE_ANALYSIS = "题目解析"
25 | private const val TITLE_CORRECT = "正确答案"
26 | private const val TITLE_KNOW_LEDGES = "知识点"
27 |
28 | private const val SCORE = "score"
29 | private const val NAME = "name"
30 | private const val TOPIC_NUM = "topicNum"
31 | private const val USER_ANSWER = "userAnswer"
32 | private const val STAND_SCORE = "standScore"
33 | private const val DISP_TITLE = "dispTitle"
34 | private const val KNOW_LEDGES = "relatedKnowledges"
35 | }
36 |
37 | private val Int.topic get() = AnalyzeListBean(TITLE_TOPIC, analyzeList[this].contentHtml)
38 |
39 | private val String.analysis get() = AnalyzeListBean(TITLE_ANALYSIS, this)
40 |
41 | private val String.imgAnswer: AnalyzeListBean
42 | get() {
43 | val array = JSONArray(this)
44 | val answers = StringBuilder()
45 | for (i in 0 until array.length()) {
46 | answers.append("
")
47 | }
48 | return AnalyzeListBean(TITLE_MY_ANSWER, answers.toString())
49 | }
50 |
51 | private val String.answer: AnalyzeListBean?
52 | get() {
53 | val mAnswers = StringBuilder()
54 | val answers = JSONArray(this)
55 | for (i in 0 until answers.length()) {
56 | val item = answers.getJSONObject(i)
57 | mAnswers.append("${item.optInt(TOPIC_NUM)}.${item.optString(USER_ANSWER)};")
58 | }
59 | return if (mAnswers.isNotEmpty())
60 | AnalyzeListBean(TITLE_MY_ANSWER, mAnswers.toString())
61 | else null
62 | }
63 |
64 | private val String.standard: AnalyzeListBean
65 | get() {
66 | var answer = this
67 | if (this.startsWith("https://")) answer = "
"
68 | return AnalyzeListBean(TITLE_CORRECT, answer)
69 | }
70 |
71 | private val String.knowledge: AnalyzeListBean
72 | get() {
73 | val buffer = StringBuilder()
74 | val groups = JSONArray(this)
75 | for (i in 0 until groups.length()) {
76 | val knowledge = groups.optJSONObject(i)
77 | val dispTitle = knowledge.optString(DISP_TITLE)
78 | val knowledges = knowledge.optJSONArray(KNOW_LEDGES)
79 | if (dispTitle.isNotEmpty() && groups.length() != 1)
80 | buffer.append("第 $dispTitle 题: ")
81 | for (it in 0 until knowledges!!.length()) {
82 | buffer.append(knowledges.optJSONObject(it).optString(NAME))
83 | if (it != knowledges.length() - 1) buffer.append(";")
84 | }
85 | buffer.append("
")
86 | }
87 | return AnalyzeListBean(TITLE_KNOW_LEDGES, buffer.toString())
88 | }
89 |
90 | private val String.score: AnalyzeListBean?
91 | get() {
92 | return if (this.isNotEmpty()) {
93 | val array = JSONArray(this)
94 | val scores = StringBuilder()
95 | for (i in 0 until array.length()) {
96 | val item = array.optJSONObject(i)
97 | scores.append(
98 | "第 ${item.optString(DISP_TITLE)} 题: " +
99 | "${item.optString(SCORE)} 分 / " +
100 | "${item.optString(STAND_SCORE)} 分"
101 | )
102 | if (array.length() != i + 1) scores.append("
")
103 | }
104 | AnalyzeListBean(TITLE_MY_SCORE, scores.toString())
105 | } else null
106 | }
107 |
108 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder =
109 | ViewHolder((from(parent.context)
110 | .inflate(R.layout.fragment_analyze, parent, false) as RecyclerView).apply {
111 | addItemDecoration(ItemDecoration())
112 | setHasFixedSize(true)
113 | })
114 |
115 | override fun getItemCount() = analyzeList.size
116 |
117 | override fun onBindViewHolder(holder: ViewHolder, i: Int) {
118 | GlobalScope.launch {
119 | val list = ArrayList()
120 | analyzeList[i].run {
121 | if (contentHtml.isNotEmpty()) list.add(i.topic)
122 | if (topicScoreDTOs.score == null) {
123 | list.add(
124 | AnalyzeListBean(
125 | TITLE_MY_SCORE,
126 | "第 $disTitleNumber 题: $score 分 / $standardScore 分"
127 | )
128 | )
129 | } else list.add(topicScoreDTOs.score!!)
130 | if (answerType == "s01Text")
131 | list.add(AnalyzeListBean(TITLE_MY_ANSWER, userAnswer))
132 | else if (userAnswers.isNotEmpty() && userAnswers.answer != null)
133 | list.add(userAnswers.answer!!)
134 | if (imageAnswers.isNotEmpty()) list.add(imageAnswers.imgAnswer)
135 | if (standardAnswer.isNotEmpty() && answerHtml == "略")
136 | list.add(standardAnswer.standard)
137 | else
138 | list.add(AnalyzeListBean(TITLE_CORRECT, answerHtml))
139 | if (analysisHtml.isNotEmpty()) list.add(analysisHtml.analysis)
140 | if (relatedKnowledgeGroups.isNotEmpty()) list.add(relatedKnowledgeGroups.knowledge)
141 | }
142 | withContext(Main) {
143 | (holder.itemView as RecyclerView).adapter = AnalyzeListAdapter(list)
144 | }
145 | }
146 | }
147 |
148 | class ViewHolder(itemView: RecyclerView) : RecyclerView.ViewHolder(itemView)
149 |
150 | class ItemDecoration : RecyclerView.ItemDecoration() {
151 | override fun getItemOffsets(
152 | outRect: Rect,
153 | view: View,
154 | parent: RecyclerView,
155 | state: RecyclerView.State
156 | ) {
157 | super.getItemOffsets(outRect, view, parent, state)
158 | outRect.top =
159 | if (parent.getChildAdapterPosition(view) == 0) 56 else 24
160 | outRect.bottom = 24
161 | outRect.left = 48
162 | outRect.right = 48
163 | }
164 | }
165 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/adapter/ExamListAdapter.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.adapter
2 |
3 | import android.graphics.Rect
4 | import android.view.LayoutInflater.from
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import androidx.recyclerview.widget.RecyclerView
9 | import kotlinx.android.synthetic.main.item_report.view.*
10 | import we.zxlite.R
11 | import we.zxlite.bean.ReportListBean
12 | import java.text.SimpleDateFormat
13 | import java.util.*
14 | import java.util.Locale.getDefault
15 | import kotlin.collections.ArrayList
16 |
17 | class ExamListAdapter(
18 | private var reportList: ArrayList,
19 | private val callback: (String, String) -> Unit
20 | ) : RecyclerView.Adapter(), View.OnClickListener {
21 |
22 | companion object {
23 | private const val minute = 60 * 1000L //分
24 | private const val hour = 60 * minute //时
25 | private const val day = 24 * hour //日
26 | private const val month = 30 * day // 月
27 | private const val year = 12 * month//年
28 | }
29 |
30 | /** 获取Num */
31 | private val Int.num: String
32 | get() = when {
33 | this < 10 -> "0$this"
34 | this in 10..99 -> this.toString()
35 | else -> "9+"
36 | }
37 |
38 | /** 获取时间字符 */
39 | private val Long.timeFormat: String
40 | get() {
41 | val date = Date().time - Date(this).time
42 | return when {
43 | date > year -> "${date / year} 年前"
44 | date > month -> "${date / month} 个月前"
45 | date > day -> "${date / day} 天前"
46 | date > hour -> "${date / hour} 小时前"
47 | date > minute -> "${date / minute} 分钟前"
48 | else -> "刚刚"
49 | } + " | " + SimpleDateFormat("yyyy-MM-dd", getDefault()).format(this)
50 | }
51 |
52 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
53 | ViewHolder(from(parent.context).inflate(R.layout.item_report, parent, false))
54 |
55 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
56 | val reportItem = reportList[position]
57 | holder.itemNum.text = (position + 1).num
58 | holder.itemTitle.text = reportItem.examName
59 | holder.itemSubTitle.text = reportItem.examCreateTime.timeFormat
60 |
61 | holder.itemView.tag = reportItem.examId
62 | holder.itemView.setOnClickListener(this@ExamListAdapter)
63 | }
64 |
65 | override fun getItemCount() = reportList.size
66 |
67 | override fun onClick(v: View) {
68 | callback(v.tag.toString(), v.itemTitle.text.toString())
69 | }
70 |
71 | class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
72 | val itemNum: TextView = itemView.itemNum
73 | val itemTitle: TextView = itemView.itemTitle
74 | val itemSubTitle: TextView = itemView.itemSubTitle
75 | }
76 |
77 | class ItemDecoration : RecyclerView.ItemDecoration() {
78 | override fun getItemOffsets(
79 | outRect: Rect,
80 | view: View,
81 | parent: RecyclerView,
82 | state: RecyclerView.State
83 | ) {
84 | super.getItemOffsets(outRect, view, parent, state)
85 | outRect.top = if (parent.getChildAdapterPosition(view) == 0) 16 else 8
86 | outRect.bottom = 8
87 | }
88 | }
89 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/adapter/GuessItemAdapter.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.adapter
2 |
3 | import android.graphics.Color
4 | import android.view.LayoutInflater.from
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import android.widget.TextView
8 | import androidx.recyclerview.widget.RecyclerView
9 | import kotlinx.android.synthetic.main.item_guess.view.*
10 | import org.json.JSONObject
11 | import we.zxlite.R
12 |
13 | class GuessItemAdapter(
14 | private val mList: Map,
15 | private val fList: Map
16 | ) :
17 | RecyclerView.Adapter() {
18 |
19 | companion object {
20 | private const val SUBJECT_NAME = "subjectName"
21 | private const val SUBJECT_CODE = "subjectCode"
22 | private const val SCORE = "score"
23 | }
24 |
25 | private var correctColor = Color.DKGRAY
26 | private var mistakeColor = Color.RED
27 |
28 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
29 | ViewHolder(from(parent.context).inflate(R.layout.item_guess, parent, false))
30 |
31 | override fun getItemCount() = mList.size
32 |
33 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
34 | val value = mList.getValue(position)
35 | val code = value.optString(SUBJECT_CODE, "0")
36 | val mScore = value.optDouble(SCORE)
37 | val fScore = fList[code]?.optDouble(SCORE) ?: 0.0
38 | holder.itemSubject.text = value.optString(SUBJECT_NAME)
39 | holder.itemMyScore.text =
40 | mScore.toBigDecimal().stripTrailingZeros().toPlainString()
41 | holder.itemGuessScore.text =
42 | fScore.toBigDecimal().stripTrailingZeros().toPlainString()
43 | when {
44 | mScore > fScore -> {
45 | holder.itemMyScore.setTextColor(correctColor)
46 | holder.itemGuessScore.setTextColor(mistakeColor)
47 | }
48 | mScore < fScore -> {
49 | holder.itemMyScore.setTextColor(mistakeColor)
50 | holder.itemGuessScore.setTextColor(correctColor)
51 | }
52 | else -> {
53 | holder.itemMyScore.setTextColor(correctColor)
54 | holder.itemGuessScore.setTextColor(correctColor)
55 | }
56 | }
57 | }
58 |
59 | class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
60 | val itemMyScore: TextView = itemView.itemMyScore
61 | val itemGuessScore: TextView = itemView.itemGuessScore
62 | val itemSubject: TextView = itemView.itemSubject
63 | }
64 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/adapter/ReportItemAdapter.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.adapter
2 |
3 | import android.view.LayoutInflater.from
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import android.widget.TextView
7 | import androidx.recyclerview.widget.RecyclerView
8 | import kotlinx.android.synthetic.main.item_general.view.*
9 | import we.zxlite.R
10 | import we.zxlite.adapter.ReportItemAdapter.ViewHolder
11 |
12 | class ReportItemAdapter(private var reportList: ArrayList) :
13 | RecyclerView.Adapter() {
14 |
15 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
16 | ViewHolder(from(parent.context).inflate(R.layout.item_general, parent, false))
17 |
18 | override fun onBindViewHolder(holder: ViewHolder, position: Int) {
19 | holder.itemTitle.text = reportList[position]
20 | }
21 |
22 | override fun getItemCount() = reportList.size
23 |
24 | class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
25 | val itemTitle: TextView = itemView.itemTitle
26 | }
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/adapter/ReportPageAdapter.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.adapter
2 |
3 | import android.view.LayoutInflater.from
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import android.widget.TextView
7 | import androidx.recyclerview.widget.GridLayoutManager
8 | import androidx.recyclerview.widget.RecyclerView
9 | import kotlinx.android.synthetic.main.fragment_report.view.*
10 | import kotlinx.android.synthetic.main.fragment_report.view.reportAdvice
11 | import kotlinx.android.synthetic.main.fragment_report.view.reportDetail
12 | import kotlinx.android.synthetic.main.fragment_report.view.reportProgress
13 | import kotlinx.android.synthetic.main.fragment_report.view.reportTitle
14 | import kotlinx.android.synthetic.main.fragment_report_general.view.*
15 | import we.zxlite.R
16 | import we.zxlite.bean.ReportPageBean
17 | import we.zxlite.view.ProgressBar
18 | import we.zxlite.view.ScoreChart
19 | import java.math.BigDecimal.ROUND_DOWN
20 |
21 | class ReportPageAdapter(
22 | private val pageList: ArrayList,
23 | private val callback: (ScoreChart, String) -> Unit
24 | ) : RecyclerView.Adapter() {
25 |
26 | companion object {
27 | private const val SUBJECT = 0 //学科
28 | private const val GENERAL = 1 //全科
29 | }
30 |
31 | //等级评估
32 | private val Int.examLevel
33 | get() = when {
34 | this < 60 -> "待及格"
35 | this < 70 -> "及格"
36 | this < 85 -> "良好"
37 | this != 100 -> "优秀"
38 | else -> "满分!继续努力"
39 | }
40 | //学科建议
41 | private val Int.examAdvice
42 | get() = when {
43 | this < 60 -> "务实基础,再接再厉"
44 | this < 70 -> "保持心态,查漏补缺"
45 | this < 85 -> "进行针对性巩固练习"
46 | else -> "按时复习,稳住优势"
47 | }
48 | //学科诊断
49 | private val Int.examDiagnosis
50 | get() = when {
51 | this < 60 -> "该科成绩较差"
52 | this < 70 -> "该科成绩一般"
53 | this < 85 -> "该科成绩良好"
54 | this != 100 -> "该科成绩优秀"
55 | else -> "该科成绩优异"
56 | }
57 |
58 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
59 | if (viewType == SUBJECT)
60 | ViewHolder(
61 | from(parent.context).inflate(R.layout.fragment_report, parent, false)
62 | )
63 | else
64 | ViewHolder(
65 | from(parent.context).inflate(R.layout.fragment_report_general, parent, false)
66 | )
67 |
68 | override fun getItemCount() = pageList.size
69 |
70 | override fun onBindViewHolder(holder: ViewHolder, i: Int) {
71 | val standardScore = //标准得分
72 | pageList[i].standardScore.toBigDecimal()
73 | val userScore = //得分
74 | pageList[i].userScore.toBigDecimal()
75 | val examScale = //占比
76 | userScore.multiply(100.toBigDecimal()).divide(standardScore, 0, ROUND_DOWN).toInt()
77 | val examDeduct = //扣分
78 | standardScore.subtract(userScore).stripTrailingZeros().toPlainString()
79 |
80 | val showScore =
81 | "${userScore.stripTrailingZeros().toPlainString()} / ${standardScore.stripTrailingZeros().toPlainString()}"
82 | val showDetail =
83 | "• 我的分数: $showScore\n\n• 等级评估: ${examScale.examLevel}\n\n• 分数总扣: $examDeduct 分\n\n• 分数占比: $examScale %"
84 | val showAdvice =
85 | "• 学科诊断: ${examScale.examDiagnosis}\n\n• 学科建议: ${examScale.examAdvice}"
86 | val showChartTitle =
87 | "• 成绩变化曲线: "
88 |
89 | if (getItemViewType(i) == SUBJECT) {
90 | holder.itemView.reportChartTitle.text = showChartTitle
91 | holder.reportTitle.text = pageList[i].paperName
92 | holder.reportDetail.text = showDetail
93 | holder.reportAdvice.text = showAdvice
94 | holder.reportProgress.value = examScale
95 |
96 | if (holder.itemView.reportChart.tag != true) {
97 | callback(holder.itemView.reportChart, pageList[i].paperId)
98 | }
99 | } else {
100 | holder.reportTitle.text = pageList[i].paperName
101 | holder.reportDetail.text = showDetail
102 | holder.reportAdvice.text = showAdvice
103 | holder.reportProgress.value = examScale
104 | val subjectList = ArrayList()
105 | for (item in pageList) {
106 | subjectList.add("• ${item.title} : ${item.userScore.toBigDecimal().stripTrailingZeros().toPlainString()} / ${item.standardScore.toBigDecimal().stripTrailingZeros().toPlainString()}")
107 | }
108 |
109 | holder.itemView.reportGeneral.layoutManager =
110 | GridLayoutManager(holder.itemView.context, 2)
111 | holder.itemView.reportGeneral.adapter =
112 | ReportItemAdapter(subjectList)
113 | }
114 | }
115 |
116 | override fun getItemViewType(i: Int) = if (pageList.size > 1 && i == 0) GENERAL else SUBJECT
117 |
118 | class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
119 | val reportTitle: TextView = itemView.reportTitle
120 | val reportDetail: TextView = itemView.reportDetail
121 | val reportAdvice: TextView = itemView.reportAdvice
122 | val reportProgress: ProgressBar = itemView.reportProgress
123 | }
124 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/bean/AnalyzeListBean.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.bean
2 |
3 | data class AnalyzeListBean(
4 | var title: String, //标题
5 | var content: String //内容
6 | )
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/bean/AnalyzePageBean.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.bean
2 |
3 | data class AnalyzePageBean(
4 | var disTitleNumber: String, //标题编号
5 | var topicNumber: Int, //主题编号
6 | var topicScoreDTOs: String, //主题分数集合
7 | var topicId: String, //主题id
8 | var topicSetId: String, //主题集id
9 | var analysisHtml: String, //解析Html
10 | var contentHtml: String, //题目Html
11 | var answerType: String, //答案类型
12 | var answerHtml: String, //答案Html
13 | var standardAnswer: String, //标准答案
14 | var standardScore: Double, //标准分数
15 | var score: Double, //得分
16 | var userAnswer: String, //用户答案
17 | var userAnswers: String, //用户答案集
18 | var imageAnswers: String, //图像答案
19 | var relatedKnowledgeGroups: String //知识点
20 | )
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/bean/ReportListBean.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.bean
2 |
3 | data class ReportListBean(
4 | var examId: String, //报告id
5 | var examName: String, //报告名称
6 | var examCreateTime: Long //报告时间
7 | )
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/bean/ReportPageBean.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.bean
2 |
3 | data class ReportPageBean(
4 | var title: String, //标题
5 | var paperId: String, //考卷id
6 | var paperName: String, //考卷名
7 | var standardScore: Double, //总分
8 | var userScore: Double, //用户得分
9 | var subjectCode: Int, //学科码
10 | var subjectName: String //学科名
11 | )
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/bean/UserConfigBean.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.bean
2 |
3 | data class UserConfigBean(
4 | var logName: String? = null, //保存的用户名
5 | var logPwd: String? = null, //保存的密码
6 | var curId: String? = null, //选中id
7 | var curName: String? = null, //选中用户名
8 | var loginName: String? = null, //登录名
9 | var serviceTime: Long? = null, //服务时间
10 | var serviceToken: String? = null //验证码
11 | ) {
12 |
13 | /** 清空配置 */
14 | fun clean() {
15 | logName = null
16 | logPwd = null
17 | curId = null
18 | curName = null
19 | loginName = null
20 | serviceTime = null
21 | serviceToken = null
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/dialog/AboutDialog.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.dialog
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import we.zxlite.R
8 |
9 | class AboutDialog : BaseSheetDialog() {
10 |
11 | override fun onCreateView(
12 | inflater: LayoutInflater,
13 | container: ViewGroup?,
14 | savedInstanceState: Bundle?
15 | ): View = inflater.inflate(R.layout.dialog_about, container)
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/dialog/AccountDialog.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.dialog
2 |
3 | import android.app.Dialog
4 | import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
5 | import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
6 | import android.os.Bundle
7 | import androidx.appcompat.app.AlertDialog
8 | import org.jetbrains.anko.db.replace
9 | import org.jetbrains.anko.db.select
10 | import org.jetbrains.anko.intentFor
11 | import we.zxlite.R
12 | import we.zxlite.activity.InitActivity
13 | import we.zxlite.utils.BaseUtils.db
14 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_NAME
15 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_VALUE
16 | import we.zxlite.utils.SqlUtils.Helper.Companion.SELECT_USER
17 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_CFG
18 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_RMB
19 |
20 | class AccountDialog : BaseAlertDialog() {
21 |
22 | override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
23 | val users = ArrayList()
24 | context!!.db.use {
25 | select(TABLE_RMB, ITEM_NAME).exec {
26 | if (moveToFirst()) while (true) {
27 | users.add(getString(0))
28 | if (isLast) break
29 | moveToNext()
30 | }
31 | }
32 | }
33 | return AlertDialog.Builder(context!!)
34 | .setTitle(R.string.menuSwitchAccount)
35 | .setItems(users.toTypedArray()) { _, i ->
36 | context!!.db.use {
37 | replace(TABLE_CFG, ITEM_NAME to SELECT_USER, ITEM_VALUE to users[i])
38 | }
39 | activity!!.startActivity(
40 | activity!!.intentFor()
41 | .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
42 | .addFlags(FLAG_ACTIVITY_NEW_TASK)
43 | )
44 | }.create()
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/dialog/BaseAlertDialog.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.dialog
2 |
3 | import androidx.fragment.app.DialogFragment
4 | import kotlinx.coroutines.CoroutineScope
5 | import kotlinx.coroutines.MainScope
6 | import kotlinx.coroutines.cancel
7 |
8 | abstract class BaseAlertDialog :DialogFragment(), CoroutineScope by MainScope(){
9 |
10 | override fun onDestroy() {
11 | super.onDestroy()
12 | cancel()
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/dialog/BaseSheetDialog.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.dialog
2 |
3 | import com.google.android.material.bottomsheet.BottomSheetDialogFragment
4 | import kotlinx.coroutines.CoroutineScope
5 | import kotlinx.coroutines.MainScope
6 | import kotlinx.coroutines.cancel
7 |
8 | abstract class BaseSheetDialog : BottomSheetDialogFragment() , CoroutineScope by MainScope() {
9 |
10 | override fun onDestroy() {
11 | super.onDestroy()
12 | cancel()
13 | }
14 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/dialog/BindDialog.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.dialog
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import kotlinx.android.synthetic.main.dialog_bind.*
8 | import kotlinx.coroutines.Dispatchers.Main
9 | import kotlinx.coroutines.launch
10 | import kotlinx.coroutines.withContext
11 | import org.jetbrains.anko.toast
12 | import org.json.JSONObject
13 | import we.zxlite.R
14 | import we.zxlite.utils.HttpUtils.Type.JsonObject
15 | import we.zxlite.utils.HttpUtils.api
16 | import we.zxlite.utils.HttpUtils.Error
17 |
18 | class BindDialog : BaseSheetDialog() {
19 |
20 | companion object {
21 | private const val SMS_URL =
22 | "https://www.zhixue.com/container/app/common/user/sendSMS4Mobile" //验证码URL
23 |
24 | private const val BIND_URL =
25 | "https://www.zhixue.com/container/app/common/user/modifyMobile" //绑定手机URL
26 | }
27 |
28 | //手机号码
29 | private val bindMobileNumber get() = bindMobile.text.toString()
30 | //手机验证码
31 | private val bindMobileCode get() = bindCode.text.toString()
32 | //短信验证参数
33 | private val smsParams get() = "?mobile=$bindMobileNumber"
34 | //绑定验证参数
35 | private val bindParams get() = "?mobile=$bindMobileNumber&code=$bindMobileCode"
36 |
37 | override fun onCreateView(
38 | inflater: LayoutInflater,
39 | container: ViewGroup?,
40 | savedInstanceState: Bundle?
41 | ): View = inflater.inflate(R.layout.dialog_bind, container)
42 |
43 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
44 | super.onViewCreated(view, savedInstanceState)
45 | bindCodeBtn.setOnClickListener {
46 | if (bindMobileNumber.isNotEmpty()) launch {
47 | activity!!.api(SMS_URL + smsParams, null, true, JsonObject).let {
48 | withContext(Main) {
49 | if (it is JSONObject) context!!.toast(R.string.smsSuccess)
50 | else context!!.toast((it as Error).message)
51 | }
52 | }
53 | } else context!!.toast(R.string.valueIncorrect)
54 | }
55 | bindBtn.setOnClickListener {
56 | val mobileNumber = bindMobileNumber
57 | val mobileCode = bindMobileCode
58 | if (mobileNumber.isNotEmpty() && mobileCode.isNotEmpty()) launch {
59 | activity!!.api(BIND_URL + bindParams, null, true, JsonObject).let {
60 | withContext(Main) {
61 | if (it is JSONObject) {
62 | context!!.toast(R.string.bindSuccess)
63 | dismiss()
64 | } else context!!.toast((it as Error).message)
65 | }
66 | }
67 | } else context!!.toast(R.string.valueIncorrect)
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/dialog/ModifyDialog.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.dialog
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import kotlinx.android.synthetic.main.dialog_modify.*
8 | import kotlinx.coroutines.Dispatchers.Main
9 | import kotlinx.coroutines.launch
10 | import kotlinx.coroutines.withContext
11 | import org.jetbrains.anko.db.replace
12 | import org.jetbrains.anko.toast
13 | import org.json.JSONObject
14 | import we.zxlite.R
15 | import we.zxlite.utils.HttpUtils.Type.JsonObject
16 | import we.zxlite.utils.HttpUtils.api
17 | import we.zxlite.utils.HttpUtils.Error
18 | import we.zxlite.utils.UserUtils.cfg
19 | import we.zxlite.utils.BaseUtils.db
20 | import we.zxlite.utils.BaseUtils.rc4
21 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_NAME
22 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_VALUE
23 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_RMB
24 |
25 | class ModifyDialog : BaseSheetDialog() {
26 |
27 | companion object {
28 | private const val MODIFY_URL =
29 | "https://www.zhixue.com/container/app/modifyOriginPWD" //修改密码URL
30 | }
31 |
32 | override fun onCreateView(
33 | inflater: LayoutInflater,
34 | container: ViewGroup?,
35 | savedInstanceState: Bundle?
36 | ): View = inflater.inflate(R.layout.dialog_modify, container)
37 |
38 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
39 | super.onViewCreated(view, savedInstanceState)
40 | modifyBtn.setOnClickListener {
41 | val newPwd = modifyNew.text.toString()
42 | val originPwd = modifyOrigin.text.toString()
43 | if (newPwd.isNotEmpty() && originPwd.isNotEmpty()) launch {
44 | val modifyParams =
45 | "loginName=${cfg.loginName?.rc4}&newPWD=${newPwd.rc4}&originPWD=${originPwd.rc4}&description=encrypt"
46 | activity!!.api(MODIFY_URL, modifyParams, true, JsonObject).let {
47 | withContext(Main) {
48 | if (it is JSONObject) {
49 | context!!.toast(R.string.modifySuccess)
50 | cfg.logPwd = newPwd
51 | context!!.db.use {
52 | replace(TABLE_RMB, ITEM_NAME to cfg.logName, ITEM_VALUE to newPwd)
53 | }
54 | dismiss()
55 | } else context!!.toast((it as Error).message)
56 | }
57 | }
58 | } else context!!.toast(R.string.valueIncorrect)
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/dialog/SelectFriendsDialog.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.dialog
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AlertDialog
5 |
6 | class SelectFriendsDialog(private val callback: (Int) -> Unit) : BaseAlertDialog() {
7 |
8 | companion object {
9 | private const val NAME_LIST = "nameList"
10 | }
11 |
12 | override fun onCreateDialog(savedInstanceState: Bundle?) =
13 | AlertDialog.Builder(context!!)
14 | .setItems(arguments!!.getStringArray(NAME_LIST)) { _, which -> callback(which) }
15 | .create()
16 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/utils/BaseUtils.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.utils
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.graphics.BitmapFactory
6 | import android.util.Base64
7 | import androidx.core.content.ContextCompat
8 | import java.net.HttpURLConnection
9 | import java.net.URL
10 | import java.security.MessageDigest
11 | import we.zxlite.utils.SqlUtils.Helper
12 | import java.lang.Integer.toHexString
13 | import kotlin.experimental.xor
14 |
15 | object BaseUtils {
16 | /** 空字符串 */
17 | const val EMPTY_STR = ""
18 | /** 获取数据库资源 */
19 | val Context.db: Helper get() = Helper.getInstance(this)
20 | /** 转为RC4 */
21 | val String.rc4: String
22 | get() {
23 | val data = this.toByteArray() //需要转换的字节
24 | val key = "iflytek_pass_edp".toByteArray() //密钥的字节
25 |
26 | val b = ByteArray(data.size)
27 | val s = ByteArray(256)
28 | var x = 0
29 | var y = 0
30 |
31 | for (i in s.indices) {
32 | s[i] = i.toByte()
33 | }
34 |
35 | for (i in s.indices) {
36 | y = y + s[i] + key[i % key.size] and 0xFF
37 | s[i] = s[i] xor s[y]
38 | s[y] = s[y] xor s[i]
39 | s[i] = s[i] xor s[y]
40 | }
41 | y = 0
42 | for (counter in data.indices) {
43 | x = x + 1 and 0xFF
44 | y = y + s[x] and 0xFF
45 | s[x] = s[x] xor s[y]
46 | s[y] = s[y] xor s[x]
47 | s[x] = s[x] xor s[y]
48 | val k = s[s[x] + s[y] and 0xFF]
49 | b[counter] = data[counter] xor k
50 | }
51 | return b.hexString
52 | }
53 | /** 转为MD5 */
54 | val String.md5: String
55 | get() {
56 | val digest = MessageDigest.getInstance("MD5")
57 | digest.update(toByteArray())
58 | return digest.digest().hexString
59 | }
60 | /** 转为位图 */
61 | val String.bitmap: Bitmap
62 | get() {
63 | val decode = Base64.decode(this, Base64.DEFAULT)
64 | return BitmapFactory.decodeByteArray(decode, 0, decode.size)
65 | }
66 | /** 转为十六进制字符串 */
67 | private val ByteArray.hexString: String
68 | get() {
69 | val builder = StringBuilder()
70 | for (byte in this) {
71 | val i: Int = byte.toInt() and 255
72 | builder.append("${if (i < 16) "0" else EMPTY_STR}${toHexString(i)}")
73 | }
74 | return builder.toString()
75 | }
76 |
77 | /** 获取颜色值 */
78 | fun Context.color(resId: Int) = ContextCompat.getColor(this, resId)
79 |
80 | /** 转为HttpURLConnection */
81 | fun String.conn() = URL(this).openConnection() as HttpURLConnection
82 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/utils/GetterUtils.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.utils
2 |
3 | import android.content.res.Resources
4 | import android.graphics.Bitmap
5 | import android.graphics.Canvas
6 | import android.graphics.Rect
7 | import android.graphics.drawable.BitmapDrawable
8 | import android.graphics.drawable.Drawable
9 | import android.text.Html
10 | import android.widget.TextView
11 | import com.bumptech.glide.request.target.CustomTarget
12 | import com.bumptech.glide.request.transition.Transition
13 | import we.zxlite.GlideApp
14 |
15 | object GetterUtils {
16 |
17 | class ImageGetter(val htmlView: TextView) :
18 | Html.ImageGetter {
19 | override fun getDrawable(source: String): Drawable {
20 | val urlDrawable = UrlDrawable()
21 | GlideApp.with(htmlView.context).asBitmap().load(source).into(BitmapTarget(urlDrawable))
22 | return urlDrawable
23 | }
24 |
25 | private inner class BitmapTarget(private val urlDrawable: UrlDrawable) :
26 | CustomTarget() {
27 | override fun onResourceReady(resource: Bitmap, transition: Transition?) {
28 | val drawable = BitmapDrawable(htmlView.context.resources, resource)
29 | htmlView.post {
30 | val right: Int
31 | val bottom: Int
32 |
33 | if (drawable.intrinsicWidth * 2 > htmlView.width) { //图片宽大于htmlView宽
34 | right = htmlView.width
35 | bottom = drawable.intrinsicHeight * htmlView.width / drawable.intrinsicWidth
36 | } else {
37 | right = drawable.intrinsicWidth * 2
38 | bottom = drawable.intrinsicHeight * 2
39 | }
40 |
41 | val rect = Rect(0, 0, right, bottom)
42 | drawable.bounds = rect
43 | urlDrawable.bounds = rect
44 | urlDrawable.drawable = drawable
45 |
46 | htmlView.text = htmlView.text
47 | htmlView.invalidate()
48 | }
49 | }
50 |
51 | override fun onLoadCleared(placeholder: Drawable?) {}
52 | }
53 |
54 | class UrlDrawable(resources: Resources? = null, bitmap: Bitmap? = null) :
55 | BitmapDrawable(resources, bitmap) {
56 | var drawable: Drawable? = null
57 |
58 | override fun draw(canvas: Canvas) {
59 | drawable?.draw(canvas)
60 | }
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/utils/HttpUtils.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.utils
2 |
3 | import android.app.Activity
4 | import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
5 | import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
6 | import kotlinx.coroutines.Dispatchers.Main
7 | import kotlinx.coroutines.GlobalScope
8 | import kotlinx.coroutines.async
9 | import kotlinx.coroutines.withContext
10 | import org.jetbrains.anko.intentFor
11 | import org.json.JSONArray
12 | import org.json.JSONObject
13 | import we.zxlite.R
14 | import we.zxlite.activity.LoginActivity
15 | import we.zxlite.utils.BaseUtils.EMPTY_STR
16 | import we.zxlite.utils.BaseUtils.conn
17 | import we.zxlite.utils.BaseUtils.md5
18 | import we.zxlite.utils.HttpUtils.Type.JsonArray
19 | import we.zxlite.utils.HttpUtils.Type.JsonObject
20 | import we.zxlite.utils.UserUtils.cfg
21 | import we.zxlite.utils.UserUtils.isExpired
22 | import we.zxlite.utils.UserUtils.login
23 | import we.zxlite.utils.UserUtils.updateConfig
24 | import java.io.DataOutputStream
25 | import java.lang.System.currentTimeMillis
26 | import java.net.SocketTimeoutException
27 | import java.net.UnknownHostException
28 | import java.util.UUID.randomUUID
29 |
30 | object HttpUtils {
31 | private const val AUTH_KEY = "iflytek!@#123student" //验证密钥
32 | private const val AUTH_CODE = "authbizcode"
33 | private const val AUTH_GUID = "authguid"
34 | private const val AUTH_TIME = "authtimestamp"
35 | private const val AUTH_TOKEN = "authtoken"
36 | private const val ERROR_CODE = "errorCode"
37 | private const val ERROR_INFO = "errorInfo"
38 | private const val ERROR_RESULT = "result"
39 | //验证参数
40 | private val tokenParams get() = "?token=${cfg.serviceToken}&childrenId=${cfg.curId}"
41 |
42 | /** 回调数据类型 */
43 | enum class Type { JsonObject, JsonArray }
44 |
45 | /** 验证接口访问
46 | * @param url 接口地址
47 | * @param params 提交数据
48 | * @param add 增加验证
49 | * @param type 返回数据类型
50 | */
51 | suspend fun Activity.api(url: String, params: String?, add: Boolean, type: Type?): Any {
52 | if (isExpired) {
53 | cfg.clean()
54 | updateConfig()
55 | if (!login()) {
56 | withContext(Main) {
57 | startActivity(
58 | intentFor()
59 | .addFlags(FLAG_ACTIVITY_CLEAR_TASK)
60 | .addFlags(FLAG_ACTIVITY_NEW_TASK)
61 | )
62 | }
63 | return Error(Exception(getString(R.string.loginFailed)))
64 | }
65 | }
66 | return connApi(url, params, add, type)
67 | }
68 |
69 | /** 接口访问
70 | * @param url 接口地址
71 | * @param params 提交数据
72 | * @param add 增加验证
73 | * @param type 返回数据类型
74 | */
75 | suspend fun connApi(url: String, params: String?, add: Boolean, type: Type?) =
76 | GlobalScope.async {
77 | val checkParams = if (params == null) tokenParams.replace("?", "&") else tokenParams
78 | val urlConn = ("$url${if (add) checkParams else EMPTY_STR}").conn()
79 | try {
80 | val authCode = "0001"
81 | val authGuid = randomUUID().toString()
82 | val authTime = currentTimeMillis().toString()
83 | val authToken = (authGuid + authTime + AUTH_KEY).md5
84 | val conn = urlConn.apply {
85 | if (params != null) { //如果不等于null 将设置为post提交
86 | requestMethod = "POST"
87 | doOutput = true
88 | }
89 | readTimeout = 10 * 1000 //读取超时10s
90 | connectTimeout = 10 * 1000 //连接超时10s
91 | setRequestProperty(AUTH_CODE, authCode)
92 | setRequestProperty(AUTH_GUID, authGuid)
93 | setRequestProperty(AUTH_TIME, authTime)
94 | setRequestProperty(AUTH_TOKEN, authToken)
95 | }
96 | if (params != null) {
97 | val stream = DataOutputStream(conn.outputStream)
98 | stream.writeBytes(params)
99 | stream.flush()
100 | stream.close()
101 | }
102 | val resultData = conn.inputStream.reader().readText()
103 | return@async when (type) {
104 | JsonObject -> resultData.jsonObject
105 | JsonArray -> resultData.jsonArray
106 | else -> resultData
107 | }
108 | } catch (e: Exception) {
109 | return@async Error(e)
110 | } finally {
111 | urlConn.disconnect()
112 | }
113 | }.await()
114 |
115 | /** 转为JSON */
116 | private fun String.json(): String = JSONObject(this).run {
117 | if (optInt(ERROR_CODE) == 0) optString(ERROR_RESULT)
118 | else throw Exception(optString(ERROR_INFO))
119 | }
120 |
121 | /** 转为JSONObject */
122 | private val String.jsonObject: Any
123 | get() {
124 | val json = json()
125 | return if (json.isNotEmpty()) JSONObject(json) else JSONObject()
126 | }
127 |
128 | /** 转为JSONArray */
129 | private val String.jsonArray: Any
130 | get() {
131 | val json = json()
132 | return if (json.isNotEmpty()) JSONArray(json) else JSONArray()
133 | }
134 |
135 | /** 返回错误信息 */
136 | class Error(private val error: Exception) {
137 | val message: String
138 | get() = when (error) {
139 | is UnknownHostException -> "网络连接错误"
140 | is SocketTimeoutException -> "网络连接超时"
141 | else -> error.message.toString()
142 | }
143 | }
144 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/utils/SqlUtils.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.utils
2 |
3 | import android.content.Context
4 | import android.database.sqlite.SQLiteDatabase
5 | import org.jetbrains.anko.db.*
6 |
7 | object SqlUtils {
8 |
9 | private const val DB_NAME = "Zxlite" //数据库名
10 |
11 | class Helper private constructor(ctx: Context) :
12 | ManagedSQLiteOpenHelper(ctx, DB_NAME, null, 1) {
13 | init {
14 | instance = this
15 | }
16 |
17 | companion object {
18 | const val TABLE_RMB = "TABLE_RMB" //记住密码
19 | const val TABLE_CFG = "TABLE_CFG" //用户配置
20 | const val ITEM_NAME = "ITEM_NAME" //项名
21 | const val ITEM_VALUE = "ITEM_VALUE" //项值
22 | const val SELECT_USER = "SELECT_USER" //选中用户
23 | const val REPORT_TYPE = "REPORT_TYPE" //报告类型
24 |
25 | private var instance: Helper? = null
26 |
27 | @Synchronized
28 | fun getInstance(ctx: Context) = instance ?: Helper(ctx.applicationContext)
29 | }
30 |
31 | override fun onCreate(db: SQLiteDatabase) {
32 | db.createTable(TABLE_RMB, true, ITEM_NAME to TEXT + UNIQUE, ITEM_VALUE to TEXT) //创建记住密码表
33 | db.createTable(TABLE_CFG, true, ITEM_NAME to TEXT + UNIQUE, ITEM_VALUE to TEXT) //创建用户配置表
34 | }
35 |
36 | override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
37 | db.dropTable(TABLE_RMB)
38 | db.dropTable(TABLE_CFG)
39 | }
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/utils/UserUtils.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.utils
2 |
3 | import android.content.Context
4 | import kotlinx.coroutines.GlobalScope
5 | import kotlinx.coroutines.async
6 | import org.jetbrains.anko.db.select
7 | import org.json.JSONObject
8 | import we.zxlite.bean.UserConfigBean
9 | import we.zxlite.utils.BaseUtils.EMPTY_STR
10 | import we.zxlite.utils.BaseUtils.db
11 | import we.zxlite.utils.BaseUtils.rc4
12 | import we.zxlite.utils.HttpUtils.connApi
13 | import we.zxlite.utils.HttpUtils.Type.JsonObject
14 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_NAME
15 | import we.zxlite.utils.SqlUtils.Helper.Companion.ITEM_VALUE
16 | import we.zxlite.utils.SqlUtils.Helper.Companion.SELECT_USER
17 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_CFG
18 | import we.zxlite.utils.SqlUtils.Helper.Companion.TABLE_RMB
19 | import java.lang.System.currentTimeMillis
20 |
21 | object UserUtils {
22 |
23 | //用户配置
24 | val cfg = UserConfigBean()
25 |
26 | //检测登录是否过期
27 | val isExpired get() = (cfg.serviceTime ?: 0) < currentTimeMillis() - 1800000L
28 |
29 | private const val LOG_URL = "https://www.zhixue.com/container/app/login" //登录账号URL
30 | private const val INFO_URL =
31 | "https://www.zhixue.com/zhixuebao/base/common/getUserInfo" //用户信息URL
32 |
33 | private const val USER_INFO = "userInfo" //用户信息
34 | private const val SERVER_INFO = "serverInfo" //服务信息
35 | private const val CUR_SERVER_TIME = "curServerTime" //服务时间
36 | private const val CUR_CHILD_ID = "curChildId" //选定Id
37 | private const val LOGIN_NAME = "loginName" //登录名
38 | private const val TOKEN = "token" //验证码
39 | private const val NAME = "name" //名字
40 | //登录参数
41 | private val logParams get() = "loginName=${cfg.logName}&password=${cfg.logPwd?.rc4}&description={'encrypt':['password']}"
42 |
43 | /** 登录
44 | * @param userName 用户名
45 | * @param userPwd 用户密码
46 | */
47 | suspend fun login(
48 | userName: String? = cfg.logName,
49 | userPwd: String? = cfg.logPwd
50 | ) = GlobalScope.async {
51 | cfg.logName = userName
52 | cfg.logPwd = userPwd
53 | connApi(LOG_URL, logParams, false, JsonObject).run {
54 | if (this is JSONObject) {
55 | cfg.loginName = optJSONObject(USER_INFO)!!.optString(LOGIN_NAME)
56 | cfg.curName = optJSONObject(USER_INFO)!!.optString(NAME)
57 | cfg.serviceTime = optJSONObject(SERVER_INFO)!!.optLong(CUR_SERVER_TIME)
58 | cfg.serviceToken = optString(TOKEN)
59 |
60 | connApi(INFO_URL, EMPTY_STR, true, JsonObject).run {
61 | if (this is JSONObject) cfg.curId = optString(CUR_CHILD_ID)
62 | }
63 | }
64 | }
65 | return@async cfg.curId != null
66 | }.await()
67 |
68 | /** 更新信息 */
69 | fun Context.updateConfig() = db.use {
70 | select(TABLE_CFG, ITEM_VALUE)
71 | .whereSimple("$ITEM_NAME = '$SELECT_USER'")
72 | .exec { if (moveToFirst()) getString(0) else null }
73 | ?.let { userName ->
74 | select(TABLE_RMB, ITEM_VALUE)
75 | .whereSimple("$ITEM_NAME = '$userName'")
76 | .exec { if (moveToFirst()) getString(0) else null }
77 | ?.let { userPwd ->
78 | cfg.logName = userName
79 | cfg.logPwd = userPwd
80 | }
81 | }
82 | }
83 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/view/ProgressBar.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.view
2 |
3 | import android.content.Context
4 | import android.graphics.Canvas
5 | import android.graphics.Paint
6 | import android.util.AttributeSet
7 | import android.view.View
8 | import we.zxlite.R
9 | import we.zxlite.utils.BaseUtils.color
10 |
11 | class ProgressBar(ctx: Context, attrs: AttributeSet) : View(ctx, attrs) {
12 |
13 | /* 进度值 */
14 | var value: Int = 0
15 | set(value) {
16 | field = value
17 | invalidate() //刷新
18 | }
19 |
20 | //画笔
21 | private val mPaint: Paint = Paint()
22 |
23 | override fun onDraw(canvas: Canvas) {
24 | super.onDraw(canvas)
25 |
26 | val progressWidth = value * measuredWidth / 100F //计算进度宽度
27 |
28 | mPaint.color = context!!.color(R.color.colorLine)
29 | canvas.drawRect(0f, 0f, measuredWidth.toFloat(), measuredHeight.toFloat(), mPaint) //画底层
30 |
31 | mPaint.color = context!!.color(R.color.colorAccent)
32 | canvas.drawRect(0f, 0f, progressWidth, measuredHeight.toFloat(), mPaint) //画进度
33 | }
34 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/view/ScoreChart.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.view
2 |
3 | import android.content.Context
4 | import android.graphics.Color
5 | import android.graphics.Color.TRANSPARENT
6 | import android.graphics.DashPathEffect
7 | import android.graphics.Typeface.DEFAULT_BOLD
8 | import android.util.AttributeSet
9 | import android.view.MotionEvent
10 | import com.github.mikephil.charting.charts.LineChart
11 | import com.github.mikephil.charting.components.AxisBase
12 | import com.github.mikephil.charting.components.Legend.LegendVerticalAlignment.TOP
13 | import com.github.mikephil.charting.components.Legend.LegendHorizontalAlignment.RIGHT
14 | import com.github.mikephil.charting.components.Legend.LegendOrientation.HORIZONTAL
15 | import com.github.mikephil.charting.components.Legend.LegendForm.LINE
16 | import com.github.mikephil.charting.components.LegendEntry
17 | import com.github.mikephil.charting.data.Entry
18 | import com.github.mikephil.charting.data.LineData
19 | import com.github.mikephil.charting.data.LineDataSet
20 | import com.github.mikephil.charting.data.LineDataSet.Mode.CUBIC_BEZIER
21 | import com.github.mikephil.charting.formatter.ValueFormatter
22 | import com.github.mikephil.charting.interfaces.datasets.ILineDataSet
23 | import we.zxlite.R
24 | import we.zxlite.utils.BaseUtils.EMPTY_STR
25 | import we.zxlite.utils.BaseUtils.color
26 |
27 | class ScoreChart(ctx: Context, attr: AttributeSet) : LineChart(ctx, attr) {
28 | //图例条目
29 | var legendEntries = ArrayList()
30 | //数据集
31 | private var dataSets = ArrayList()
32 | //分割线颜色
33 | private val diverColor get() = context!!.color(R.color.colorChartDiver)
34 | //线的颜色
35 | private val lineColor get() = context!!.color(R.color.colorAccent)
36 |
37 | init {
38 | dataSets.add(initDefaultLine())
39 | description.isEnabled = false
40 | isDoubleTapToZoomEnabled = false
41 | isDragEnabled = false
42 | legend.verticalAlignment = TOP
43 | legend.horizontalAlignment = RIGHT
44 | legend.orientation = HORIZONTAL
45 | data = LineData(dataSets)
46 | setTouchEnabled(false)
47 | setScaleEnabled(false)
48 | setAxis()
49 | }
50 |
51 | override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
52 | parent.requestDisallowInterceptTouchEvent(false)
53 | return super.dispatchTouchEvent(ev)
54 | }
55 |
56 | fun addLine(name: String, entries: ArrayList, length: Float) {
57 | val effect = DashPathEffect(floatArrayOf(length, length), 0f)
58 | legendEntries.add(LegendEntry(name, LINE, 10f, 2f, effect, lineColor))
59 | dataSets.add(LineDataSet(entries, null).apply {
60 | lineWidth = 2f
61 | circleRadius = 3f
62 | color = lineColor
63 | mode = CUBIC_BEZIER
64 | setDrawCircles(true)
65 | setDrawFilled(false)
66 | setDrawValues(false)
67 | setCircleColor(lineColor)
68 | enableDashedLine(length, length, 0f)
69 | })
70 | }
71 |
72 | private fun initDefaultLine(): LineDataSet {
73 | val pointValues = ArrayList()
74 | for (i in 0..4) {
75 | pointValues.add(Entry((i * 2).toFloat(), (i * 2).toFloat()))
76 | }
77 | return LineDataSet(pointValues, null).apply {
78 | setDrawCircles(false)
79 | setDrawFilled(false)
80 | setDrawValues(false)
81 | color = TRANSPARENT
82 | }
83 | }
84 |
85 | private fun setAxis() {
86 | xAxis.isEnabled = false
87 | axisLeft.isEnabled = true
88 | axisRight.isEnabled = false
89 | axisLeft.axisMinimum = 0f
90 | axisLeft.axisMaximum = 9f
91 | axisLeft.xOffset = 10f
92 | axisLeft.yOffset = -8f
93 | axisLeft.typeface = DEFAULT_BOLD
94 | axisLeft.textColor = Color.GRAY
95 | axisLeft.gridColor = diverColor
96 | axisLeft.axisLineColor = diverColor
97 | axisLeft.axisLineWidth = 1.5f
98 | axisLeft.gridLineWidth = 1.5f
99 | axisLeft.setLabelCount(6, false)
100 | axisLeft.valueFormatter = LevelValueFormatter()
101 | }
102 |
103 | class LevelValueFormatter : ValueFormatter() {
104 | override fun getAxisLabel(value: Float, axis: AxisBase?): String {
105 | return when (value.toInt()) {
106 | 0 -> "E"
107 | 2 -> "D"
108 | 4 -> "C"
109 | 6 -> "B"
110 | 8 -> "A"
111 | else -> EMPTY_STR
112 | }
113 | }
114 | }
115 |
116 | }
--------------------------------------------------------------------------------
/app/src/main/java/we/zxlite/view/ShadowView.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite.view
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import android.view.View
6 | import we.zxlite.R
7 |
8 | /** 阴影控件
9 | * isTop 是否是顶部阴影
10 | */
11 | class ShadowView(ctx: Context, attrs: AttributeSet) : View(ctx, attrs) {
12 | init {
13 | val styleAttrs = ctx.obtainStyledAttributes(attrs, R.styleable.ShadowView)
14 |
15 | if (styleAttrs.getBoolean(R.styleable.ShadowView_isTop, true)) {
16 | setBackgroundResource(R.drawable.shadow_top) //设置顶部阴影
17 | } else {
18 | setBackgroundResource(R.drawable.shadow_btm) //设置底部阴影
19 | }
20 |
21 | styleAttrs.recycle()
22 | }
23 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable/edit_line.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_back.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/nav_text_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shadow_btm.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/shadow_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_analyze.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
25 |
26 |
27 |
35 |
36 |
42 |
43 |
50 |
51 |
63 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_guess.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
25 |
26 |
27 |
41 |
42 |
57 |
58 |
72 |
73 |
85 |
86 |
92 |
93 |
100 |
101 |
114 |
115 |
124 |
125 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_init.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
21 |
22 |
35 |
36 |
46 |
47 |
67 |
68 |
87 |
88 |
99 |
100 |
112 |
113 |
126 |
127 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
23 |
24 |
28 |
29 |
30 |
36 |
37 |
45 |
46 |
53 |
54 |
55 |
56 |
69 |
70 |
71 |
80 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_paper.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
18 |
19 |
25 |
26 |
27 |
36 |
37 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_register.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
21 |
22 |
35 |
36 |
46 |
47 |
67 |
68 |
87 |
88 |
109 |
110 |
122 |
123 |
133 |
134 |
155 |
156 |
165 |
166 |
177 |
178 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_report.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
24 |
25 |
26 |
34 |
35 |
41 |
42 |
49 |
50 |
62 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
18 |
19 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_bind.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
31 |
32 |
49 |
50 |
61 |
62 |
81 |
82 |
91 |
92 |
103 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_modify.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
19 |
20 |
31 |
32 |
49 |
50 |
61 |
62 |
81 |
82 |
93 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_analyze.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_report.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
16 |
17 |
32 |
33 |
41 |
42 |
53 |
54 |
62 |
63 |
71 |
72 |
83 |
84 |
92 |
93 |
103 |
104 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_report_general.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
16 |
17 |
32 |
33 |
41 |
42 |
53 |
54 |
62 |
63 |
71 |
72 |
83 |
84 |
92 |
93 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
22 |
23 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_analyze.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_general.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_guess.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
12 |
13 |
20 |
21 |
31 |
32 |
39 |
40 |
41 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_report.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
15 |
16 |
29 |
30 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_tab.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu_report.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #FFFFFF
5 | #32C2B3
6 | #FFC107
7 | #80888888
8 | #3C4245
9 | #A5A9AF
10 | #ECEFF1
11 | #EEEEEE
12 | #262626
13 | #F5F5F5
14 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 智学网
3 | 报告类型
4 | 账号安全
5 | 其他相关
6 | 考试报告
7 | 作业报告
8 | 绑定手机
9 | 修改密码
10 | 检测更新
11 | 意见反馈
12 | 关于我们
13 | 注销登录
14 | 切换账号
15 | 原卷查看
16 | 题目解析
17 | 好友伴学
18 | 欢迎登录
19 | 智学,让学习更简单!
20 | 输入手机号或用户名
21 | 输入密码
22 | 登录
23 | 注册账号
24 | 忘记密码
25 | 登录失败
26 | 欢迎注册
27 | 智学,让学习更简单
28 | 输入手机号码
29 | 输入密码(不少于6位)
30 | 输入图像验证码
31 | 获取验证码
32 | 输入手机验证码
33 | 注册
34 | 注册成功
35 | 发送成功
36 | 参数填写不正确
37 | 确定
38 | 返回
39 | 加Q群获取最新版
40 | 注销登录?
41 | 通过邮箱反馈
42 | 请输入手机号码
43 | 请输入验证码
44 | 绑定
45 | 获取验证码
46 | 绑定成功
47 | 修改成功
48 | 请输入旧密码
49 | 请输入新密码
50 | 绑定
51 | 我的分数
52 | 学科
53 | TA的分数
54 | 选择
55 | 请选择伴学对象
56 | 未安装手Q或安装的版本不支持
57 | 未安装邮箱软件
58 | 本软件为免费软件,由个人独立开发完成。\n此软件仅供学习交流,勿于商业用途。\n在软件中难免存在一些未修复的漏洞,我深感歉意。\n希望你能尽快联系我修复问题。
59 | 学情报告
60 | 原卷查看
61 | 题目解析
62 | 好友伴学
63 | 没有好友
64 | 全科无法查看
65 | 已将全班添加至列表
66 | 请稍等
67 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
14 |
15 |
21 |
--------------------------------------------------------------------------------
/app/src/test/java/we/zxlite/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package we.zxlite
2 |
3 | import org.junit.Test
4 |
5 | import org.junit.Assert.*
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * See [testing documentation](http://d.android.com/tools/testing).
11 | */
12 | class ExampleUnitTest {
13 | @Test
14 | fun addition_isCorrect() {
15 | assertEquals(4, 2 + 2)
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.anko_version = '0.10.8'
5 | ext.kotlin_version = '1.3.50'
6 | ext.kotlinx_version = '1.3.2'
7 | repositories {
8 | google()
9 | jcenter()
10 |
11 | }
12 | dependencies {
13 | classpath 'com.android.tools.build:gradle:3.5.2'
14 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module build.gradle files
17 | }
18 | }
19 |
20 | allprojects {
21 | repositories {
22 | google()
23 | jcenter()
24 |
25 | }
26 | }
27 |
28 | task clean(type: Delete) {
29 | delete rootProject.buildDir
30 | }
31 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app's APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Git-WeStudio/Zxlite/a737f0bdac52346e754f208129e8f64988116b1d/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Sat Nov 02 11:24:55 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | rootProject.name='智学网'
3 |
--------------------------------------------------------------------------------