├── .editorconfig
├── .github
└── workflows
│ ├── macos.yml
│ ├── ubuntu.yml
│ └── windows.yml
├── .gitignore
├── LICENSE
├── README.md
├── app
├── .gitignore
├── build.gradle
├── libs
│ ├── alibc_link_partner-4.1.15.aar
│ ├── alibc_link_partner-4.1.23.aar
│ ├── alipaysdk-15.8.00.201112210139.aar
│ ├── alipaysdk-noutdid-15.8.00.201112210139.aar
│ ├── apsecuritysdk-all-3.3.0.jar
│ ├── avmpaar3-5.4.200.aar
│ ├── avmpaar3-5.4.36.aar
│ ├── mtopsdk_allinone_open-3.1.2.5.jar
│ ├── mtopsdk_allinone_open-3.1.7.2.jar
│ ├── securitybodyaar3-5.4.200.aar
│ ├── securitybodyaar3-5.4.99.aar
│ ├── securityguardaar3-5.4.171.aar
│ ├── securityguardaar3-5.4.200.aar
│ ├── sgmiddletieraar3-5.4.200.aar
│ ├── sgmiddletieraar3-5.4.9.aar
│ └── standardcashier-single-15.6.5.aar
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── com
│ │ └── qiyutech
│ │ └── tbk
│ │ └── ExampleInstrumentedTest.kt
│ ├── main
│ ├── AndroidManifest.xml
│ ├── assets
│ │ └── www
│ │ │ └── html
│ │ │ └── privacy.html
│ ├── java
│ │ └── com
│ │ │ └── qiyutech
│ │ │ └── tbk
│ │ │ ├── CouponActivity.kt
│ │ │ ├── DevInfoActivity.kt
│ │ │ ├── GroupActivity.kt
│ │ │ ├── HomeActivity.kt
│ │ │ ├── ItemDetailV2Activity.kt
│ │ │ ├── MeActivity.kt
│ │ │ ├── MyApplication.kt
│ │ │ ├── PrivacyActivity.kt
│ │ │ ├── SafeImgActivity.kt
│ │ │ ├── SearchActivity.kt
│ │ │ ├── SearchDetailNativeActivity.kt
│ │ │ ├── SettingsActivity.kt
│ │ │ ├── TaoBaoActivity.kt
│ │ │ ├── UserInfoActivity.kt
│ │ │ ├── UserPasswordActivity.kt
│ │ │ ├── activity
│ │ │ ├── question
│ │ │ │ └── MyJsonObjectRequest.kt
│ │ │ └── taobao
│ │ │ │ └── MyAuthCb.kt
│ │ │ ├── api
│ │ │ └── ZTK.kt
│ │ │ ├── application
│ │ │ ├── AliBCCallback.kt
│ │ │ └── AppSwipeBack.kt
│ │ │ ├── dt
│ │ │ ├── DtsV2.kt
│ │ │ ├── Stub.kt
│ │ │ └── shared.kt
│ │ │ ├── events
│ │ │ ├── LoginEvent.kt
│ │ │ └── LogoutEvent.kt
│ │ │ ├── extend
│ │ │ └── MyNetworkImageView.kt
│ │ │ ├── fragments
│ │ │ ├── SFooterFragment.kt
│ │ │ ├── TextHeaderFragment.kt
│ │ │ ├── home
│ │ │ │ └── HomeFragmentGuessYouLike.kt
│ │ │ ├── me
│ │ │ │ ├── MeFragmentDefault.kt
│ │ │ │ ├── MeFragmentSlot.kt
│ │ │ │ └── MeFragmentUser.kt
│ │ │ └── settings
│ │ │ │ ├── SettingsFragmentLogin.kt
│ │ │ │ └── SettingsFragmentUser.kt
│ │ │ ├── logic
│ │ │ ├── AppErrnoLogic.kt
│ │ │ ├── CouponLogic.kt
│ │ │ ├── DisplayLogic.kt
│ │ │ ├── TaoBaoLogic.kt
│ │ │ └── UserLogic.kt
│ │ │ ├── utils
│ │ │ ├── AppNavUtils.kt
│ │ │ ├── AppUtils.kt
│ │ │ ├── ClipboardUtils.kt
│ │ │ ├── DialogUtils.kt
│ │ │ ├── DiskImageCache.kt
│ │ │ ├── LayoutUtils.kt
│ │ │ ├── LoadKeywordUtils.kt
│ │ │ ├── MyHttpUtils.kt
│ │ │ ├── MyJsonUtils.kt
│ │ │ ├── MySearchUtils.kt
│ │ │ ├── MyWebViewUtils.kt
│ │ │ ├── NetworkImageUtils.kt
│ │ │ ├── PopupUtils.kt
│ │ │ ├── PrivacyUtils.kt
│ │ │ ├── PushUtils.kt
│ │ │ ├── TipUtils.kt
│ │ │ └── WebUtils.kt
│ │ │ └── values
│ │ │ ├── ApiUrlsV2.kt
│ │ │ ├── AppSpKeys.kt
│ │ │ ├── HttpFile.kt
│ │ │ ├── HttpTags.kt
│ │ │ └── LogTags.kt
│ └── res
│ │ ├── color
│ │ └── bottom_nav_color.xml
│ │ ├── drawable-hdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── drawable-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── drawable-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── drawable-xxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── drawable-xxxhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── drawable
│ │ ├── button_round_corner.xml
│ │ ├── coupon_bg.png
│ │ ├── f_icon_coupon.png
│ │ ├── f_icon_group.png
│ │ ├── f_icon_home.png
│ │ ├── f_icon_user.png
│ │ ├── forward.png
│ │ ├── item_detail_coupon_bg.xml
│ │ ├── search.png
│ │ ├── search_button_bg.xml
│ │ ├── search_view_bg.xml
│ │ ├── star.png
│ │ └── yw_1222.jpg
│ │ ├── layout
│ │ ├── activity_coupon.xml
│ │ ├── activity_dev_info.xml
│ │ ├── activity_group.xml
│ │ ├── activity_home.xml
│ │ ├── activity_item_detail_v2.xml
│ │ ├── activity_me.xml
│ │ ├── activity_privacy.xml
│ │ ├── activity_search.xml
│ │ ├── activity_search_detail_native.xml
│ │ ├── activity_tao_bao.xml
│ │ ├── activity_user_info.xml
│ │ ├── fragment_home_guess_you_like.xml
│ │ ├── fragment_me_default.xml
│ │ ├── fragment_me_slot.xml
│ │ ├── fragment_me_user.xml
│ │ ├── fragment_s_footer.xml
│ │ ├── fragment_settings_login.xml
│ │ ├── fragment_settings_user.xml
│ │ ├── fragment_text_header.xml
│ │ ├── layout_recycle_view_item_info.xml
│ │ ├── layout_recycle_view_search_detail_item_info.xml
│ │ ├── me_activity_divider.xml
│ │ ├── parts_simple_kv_info.xml
│ │ ├── parts_tbk_sort_header.xml
│ │ ├── popup_clean_cache.xml
│ │ ├── s_footer.xml
│ │ ├── search_search_item.xml
│ │ ├── settings_activity.xml
│ │ ├── t_grid_demo.xml
│ │ └── user_password_activity.xml
│ │ ├── menu
│ │ └── home_navigation_menu.xml
│ │ ├── mipmap-hdpi
│ │ ├── back.png
│ │ ├── forward.png
│ │ ├── me_order.png
│ │ ├── settings.png
│ │ └── tao_bao_auth.png
│ │ ├── mipmap-mdpi
│ │ ├── back.png
│ │ ├── forward.png
│ │ ├── me_order.png
│ │ ├── settings.png
│ │ └── tao_bao_auth.png
│ │ ├── mipmap-xhdpi
│ │ ├── back.png
│ │ ├── forward.png
│ │ ├── me_order.png
│ │ ├── settings.png
│ │ └── tao_bao_auth.png
│ │ ├── mipmap-xxhdpi
│ │ ├── back.png
│ │ ├── forward.png
│ │ ├── me_order.png
│ │ ├── settings.png
│ │ └── tao_bao_auth.png
│ │ ├── mipmap-xxxhdpi
│ │ ├── back.png
│ │ ├── forward.png
│ │ ├── me_order.png
│ │ ├── settings.png
│ │ └── tao_bao_auth.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ ├── values-zh
│ │ └── strings.xml
│ │ └── values
│ │ ├── arrays.xml
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── com
│ └── qiyutech
│ └── tbk
│ └── ExampleUnitTest.kt
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── keystore
├── readme.md
└── tbk
└── settings.gradle
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = true
6 | tab_width = 4
7 | indent_size = 4
8 | indent_style = space
9 |
10 | [*.xml]
11 | max_line_length = off
12 |
13 | [*.yml]
14 | indent_size = 2
15 |
16 | [Makefile]
17 | indent_style = tab
18 |
--------------------------------------------------------------------------------
/.github/workflows/macos.yml:
--------------------------------------------------------------------------------
1 | name: macOS
2 |
3 | on: [ push, pull_request ]
4 |
5 |
6 | jobs:
7 | build:
8 | runs-on: macos-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v2
12 |
13 | - uses: actions/setup-java@v2
14 | with:
15 | distribution: 'adopt'
16 | java-version: '11'
17 |
18 | - name: Build APK
19 | run: ./gradlew build
20 |
21 | - uses: actions/upload-artifact@v2
22 | with:
23 | name: macos
24 | path: app/build/outputs/apk/prod/release/
25 |
--------------------------------------------------------------------------------
/.github/workflows/ubuntu.yml:
--------------------------------------------------------------------------------
1 | name: Ubuntu
2 |
3 | on: [ push, pull_request ]
4 |
5 |
6 | jobs:
7 | build:
8 | runs-on: ubuntu-20.04
9 |
10 | steps:
11 | - uses: actions/checkout@v2
12 |
13 | - uses: actions/setup-java@v2
14 | with:
15 | distribution: 'adopt'
16 | java-version: '11'
17 |
18 | - name: Build APK
19 | run: ./gradlew build
20 |
21 | - uses: actions/upload-artifact@v2
22 | with:
23 | name: ubuntu
24 | path: app/build/outputs/apk/prod/release/
25 |
--------------------------------------------------------------------------------
/.github/workflows/windows.yml:
--------------------------------------------------------------------------------
1 | name: Windows
2 |
3 | on: [ push, pull_request ]
4 |
5 |
6 | jobs:
7 | build:
8 | runs-on: windows-latest
9 |
10 | steps:
11 | - uses: actions/checkout@v2
12 |
13 | - uses: actions/setup-java@v2
14 | with:
15 | distribution: 'adopt'
16 | java-version: '11'
17 |
18 | - name: Build APK
19 | run: ./gradlew build
20 |
21 | - uses: actions/upload-artifact@v2
22 | with:
23 | name: windows
24 | path: app/build/outputs/apk/prod/release/
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | demo.json
3 | *.iml
4 | .gradle
5 | local.properties
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 | .cxx
11 |
12 | app/release/app-release.apk
13 | app/release/output.json
14 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 奇遇淘客 Android 版
2 |
3 | 
4 | 
5 | 
6 |
7 |
8 | ## 奇遇淘客代码库
9 |
10 | * [奇遇淘客 iOS 版](https://github.com/QiYuTechDev/QiYuTkiOS)
11 | * [奇遇淘客 服务器端](https://github.com/QiYuTechDev/QiYuTkServer)
12 |
13 | ## 奇遇淘客文档
14 |
15 | [奇遇淘客 文档](https://tbk.qiyutech.tech/)
16 | [奇遇淘客 Android](https://tbk.qiyutech.tech/android/index.html)
17 |
18 | ## 博客文章
19 |
20 | [发布记录](https://blog.qiyutech.tech/202101/28_tbk_android/)
21 |
22 | ## Android Studio 版本
23 |
24 | ```text
25 | Android Studio Chipmunk | 2021.2.1 Patch 1
26 | Build #AI-212.5712.43.2112.8609683, built on May 19, 2022
27 | Runtime version: 11.0.12+0-b1504.28-7817840 x86_64
28 | VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
29 | macOS 11.6.7
30 | GC: G1 Young Generation, G1 Old Generation
31 | Memory: 2048M
32 | Cores: 8
33 | Registry: external.system.auto.import.disabled=true
34 | ```
35 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/libs/alibc_link_partner-4.1.15.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/alibc_link_partner-4.1.15.aar
--------------------------------------------------------------------------------
/app/libs/alibc_link_partner-4.1.23.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/alibc_link_partner-4.1.23.aar
--------------------------------------------------------------------------------
/app/libs/alipaysdk-15.8.00.201112210139.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/alipaysdk-15.8.00.201112210139.aar
--------------------------------------------------------------------------------
/app/libs/alipaysdk-noutdid-15.8.00.201112210139.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/alipaysdk-noutdid-15.8.00.201112210139.aar
--------------------------------------------------------------------------------
/app/libs/apsecuritysdk-all-3.3.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/apsecuritysdk-all-3.3.0.jar
--------------------------------------------------------------------------------
/app/libs/avmpaar3-5.4.200.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/avmpaar3-5.4.200.aar
--------------------------------------------------------------------------------
/app/libs/avmpaar3-5.4.36.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/avmpaar3-5.4.36.aar
--------------------------------------------------------------------------------
/app/libs/mtopsdk_allinone_open-3.1.2.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/mtopsdk_allinone_open-3.1.2.5.jar
--------------------------------------------------------------------------------
/app/libs/mtopsdk_allinone_open-3.1.7.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/mtopsdk_allinone_open-3.1.7.2.jar
--------------------------------------------------------------------------------
/app/libs/securitybodyaar3-5.4.200.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/securitybodyaar3-5.4.200.aar
--------------------------------------------------------------------------------
/app/libs/securitybodyaar3-5.4.99.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/securitybodyaar3-5.4.99.aar
--------------------------------------------------------------------------------
/app/libs/securityguardaar3-5.4.171.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/securityguardaar3-5.4.171.aar
--------------------------------------------------------------------------------
/app/libs/securityguardaar3-5.4.200.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/securityguardaar3-5.4.200.aar
--------------------------------------------------------------------------------
/app/libs/sgmiddletieraar3-5.4.200.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/sgmiddletieraar3-5.4.200.aar
--------------------------------------------------------------------------------
/app/libs/sgmiddletieraar3-5.4.9.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/sgmiddletieraar3-5.4.9.aar
--------------------------------------------------------------------------------
/app/libs/standardcashier-single-15.6.5.aar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/libs/standardcashier-single-15.6.5.aar
--------------------------------------------------------------------------------
/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 |
23 | -keep class com.qiyutech.tbk.** {*;}
24 |
25 | -keepattributes Signature
26 | -ignorewarnings
27 | -keep class javax.ws.rs.** { *; }
28 | -keep class com.alibaba.fastjson.** { *; }
29 | -dontwarn com.alibaba.fastjson.**
30 | -keep class sun.misc.Unsafe { *; }
31 | -dontwarn sun.misc.**
32 | -keep class com.taobao.** {*;}
33 | -keep class com.alibaba.** {*;}
34 | -keep class com.alipay.** {*;}
35 | -dontwarn com.taobao.**
36 | -dontwarn com.alibaba.**
37 | -dontwarn com.alipay.**
38 | -keep class com.ut.** {*;}
39 | -dontwarn com.ut.**
40 | -keep class com.ta.** {*;}
41 | -dontwarn com.ta.**
42 | -keep class org.json.** {*;}
43 | -keep class com.ali.auth.** {*;}
44 | -dontwarn com.ali.auth.**
45 | -keep class com.taobao.securityjni.** {*;}
46 | -keep class com.taobao.wireless.security.** {*;}
47 | -keep class com.taobao.dp.**{*;}
48 | -keep class com.alibaba.wireless.security.**{*;}
49 | -keep interface mtopsdk.mtop.global.init.IMtopInitTask {*;}
50 | -keep class * implements mtopsdk.mtop.global.init.IMtopInitTask {*;}
51 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/com/qiyutech/tbk/ExampleInstrumentedTest.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
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 tbk under test.
21 | val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22 | assertEquals("com.qiyutech.tbk", appContext.packageName)
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
23 |
26 |
30 |
33 |
37 |
41 |
46 |
50 |
55 |
59 |
63 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
79 |
83 |
87 |
91 |
96 |
100 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/app/src/main/assets/www/html/privacy.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 奇遇淘客隐私协议
6 |
7 |
8 |
9 |
10 |
11 | 您的隐私协议
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/CouponActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.app.SearchManager
4 | import android.os.Bundle
5 | import androidx.appcompat.app.AppCompatActivity
6 | import androidx.cursoradapter.widget.CursorAdapter
7 | import androidx.cursoradapter.widget.SimpleCursorAdapter
8 | import com.qiyutech.tbk.databinding.ActivityCouponBinding
9 | import com.qiyutech.tbk.fragments.home.HomeFragmentGuessYouLike
10 | import com.qiyutech.tbk.logic.CouponSearchQueryTextListener
11 | import com.qiyutech.tbk.logic.CouponSearchSuggestion
12 | import com.qiyutech.tbk.utils.AppUtils
13 |
14 | /**
15 | * 优惠券界面
16 | */
17 | class CouponActivity : AppCompatActivity() {
18 |
19 | override fun onCreate(savedInstanceState: Bundle?) {
20 | super.onCreate(savedInstanceState)
21 | setContentView(R.layout.activity_coupon)
22 |
23 | this.initItemSearchView()
24 |
25 | supportFragmentManager.beginTransaction()
26 | .replace(R.id.guess_you_like_fragment, HomeFragmentGuessYouLike())
27 | .commit()
28 | }
29 |
30 | /**
31 | * 初始化商品的搜索 只需要一次就行了
32 | */
33 | private fun initItemSearchView() {
34 | val from = arrayOf(SearchManager.SUGGEST_COLUMN_TEXT_1)
35 | val to = intArrayOf(R.id.item_label)
36 | val cursorAdapter = SimpleCursorAdapter(
37 | this,
38 | R.layout.search_search_item,
39 | null,
40 | from,
41 | to,
42 | CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
43 | )
44 |
45 | val view = AppUtils.getRootView(this)
46 | val bd = ActivityCouponBinding.bind(view)
47 |
48 | val searchView = bd.itemSearchView
49 | searchView.suggestionsAdapter = cursorAdapter
50 | searchView.setOnQueryTextListener(CouponSearchQueryTextListener(this, searchView))
51 | searchView.setOnSuggestionListener(CouponSearchSuggestion(searchView))
52 | }
53 |
54 | override fun onDestroy() {
55 | super.onDestroy()
56 |
57 | viewModelStore.clear()
58 | }
59 |
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/DevInfoActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import com.qiyutech.tbk.databinding.ActivityDevInfoBinding
6 | import com.qiyutech.tbk.databinding.PartsSimpleKvInfoBinding
7 | import com.qiyutech.tbk.fragments.TextHeaderFragment
8 | import com.qiyutech.tbk.utils.AppUtils
9 |
10 | /**
11 | * 开发信息模式
12 | */
13 | class DevInfoActivity : AppCompatActivity() {
14 | override fun onCreate(savedInstanceState: Bundle?) {
15 | super.onCreate(savedInstanceState)
16 | setContentView(R.layout.activity_dev_info)
17 |
18 | supportFragmentManager.beginTransaction()
19 | .replace(R.id.header, TextHeaderFragment("开发信息", true))
20 | .commit()
21 |
22 | val rv = AppUtils.getRootView(this)
23 | val bd = ActivityDevInfoBinding.bind(rv)
24 |
25 |
26 | val debug = if (AppUtils.inDebugMode()) {
27 | "是"
28 | } else {
29 | "否"
30 | }
31 | val test = if (AppUtils.inDevEnv()) {
32 | "是"
33 | } else {
34 | "否"
35 | }
36 |
37 | setKV(bd.debug, "调试", debug)
38 | setKV(bd.test, "测试", test)
39 | setKV(bd.server, "服务器", BuildConfig.BASE_URL)
40 | setKV(bd.sdkInt, "Android SDK", android.os.Build.VERSION.SDK_INT.toString())
41 | setKV(bd.mobileModel, "设备型号", android.os.Build.MODEL)
42 | setKV(bd.manufacturer, "制造商", android.os.Build.MANUFACTURER)
43 | }
44 |
45 | private fun setKV(p: PartsSimpleKvInfoBinding, k: String, v: String) {
46 | p.key.text = k
47 | p.value.text = v
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/GroupActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import com.qiyutech.tbk.fragments.TextHeaderFragment
6 |
7 |
8 | /**
9 | * 微信群 界面
10 | */
11 | class GroupActivity : AppCompatActivity() {
12 | override fun onCreate(savedInstanceState: Bundle?) {
13 | super.onCreate(savedInstanceState)
14 | setContentView(R.layout.activity_group)
15 |
16 | supportFragmentManager.beginTransaction()
17 | .replace(R.id.group_header, TextHeaderFragment("微信群"))
18 | .commit()
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/HomeActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.os.Bundle
4 | import android.util.Log
5 | import androidx.appcompat.app.AppCompatActivity
6 | import com.qiyutech.tbk.fragments.TextHeaderFragment
7 | import com.qiyutech.tbk.utils.AppNavUtils
8 | import com.qiyutech.tbk.utils.AppPrivacyUtils
9 | import com.qiyutech.tbk.utils.DialogUtils
10 | import com.qiyutech.tbk.utils.PushUtils
11 | import com.qiyutech.tbk.values.LogTags
12 |
13 |
14 | /**
15 | * 主页面
16 | */
17 | class HomeActivity : AppCompatActivity() {
18 | private var mAlreadyInit = false
19 |
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | setContentView(R.layout.activity_home)
23 |
24 | supportFragmentManager.beginTransaction()
25 | .replace(R.id.index_header, TextHeaderFragment("奇遇淘客"))
26 | .commit()
27 |
28 | }
29 |
30 |
31 | override fun onStart() {
32 | super.onStart()
33 |
34 | if (!mAlreadyInit) {
35 | oneTimeInit()
36 | }
37 |
38 | if (!AppPrivacyUtils.isPrivacyAgree(this)) {
39 | AppNavUtils.gotoPrivacy(this, false)
40 | }
41 | }
42 |
43 |
44 | private fun oneTimeInit() {
45 | if (mAlreadyInit) {
46 | return
47 | }
48 | PushUtils.reportPushId(this)
49 | notificationCheck()
50 |
51 | mAlreadyInit = true
52 | }
53 |
54 | private fun notificationCheck() {
55 | if (PushUtils.isNotificationEnabled(applicationContext)) {
56 | Log.i(LogTags.Push, "推送已经开启")
57 | } else {
58 | Log.i(LogTags.Push, "推送没有开启")
59 | val dialog = DialogUtils.notificationDialog(this)
60 | dialog.show()
61 | }
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/ItemDetailV2Activity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.graphics.Paint
4 | import android.os.Bundle
5 | import android.view.View
6 | import androidx.appcompat.app.AppCompatActivity
7 | import com.qiyutech.tbk.databinding.ActivityItemDetailV2Binding
8 | import com.qiyutech.tbk.dt.ApiTbkItemDetailStub
9 | import com.qiyutech.tbk.dt.DtTbkItemDetailForm
10 | import com.qiyutech.tbk.extend.MyManualImageView
11 | import com.qiyutech.tbk.logic.AppErrnoLogic
12 | import com.qiyutech.tbk.logic.TaoBaoLogic
13 | import com.qiyutech.tbk.utils.AppUtils
14 | import com.qiyutech.tbk.utils.TipUtils
15 |
16 | /**
17 | * 商品详情页 v2 版本
18 | */
19 | class ItemDetailV2Activity : AppCompatActivity() {
20 | // 商品 ID
21 | private var itemId: String = ""
22 |
23 |
24 | override fun onCreate(savedInstanceState: Bundle?) {
25 | super.onCreate(savedInstanceState)
26 | setContentView(R.layout.activity_item_detail_v2)
27 |
28 | itemId = intent.getStringExtra("item_id")!!
29 | }
30 |
31 | override fun onStart() {
32 | super.onStart()
33 |
34 | initGoodInfo()
35 | }
36 |
37 | private fun initGoodInfo() {
38 | val form = DtTbkItemDetailForm(tao_id = itemId)
39 | ApiTbkItemDetailStub.myPost(this, form, { ret ->
40 | AppErrnoLogic.genericServerErrnoProcess(ret.errno, this)
41 |
42 | val bd = this.getBinding()
43 | ret.data?.let { data ->
44 | // std details
45 | data.price_coupon?.let {
46 | bd.couponPrice.text = it.toInt().toString()
47 | }
48 | bd.productName.text = data.title_long
49 | bd.productIcon.loadImageFromUrl(data.tao_img)
50 | data.seller_logo?.let {
51 | bd.shopIcon.loadImageFromUrl(it)
52 | }
53 | bd.priceActual.text = "¥ ${data.price_actual}"
54 | bd.priceOrigin.text = "¥ ${data.price_origin}"
55 | // add middle line
56 | bd.priceOrigin.paintFlags = bd.priceOrigin.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
57 | bd.monthSale.text = data.sale_month.toString()
58 | data.seller_name?.let {
59 | bd.sellerName.text = it
60 | }
61 | bd.descScore.text = data.score_dsr.toString()
62 | bd.serviceScore.text = data.score_service.toString()
63 | bd.shipScore.text = data.score_ship.toString()
64 |
65 |
66 | data.tao_details?.let {
67 | it.forEach { url ->
68 | val img = MyManualImageView(this)
69 | bd.imageList.addView(img)
70 | img.loadImageFromUrl(url)
71 | }
72 | }
73 | }
74 | }, {
75 | TipUtils.toastLong(this, "获取商品信息失败: ${it.localizedMessage}")
76 | })
77 | }
78 |
79 | /**
80 | * 尝试购买 商品 信息
81 | */
82 | fun tryToBuy(view: View) {
83 | val tb = TaoBaoLogic(this)
84 | tb.buyItem(itemId)
85 | }
86 |
87 | fun shareToSys(view: View) {
88 |
89 | }
90 |
91 | @Suppress("UNUSED_PARAMETER")
92 | fun itemDetailV2Finish(view: View) {
93 | this.finish()
94 | }
95 |
96 | fun getBinding(): ActivityItemDetailV2Binding {
97 | val rv = AppUtils.getRootView(this)
98 | return ActivityItemDetailV2Binding.bind(rv)
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/MeActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import androidx.activity.viewModels
6 | import androidx.appcompat.app.AppCompatActivity
7 | import androidx.lifecycle.MutableLiveData
8 | import androidx.lifecycle.ViewModel
9 | import com.qiyutech.tbk.fragments.SFooterFragment
10 | import com.qiyutech.tbk.fragments.me.MeFragmentDefault
11 | import com.qiyutech.tbk.fragments.me.MeFragmentUser
12 | import com.qiyutech.tbk.logic.TaoBaoLogic
13 | import com.qiyutech.tbk.utils.AppUtils
14 |
15 |
16 | /**
17 | * ViewModel
18 | */
19 | class MeActivityUserViewModel : ViewModel() {
20 | /**
21 | * 展示的名称
22 | */
23 | val displayName: MutableLiveData by lazy {
24 | MutableLiveData("...")
25 | }
26 |
27 | /**
28 | * 用户 ID
29 | */
30 | val uuid: MutableLiveData by lazy {
31 | MutableLiveData("...")
32 | }
33 |
34 | }
35 |
36 |
37 | /**
38 | * 我的界面
39 | */
40 | class MeActivity : AppCompatActivity() {
41 |
42 | private val viewModel: MeActivityUserViewModel by viewModels()
43 |
44 |
45 | override fun onCreate(savedInstanceState: Bundle?) {
46 | super.onCreate(savedInstanceState)
47 | setContentView(R.layout.activity_me)
48 | }
49 |
50 | override fun onStart() {
51 | super.onStart()
52 |
53 | supportFragmentManager
54 | .beginTransaction()
55 | .replace(R.id.home_footer_container, SFooterFragment())
56 | .commit()
57 | }
58 |
59 | override fun onResume() {
60 | super.onResume()
61 |
62 | refreshActivityUI()
63 | }
64 |
65 | private fun refreshActivityUI() {
66 |
67 | val fragment = if (AppUtils.checkUserLogin(this)) {
68 | MeFragmentUser()
69 | } else {
70 | MeFragmentDefault()
71 | }
72 |
73 | supportFragmentManager.beginTransaction()
74 | .replace(R.id.slot, fragment)
75 | .commit()
76 | }
77 |
78 |
79 | override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
80 | if (requestCode == AUTH_REQUEST_CODE) {
81 | TaoBaoLogic.detectTaoBaoBind(this)
82 | return
83 | }
84 |
85 | super.onActivityResult(requestCode, resultCode, data)
86 | }
87 |
88 |
89 | /**
90 | * https://developer.android.com/topic/libraries/architecture/viewmodel
91 | */
92 | fun getUserViewModel(): MeActivityUserViewModel {
93 | return viewModel
94 | }
95 |
96 |
97 | override fun onDestroy() {
98 | super.onDestroy()
99 |
100 | viewModelStore.clear()
101 | }
102 |
103 |
104 | companion object {
105 | var AUTH_REQUEST_CODE = 2000
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/MyApplication.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.app.Application
4 | import android.webkit.WebView
5 | import com.alibaba.baichuan.android.trade.AlibcTradeSDK
6 | import com.billy.android.swipe.SmartSwipeBack
7 | import com.qiyutech.tbk.application.AliBCCallback
8 | import com.qiyutech.tbk.application.AppSwipeBack
9 | import com.qiyutech.tbk.utils.AppUtils
10 | import com.qiyutech.tbk.values.AppSpKeys
11 | import java.util.*
12 |
13 |
14 | /**
15 | * 我的基础程序进程
16 | */
17 | class MyApplication : Application() {
18 | override fun onCreate() {
19 | super.onCreate()
20 |
21 | SmartSwipeBack.activitySlidingBack(this, AppSwipeBack())
22 |
23 | AlibcTradeSDK.asyncInit(this, AliBCCallback(this))
24 |
25 | /// 自动生成 uuid 如果没有生成
26 | val t = AppUtils.getPreference(this)
27 | if (!t.contains(AppSpKeys.TBK_UUID)) {
28 | val uuid = "android-" + UUID.randomUUID().toString()
29 | t.edit().putString(AppSpKeys.TBK_UUID, uuid).apply()
30 | }
31 |
32 |
33 | if (AppUtils.inDevEnv()) {
34 | WebView.setWebContentsDebuggingEnabled(true)
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/PrivacyActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import android.webkit.WebView
6 | import androidx.appcompat.app.AppCompatActivity
7 | import com.qiyutech.tbk.databinding.ActivityPrivacyBinding
8 | import com.qiyutech.tbk.fragments.TextHeaderFragment
9 | import com.qiyutech.tbk.utils.AppPrivacyUtils
10 | import com.qiyutech.tbk.utils.AppUtils
11 | import com.qiyutech.tbk.values.HttpFile
12 |
13 | /**
14 | * 隐私协议活动
15 | */
16 | class PrivacyActivity : AppCompatActivity() {
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(R.layout.activity_privacy)
21 |
22 | supportFragmentManager.beginTransaction()
23 | .replace(R.id.header, TextHeaderFragment("奇遇淘客用户隐私协议", true))
24 | .commit()
25 |
26 | val wv = getWebView()
27 | wv.loadUrl(HttpFile.privacy)
28 | }
29 |
30 | override fun onStart() {
31 | super.onStart()
32 |
33 | val viewMode = intent.getBooleanExtra("view", false)
34 | if (viewMode) {
35 | val view = AppUtils.getRootView(this)
36 | val pb = ActivityPrivacyBinding.bind(view)
37 | pb.bottomButtons.visibility = View.GONE
38 | }
39 | }
40 |
41 | /**
42 | * 同意隐私协议
43 | */
44 | @Suppress("UNUSED_PARAMETER")
45 | fun agreePrivacy(view: View) {
46 | AppPrivacyUtils.setPrivacyAgree(this)
47 | privacyCloseActivity(view)
48 | }
49 |
50 |
51 | /**
52 | * 拒绝隐私协议
53 | * 直接退出程序
54 | */
55 | fun disagreePrivacy(view: View) {
56 | this.finishAffinity()
57 | }
58 |
59 | fun privacyCloseActivity(view: View) {
60 | this.finish()
61 | }
62 |
63 | override fun onDestroy() {
64 | super.onDestroy()
65 | getWebView().destroy()
66 | }
67 |
68 | private fun getWebView(): WebView {
69 | val view = AppUtils.getRootView(this)
70 | val pb = ActivityPrivacyBinding.bind(view)
71 | return pb.privacyWebView
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/SafeImgActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 |
6 | class SafeImgActivity : AppCompatActivity() {
7 |
8 | override fun onCreate(savedInstanceState: Bundle?) {
9 | super.onCreate(savedInstanceState)
10 | setContentView(R.layout.t_grid_demo)
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/SearchActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.app.SearchManager
4 | import android.database.Cursor
5 | import android.database.MatrixCursor
6 | import android.graphics.Color
7 | import android.os.Bundle
8 | import android.provider.BaseColumns
9 | import android.util.Log
10 | import android.view.View
11 | import android.view.ViewGroup
12 | import android.widget.Toast
13 | import androidx.appcompat.app.AppCompatActivity
14 | import androidx.appcompat.widget.AppCompatButton
15 | import androidx.appcompat.widget.SearchView
16 | import androidx.cursoradapter.widget.CursorAdapter
17 | import androidx.cursoradapter.widget.SimpleCursorAdapter
18 | import com.google.android.flexbox.FlexboxLayout
19 | import com.qiyutech.tbk.databinding.ActivitySearchBinding
20 | import com.qiyutech.tbk.dt.ApiDtkSearchSuggestionStub
21 | import com.qiyutech.tbk.dt.DtGoodsSearchSuggestionArgs
22 | import com.qiyutech.tbk.logic.AppErrnoLogic
23 | import com.qiyutech.tbk.utils.AppUtils
24 | import com.qiyutech.tbk.utils.LayoutUtils
25 | import com.qiyutech.tbk.utils.LoadKeywordUtils
26 | import com.qiyutech.tbk.utils.MySearchUtils
27 | import com.qiyutech.tbk.values.AppPreferenceUtils
28 |
29 |
30 | /**
31 | * 搜索 建议
32 | */
33 | private class SearchSuggestion(private val searchView: SearchView) :
34 | SearchView.OnSuggestionListener {
35 |
36 | override fun onSuggestionClick(position: Int): Boolean {
37 | val cursor = searchView.suggestionsAdapter.getItem(position) as Cursor
38 | val selection = cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1))
39 | searchView.setQuery(selection, false)
40 | return true
41 | }
42 |
43 | override fun onSuggestionSelect(position: Int): Boolean {
44 | return false
45 | }
46 | }
47 |
48 | private class SearchQueryTextListener(
49 | private val activity: SearchActivity,
50 | private val searchView: SearchView
51 | ) :
52 | SearchView.OnQueryTextListener {
53 |
54 | override fun onQueryTextSubmit(query: String?): Boolean {
55 | // extract to search method
56 | if (query.isNullOrBlank()) {
57 | return false
58 | }
59 |
60 | MySearchUtils.doSearch(activity, query)
61 |
62 | return true
63 | }
64 |
65 | override fun onQueryTextChange(query: String?): Boolean {
66 | if (query.isNullOrBlank()) {
67 | return true
68 | }
69 |
70 | val args = DtGoodsSearchSuggestionArgs(keyWords = query, type = "3")
71 | ApiDtkSearchSuggestionStub.myPost(activity, args,
72 | { v ->
73 | AppErrnoLogic.genericServerErrnoProcess(v.errno, activity)
74 | if (v.errno != 0) {
75 | Log.w("request suggest failed:", v.toString())
76 | return@myPost
77 | }
78 | val cursor =
79 | MatrixCursor(arrayOf(BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1))
80 |
81 | v.data?.forEachIndexed { index, suggestion ->
82 | val item = arrayOf(index, suggestion)
83 | cursor.addRow(item)
84 | }
85 |
86 | this.searchView.suggestionsAdapter.changeCursor(cursor)
87 |
88 | },
89 | { error -> Log.e("search suggest", "错误: $error") }
90 | )
91 |
92 | return false
93 | }
94 | }
95 |
96 | /**
97 | * 商品主搜索界面
98 | */
99 | class SearchActivity : AppCompatActivity() {
100 | override fun onCreate(savedInstanceState: Bundle?) {
101 | super.onCreate(savedInstanceState)
102 | setContentView(R.layout.activity_search)
103 |
104 | val from = arrayOf(SearchManager.SUGGEST_COLUMN_TEXT_1)
105 | val to = intArrayOf(R.id.item_label)
106 | val cursorAdapter = SimpleCursorAdapter(
107 | this,
108 | R.layout.search_search_item,
109 | null,
110 | from,
111 | to,
112 | CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
113 | )
114 |
115 | val view = AppUtils.getRootView(this)
116 | val asb = ActivitySearchBinding.bind(view)
117 |
118 | val searchInput = asb.searchSearchInput
119 | searchInput.suggestionsAdapter = cursorAdapter
120 |
121 | searchInput.setOnQueryTextListener(SearchQueryTextListener(this, searchInput))
122 | searchInput.setOnSuggestionListener(SearchSuggestion(searchInput))
123 | }
124 |
125 | override fun onStart() {
126 | super.onStart()
127 |
128 | val lku = LoadKeywordUtils(this)
129 | lku.loadKeyword()
130 |
131 | loadSearchHistoryKeyword()
132 | }
133 |
134 |
135 | fun closeSearchActivity(view: View) {
136 | this.finish()
137 | }
138 |
139 | /**
140 | * 搜索商品
141 | */
142 | fun doSearchItem(view: View) {
143 | val root = AppUtils.getRootView(this)
144 | val sb = ActivitySearchBinding.bind(root)
145 | val input = sb.searchSearchInput
146 | val query = input.query.toString()
147 | if (query.isBlank()) {
148 | Toast.makeText(this, "查询内容为空", Toast.LENGTH_SHORT).show()
149 | return
150 | } else {
151 | MySearchUtils.doSearch(this, query)
152 | }
153 | }
154 |
155 | /**
156 | * 获取 自定义的 btn
157 | */
158 | private fun getBtn(): AppCompatButton {
159 | val ctx = baseContext
160 |
161 | val btn = AppCompatButton(this)
162 | btn.layoutParams = FlexboxLayout.LayoutParams(
163 | ViewGroup.LayoutParams.WRAP_CONTENT,
164 | LayoutUtils.spToInt(ctx, 36)
165 | )
166 |
167 | val layer2 = btn.layoutParams as ViewGroup.MarginLayoutParams
168 | layer2.topMargin = LayoutUtils.spToInt(ctx, 4)
169 | layer2.bottomMargin = LayoutUtils.spToInt(ctx, 4)
170 | layer2.marginStart = LayoutUtils.spToInt(ctx, 5)
171 | layer2.marginEnd = LayoutUtils.spToInt(ctx, 5)
172 |
173 | btn.setBackgroundResource(R.drawable.search_button_bg)
174 | btn.setTextColor(Color.parseColor("#666666"))
175 | btn.setPadding(30, 0, 30, 0)
176 |
177 | return btn
178 | }
179 |
180 | /**
181 | * 加载搜索的历史
182 | */
183 | fun loadSearchHistoryKeyword() {
184 | val view = AppUtils.getRootView(this)
185 | val asb = ActivitySearchBinding.bind(view)
186 |
187 | val searchFlexBoxLayout = asb.searchHistoryFlexBoxLayoutId
188 | searchFlexBoxLayout.removeAllViews()
189 |
190 | AppPreferenceUtils.getSearchHistory(this).map {
191 | val btn = this.getBtn()
192 | btn.text = it
193 |
194 | btn.setOnClickListener { _ ->
195 | MySearchUtils.doSearch(this, it)
196 | }
197 |
198 | btn.requestLayout()
199 | searchFlexBoxLayout.addView(btn)
200 | }
201 | searchFlexBoxLayout.requestLayout()
202 | }
203 |
204 | /// 把搜索的热词加载到界面中
205 | fun pushHotSearchKeyword(dataList: List) {
206 | val view = AppUtils.getRootView(this)
207 | val asb = ActivitySearchBinding.bind(view)
208 |
209 | val fl = asb.hotSearchFlexBoxLayoutId
210 | fl.removeAllViews()
211 | dataList.map {
212 | val btn = this.getBtn()
213 | btn.text = it
214 | btn.setOnClickListener { _ ->
215 | MySearchUtils.doSearch(this, it)
216 | }
217 | btn.requestLayout()
218 | fl.addView(btn)
219 | }
220 | fl.requestLayout()
221 | }
222 | }
223 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/SettingsActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.annotation.SuppressLint
4 | import android.os.Bundle
5 | import android.view.View
6 | import android.widget.Toast
7 | import androidx.appcompat.app.AppCompatActivity
8 | import com.qiyutech.tbk.fragments.settings.SettingsFragmentLogin
9 | import com.qiyutech.tbk.fragments.settings.SettingsFragmentUser
10 | import com.qiyutech.tbk.logic.UserLogic
11 | import com.qiyutech.tbk.utils.AppUtils
12 | import com.qiyutech.tbk.utils.DialogUtils
13 | import com.qiyutech.tbk.utils.PopupUtils
14 |
15 | /**
16 | * 配置 UI 页面
17 | */
18 | class SettingsActivity : AppCompatActivity() {
19 | @SuppressLint("InflateParams")
20 | override fun onCreate(savedInstanceState: Bundle?) {
21 | super.onCreate(savedInstanceState)
22 | setContentView(R.layout.settings_activity)
23 | }
24 |
25 | override fun onStart() {
26 | super.onStart()
27 |
28 | this.refreshUI()
29 | }
30 |
31 | private fun refreshUI() {
32 | val fragment = if (AppUtils.checkUserLogin(this)) {
33 | SettingsFragmentUser()
34 | } else {
35 | SettingsFragmentLogin()
36 | }
37 |
38 | supportFragmentManager.beginTransaction()
39 | .replace(R.id.setting_slot, fragment)
40 | .commit()
41 | }
42 |
43 |
44 | // 注销用户
45 | @Suppress("UNUSED_PARAMETER")
46 | fun settingUserCancel(view: View) {
47 | if (!AppUtils.checkUserLogin(this)) {
48 | return
49 | }
50 |
51 | /// 用户确认之后执行 注销用户的逻辑
52 | DialogUtils.userCancelDialog(this) {
53 | UserLogic.cancel(this)
54 | }.show()
55 | }
56 |
57 | /**
58 | * 退出登陆
59 | */
60 | @Suppress("UNUSED_PARAMETER")
61 | fun settingUserLogout(view: View) {
62 | if (AppUtils.checkUserLogin(this)) {
63 | UserLogic.logout(this)
64 | Toast.makeText(this, "您已经退出登陆!", Toast.LENGTH_LONG).show()
65 | } else {
66 | Toast.makeText(this, "您当前没有登陆!", Toast.LENGTH_LONG).show()
67 | }
68 | setNotLoginView()
69 | }
70 |
71 | fun setNotLoginView() {
72 | // 用户已经退出登陆
73 | this.refreshUI()
74 | }
75 |
76 | /**
77 | * android 清理缓存
78 | */
79 | fun deleteCacheFiles(view: View) {
80 |
81 | val (_, popupWindow) = PopupUtils.createPopup(
82 | view,
83 | inflater = layoutInflater,
84 | R.layout.popup_clean_cache,
85 | false
86 | )
87 |
88 | val activity = this
89 | val cache = cacheDir
90 |
91 | Thread {
92 | cache.deleteRecursively()
93 |
94 | runOnUiThread {
95 | popupWindow.dismiss()
96 | Toast.makeText(activity, "清理缓存完成", Toast.LENGTH_LONG).show()
97 | }
98 | }.start()
99 | }
100 |
101 |
102 | /**
103 | * 检测是否有新版本 [android 检测] iOS 使用 App Store 接口就可以了
104 | */
105 | fun checkAppUpgrade(view: View) {
106 | Toast.makeText(this, "此功能已经移除", Toast.LENGTH_LONG).show()
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/TaoBaoActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.annotation.SuppressLint
4 | import android.app.Activity
5 | import android.content.Intent
6 | import android.os.Bundle
7 | import android.util.Log
8 | import android.webkit.WebChromeClient
9 | import android.webkit.WebView
10 | import android.webkit.WebViewClient
11 | import android.widget.Toast
12 | import androidx.appcompat.app.AppCompatActivity
13 | import com.alibaba.baichuan.android.trade.AlibcTrade
14 | import com.alibaba.baichuan.android.trade.model.AlibcShowParams
15 | import com.alibaba.baichuan.android.trade.model.OpenType
16 | import com.alibaba.baichuan.trade.biz.applink.adapter.AlibcFailModeType
17 | import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams
18 | import com.alibaba.baichuan.trade.biz.login.AlibcLogin
19 | import com.alibaba.baichuan.trade.biz.login.AlibcLoginCallback
20 | import com.qiyutech.tbk.activity.taobao.MyAuthTradeCb
21 | import com.qiyutech.tbk.databinding.ActivityTaoBaoBinding
22 | import com.qiyutech.tbk.utils.AppUtils
23 | import com.qiyutech.tbk.values.AppPreferenceUtils
24 | import com.qiyutech.tbk.values.LogTags
25 |
26 | @SuppressLint("SetJavaScriptEnabled")
27 | class TaoBaoActivity : AppCompatActivity() {
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | setContentView(R.layout.activity_tao_bao)
31 | }
32 |
33 | @SuppressLint("JavascriptInterface")
34 | override fun onStart() {
35 | super.onStart()
36 |
37 | val wv = getTaoBaoWebView()
38 | wv.settings.javaScriptEnabled = true
39 |
40 | when (intent.getStringExtra("type")) {
41 | "auth" -> {
42 | myOpenAuthPage()
43 | }
44 | else -> {
45 | this.finish()
46 | }
47 | }
48 | }
49 |
50 |
51 | override fun onDestroy() {
52 | super.onDestroy()
53 |
54 | val wv = getTaoBaoWebView()
55 | wv.destroy()
56 | }
57 |
58 | private fun getTaoBaoWebView(): WebView {
59 | val view = AppUtils.getRootView(this)
60 | val tbd = ActivityTaoBaoBinding.bind(view)
61 | return tbd.taoBaoWebView
62 | }
63 |
64 | private fun myOpenAuthPage() {
65 | val url = intent.getStringExtra("url")
66 |
67 | val activity = this
68 |
69 | /// 淘宝授权免密码输入
70 | /// https://blog.csdn.net/get_moon/article/details/102593901
71 |
72 | val alibc = AlibcLogin.getInstance()
73 | alibc.showLogin(object : AlibcLoginCallback {
74 | override fun onSuccess(LoginResult: Int, openId: String?, userNick: String?) {
75 | // loginResult(0--登录初始化成功;1--登录初始化完成;2--登录成功)
76 | // openId:用户id
77 | // userNick: 用户昵称
78 |
79 | // save user nick
80 | // save user avatar
81 | val session = alibc.session
82 | AppPreferenceUtils.setTaoId(activity, session.userid)
83 |
84 | Log.i(LogTags.AliBC, "$session")
85 |
86 | val show = AlibcShowParams()
87 |
88 | show.openType = OpenType.Auto
89 | show.clientType = "taobao"
90 | show.nativeOpenFailedMode = AlibcFailModeType.AlibcNativeFailModeJumpH5
91 |
92 | val taoke = AlibcTaokeParams("", "", "")
93 | taoke.pid = BuildConfig.ALI_PID
94 |
95 | AlibcTrade.openByUrl(
96 | activity,
97 | "",
98 | url,
99 | getTaoBaoWebView(),
100 | WebViewClient(),
101 | WebChromeClient(),
102 | show,
103 | taoke,
104 | null,
105 | MyAuthTradeCb()
106 | )
107 | }
108 |
109 | override fun onFailure(code: Int, msg: String?) {
110 | // code 错误码
111 | // msg 错误信息
112 | Toast.makeText(activity, "淘宝授权失败($code): $msg", Toast.LENGTH_SHORT).show()
113 | }
114 | })
115 | }
116 |
117 | companion object {
118 | fun openAuthPage(activity: Activity, url: String) {
119 | val intent = Intent(activity, TaoBaoActivity::class.java)
120 |
121 | intent.putExtra("type", "auth") // enum type
122 | intent.putExtra("url", url)
123 |
124 | // activity.startActivity(intent)
125 | activity.startActivityForResult(intent, MeActivity.AUTH_REQUEST_CODE)
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/UserInfoActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import com.qiyutech.tbk.databinding.ActivityUserInfoBinding
6 | import com.qiyutech.tbk.databinding.PartsSimpleKvInfoBinding
7 | import com.qiyutech.tbk.fragments.TextHeaderFragment
8 | import com.qiyutech.tbk.logic.TaoBaoLogic
9 | import com.qiyutech.tbk.utils.AppUtils
10 | import com.qiyutech.tbk.utils.DialogUtils
11 | import com.qiyutech.tbk.values.AppPreferenceUtils
12 |
13 | /**
14 | * 用户状态展示
15 | */
16 | class UserInfoActivity : AppCompatActivity() {
17 | override fun onCreate(savedInstanceState: Bundle?) {
18 | super.onCreate(savedInstanceState)
19 | setContentView(R.layout.activity_user_info)
20 |
21 |
22 | supportFragmentManager.beginTransaction()
23 | .replace(R.id.header, TextHeaderFragment("用户信息", true))
24 | .commit()
25 |
26 | initBtnEvent()
27 | }
28 |
29 | override fun onStart() {
30 | super.onStart()
31 |
32 | initUserInfo()
33 | }
34 |
35 | private fun initBtnEvent() {
36 | val bd = getBinding()
37 | bd.bindTb.setOnClickListener {
38 | val doBind = {
39 | val logic = TaoBaoLogic(this)
40 | logic.tryAuth()
41 | }
42 | AppPreferenceUtils.getUserInfo(this)?.let { userInfo ->
43 | userInfo.relation_id?.let {
44 | // 已经绑定了淘宝账号, 是否重新绑定
45 | DialogUtils.reBindTbDialog(this) {
46 | doBind()
47 | }
48 | return@setOnClickListener
49 | }
50 | }
51 | doBind()
52 | }
53 | }
54 |
55 | private fun initUserInfo() {
56 | val userInfo = AppPreferenceUtils.getUserInfo(this)
57 | if (userInfo == null) {
58 | this.finish()
59 | return
60 | }
61 |
62 | val bd = getBinding()
63 |
64 | setKV(bd.mobile, "手机号码", userInfo.mobile ?: "")
65 | setKV(bd.taoId, "淘宝ID", userInfo.tao_id ?: "")
66 | setKV(bd.wx, "微信", userInfo.wx ?: "")
67 | setKV(bd.relationId, "渠道ID", userInfo.relation_id ?: "")
68 | setKV(bd.aliName, "支付宝姓名", userInfo.ali_name ?: "")
69 | setKV(bd.aliAccount, "支付宝账号", userInfo.ali_account ?: "")
70 | }
71 |
72 | private fun setKV(bd: PartsSimpleKvInfoBinding, k: String, v: String) {
73 | bd.key.text = k
74 | bd.value.text = v
75 | }
76 |
77 | private fun getBinding(): ActivityUserInfoBinding {
78 | val rv = AppUtils.getRootView(this)
79 | return ActivityUserInfoBinding.bind(rv)
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/UserPasswordActivity.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import android.os.Bundle
4 | import android.view.View
5 | import android.widget.Toast
6 | import androidx.appcompat.app.AppCompatActivity
7 | import com.qiyutech.tbk.databinding.UserPasswordActivityBinding
8 | import com.qiyutech.tbk.fragments.TextHeaderFragment
9 | import com.qiyutech.tbk.logic.UserLogic
10 | import com.qiyutech.tbk.utils.AppUtils
11 |
12 |
13 | /**
14 | * 账号密码登陆页面
15 | */
16 | class UserPasswordActivity : AppCompatActivity() {
17 |
18 | override fun onCreate(savedInstanceState: Bundle?) {
19 | super.onCreate(savedInstanceState)
20 | setContentView(R.layout.user_password_activity)
21 |
22 | supportFragmentManager.beginTransaction()
23 | .replace(R.id.user_password_header, TextHeaderFragment("奇遇淘客登录", true))
24 | .commit()
25 | }
26 |
27 | /**
28 | * 关闭当前的界面
29 | */
30 | fun userPasswordClose(view: View) {
31 | this.finish()
32 | }
33 |
34 | /**
35 | * 用户密码登陆
36 | */
37 | fun usernamePasswordLogin(view: View) {
38 | val rv = AppUtils.getRootView(this)
39 | val bind = UserPasswordActivityBinding.bind(rv)
40 |
41 | val username = bind.usernameText.text.toString()
42 | val password = bind.passwordText.text.toString()
43 |
44 | if (username.isEmpty()) {
45 | Toast.makeText(this, "账号不能为空", Toast.LENGTH_LONG).show()
46 | return
47 | }
48 |
49 | if (password.isEmpty()) {
50 | Toast.makeText(this, "密码不能为空", Toast.LENGTH_LONG).show()
51 | return
52 | }
53 |
54 | UserLogic.usernamePasswordTryLogin(this, username = username, password = password)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/activity/question/MyJsonObjectRequest.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.activity.question
2 |
3 | import com.android.volley.Response
4 | import com.android.volley.toolbox.JsonObjectRequest
5 | import org.json.JSONObject
6 |
7 | class MyJsonObjectRequest(
8 | i: Int,
9 | url: String,
10 | json: JSONObject,
11 | success: Response.Listener,
12 | failure: Response.ErrorListener
13 | ) :
14 | JsonObjectRequest(i, url, json, success, failure) {
15 |
16 | override fun getHeaders(): Map {
17 | return mapOf("Accept" to "application/json", "Content-Type" to "application/json")
18 | }
19 | }
20 |
21 | class MyGetRequest(
22 | url: String,
23 | success: Response.Listener,
24 | failure: Response.ErrorListener
25 | ) : JsonObjectRequest(Method.GET, url, null, success, failure) {
26 |
27 | override fun getHeaders(): Map {
28 | return mapOf("accept" to "application/json")
29 | }
30 | }
31 |
32 |
33 | class MySuggestRequest(
34 | url: String,
35 | success: Response.Listener,
36 | failure: Response.ErrorListener
37 | ) :
38 | JsonObjectRequest(url, null, success, failure) {
39 |
40 | override fun getHeaders(): Map {
41 | return mapOf("accept" to "application/json")
42 | }
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/activity/taobao/MyAuthCb.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.activity.taobao
2 |
3 | import android.util.Log
4 | import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback
5 | import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult
6 | import com.qiyutech.tbk.values.LogTags
7 |
8 | /**
9 | * 打开 认证页面的 回调
10 | */
11 | class MyAuthTradeCb : AlibcTradeCallback {
12 | override fun onFailure(p0: Int, p1: String?) {
13 | Log.e(LogTags.AliBC, "错误信息: ${p0}: $p1")
14 | }
15 |
16 | override fun onTradeSuccess(p: AlibcTradeResult?) {
17 | if (p == null) {
18 | return
19 | }
20 | Log.i(LogTags.AliBC, p.toString())
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/api/ZTK.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.api
2 |
3 | import androidx.appcompat.app.AppCompatActivity
4 | import com.android.volley.VolleyError
5 | import com.android.volley.toolbox.JsonObjectRequest
6 | import com.android.volley.toolbox.Volley
7 | import com.qiyutech.tbk.dt.DtKeywordResponseModel
8 | import com.qiyutech.tbk.dt.DtSuggestResponseModel
9 | import com.qiyutech.tbk.utils.MyHttpUtils
10 | import com.qiyutech.tbk.values.TbkAPIUrls
11 | import java.net.URLEncoder
12 |
13 | /**
14 | * 折淘客 API 接口
15 | */
16 | class ZTK(val activity: AppCompatActivity, val tag: String) {
17 |
18 | /**
19 | * 获取 推荐词 的请求
20 | */
21 | fun suggestV2(
22 | q: String,
23 | success: (DtSuggestResponseModel) -> Unit,
24 | failure: (VolleyError) -> Unit
25 | ) {
26 | val url = "${TbkAPIUrls.ZtkSuggest}?content=${URLEncoder.encode(q, "UTF-8")}"
27 | val r = MyHttpUtils.getRequest(url, success, failure)
28 | addToQueue(r)
29 | }
30 |
31 |
32 | /**
33 | * 热词推荐
34 | */
35 | fun hotKeyword(success: (DtKeywordResponseModel) -> Unit, failure: (VolleyError) -> Unit) {
36 | val r = MyHttpUtils.getRequest(
37 | TbkAPIUrls.ZtkKeyword,
38 | success,
39 | failure
40 | )
41 | addToQueue(r)
42 | }
43 |
44 | private fun addToQueue(r: JsonObjectRequest) {
45 | r.tag = tag
46 | val volley = Volley.newRequestQueue(activity)
47 | volley.add(r)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/application/AliBCCallback.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.application
2 |
3 | import android.app.Application
4 | import android.util.Log
5 | import android.widget.Toast
6 | import com.alibaba.baichuan.android.trade.callback.AlibcTradeInitCallback
7 | import com.qiyutech.tbk.values.LogTags
8 |
9 | /**
10 | * 阿里百川回调
11 | */
12 | class AliBCCallback(private val app: Application) : AlibcTradeInitCallback {
13 | override fun onFailure(p0: Int, p1: String?) {
14 | Toast.makeText(app.baseContext, "阿里百川初始化失败: $p1($p0)", Toast.LENGTH_LONG).show()
15 | Log.i(LogTags.AliBC, "初始化失败: $p1($p0)")
16 | }
17 |
18 | override fun onSuccess() {
19 | Log.i(LogTags.AliBC, "初始化成功")
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/application/AppSwipeBack.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.application
2 |
3 | import android.app.Activity
4 | import com.billy.android.swipe.SmartSwipeBack
5 | import com.qiyutech.tbk.*
6 |
7 | /**
8 | * 侧边滑动返回
9 | *
10 | * https://qibilly.com/SmartSwipe-tutorial/pages/SmartSwipeBack.html
11 | */
12 | class AppSwipeBack : SmartSwipeBack.ActivitySwipeBackFilter {
13 | override fun onFilter(activity: Activity?): Boolean {
14 | if (activity == null) {
15 | return false
16 | }
17 |
18 | return when (activity) {
19 | is DevInfoActivity -> true
20 | is ItemDetailV2Activity -> true
21 | is PrivacyActivity -> true
22 | is SearchActivity -> true
23 | is SearchDetailNativeActivity -> true
24 | is SettingsActivity -> true
25 | is TaoBaoActivity -> true
26 | is UserInfoActivity -> true
27 | is UserPasswordActivity -> true
28 | else -> false
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/dt/shared.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.dt
2 |
3 |
4 | enum class TbkSortType {
5 | Common, // 综合排序
6 | Sales, // 销量
7 | Price; // 价格
8 |
9 |
10 | fun getString(): String? {
11 | return when (this) {
12 | Common -> null
13 | Sales -> "total_sales_des"
14 | Price -> "price_asc"
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/events/LoginEvent.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.events
2 |
3 | import android.content.Context
4 | import com.qiyutech.tbk.logic.TaoBaoLogic
5 | import com.qiyutech.tbk.utils.PushUtils
6 |
7 | /**
8 | * 登陆之后的回调
9 | */
10 | object LoginEvent {
11 | /**
12 | * 回调函数
13 | */
14 | fun callback(ctx: Context) {
15 | /// 登陆之后 需要发送 绑定新的 push ID
16 | PushUtils.reportPushId(ctx)
17 | /// 登陆之后自动检测是否已经绑定淘宝号
18 | TaoBaoLogic.detectTaoBaoBind(ctx)
19 | }
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/events/LogoutEvent.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.events
2 |
3 | import android.content.Context
4 | import com.qiyutech.tbk.utils.PushUtils
5 |
6 | /**
7 | * 退出登陆之后的事件
8 | */
9 | object LogoutEvent {
10 | /**
11 | * 回调函数
12 | */
13 | fun callback(ctx: Context) {
14 | PushUtils.reportPushId(ctx)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/extend/MyNetworkImageView.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.extend
2 |
3 | import android.content.Context
4 | import android.util.AttributeSet
5 | import androidx.appcompat.widget.AppCompatImageView
6 | import com.bumptech.glide.Glide
7 | import com.bumptech.glide.load.engine.DiskCacheStrategy
8 | import com.qiyutech.tbk.utils.NetworkImageUtils
9 | import com.qiyutech.tbk.utils.TipUtils
10 |
11 | /**
12 | * 编程自动加载图片
13 | */
14 | class MyManualImageView(ctx: Context) : AppCompatImageView(ctx) {
15 | /**
16 | * 自动加载图片
17 | */
18 | fun loadImageFromUrl(imageUrl: String) {
19 | val url = if (imageUrl.startsWith("//")) {
20 | "http:${imageUrl}"
21 | } else {
22 | imageUrl
23 | }
24 |
25 | Glide.with(context)
26 | .load(url)
27 | .diskCacheStrategy(DiskCacheStrategy.ALL)
28 | .skipMemoryCache(true)
29 | .into(this)
30 | }
31 | }
32 |
33 | /**
34 | * 网络图片 View
35 | * 自动加载网络图片 如果需要的话
36 | */
37 | class MyNetworkImageView(ctx: Context, attrSet: AttributeSet) : AppCompatImageView(ctx, attrSet) {
38 | /**
39 | * 自动加载图片
40 | */
41 | fun loadImageFromUrl(imageUrl: String, displayError: Boolean = false) {
42 | val url = if (imageUrl.startsWith("//")) {
43 | "http:${imageUrl}"
44 | } else {
45 | imageUrl
46 | }
47 |
48 | // 使用 glide 加载会导致 slot 图片不展示
49 | NetworkImageUtils.download(context,
50 | url,
51 | this.scaleType,
52 | { image -> this.setImageBitmap(image) },
53 | {
54 | if (displayError) {
55 | TipUtils.toastShort(context, "下载图片失败: $it")
56 | }
57 | })
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/fragments/SFooterFragment.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.fragments
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import com.qiyutech.tbk.*
9 | import com.qiyutech.tbk.databinding.SFooterBinding
10 | import com.qiyutech.tbk.utils.AppNavUtils
11 |
12 |
13 | /**
14 | * 导航依赖
15 | */
16 | class SFooterFragment : Fragment(R.layout.fragment_s_footer) {
17 | /// 绑定视图到 Fragment
18 | /// https://developer.android.com/topic/libraries/view-binding
19 | private var _binding: SFooterBinding? = null
20 |
21 | // This property is only valid between onCreateView and
22 | // onDestroyView.
23 | private val binding get() = _binding!!
24 |
25 |
26 | override fun onCreateView(
27 | inflater: LayoutInflater,
28 | container: ViewGroup?,
29 | savedInstanceState: Bundle?
30 | ): View {
31 | _binding = SFooterBinding.inflate(inflater, container, false)
32 |
33 | return binding.root
34 | }
35 |
36 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
37 | super.onViewCreated(view, savedInstanceState)
38 |
39 | val menu = binding.homeFooter.menu
40 |
41 | val index = menu.getItem(0)
42 | if (activity is HomeActivity) {
43 | index.isChecked = true
44 | } else {
45 | index.setOnMenuItemClickListener {
46 | AppNavUtils.gotoHome(requireActivity())
47 | true
48 | }
49 | }
50 |
51 | val group = menu.getItem(1)
52 | if (activity is GroupActivity) {
53 | group.isChecked = true
54 | } else {
55 | group.setOnMenuItemClickListener {
56 | AppNavUtils.gotoGroup(requireActivity())
57 | true
58 | }
59 | }
60 |
61 |
62 | val coupon = menu.getItem(2)
63 | if (activity is CouponActivity) {
64 | coupon.isChecked = true
65 | } else {
66 | coupon.setOnMenuItemClickListener {
67 | AppNavUtils.gotoCoupon(requireActivity())
68 | true
69 | }
70 | }
71 |
72 | val me = menu.getItem(3)
73 | if (activity is MeActivity) {
74 | me.isChecked = true
75 | } else {
76 | me.setOnMenuItemClickListener {
77 | AppNavUtils.gotoMe(requireActivity())
78 | true
79 | }
80 | }
81 | }
82 |
83 | override fun onDestroyView() {
84 | super.onDestroyView()
85 | _binding = null
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/fragments/TextHeaderFragment.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.fragments
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import com.qiyutech.tbk.databinding.FragmentTextHeaderBinding
9 |
10 |
11 | /**
12 | * 简单的文字 header 界面
13 | *
14 | * 也许应该增加是否需要返回按钮
15 | */
16 | class TextHeaderFragment(
17 | private val title: String,
18 | private val displayBack: Boolean = false
19 | ) : Fragment() {
20 |
21 | private var bd: FragmentTextHeaderBinding? = null
22 |
23 | override fun onCreateView(
24 | inflater: LayoutInflater,
25 | container: ViewGroup?,
26 | savedInstanceState: Bundle?
27 | ): View? {
28 | bd = FragmentTextHeaderBinding.inflate(inflater, container, false)
29 | bd?.let {
30 | it.title.text = title
31 |
32 | this.initBackButton()
33 |
34 | return it.root
35 | }
36 | return null
37 | }
38 |
39 | private fun initBackButton() {
40 | bd?.let {
41 | if (!displayBack) {
42 | it.backBtn.visibility = View.GONE
43 | }
44 | it.backBtn.setOnClickListener {
45 | this.requireActivity().finish()
46 | }
47 | }
48 | }
49 |
50 | /**
51 | * 设置新的 title
52 | */
53 | fun setTitle(title: String) {
54 | bd?.let {
55 | it.title.text = title
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/fragments/me/MeFragmentDefault.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.fragments.me
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import com.qiyutech.tbk.databinding.FragmentMeDefaultBinding
9 | import com.qiyutech.tbk.utils.AppNavUtils
10 |
11 |
12 | /**
13 | * 我的默认界面【没有登录】
14 | */
15 | class MeFragmentDefault : Fragment() {
16 |
17 | var bd: FragmentMeDefaultBinding? = null
18 |
19 | override fun onCreateView(
20 | inflater: LayoutInflater, container: ViewGroup?,
21 | savedInstanceState: Bundle?
22 | ): View {
23 | val t = FragmentMeDefaultBinding.inflate(inflater, container, false)
24 | bd = t
25 | return t.root
26 | }
27 |
28 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
29 | super.onViewCreated(view, savedInstanceState)
30 | bd?.let {
31 |
32 | it.gotoSetting.setOnClickListener {
33 | AppNavUtils.gotoSettings(requireActivity())
34 | }
35 |
36 | it.meName.setOnClickListener {
37 | // todo login
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/fragments/me/MeFragmentSlot.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.fragments.me
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import com.qiyutech.tbk.databinding.FragmentMeSlotBinding
9 |
10 |
11 | /**
12 | * 我的已经登陆的界面
13 | */
14 | class MeFragmentSlot : Fragment() {
15 |
16 | var bd: FragmentMeSlotBinding? = null
17 |
18 | override fun onCreateView(
19 | inflater: LayoutInflater, container: ViewGroup?,
20 | savedInstanceState: Bundle?
21 | ): View {
22 | val t = FragmentMeSlotBinding.inflate(inflater, container, false)
23 | bd = t
24 | return t.root
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/fragments/me/MeFragmentUser.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.fragments.me
2 |
3 | import android.os.Bundle
4 | import android.util.Log
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import android.widget.Toast
9 | import androidx.fragment.app.Fragment
10 | import com.qiyutech.tbk.MeActivity
11 | import com.qiyutech.tbk.MeActivityUserViewModel
12 | import com.qiyutech.tbk.databinding.FragmentMeUserBinding
13 | import com.qiyutech.tbk.dt.ApiUserProfileStub
14 | import com.qiyutech.tbk.dt.DtUserTokenForm
15 | import com.qiyutech.tbk.logic.AppErrnoLogic
16 | import com.qiyutech.tbk.logic.DisplayLogic
17 | import com.qiyutech.tbk.logic.TaoBaoLogic
18 | import com.qiyutech.tbk.utils.AppNavUtils
19 | import com.qiyutech.tbk.utils.TipUtils
20 | import com.qiyutech.tbk.values.AppPreferenceUtils
21 |
22 |
23 | /**
24 | * 我的已经登陆的界面
25 | */
26 | class MeFragmentUser : Fragment() {
27 |
28 | var bd: FragmentMeUserBinding? = null
29 |
30 | override fun onCreateView(
31 | inflater: LayoutInflater, container: ViewGroup?,
32 | savedInstanceState: Bundle?
33 | ): View {
34 | val t = FragmentMeUserBinding.inflate(inflater, container, false)
35 | bd = t
36 | return t.root
37 | }
38 |
39 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
40 | super.onViewCreated(view, savedInstanceState)
41 |
42 | bd?.let {
43 | initButtonEvent(it, view)
44 | }
45 |
46 | setValueAndInitObserver()
47 | initSwipeRefresh()
48 | }
49 |
50 | private fun initButtonEvent(bd: FragmentMeUserBinding, view: View) {
51 | val activity = this.requireActivity() as MeActivity
52 |
53 | bd.meIcon.setOnClickListener {
54 | AppNavUtils.gotoUserInfo(activity)
55 | }
56 |
57 |
58 | bd.gotoOrder.setOnClickListener {
59 | TipUtils.barShort(view, "功能已经移除")
60 | }
61 |
62 |
63 |
64 | bd.tryTaobaoAuth.setOnClickListener {
65 | val bind = AppPreferenceUtils.getBindTaoBao(activity)
66 | if (bind) {
67 | Toast.makeText(activity, "淘宝已经授权", Toast.LENGTH_LONG).show()
68 | return@setOnClickListener
69 | }
70 |
71 | // 尝试淘宝授权
72 | val logic = TaoBaoLogic(activity)
73 | logic.tryAuth()
74 | }
75 |
76 |
77 |
78 | bd.gotoSetting.setOnClickListener {
79 | AppNavUtils.gotoSettings(activity)
80 | }
81 | }
82 |
83 | private fun initSwipeRefresh() {
84 | bd?.let {
85 | it.swipeRefresh.setOnRefreshListener {
86 | this.doFetchUserProfile()
87 | }
88 | }
89 | }
90 |
91 |
92 | private fun doFetchUserProfile() {
93 | val activity = this.requireActivity() as MeActivity
94 | val form = DtUserTokenForm(token = AppPreferenceUtils.getUserToken(activity))
95 | ApiUserProfileStub.myPost(activity, form,
96 | { ret ->
97 | AppErrnoLogic.genericServerErrnoProcess(ret.errno, activity)
98 | Log.i("user/profile", "$ret")
99 | try {
100 | if (ret.errno != 0) {
101 | TipUtils.toastShort(activity, "更新状态失败: ${ret.errmsg}")
102 | return@myPost
103 | }
104 | ret.data?.let { data ->
105 | AppPreferenceUtils.setUserInfo(activity, data)
106 | val viewModel = this.getUserViewModel()
107 | viewModel.displayName.value = DisplayLogic.getDisplayName(activity)
108 | viewModel.uuid.value = AppPreferenceUtils.getUserUuid(activity)
109 | TipUtils.toastShort(activity, "更新用户状态成功")
110 | }
111 | } finally {
112 | bd?.swipeRefresh?.isRefreshing = false
113 | }
114 | },
115 | { error ->
116 | Log.e("user/profile", "错误信息: ${error.localizedMessage}")
117 | TipUtils.toastShort(activity, "更新用户状态失败: ${error.localizedMessage}")
118 | bd?.swipeRefresh?.isRefreshing = false
119 | })
120 | }
121 |
122 | private fun setValueAndInitObserver() {
123 | val activity = this.requireActivity() as MeActivity
124 |
125 | val owner = viewLifecycleOwner
126 | // Get the ViewModel.
127 | val model = getUserViewModel()
128 | // Observe the LiveData, passing in this activity
129 | // as the LifecycleOwner and the observer.
130 | model.displayName.removeObservers(owner)
131 | model.uuid.removeObservers(owner)
132 |
133 | model.displayName.observe(owner, { newMobile ->
134 | bd!!.meName.text = newMobile
135 | })
136 |
137 | AppPreferenceUtils.getUserInfo(activity)?.let { userInfo ->
138 | userInfo.tao_id?.let { taoId ->
139 | // extract to download image
140 | val imageUrl =
141 | "https://wwc.alicdn.com/avatar/getAvatar.do?userId=${taoId}&width=160&height=160&type=sns"
142 | bd!!.userIcon.loadImageFromUrl(imageUrl)
143 | }
144 | }
145 |
146 | // update UI element
147 | model.displayName.value = DisplayLogic.getDisplayName(activity)
148 | model.uuid.value = AppPreferenceUtils.getUserUuid(activity)
149 |
150 | }
151 |
152 |
153 | private fun getUserViewModel(): MeActivityUserViewModel {
154 | val activity = this.requireActivity() as MeActivity
155 |
156 | return activity.getUserViewModel()
157 | }
158 | }
159 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/fragments/settings/SettingsFragmentLogin.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.fragments.settings
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import com.qiyutech.tbk.R
9 | import com.qiyutech.tbk.SettingsActivity
10 | import com.qiyutech.tbk.databinding.FragmentSettingsLoginBinding
11 | import com.qiyutech.tbk.fragments.TextHeaderFragment
12 | import com.qiyutech.tbk.utils.AppNavUtils
13 | import com.qiyutech.tbk.utils.AppUtils
14 |
15 | /**
16 | * 用户没有登陆的界面
17 | */
18 | class SettingsFragmentLogin : Fragment() {
19 | /// 版本点击了多少次
20 | var versionClicked = 0
21 |
22 | private var bd: FragmentSettingsLoginBinding? = null
23 |
24 | override fun onCreateView(
25 | inflater: LayoutInflater, container: ViewGroup?,
26 | savedInstanceState: Bundle?
27 | ): View? {
28 | bd = FragmentSettingsLoginBinding.inflate(inflater, container, false)
29 | bd?.let {
30 | it.version.text = AppUtils.versionName()
31 |
32 | it.currentVersion.setOnClickListener {
33 | versionClicked += 1
34 | if (versionClicked == 6) {
35 | AppNavUtils.gotoDevInfo(requireActivity())
36 | }
37 | }
38 | it.checkVersionUpdate.setOnClickListener { view ->
39 | val activity = this.requireActivity() as SettingsActivity
40 | activity.checkAppUpgrade(view)
41 | }
42 | it.showPrivacy.setOnClickListener {
43 | AppNavUtils.gotoPrivacy(this.requireActivity())
44 | }
45 | it.cleanCache.setOnClickListener { view ->
46 | val activity = this.requireActivity() as SettingsActivity
47 | activity.deleteCacheFiles(view)
48 | }
49 | it.userLogin.setOnClickListener {
50 | val activity = this.requireActivity() as SettingsActivity
51 | AppNavUtils.gotoUserPassword(activity)
52 | }
53 | return it.root
54 | }
55 | return null
56 | }
57 |
58 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
59 | super.onViewCreated(view, savedInstanceState)
60 |
61 | val activity = this.requireActivity()
62 | activity.supportFragmentManager.beginTransaction()
63 | .replace(R.id.setting_header, TextHeaderFragment("设置", true))
64 | .commit()
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/fragments/settings/SettingsFragmentUser.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.fragments.settings
2 |
3 | import android.os.Bundle
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.fragment.app.Fragment
8 | import com.qiyutech.tbk.R
9 | import com.qiyutech.tbk.SettingsActivity
10 | import com.qiyutech.tbk.databinding.FragmentSettingsUserBinding
11 | import com.qiyutech.tbk.fragments.TextHeaderFragment
12 | import com.qiyutech.tbk.utils.AppNavUtils
13 | import com.qiyutech.tbk.utils.AppUtils
14 |
15 |
16 | /**
17 | * 用户已经登陆的 fragment
18 | */
19 | class SettingsFragmentUser : Fragment() {
20 | var versionClicked: Int = 0
21 |
22 | private var bd: FragmentSettingsUserBinding? = null
23 |
24 | override fun onCreateView(
25 | inflater: LayoutInflater, container: ViewGroup?,
26 | savedInstanceState: Bundle?
27 | ): View? {
28 | bd = FragmentSettingsUserBinding.inflate(inflater, container, false)
29 | bd?.let {
30 | it.version.text = AppUtils.versionName()
31 |
32 | it.currentVersion.setOnClickListener {
33 | versionClicked += 1
34 | if (versionClicked == 6) {
35 | AppNavUtils.gotoDevInfo(requireActivity())
36 | }
37 | }
38 | it.checkVersionUpdate.setOnClickListener { view ->
39 | val activity = this.requireActivity() as SettingsActivity
40 | activity.checkAppUpgrade(view)
41 | }
42 | it.showPrivacy.setOnClickListener {
43 | AppNavUtils.gotoPrivacy(this.requireActivity())
44 | }
45 | it.cleanCache.setOnClickListener { view ->
46 | val activity = this.requireActivity() as SettingsActivity
47 | activity.deleteCacheFiles(view)
48 | }
49 | it.exitLogin.setOnClickListener { view ->
50 | val activity = this.requireActivity() as SettingsActivity
51 | activity.settingUserLogout(view)
52 | }
53 | it.cancelUser.setOnClickListener { view ->
54 | val activity = this.requireActivity() as SettingsActivity
55 | activity.settingUserCancel(view)
56 | }
57 |
58 | return it.root
59 | }
60 | return null
61 | }
62 |
63 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
64 | super.onViewCreated(view, savedInstanceState)
65 |
66 | bd?.let {
67 | val activity = this.requireActivity()
68 |
69 | activity.supportFragmentManager.beginTransaction()
70 | .replace(R.id.setting_header, TextHeaderFragment("设置", true))
71 | .commit()
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/logic/AppErrnoLogic.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.logic
2 |
3 | import android.content.Context
4 | import android.util.Log
5 | import com.qiyutech.tbk.dt.DtAppErrno
6 | import com.qiyutech.tbk.utils.AppUtils
7 | import com.qiyutech.tbk.utils.TipUtils
8 |
9 | /**
10 | * 奇遇淘客错误处理逻辑
11 | */
12 | object AppErrnoLogic {
13 | /**
14 | * 通用的奇遇淘客错误处理逻辑
15 | *
16 | * 每一个请求都要使用这个函数去处理错误码
17 | */
18 | fun genericServerErrnoProcess(errno: DtAppErrno, ctx: Context) {
19 | when (errno) {
20 | 0 -> {
21 | // success do nothing
22 | }
23 | 1 -> {
24 | // 未知的错误
25 | TipUtils.toastLong(ctx, "未知错误 ~_~ 请稍后再试 (错误码: ${errno})")
26 | }
27 | 2 -> {
28 | // 系统内部错误
29 | TipUtils.toastLong(ctx, "网络错误 ~_~ 请稍后再试 (错误码: ${errno})")
30 | }
31 | 10 -> {
32 | // 无效的用输入
33 | }
34 | 11 -> {
35 | // 认证失败 [登陆失败]
36 | TipUtils.toastLong(ctx, "登录凭证已经过期,请重新登录")
37 | UserLogic.logout(ctx)
38 | }
39 | 20 -> {
40 | // not_found = 20 # 未找到指定内容
41 | }
42 | 21 -> {
43 | // token_invalid = 21 # 无效的 token [客户端应该执行退出 , 重新登录]
44 | // 执行 UserLogout 操作
45 | TipUtils.toastShort(ctx, "请登录后再试 (错误码: ${errno})")
46 | UserLogic.logout(ctx)
47 | }
48 | 22 -> {
49 | // ztk_error = 22 # 折淘客错误
50 | }
51 | 23 -> {
52 | // user_not_exists = 23 # 用户不存在
53 | }
54 | 24 -> {
55 | // 大淘客错误
56 | TipUtils.toastShort(ctx, "请求淘宝商品失败 错误($errno)")
57 | Log.i("大淘客", "请求大淘客失败")
58 | }
59 | 30 -> {
60 | // release_not_found = 30 # 没有发布的历史
61 | }
62 | 40 -> {
63 | // no_channel_id = 40 # 没有渠道 id
64 | }
65 | 41 -> {
66 | // item_not_found = 41 # 没有找到指定的商品
67 | TipUtils.toastLong(ctx, "没有找到对应的商品 (错误码: ${errno})")
68 | }
69 | else -> {
70 | // any other unknown value do nothing
71 | if (AppUtils.inDebugMode()) {
72 | TipUtils.toastLong(ctx, "系统遇到了未知的错误, 请检查是否为最新版 (错误码: ${errno})")
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/logic/CouponLogic.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.logic
2 |
3 | import android.app.SearchManager
4 | import android.database.Cursor
5 | import android.database.MatrixCursor
6 | import android.provider.BaseColumns
7 | import android.util.Log
8 | import androidx.appcompat.widget.SearchView
9 | import com.qiyutech.tbk.CouponActivity
10 | import com.qiyutech.tbk.dt.ApiDtkSearchSuggestionStub
11 | import com.qiyutech.tbk.dt.DtGoodsSearchSuggestionArgs
12 | import com.qiyutech.tbk.utils.MySearchUtils
13 |
14 |
15 | class CouponSearchSuggestion(private val searchView: SearchView) :
16 | SearchView.OnSuggestionListener {
17 |
18 | override fun onSuggestionClick(position: Int): Boolean {
19 | val cursor = searchView.suggestionsAdapter.getItem(position) as Cursor
20 | val selection = cursor.getString(cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1))
21 | searchView.setQuery(selection, false)
22 | return true
23 | }
24 |
25 | override fun onSuggestionSelect(position: Int): Boolean {
26 | return false
27 | }
28 | }
29 |
30 |
31 | class CouponSearchQueryTextListener(
32 | private val activity: CouponActivity,
33 | private val searchView: SearchView
34 | ) : SearchView.OnQueryTextListener {
35 |
36 | override fun onQueryTextSubmit(query: String?): Boolean {
37 | // extract to search method
38 | if (query.isNullOrBlank()) {
39 | return false
40 | }
41 | MySearchUtils.doCouponSearch(activity, query)
42 | return true
43 | }
44 |
45 | override fun onQueryTextChange(newText: String?): Boolean {
46 | if (newText.isNullOrBlank()) {
47 | return true
48 | }
49 |
50 | val args = DtGoodsSearchSuggestionArgs(keyWords = newText, type = "3")
51 | ApiDtkSearchSuggestionStub.myPost(activity, args,
52 | { v ->
53 | AppErrnoLogic.genericServerErrnoProcess(v.errno, activity)
54 | if (v.errno != 0) {
55 | Log.w("request suggest failed:", v.toString())
56 | return@myPost
57 | }
58 | Log.i("search", v.toString())
59 | val cursor =
60 | MatrixCursor(arrayOf(BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1))
61 |
62 | v.data?.forEachIndexed { index, suggestion ->
63 | val item = arrayOf(index, suggestion)
64 | cursor.addRow(item)
65 | }
66 |
67 | this.searchView.suggestionsAdapter.changeCursor(cursor)
68 |
69 | },
70 | { error -> Log.e("search suggest", "错误: $error") }
71 | )
72 |
73 | return false
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/logic/DisplayLogic.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.logic
2 |
3 | import android.content.Context
4 | import com.qiyutech.tbk.values.AppPreferenceUtils
5 |
6 | /**
7 | * 展示的逻辑
8 | */
9 | object DisplayLogic {
10 | /**
11 | * 获取展示的名称
12 | *
13 | * 在我的里面展示的名称
14 | */
15 | fun getDisplayName(ctx: Context): String {
16 | AppPreferenceUtils.getUserInfo(ctx)?.let {
17 | it.mobile?.let { mobile ->
18 | return mobile
19 | }
20 | }
21 |
22 | // 啥都没有就显示奇遇淘客
23 | return "奇遇淘客"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/logic/TaoBaoLogic.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.logic
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.util.Log
6 | import android.webkit.WebChromeClient
7 | import android.webkit.WebViewClient
8 | import com.alibaba.baichuan.android.trade.AlibcTrade
9 | import com.alibaba.baichuan.android.trade.callback.AlibcTradeCallback
10 | import com.alibaba.baichuan.android.trade.model.AlibcShowParams
11 | import com.alibaba.baichuan.android.trade.model.OpenType
12 | import com.alibaba.baichuan.trade.biz.context.AlibcResultType
13 | import com.alibaba.baichuan.trade.biz.context.AlibcTradeResult
14 | import com.alibaba.baichuan.trade.biz.core.taoke.AlibcTaokeParams
15 | import com.qiyutech.tbk.BuildConfig
16 | import com.qiyutech.tbk.TaoBaoActivity
17 | import com.qiyutech.tbk.dt.*
18 | import com.qiyutech.tbk.utils.TipUtils
19 | import com.qiyutech.tbk.values.AppPreferenceUtils
20 | import com.qiyutech.tbk.values.LogTags
21 |
22 | /**
23 | * 淘宝的逻辑
24 | */
25 | class TaoBaoLogic(private val activity: Activity) {
26 | /**
27 | * 尝试淘宝授权
28 | */
29 | fun tryAuth() {
30 | val form = DtAuthUrlForm(token = AppPreferenceUtils.getUserToken(activity))
31 |
32 | ApiTaobaoAuthUrlStub.myPost(activity, form,
33 | { resp ->
34 | AppErrnoLogic.genericServerErrnoProcess(resp.errno, activity)
35 | if (resp.errno == 0) {
36 | resp.data?.let {
37 | Log.i(LogTags.TaoBao, it.url)
38 | openAliBCAuthPage(it.url)
39 | }
40 | } else {
41 | Log.e(LogTags.TaoBao, resp.errmsg)
42 | }
43 | },
44 | { error ->
45 | TipUtils.toastShort(activity, "获取授权地址失败: ${error.localizedMessage}")
46 | })
47 | }
48 |
49 | /**
50 | * 打开 阿里百川授权页面
51 | * showPageByUrl
52 | */
53 | private fun openAliBCAuthPage(url: String) {
54 |
55 | TaoBaoActivity.openAuthPage(activity, url)
56 |
57 | }
58 |
59 | /**
60 | * 购买一个商品
61 | * 拉起淘宝去购买
62 | */
63 | fun buyItem(itemId: String) {
64 | val token = AppPreferenceUtils.getUserToken(activity)
65 | if (token == "") {
66 | TipUtils.toastLong(activity, "请登陆后购买 [我的-登陆]")
67 | return
68 | }
69 | val bind = AppPreferenceUtils.getBindTaoBao(activity)
70 | if (!bind) {
71 | TipUtils.toastLong(activity, "请先进行淘宝授权 [我的-淘宝授权]")
72 | return
73 | }
74 |
75 | val form = DtGaoYongForm(item_id = itemId, token = token)
76 | ApiZtkGaoYongStub.myPost(activity, form,
77 | { ret ->
78 | AppErrnoLogic.genericServerErrnoProcess(ret.errno, activity)
79 | if (ret.errno == 0) {
80 | ret.data?.let { data ->
81 | openByUrl(data.coupon_click_url)
82 | }
83 | } else {
84 | Log.e(LogTags.AliBuy, "请求服务器失败: ${ret.errmsg}")
85 | TipUtils.toastLong(activity, "请求服务器失败,请稍后再试 ~_~!")
86 | }
87 | }, {
88 | Log.e(LogTags.AliBuy, "请求失败: ${it.localizedMessage}")
89 | })
90 | }
91 |
92 |
93 | /**
94 | * 打开商品信息
95 | */
96 | private fun openByUrl(url: String) {
97 | val show = AlibcShowParams()
98 |
99 | show.openType = OpenType.Auto
100 | show.clientType = "taobao"
101 |
102 | val taoke = AlibcTaokeParams("", "", "")
103 |
104 | taoke.setPid(BuildConfig.ALI_PID)
105 | // taoke.setUnionId("")
106 | taoke.setAdzoneid(BuildConfig.ALI_ADZONE_ID)
107 |
108 | AlibcTrade.openByUrl(activity,
109 | "",
110 | url,
111 | null,
112 | WebViewClient(),
113 | WebChromeClient(),
114 | show,
115 | taoke,
116 | null,
117 | object : AlibcTradeCallback {
118 | override fun onTradeSuccess(p0: AlibcTradeResult?) {
119 | if (p0 == null) {
120 | return
121 | }
122 |
123 | Log.i(LogTags.AliBuy, "购买成功")
124 | when (p0.resultType) {
125 | AlibcResultType.TYPECART -> {
126 | }
127 | AlibcResultType.TYPEPAY -> {
128 | }
129 | else -> {
130 | }
131 | }
132 | }
133 |
134 | override fun onFailure(p0: Int, p1: String?) {
135 | Log.e(LogTags.AliBuy, "错误码: $p0")
136 | Log.e(LogTags.AliBuy, "错误信息: $p1")
137 | }
138 | })
139 | }
140 |
141 | companion object {
142 | /**
143 | * 检测淘宝是否已经绑定
144 | */
145 | fun detectTaoBaoBind(ctx: Context) {
146 | val form = DtUserTokenForm(token = AppPreferenceUtils.getUserToken(ctx))
147 |
148 | ApiUserTbStub.myPost(ctx, form, { ret ->
149 | AppErrnoLogic.genericServerErrnoProcess(ret.errno, ctx)
150 | if (ret.errno != 0) {
151 | Log.e(LogTags.AliBC, "授权失败!")
152 | return@myPost
153 | }
154 |
155 | if (ret.data == true) { // 已经经过淘宝认证
156 | val form2 = DtUserTokenForm(token = AppPreferenceUtils.getUserToken(ctx))
157 | ApiUserProfileStub.myPost(
158 | ctx, form2,
159 | { ret2 ->
160 | ret2.data?.let { data ->
161 | AppPreferenceUtils.setUserInfo(ctx, data)
162 | }
163 | Log.i("user/profile", "$ret")
164 | },
165 | { error ->
166 | Log.e("user/profile", "错误信息: ${error.localizedMessage}")
167 | TipUtils.toastShort(ctx, "更新用户状态失败: ${error.localizedMessage}")
168 | })
169 | }
170 | }, {
171 | Log.e(LogTags.AliBC, "请求获取淘宝认证失败: $it")
172 | })
173 | }
174 | }
175 | }
176 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/logic/UserLogic.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.logic
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.util.Log
6 | import android.widget.Toast
7 | import com.qiyutech.tbk.SettingsActivity
8 | import com.qiyutech.tbk.UserPasswordActivity
9 | import com.qiyutech.tbk.dt.*
10 | import com.qiyutech.tbk.events.LoginEvent
11 | import com.qiyutech.tbk.events.LogoutEvent
12 | import com.qiyutech.tbk.utils.MyHttpUtils
13 | import com.qiyutech.tbk.utils.TipUtils
14 | import com.qiyutech.tbk.values.AppPreferenceUtils
15 | import com.qiyutech.tbk.values.LogTags
16 | import com.qiyutech.tbk.values.TbkAPIUrls
17 |
18 |
19 | object UserLogic {
20 |
21 | /**
22 | * 用户密码尝试登陆
23 | */
24 | fun usernamePasswordTryLogin(
25 | activity: UserPasswordActivity,
26 | username: String,
27 | password: String
28 | ) {
29 |
30 | val form = DtUserNativeAuthForm(username, password)
31 |
32 | ApiUserAuthStub.myPost(activity, form, { ret ->
33 | if (ret.errno != 0) {
34 | Toast.makeText(activity, "请求失败(${ret.errno}): ${ret.errmsg}", Toast.LENGTH_LONG)
35 | .show()
36 | return@myPost
37 | }
38 |
39 | ret.data?.let {
40 | AppPreferenceUtils.setUserToken(activity, it.token)
41 |
42 | /// 登陆成功
43 | LoginEvent.callback(activity) // 回调登陆成功
44 | Toast.makeText(activity, "登陆成功", Toast.LENGTH_LONG).show()
45 |
46 | fetchProfile(activity, { info ->
47 | AppPreferenceUtils.setUserInfo(activity, info)
48 | }) {
49 | Toast.makeText(activity, "获取用户信息失败", Toast.LENGTH_LONG).show()
50 | }
51 |
52 | activity.finish()
53 | return@myPost
54 | }
55 |
56 | Toast.makeText(activity, "认证失败: ${ret.errmsg}(${ret.errno})", Toast.LENGTH_LONG).show()
57 | }) {
58 | Toast.makeText(activity, "请求服务器失败: $it", Toast.LENGTH_LONG).show()
59 | }
60 | }
61 |
62 |
63 | /**
64 | * 获取用户的状态
65 | */
66 | fun fetchProfile(
67 | activity: Activity,
68 | success: (DtUserProfileDataModel) -> Unit,
69 | failure: () -> Unit
70 | ) {
71 | val form = DtUserTokenForm(token = AppPreferenceUtils.getUserToken(activity))
72 | ApiUserProfileStub.myPost(activity, form,
73 | { ret ->
74 | AppErrnoLogic.genericServerErrnoProcess(ret.errno, activity)
75 | Log.i("user/profile", "$ret")
76 | if (ret.errno != 0) {
77 | TipUtils.toastShort(activity, "更新状态失败: ${ret.errmsg}")
78 | failure()
79 | } else {
80 | ret.data?.let { data ->
81 | AppPreferenceUtils.setUserInfo(activity, data)
82 | success(data)
83 | }
84 | }
85 | },
86 | { error ->
87 | Log.e("user/profile", "错误信息: ${error.localizedMessage}")
88 | TipUtils.toastShort(activity, "更新用户状态失败: ${error.localizedMessage}")
89 | failure()
90 | })
91 |
92 | }
93 |
94 |
95 | /**
96 | * 用户退出登陆
97 | */
98 | fun logout(activity: Context) {
99 | // 删除 token
100 | AppPreferenceUtils.setUserToken(activity, "")
101 | // 删除已经登陆的用户信息
102 | AppPreferenceUtils.delUserInfo(activity)
103 |
104 | /// 登出之后的事件
105 | LogoutEvent.callback(activity)
106 | }
107 |
108 | /**
109 | * 用户注销账号
110 | */
111 | fun cancel(ctx: SettingsActivity) {
112 | val form = DtUserTokenForm(token = AppPreferenceUtils.getUserToken(ctx))
113 |
114 | val r = MyHttpUtils.postRequest(
115 | TbkAPIUrls.UserCancel, form,
116 | { ret: DtUserCancelResponseModel ->
117 | AppErrnoLogic.genericServerErrnoProcess(ret.errno, ctx)
118 |
119 | if (ret.errno == 0 && ret.data == true) {
120 | Toast.makeText(ctx, "注销用户成功", Toast.LENGTH_LONG).show()
121 | // 注销成功 自动退出登陆
122 | logout(ctx)
123 | ctx.setNotLoginView()
124 | } else {
125 | Toast.makeText(ctx, "注销用户失败(${ret.errno}): ${ret.errmsg}", Toast.LENGTH_LONG)
126 | .show()
127 | }
128 | },
129 | {
130 | Toast.makeText(ctx, "请求服务器失败: $it", Toast.LENGTH_LONG).show()
131 | })
132 |
133 | MyHttpUtils.addToQueue(ctx, LogTags.User, r)
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/AppNavUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.app.Activity
4 | import android.content.Intent
5 | import com.qiyutech.tbk.*
6 |
7 | /**
8 | * [AppNavUtils] 全局导航辅助类
9 | */
10 | object AppNavUtils {
11 |
12 | /**
13 | * 从当前的 [activity] 跳转到 [SettingsActivity]
14 | */
15 | fun gotoSettings(activity: Activity) {
16 | val intent = Intent(activity, SettingsActivity::class.java)
17 | goto(activity, intent)
18 | }
19 |
20 | /**
21 | * 从当前的 [activity] 跳转到 [GroupActivity]
22 | */
23 | fun gotoGroup(activity: Activity) {
24 | val intent = Intent(activity, GroupActivity::class.java)
25 | goto(activity, intent)
26 | }
27 |
28 | /**
29 | * 从当前的 [activity] 跳转到 [HomeActivity]
30 | */
31 | fun gotoHome(activity: Activity) {
32 | val intent = Intent(activity, HomeActivity::class.java)
33 | goto(activity, intent)
34 | }
35 |
36 | /**
37 | * 从当前的 [activity] 跳转到 [CouponActivity]
38 | */
39 | fun gotoCoupon(activity: Activity) {
40 | val intent = Intent(activity, CouponActivity::class.java)
41 | goto(activity, intent)
42 | }
43 |
44 | /**
45 | * 从当前的 [activity] 跳转到 [PrivacyActivity]
46 | *
47 | * view 是否是展示模式:
48 | * 如果是展示模式则不附带 确认/不同意 按钮
49 | * 默认是 纯展示 模式
50 | */
51 | fun gotoPrivacy(activity: Activity, view: Boolean = true) {
52 | val intent = Intent(activity, PrivacyActivity::class.java)
53 | intent.putExtra("view", view)
54 | goto(activity, intent)
55 | }
56 |
57 |
58 | /**
59 | * 从当前的 [activity] 跳转到 [SearchDetailNativeActivity]
60 | */
61 | fun gotoSearchDetailNative(activity: Activity, query: String) {
62 | val intent = Intent(activity, SearchDetailNativeActivity::class.java)
63 | intent.putExtra("query", query)
64 | goto(activity, intent)
65 | }
66 |
67 |
68 | /**
69 | * 从当前的 [activity] 跳转到 [MeActivity]
70 | */
71 | fun gotoMe(activity: Activity) {
72 | val intent = Intent(activity, MeActivity::class.java)
73 | goto(activity, intent)
74 | }
75 |
76 |
77 | /**
78 | * 跳转到商品详情页面
79 | */
80 | fun gotoItemDetailV2(activity: Activity, itemId: String) {
81 | val intent = Intent(activity, ItemDetailV2Activity::class.java)
82 | intent.putExtra("item_id", itemId)
83 | goto(activity, intent)
84 | }
85 |
86 |
87 | /**
88 | * 从当前的 [activity] 跳转到 [UserPasswordActivity]
89 | *
90 | * 账号登陆
91 | */
92 | fun gotoUserPassword(activity: Activity) {
93 | val intent = Intent(activity, UserPasswordActivity::class.java)
94 | goto(activity, intent)
95 | }
96 |
97 |
98 | /**
99 | * 跳转到开发信息界面
100 | */
101 | fun gotoDevInfo(activity: Activity) {
102 | val intent = Intent(activity, DevInfoActivity::class.java)
103 | goto(activity, intent)
104 | }
105 |
106 | /**
107 | * 跳转到用户信息界面
108 | */
109 | fun gotoUserInfo(activity: Activity) {
110 | val intent = Intent(activity, UserInfoActivity::class.java)
111 | goto(activity, intent)
112 | }
113 |
114 |
115 | private fun goto(activity: Activity, intent: Intent) {
116 | activity.startActivity(intent)
117 | activity.overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out)
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/AppUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 | import android.content.SharedPreferences
5 | import android.view.View
6 | import android.view.ViewGroup
7 | import androidx.appcompat.app.AppCompatActivity
8 | import com.qiyutech.tbk.BuildConfig
9 | import com.qiyutech.tbk.values.AppPreferenceUtils
10 | import com.qiyutech.tbk.values.AppSharedPreferencesName
11 |
12 | /**
13 | * App 辅助函数
14 | */
15 | object AppUtils {
16 | /**
17 | * 获取 activity 的 RootView
18 | *
19 | * 主要是为了:
20 | * ***Binding.bind(view)
21 | */
22 | fun getRootView(activity: AppCompatActivity): View {
23 | /// 怎么样获取 root view
24 | /// https://stackoverflow.com/questions/4486034/get-root-view-from-current-activity
25 | return activity.findViewById(android.R.id.content).getChildAt(0)
26 | }
27 |
28 | /**
29 | * 是否在开发环境 (也就是允许获取测试商品)
30 | */
31 | fun inDevEnv(): Boolean {
32 | if (BuildConfig.ENV == "dev") {
33 | return true
34 | }
35 | return false
36 | }
37 |
38 | /**
39 | * 是否在调试环境中
40 | */
41 | fun inDebugMode(): Boolean {
42 | return BuildConfig.DEBUG
43 | }
44 |
45 | fun versionName(): String {
46 | return if (inDevEnv()) {
47 | BuildConfig.VERSION_NAME + "-dev"
48 | } else {
49 | BuildConfig.VERSION_NAME
50 | }
51 | }
52 |
53 | /**
54 | * 获取共享的配置
55 | */
56 | fun getPreference(ctx: Context): SharedPreferences {
57 | return ctx.getSharedPreferences(AppSharedPreferencesName.NAME, Context.MODE_PRIVATE)
58 | }
59 |
60 | /**
61 | * 检测用户是否登陆
62 | */
63 | fun checkUserLogin(ctx: Context): Boolean {
64 | val token = AppPreferenceUtils.getUserToken(ctx)
65 | return token != ""
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/ClipboardUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.app.Activity
4 | import android.content.ClipData
5 | import android.content.ClipDescription.MIMETYPE_TEXT_PLAIN
6 | import android.content.ClipboardManager
7 |
8 | object ClipboardUtils {
9 | /**
10 | * 复制到剪切板
11 | */
12 | fun copy(txt: String, activity: Activity) {
13 | val clip =
14 | activity.getSystemService(Activity.CLIPBOARD_SERVICE) as ClipboardManager
15 | val data = ClipData.newPlainText("TEXT", txt)
16 | clip.setPrimaryClip(data)
17 | }
18 |
19 | fun read(activity: Activity): String {
20 | val clip = activity.getSystemService(Activity.CLIPBOARD_SERVICE) as ClipboardManager
21 |
22 | clip.primaryClipDescription?.let { desc ->
23 | if (desc.hasMimeType(MIMETYPE_TEXT_PLAIN)) {
24 | clip.primaryClip?.let {
25 | it.getItemAt(0)?.let { item ->
26 | return item.text.toString()
27 | }
28 | }
29 | }
30 | }
31 |
32 | return ""
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/DialogUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.util.Log
4 | import androidx.appcompat.app.AlertDialog
5 | import androidx.appcompat.app.AppCompatActivity
6 | import com.qiyutech.tbk.values.LogTags
7 |
8 | /// 弹窗辅助类
9 | object DialogUtils {
10 |
11 | /**
12 | * 推送通知检测对话框
13 | */
14 | fun notificationDialog(activity: AppCompatActivity): AlertDialog {
15 | val builder = AlertDialog.Builder(activity)
16 | builder.apply {
17 | setPositiveButton("去开启") { _, _ ->
18 | PushUtils.requestNotify(activity)
19 | }
20 | setNegativeButton("不用了") { _, _ ->
21 | }
22 | }
23 |
24 | builder.setTitle("开启推送")
25 | builder.setMessage("您没有给奇遇淘客开启消息推送,这样会导致错过一些重要信息, 是否去开启?")
26 |
27 | return builder.create()
28 | }
29 |
30 | /**
31 | * 淘宝重新授权
32 | */
33 | fun reBindTbDialog(
34 | activity: AppCompatActivity,
35 | doFunc: (activity: AppCompatActivity) -> Unit
36 | ): AlertDialog {
37 | val builder = AlertDialog.Builder(activity)
38 |
39 | builder.apply {
40 | setPositiveButton("重新授权") { _, _ ->
41 | doFunc(activity)
42 | }
43 | setNegativeButton("取消") { _, _ ->
44 | }
45 | }
46 |
47 | builder.setTitle("淘宝授权")
48 | builder.setMessage("您已经绑定过淘宝账号,重新授权会导致之前绑定的账号失效?")
49 |
50 | return builder.create()
51 | }
52 |
53 | /**
54 | * 用户注销用户的弹窗
55 | */
56 | fun userCancelDialog(
57 | activity: AppCompatActivity,
58 | doFunc: (AppCompatActivity) -> Unit
59 | ): AlertDialog {
60 | val builder = AlertDialog.Builder(activity)
61 | builder.apply {
62 | setPositiveButton("确认注销") { _, _ ->
63 | doFunc(activity)
64 | }
65 | setNegativeButton("取消") { _, _ ->
66 | }
67 | }
68 |
69 | builder.setTitle("注销账户")
70 | builder.setMessage("您是否确认注销当前的用户?\n\n注销账户之后:\n您将无法使用与会员有关的相关功能")
71 |
72 | return builder.create()
73 | }
74 |
75 | /**
76 | * 创建 dialog
77 | */
78 | fun createDialog(activity: AppCompatActivity): AlertDialog {
79 | val builder = AlertDialog.Builder(activity)
80 |
81 | builder.apply {
82 | setPositiveButton("确认") { dialog, id ->
83 | // User clicked OK button
84 | Log.i(LogTags.Dialog, id.toString())
85 | Log.i(LogTags.Dialog, "确认")
86 | }
87 | setNegativeButton("取消") { dialog, id ->
88 | // User cancelled the dialog
89 | Log.i(LogTags.Dialog, id.toString())
90 | Log.i(LogTags.Dialog, "取消")
91 | }
92 | setNeutralButton("你猜") { dialog, id ->
93 | Log.i(LogTags.Dialog, id.toString())
94 | Log.i(LogTags.Dialog, "你猜")
95 | }
96 | }
97 |
98 | // Set other dialog properties
99 | builder.setTitle("测试弹窗")
100 | builder.setMessage("这是一个测试的消息")
101 |
102 | // Create the AlertDialog
103 | return builder.create()
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/DiskImageCache.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.graphics.BitmapFactory
6 | import android.util.Log
7 | import com.bumptech.glide.disklrucache.DiskLruCache
8 | import com.qiyutech.tbk.values.LogTags
9 | import java.io.BufferedInputStream
10 | import java.io.BufferedOutputStream
11 | import java.math.BigInteger
12 | import java.security.MessageDigest
13 |
14 | object MyImageDiskCache {
15 |
16 | /// 缓存的大小
17 | private const val CACHE_SIZE: Long = 1 * 1024 * 1024 * 1024
18 |
19 | fun putImage(ctx: Context, url: String, bitmap: Bitmap) {
20 | Log.d(LogTags.CACHE_IMAGE, "put $url")
21 | val cache = DiskLruCache.open(ctx.cacheDir, 1, 1, CACHE_SIZE)
22 | val key = getCacheKey(url)
23 | cache.edit(key).let { editor ->
24 | editor.getFile(0).let { file ->
25 | val out = BufferedOutputStream(file.outputStream())
26 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
27 | out.close()
28 | editor.commit()
29 | cache.flush()
30 | }
31 | }
32 | }
33 |
34 | fun getImage(ctx: Context, url: String): Bitmap? {
35 | val cache = DiskLruCache.open(ctx.cacheDir, 1, 1, CACHE_SIZE)
36 | val key = getCacheKey(url)
37 | cache.get(key)?.let { value ->
38 | value.getFile(0)?.let { file ->
39 | file.inputStream().let { input ->
40 | val buffer = BufferedInputStream(input, 1024 * 1024)
41 | Log.d(LogTags.CACHE_IMAGE, "get success: $url")
42 | return BitmapFactory.decodeStream(buffer)
43 | }
44 | }
45 | }
46 | Log.d(LogTags.CACHE_IMAGE, "get failed: $url")
47 | return null
48 | }
49 |
50 | private fun getCacheKey(url: String): String {
51 | val md = MessageDigest.getInstance("MD5")
52 | val v = md.digest(url.toByteArray(Charsets.UTF_8))
53 | val b = BigInteger(v)
54 | return String.format("%032x", b)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/LayoutUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 |
5 | /**
6 | * @author me
7 | * @doc https://stackoverflow.com/questions/29664993/how-to-convert-dp-px-sp-among-each-other-especially-dp-and-sp
8 | */
9 | object LayoutUtils {
10 | fun spToInt(ctx: Context, sp: Int): Int {
11 | val multi = ctx.resources.displayMetrics.scaledDensity
12 |
13 | return (sp * multi).toInt()
14 | }
15 |
16 | fun dpToInt(ctx: Context, dp: Int): Int {
17 | val multi = ctx.resources.displayMetrics.density
18 |
19 | return (dp * multi).toInt()
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/LoadKeywordUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.widget.Toast
4 | import com.qiyutech.tbk.SearchActivity
5 | import com.qiyutech.tbk.api.ZTK
6 | import com.qiyutech.tbk.values.HttpTags
7 |
8 | /**
9 | * 加载热词搜索列表
10 | */
11 | class LoadKeywordUtils(private val activity: SearchActivity) {
12 | /**
13 | * 加载搜索热词列表
14 | */
15 | fun loadKeyword() {
16 | val ztk = ZTK(activity, HttpTags.SEARCH)
17 | ztk.hotKeyword(
18 | { v ->
19 | if (v.errno != 0) {
20 | Toast.makeText(activity, v.errmsg, Toast.LENGTH_SHORT).show()
21 | } else {
22 | v.data?.let { data ->
23 | activity.pushHotSearchKeyword(data)
24 | }
25 | }
26 | },
27 | {
28 | println(it)
29 | }
30 | )
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/MyHttpUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 | import com.android.volley.Request
5 | import com.android.volley.VolleyError
6 | import com.android.volley.toolbox.Volley
7 | import com.qiyutech.tbk.activity.question.MyGetRequest
8 | import com.qiyutech.tbk.activity.question.MyJsonObjectRequest
9 |
10 | object MyHttpUtils {
11 |
12 | /**
13 | * 取消所有的 HTTP 请求
14 | *
15 | * 应该在 onStop 的时候使用
16 | */
17 | fun cancelAllRequest(ctx: Context, tag: String) {
18 | Volley.newRequestQueue(ctx).cancelAll(tag)
19 | }
20 |
21 | /**
22 | * 添加到 HTTP 处理队列
23 | * 不要忘记了 在 onStop 的时候调用 cancelAllRequest
24 | */
25 | fun addToQueue(ctx: Context, tag: String, request: Request) {
26 | request.tag = tag
27 | Volley.newRequestQueue(ctx).add(request)
28 | }
29 |
30 | inline fun getRequest(
31 | url: String,
32 | crossinline success: (Out) -> Unit,
33 | crossinline failure: (VolleyError) -> Unit
34 | ): MyGetRequest {
35 |
36 | return MyGetRequest(
37 | url,
38 | { response ->
39 | val out = MyJsonUtils.fromJsonToClass(response, Out::class.java)
40 | success(out)
41 | },
42 | { failure(it) })
43 | }
44 |
45 | inline fun postRequest(
46 | url: String,
47 | data: Data,
48 | crossinline success: (Out) -> Unit,
49 | crossinline failure: (VolleyError) -> Unit
50 | ): MyJsonObjectRequest {
51 | val json = MyJsonUtils.fromClassToJson(data)
52 |
53 | return MyJsonObjectRequest(
54 | Request.Method.POST, url, json,
55 | { response ->
56 | val out = MyJsonUtils.fromJsonToClass(response, Out::class.java)
57 | success(out)
58 | },
59 | { failure(it) })
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/MyJsonUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import com.google.gson.Gson
4 | import org.json.JSONObject
5 | import java.lang.reflect.Type
6 |
7 |
8 | object MyJsonUtils {
9 |
10 | fun fromString(s: String, t: Class): T {
11 | return Gson().fromJson(s, t as Type)
12 | }
13 |
14 | fun toString(v: T): String {
15 | return Gson().toJson(v)
16 | }
17 |
18 | fun fromJsonToClass(v: JSONObject, t: Class): T {
19 | val s = v.toString()
20 | return Gson().fromJson(s, t as Type)
21 | }
22 |
23 |
24 | inline fun fromClassToJson(v: T): JSONObject {
25 | val s = Gson().toJson(v)
26 | return JSONObject(s)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/MySearchUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import com.qiyutech.tbk.CouponActivity
4 | import com.qiyutech.tbk.SearchActivity
5 | import com.qiyutech.tbk.values.AppPreferenceUtils
6 |
7 | object MySearchUtils {
8 | /**
9 | * 执行搜索功能
10 | */
11 | fun doSearch(activity: SearchActivity, query: String) {
12 | val history = AppPreferenceUtils.getSearchHistory(activity)
13 | val newHistory = history.toMutableList()
14 | newHistory.add(0, query)
15 | AppPreferenceUtils.setSearchHistory(activity, newHistory)
16 |
17 | // 重新加载搜索历史
18 | activity.loadSearchHistoryKeyword()
19 |
20 | AppNavUtils.gotoSearchDetailNative(activity, query)
21 | }
22 |
23 | /**
24 | * 优惠券界面的搜索
25 | */
26 | fun doCouponSearch(activity: CouponActivity, query: String) {
27 | AppNavUtils.gotoSearchDetailNative(activity, query)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/MyWebViewUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.annotation.SuppressLint
4 | import android.webkit.WebChromeClient
5 | import android.webkit.WebView
6 | import androidx.fragment.app.FragmentActivity
7 |
8 | /**
9 | * WebView 辅助函数
10 | */
11 | object MyWebViewUtils {
12 | @SuppressLint("SetJavaScriptEnabled")
13 | fun initWebView(activity: FragmentActivity, webView: WebView) {
14 | webView.settings.javaScriptEnabled = true
15 | webView.settings.allowFileAccess = true
16 | // alert need this
17 | webView.webChromeClient = WebChromeClient()
18 |
19 | val c = AndroidWebViewInterface(activity, webView)
20 | webView.addJavascriptInterface(c, AndroidBindingName)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/NetworkImageUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 | import android.graphics.Bitmap
5 | import android.widget.ImageView
6 | import com.android.volley.VolleyError
7 | import com.android.volley.toolbox.ImageRequest
8 | import com.qiyutech.tbk.values.HttpTags
9 |
10 |
11 | /**
12 | * 网络图片加载辅助工具
13 | */
14 | object NetworkImageUtils {
15 | /**
16 | * 下载图片
17 | */
18 | fun download(
19 | ctx: Context,
20 | url: String,
21 | scale: ImageView.ScaleType,
22 | success: (Bitmap) -> Unit,
23 | failure: (VolleyError) -> Unit
24 | ) {
25 | val cacheImg = MyImageDiskCache.getImage(ctx, url)
26 | if (cacheImg == null) {
27 | val r = ImageRequest(
28 | url, { img ->
29 | MyImageDiskCache.putImage(ctx, url, img)
30 | success(img)
31 | }, 0, 0, scale, null
32 | ) { failure(it) }
33 | MyHttpUtils.addToQueue(ctx, HttpTags.IMAGE, r)
34 | } else {
35 | success(cacheImg)
36 | }
37 | }
38 |
39 | /**
40 | * 取消当前所有的下载
41 | */
42 | fun cancelAll(ctx: Context) {
43 | MyHttpUtils.cancelAllRequest(ctx, HttpTags.IMAGE)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/PopupUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.view.Gravity
4 | import android.view.LayoutInflater
5 | import android.view.View
6 | import android.widget.LinearLayout
7 | import android.widget.PopupWindow
8 | import androidx.annotation.LayoutRes
9 |
10 | /**
11 | * 弹出框辅助类
12 | */
13 | object PopupUtils {
14 | /**
15 | * 创建弹出框
16 | * boolean focusable = true; // lets taps outside the popup also dismiss it
17 | *
18 | * doc: https://stackoverflow.com/questions/5944987/how-to-create-a-popup-window-popupwindow-in-android
19 | */
20 | fun createPopup(
21 | view: View,
22 | inflater: LayoutInflater,
23 | @LayoutRes resource: Int,
24 | focusable: Boolean
25 | ): Pair {
26 | val popupView = inflater.inflate(resource, null)
27 |
28 | val width = LinearLayout.LayoutParams.WRAP_CONTENT
29 | val height = LinearLayout.LayoutParams.WRAP_CONTENT
30 |
31 | val popupWindow = PopupWindow(popupView, width, height, focusable)
32 | popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0)
33 |
34 | return Pair(popupView, popupWindow)
35 | }
36 |
37 | fun createFullScreenPopup(
38 | view: View,
39 | inflater: LayoutInflater,
40 | @LayoutRes resource: Int,
41 | focusable: Boolean
42 | ): Pair {
43 | val popupView = inflater.inflate(resource, null)
44 |
45 | val width = LinearLayout.LayoutParams.MATCH_PARENT
46 | val height = LinearLayout.LayoutParams.MATCH_PARENT
47 |
48 | val popupWindow = PopupWindow(popupView, width, height, focusable)
49 | popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0)
50 |
51 | return Pair(popupView, popupWindow)
52 | }
53 |
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/PrivacyUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 | import com.qiyutech.tbk.values.AppPreferenceUtils
5 |
6 | /**
7 | * 奇遇淘客隐私政策辅助类
8 | */
9 | object AppPrivacyUtils {
10 | /**
11 | * 是否已经同意隐私政策
12 | */
13 | fun isPrivacyAgree(ctx: Context): Boolean {
14 | return AppPreferenceUtils.getPrivacyAgree(ctx)
15 | }
16 |
17 | /**
18 | * 设置已经同意隐私政策
19 | */
20 | fun setPrivacyAgree(ctx: Context) {
21 | AppPreferenceUtils.setPrivacyAgree(ctx)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/PushUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.net.Uri
6 | import android.os.Build
7 | import android.provider.Settings
8 | import androidx.core.app.NotificationManagerCompat
9 |
10 | /**
11 | * 推送活动
12 | */
13 | object PushUtils {
14 | /**
15 | * 检测 通知消息是否已经 打开
16 | */
17 | fun isNotificationEnabled(context: Context): Boolean {
18 | return NotificationManagerCompat.from(context).areNotificationsEnabled()
19 | }
20 |
21 | /**
22 | * 上报 设备的 推送 id
23 | *
24 | * 在
25 | * * 用户登陆
26 | * * 用户登出
27 | * * 打开 APP
28 | * 的时候需要上报
29 | */
30 | fun reportPushId(context: Context) {
31 | }
32 |
33 | /**
34 | * 通知权限申请
35 | * @param context
36 | */
37 | fun requestNotify(context: Context) {
38 | ///< 直接跳转到应用通知设置的代码
39 | val localIntent = Intent()
40 |
41 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
42 | localIntent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
43 | localIntent.putExtra(Settings.EXTRA_APP_PACKAGE, context.packageName)
44 | localIntent.putExtra(Settings.EXTRA_CHANNEL_ID, context.applicationInfo.uid)
45 | } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
46 | localIntent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
47 | localIntent.data = Uri.fromParts("package", context.packageName, null)
48 | }
49 |
50 | context.startActivity(localIntent)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/TipUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.content.Context
4 | import android.view.View
5 | import android.widget.Toast
6 | import com.google.android.material.snackbar.Snackbar
7 |
8 | object TipUtils {
9 |
10 | fun toastShort(ctx: Context, s: String) {
11 | Toast.makeText(ctx, s, Toast.LENGTH_SHORT).show()
12 | }
13 |
14 | fun toastLong(ctx: Context, s: String) {
15 | Toast.makeText(ctx, s, Toast.LENGTH_LONG).show()
16 | }
17 |
18 | fun barShort(view: View, msg: String) {
19 | Snackbar.make(view, msg, Snackbar.LENGTH_SHORT).show()
20 | }
21 |
22 | fun barLong(view: View, msg: String) {
23 | Snackbar.make(view, msg, Snackbar.LENGTH_LONG).show()
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/utils/WebUtils.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.utils
2 |
3 | import android.webkit.JavascriptInterface
4 | import android.webkit.WebView
5 | import android.webkit.WebViewClient
6 | import androidx.appcompat.app.AppCompatActivity
7 | import androidx.appcompat.widget.LinearLayoutCompat
8 | import androidx.fragment.app.FragmentActivity
9 | import com.qiyutech.tbk.BuildConfig
10 | import com.qiyutech.tbk.logic.TaoBaoLogic
11 | import com.qiyutech.tbk.values.AppPreferenceUtils
12 | import com.qiyutech.tbk.values.AppSpKeys
13 |
14 |
15 | const val AndroidBindingName: String = "MyAndroidAutoResize"
16 |
17 | /**
18 | * 自动设置 WebView 的高度
19 | * 注意: 请使用 ScrollView LinearView 包裹起来
20 | */
21 | class MyWebViewAutoResizeClient(private val webView: WebView) : WebViewClient() {
22 | /* use js control for simplify
23 | override fun onPageFinished(view: WebView?, url: String?) {
24 | webView.loadUrl("javascript:${AndroidAutoResizeBindingName}.resize(document.body.getBoundingClientRect().height)")
25 | super.onPageFinished(view, url)
26 | }
27 | */
28 | }
29 |
30 | class ItemDetailWebViewClient(private val itemId: String) : WebViewClient() {
31 | override fun onPageFinished(view: WebView?, url: String?) {
32 | super.onPageFinished(view, url)
33 | view!!.loadUrl("javascript:item_detail_init('${itemId}')")
34 | }
35 | }
36 |
37 |
38 | /**
39 | * 自动设置 resize
40 | * binding with this: AndroidAutoResizeBindingName
41 | */
42 | class AndroidWebViewInterface(private var activity: FragmentActivity, private var wv: WebView) {
43 |
44 | @JavascriptInterface
45 | fun resize(height: Float) {
46 | activity.runOnUiThread {
47 | run {
48 | val dm = activity.resources.displayMetrics
49 | val w = dm.widthPixels
50 | val h = (height * dm.density).toInt()
51 | wv.layoutParams = LinearLayoutCompat.LayoutParams(w, h)
52 | }
53 | }
54 | }
55 |
56 | /// 打开一个指定的商品
57 | @JavascriptInterface
58 | fun openItem(item: String) {
59 | activity.runOnUiThread {
60 | run {
61 | AppNavUtils.gotoItemDetailV2(activity, item)
62 | }
63 | }
64 | }
65 |
66 | @JavascriptInterface
67 | fun buyItem(item: String) {
68 | activity.runOnUiThread {
69 | run {
70 | val tb = TaoBaoLogic(activity = activity as AppCompatActivity)
71 | tb.buyItem(item)
72 | }
73 | }
74 | }
75 |
76 | @JavascriptInterface
77 | fun uuid(): String {
78 | val sp = AppUtils.getPreference(activity)
79 | return sp.getString(AppSpKeys.TBK_UUID, "") ?: ""
80 | }
81 |
82 | @JavascriptInterface
83 | fun token(): String {
84 | return AppPreferenceUtils.getUserToken(activity)
85 | }
86 |
87 | /**
88 | * 获取基础的 url
89 | */
90 | @JavascriptInterface
91 | fun baseUrl(): String {
92 | return BuildConfig.BASE_URL
93 | }
94 |
95 |
96 | @JavascriptInterface
97 | fun openSuperSubCategory(subCid: Int, title: String) {
98 | activity.runOnUiThread {
99 | run {
100 | // 跳转到超级分类
101 | // 当前已经移除
102 | }
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/values/ApiUrlsV2.kt:
--------------------------------------------------------------------------------
1 | // 这个文件是由于 openapi.json 自动生成的
2 | // 请不要使用手工编辑
3 |
4 | package com.qiyutech.tbk.values
5 |
6 | import com.qiyutech.tbk.BuildConfig
7 |
8 | object TbkAPIUrls {
9 |
10 |
11 | const val Ping: String = BuildConfig.BASE_URL + "/ping"
12 | const val DtkFastBuy: String = BuildConfig.BASE_URL + "/dtk/fast_buy"
13 | const val DtkGoodsDetail: String = BuildConfig.BASE_URL + "/dtk/goods_detail"
14 | const val DtkGoodsList: String = BuildConfig.BASE_URL + "/dtk/goods_list"
15 | const val DtkGoodsNineOpGoodsList: String =
16 | BuildConfig.BASE_URL + "/dtk/goods_nine_op_goods_list"
17 | const val DtkGoodsPriceTrend: String = BuildConfig.BASE_URL + "/dtk/goods_price_trend"
18 | const val DtkGuessYouLike: String = BuildConfig.BASE_URL + "/dtk/guess_you_like"
19 | const val DtkPrivilegeLink: String = BuildConfig.BASE_URL + "/dtk/privilege_link"
20 | const val DtkRankingList: String = BuildConfig.BASE_URL + "/dtk/ranking_list"
21 | const val DtkSearchGoods: String = BuildConfig.BASE_URL + "/dtk/search_goods"
22 | const val DtkSearchSuggestion: String = BuildConfig.BASE_URL + "/dtk/search_suggestion"
23 | const val DtkSuperCategory: String = BuildConfig.BASE_URL + "/dtk/super_category"
24 | const val DtkSuperSearch: String = BuildConfig.BASE_URL + "/dtk/super_search"
25 | const val DtkBrandList: String = BuildConfig.BASE_URL + "/dtk/brand_list"
26 | const val DtkTbService: String = BuildConfig.BASE_URL + "/dtk/tb_service"
27 | const val DtkTop100: String = BuildConfig.BASE_URL + "/dtk/top_100"
28 | const val OrderList: String = BuildConfig.BASE_URL + "/order/list"
29 | const val ShareAndroidRelationTkl: String = BuildConfig.BASE_URL + "/share/android/relation_tkl"
30 | const val ShareIosRelationTkl: String = BuildConfig.BASE_URL + "/share/ios/relation_tkl"
31 | const val ShareIosNoRelationTkl: String = BuildConfig.BASE_URL + "/share/ios/no_relation_tkl"
32 | const val SysConfig: String = BuildConfig.BASE_URL + "/sys/config"
33 | const val TaobaoAuthUrl: String = BuildConfig.BASE_URL + "/taobao/auth_url"
34 | const val TbkDtkBrandGoods: String = BuildConfig.BASE_URL + "/tbk/dtk/brand_goods"
35 | const val TbkDtkBrandList: String = BuildConfig.BASE_URL + "/tbk/dtk/brand_list"
36 | const val TbkItemDetail: String = BuildConfig.BASE_URL + "/tbk/item_detail"
37 | const val UserAuth: String = BuildConfig.BASE_URL + "/user/auth"
38 | const val UserCancel: String = BuildConfig.BASE_URL + "/user/cancel"
39 | const val UserBind: String = BuildConfig.BASE_URL + "/user/bind"
40 | const val UserProfile: String = BuildConfig.BASE_URL + "/user/profile"
41 | const val UserTb: String = BuildConfig.BASE_URL + "/user/tb"
42 | const val ZtkBangDanTuiJian: String = BuildConfig.BASE_URL + "/ztk/bang_dan_tui_jian"
43 | const val ZtkGuessYouLike: String = BuildConfig.BASE_URL + "/ztk/guess_you_like"
44 | const val ZtkItemV2: String = BuildConfig.BASE_URL + "/ztk/item_v2"
45 | const val ZtkJuHuaSuan: String = BuildConfig.BASE_URL + "/ztk/ju_hua_suan"
46 | const val ZtkNineNine: String = BuildConfig.BASE_URL + "/ztk/nine_nine"
47 | const val ZtkSuggest: String = BuildConfig.BASE_URL + "/ztk/suggest"
48 | const val ZtkTmallChaoShi: String = BuildConfig.BASE_URL + "/ztk/tmall_chao_shi"
49 | const val ZtkTmallShangPin: String = BuildConfig.BASE_URL + "/ztk/tmall_shang_pin"
50 | const val ZtkGaoYong: String = BuildConfig.BASE_URL + "/ztk/gao_yong"
51 | const val ZtkKeyword: String = BuildConfig.BASE_URL + "/ztk/keyword"
52 | const val ZtkSearch: String = BuildConfig.BASE_URL + "/ztk/search"
53 | }
54 |
55 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/values/AppSpKeys.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.values
2 |
3 | import android.content.Context
4 | import com.google.gson.Gson
5 | import com.qiyutech.tbk.dt.DtUserProfileDataModel
6 | import com.qiyutech.tbk.utils.AppUtils
7 | import com.qiyutech.tbk.utils.MyJsonUtils
8 |
9 | object AppSharedPreferencesName {
10 | const val NAME = "TBKSharedPreference"
11 | }
12 |
13 | /**
14 | * Android Shared Preference keys
15 | */
16 | object AppSpKeys {
17 | /// 跟设备管理的 UUID
18 | const val TBK_UUID = "TBK-uuid"
19 |
20 | /// 用户信息
21 | const val USER_INFO_BIG_KEY = "user-info-key"
22 |
23 | /// 搜索历史
24 | const val SEARCH_HISTORY = "search-history"
25 |
26 | /// 获取用户的 token
27 | const val USER_TOKEN = "user-token"
28 |
29 | /// 用户是否已经同意 隐私政策
30 | const val PRIVACY_AGREE = "privacy-agree"
31 | }
32 |
33 | object AppPreferenceUtils {
34 |
35 |
36 | /**
37 | * 设置 tao ID
38 | */
39 | fun setTaoId(ctx: Context, taoId: String) {
40 | getUserInfo(ctx)?.let {
41 | val newData = DtUserProfileDataModel(
42 | mobile = it.mobile,
43 | tao_id = taoId,
44 | wx = it.wx,
45 | relation_id = it.relation_id,
46 | ali_name = it.ali_name,
47 | ali_account = it.ali_account
48 | )
49 | setUserInfo(ctx, newData)
50 | }
51 | }
52 |
53 | /**
54 | * 获取 是否已经同意隐私政策
55 | */
56 | fun getPrivacyAgree(ctx: Context): Boolean {
57 | val sp = AppUtils.getPreference(ctx)
58 | return sp.getBoolean(AppSpKeys.PRIVACY_AGREE, false)
59 | }
60 |
61 | /**
62 | * 设置为已经同意隐私政策
63 | */
64 | fun setPrivacyAgree(ctx: Context) {
65 | val sp = AppUtils.getPreference(ctx)
66 | sp.edit().putBoolean(AppSpKeys.PRIVACY_AGREE, true).apply()
67 | }
68 |
69 | fun getSearchHistory(ctx: Context): Array {
70 | val sp = AppUtils.getPreference(ctx)
71 | val history = sp.getString(AppSpKeys.SEARCH_HISTORY, "")
72 | if (history === "") {
73 | return arrayOf()
74 | }
75 |
76 | return try {
77 | Gson().fromJson(history, Array::class.java)
78 | } catch (e: Exception) {
79 | arrayOf()
80 | }
81 | }
82 |
83 | /**
84 | * 设置 搜索历史
85 | */
86 | fun setSearchHistory(ctx: Context, history: List) {
87 | val count = history.count()
88 |
89 | val newHistory = if (count > 10) {
90 | history.drop(count - 10)
91 | } else {
92 | history
93 | }
94 | // use set of to delete duplicated item
95 | val s = Gson().toJson(newHistory.toSet().toList())
96 |
97 | val sp = AppUtils.getPreference(ctx)
98 |
99 | sp.edit().putString(AppSpKeys.SEARCH_HISTORY, s).apply()
100 | }
101 |
102 |
103 | /**
104 | * 获取是否已经绑定淘宝账号
105 | */
106 | fun getBindTaoBao(ctx: Context): Boolean {
107 | getUserInfo(ctx)?.let {
108 | it.relation_id?.let { relation ->
109 | if (relation.isBlank()) {
110 | return false
111 | }
112 | return true
113 | }
114 | }
115 | return false
116 | }
117 |
118 |
119 | fun setUserToken(ctx: Context, token: String) {
120 | setKeyValue(ctx, AppSpKeys.USER_TOKEN, token)
121 | }
122 |
123 | /**
124 | * 设置用户消息
125 | */
126 | fun setUserInfo(ctx: Context, info: DtUserProfileDataModel) {
127 | val s = MyJsonUtils.toString(info)
128 | AppUtils.getPreference(ctx)
129 | .edit()
130 | .putString(AppSpKeys.USER_INFO_BIG_KEY, s)
131 | .apply()
132 | }
133 |
134 | /**
135 | * 删除用户信息
136 | */
137 | fun delUserInfo(ctx: Context) {
138 | AppUtils.getPreference(ctx)
139 | .edit()
140 | .remove(AppSpKeys.USER_INFO_BIG_KEY)
141 | .apply()
142 | }
143 |
144 | fun getUserInfo(ctx: Context): DtUserProfileDataModel? {
145 | val s = AppUtils.getPreference(ctx).getString(AppSpKeys.USER_INFO_BIG_KEY, "")
146 | if (s.isNullOrBlank()) {
147 | return null
148 | }
149 |
150 | return MyJsonUtils.fromString(s, DtUserProfileDataModel::class.java)
151 | }
152 |
153 | fun getUserToken(ctx: Context): String {
154 | return getOrDefault(ctx, AppSpKeys.USER_TOKEN, "")
155 | }
156 |
157 |
158 | fun getUserUuid(ctx: Context): String {
159 | return ""
160 | }
161 |
162 |
163 | private fun getOrDefault(ctx: Context, key: String, default: String): String {
164 | val sp = AppUtils.getPreference(ctx)
165 | val ret = sp.getString(key, default)
166 | return if (ret.isNullOrBlank()) {
167 | ""
168 | } else {
169 | ret
170 | }
171 | }
172 |
173 | private fun setKeyValue(ctx: Context, key: String, value: String) {
174 | val sp = AppUtils.getPreference(ctx)
175 | sp.edit().putString(key, value).apply()
176 | }
177 | }
178 |
179 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/values/HttpFile.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.values
2 |
3 | object HttpFile {
4 | // 隐私
5 | const val privacy = "file:///android_asset/www/html/privacy.html"
6 | }
7 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/values/HttpTags.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.values
2 |
3 |
4 | object HttpTags {
5 | // 搜索
6 | const val SEARCH = "search"
7 |
8 | // 下载图片
9 | const val IMAGE = "image"
10 | }
11 |
--------------------------------------------------------------------------------
/app/src/main/java/com/qiyutech/tbk/values/LogTags.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk.values
2 |
3 |
4 | object LogTags {
5 | const val TaoBao = "淘宝"
6 | const val AliBC = "阿里百川"
7 | const val AliBuy = "淘宝购买"
8 | const val Push = "推送"
9 | const val Dialog = "对话框"
10 | const val User = "用户"
11 | const val CACHE_IMAGE = "图片缓存"
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/res/color/bottom_nav_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button_round_corner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/coupon_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/coupon_bg.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/f_icon_coupon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/f_icon_coupon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/f_icon_group.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/f_icon_group.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/f_icon_home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/f_icon_home.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/f_icon_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/f_icon_user.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/forward.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/item_detail_coupon_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/search.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/search_button_bg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/search_view_bg.xml:
--------------------------------------------------------------------------------
1 |
4 |
6 |
7 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/star.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/star.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/yw_1222.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/drawable/yw_1222.jpg
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_coupon.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
21 |
25 |
35 |
36 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
71 |
72 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_dev_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
24 |
25 |
31 |
32 |
38 |
39 |
45 |
46 |
52 |
53 |
59 |
60 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_group.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
21 |
22 |
30 |
31 |
32 |
33 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 |
21 |
22 |
28 |
29 |
37 |
38 |
39 |
40 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_me.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
12 |
13 |
19 |
20 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_privacy.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
20 |
21 |
22 |
30 |
31 |
38 |
39 |
46 |
47 |
57 |
58 |
59 |
60 |
61 |
68 |
69 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_search.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
30 |
31 |
34 |
47 |
48 |
57 |
58 |
59 |
60 |
61 |
62 |
68 |
69 |
72 |
73 |
82 |
83 |
84 |
88 |
89 |
96 |
97 |
98 |
99 |
100 |
106 |
107 |
110 |
111 |
119 |
120 |
121 |
122 |
126 |
127 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_search_detail_native.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
23 |
24 |
31 |
32 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_tao_bao.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_user_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
22 |
23 |
27 |
28 |
35 |
36 |
42 |
43 |
49 |
50 |
56 |
57 |
63 |
64 |
70 |
71 |
77 |
78 |
84 |
85 |
91 |
92 |
93 |
94 |
95 |
101 |
102 |
110 |
111 |
119 |
120 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_home_guess_you_like.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
14 |
15 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_me_default.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
17 |
18 |
26 |
27 |
36 |
37 |
44 |
45 |
46 |
47 |
57 |
58 |
66 |
67 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
95 |
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_me_slot.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_s_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_text_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
18 |
19 |
30 |
31 |
32 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/me_activity_divider.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/parts_simple_kv_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/parts_tbk_sort_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
15 |
16 |
22 |
23 |
24 |
25 |
29 |
30 |
36 |
37 |
38 |
39 |
43 |
44 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/popup_clean_cache.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 |
21 |
22 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/s_footer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/search_search_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/settings_activity.xml:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/t_grid_demo.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/user_password_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
18 |
19 |
29 |
30 |
43 |
44 |
54 |
55 |
68 |
69 |
70 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/home_navigation_menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-hdpi/back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-hdpi/forward.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/me_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-hdpi/me_order.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-hdpi/settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/tao_bao_auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-hdpi/tao_bao_auth.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-mdpi/back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-mdpi/forward.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/me_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-mdpi/me_order.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-mdpi/settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/tao_bao_auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-mdpi/tao_bao_auth.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xhdpi/back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xhdpi/forward.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/me_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xhdpi/me_order.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xhdpi/settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/tao_bao_auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xhdpi/tao_bao_auth.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxhdpi/back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxhdpi/forward.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/me_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxhdpi/me_order.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxhdpi/settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/tao_bao_auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxhdpi/tao_bao_auth.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxxhdpi/back.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/forward.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxxhdpi/forward.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/me_order.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxxhdpi/me_order.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxxhdpi/settings.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/tao_bao_auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/app/src/main/res/mipmap-xxxhdpi/tao_bao_auth.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 奇遇淘客
4 | 设置
5 | 登录/注册
6 | 加载中…
7 | ***
8 | 月销:
9 | 产品名称加载中…
10 | 优惠券
11 | 商家名称加载中
12 | 0
13 | 券后价:
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #6200EE
4 | #3700B3
5 | #03DAC5
6 |
10 | #DAA520
11 | #ff0000
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16sp
5 | 8sp
6 | 8sp
7 | 32dp
8 | 16sp
9 | 8sp
10 | 8sp
11 |
12 | 12sp
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 奇遇淘客
3 |
4 | Settings
5 |
6 |
7 |
8 |
9 |
10 |
11 | 登录/注册
12 |
13 | 加载中…
14 | ***
15 | 月销:
16 | 产品名称加载中…
17 | 优惠券
18 | 商家名称加载中
19 | 0
20 | 券后价:
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
14 |
20 |
21 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/test/java/com/qiyutech/tbk/ExampleUnitTest.kt:
--------------------------------------------------------------------------------
1 | package com.qiyutech.tbk
2 |
3 | import com.google.gson.Gson
4 | import org.json.JSONObject
5 | import org.junit.Assert.assertEquals
6 | import org.junit.Test
7 |
8 |
9 | data class Demo(val demo: String)
10 |
11 | /**
12 | * Example local unit test, which will execute on the development machine (host).
13 | *
14 | * See [testing documentation](http://d.android.com/tools/testing).
15 | */
16 | class ExampleUnitTest {
17 | @Test
18 | fun addition_isCorrect() {
19 | assertEquals(4, 2 + 2)
20 | }
21 |
22 | @Test
23 | fun jsonDemo() {
24 | val s = Gson().toJson(Demo("hello"))
25 | assertEquals("JSON string:", "{\"demo\":\"hello\"}", s)
26 | }
27 |
28 | @Test
29 | fun good() {
30 | val v = Demo("hello")
31 | val s = Gson().toJson(v)
32 | val v2 = Gson().fromJson(s, Demo::class.java)
33 | assertEquals(v, v2)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | ext {
3 | sourceCompatibility = kotlin_version
4 | }
5 |
6 | buildscript {
7 | ext.kotlin_version = '1.5.0'
8 |
9 | repositories {
10 | google()
11 | jcenter()
12 | mavenCentral()
13 | maven {
14 | url "http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories/"
15 | allowInsecureProtocol = true
16 | }
17 | }
18 |
19 | dependencies {
20 | classpath 'com.android.tools.build:gradle:7.0.0'
21 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21"
22 |
23 | // NOTE: Do not place your application dependencies here; they belong
24 | // in the individual module build.gradle files
25 | }
26 | }
27 |
28 | allprojects {
29 | repositories {
30 | google()
31 | jcenter()
32 | mavenCentral()
33 | maven {
34 | url "http://repo.baichuan-android.taobao.com/content/groups/BaichuanRepositories/"
35 | allowInsecureProtocol = true
36 | }
37 |
38 | // https://www.jianshu.com/p/5f0edc95a398
39 | flatDir {
40 | dirs project(':app').file('libs')
41 | }
42 | }
43 | }
44 |
45 | task clean(type: Delete) {
46 | delete rootProject.buildDir
47 | }
48 |
--------------------------------------------------------------------------------
/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 tbk'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 | # for dev vivo install
23 | android.injected.testOnly=false
24 | ##################################
25 | # opt build time
26 | # https://stackoverflow.com/questions/45327617/very-very-slow-gradle-build-on-android-studio
27 | #org.gradle.daemon=true
28 | #org.gradle.configureondemand=true
29 | #org.gradle.parallel=true
30 | #android.enableBuildCache=true
31 | #org.gradle.caching=true
32 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip
6 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/keystore/readme.md:
--------------------------------------------------------------------------------
1 | 数字签名
2 |
--------------------------------------------------------------------------------
/keystore/tbk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/QiYuTechOrg/QiYuTkAndroid/35188be591e96b84de366098bdaf8e6bd92197ac/keystore/tbk
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'TaoBaoKe'
2 | include ':app'
3 |
--------------------------------------------------------------------------------