Compare commits
No commits in common. 'main' and 'master' have entirely different histories.
@ -0,0 +1 @@
|
||||
PaymentApp
|
||||
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetSelector">
|
||||
<selectionStates>
|
||||
<SelectionState runConfigName="app">
|
||||
<option name="selectionMode" value="DROPDOWN" />
|
||||
</SelectionState>
|
||||
</selectionStates>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
@ -1,3 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" default="true">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
@ -1,71 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="5ec2d936-8715-4e0b-8805-53fdae86e6b1" name="更改" comment="" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/.." />
|
||||
</component>
|
||||
<component name="KubernetesApiPersistence"><![CDATA[{}]]></component>
|
||||
<component name="KubernetesApiProvider"><![CDATA[{
|
||||
"isMigrated": true
|
||||
}]]></component>
|
||||
<component name="ProjectColorInfo"><![CDATA[{
|
||||
"associatedIndex": 8
|
||||
}]]></component>
|
||||
<component name="ProjectId" id="353KvvnLsqiKIkfvLAIZPVYufRW" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultAutoModeForALLUsers.v1": "true",
|
||||
"com.intellij.ml.llm.matterhorn.ej.ui.settings.DefaultModelSelectionForGA.v1": "true",
|
||||
"git-widget-placeholder": "zhanghao__branch",
|
||||
"ignore.virus.scanning.warn.message": "true",
|
||||
"junie.onboarding.icon.badge.shown": "true",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "C:/Users/22978/Desktop/mobile pay app/team_noob/MobilePayPrototype",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"to.speed.mode.migration.done": "true",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-jdk-9823dce3aa75-bf35d07a577b-intellij.indexing.shared.core-IU-252.27397.103" />
|
||||
<option value="bundled-js-predefined-d6986cc7102b-3aa1da707db6-JavaScript-IU-252.27397.103" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="默认任务">
|
||||
<changelist id="5ec2d936-8715-4e0b-8805-53fdae86e6b1" name="更改" comment="" />
|
||||
<created>1762333548417</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1762333548417</updated>
|
||||
<workItem from="1762333572907" duration="2380000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
||||
@ -1,202 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ArtifactsWorkspaceSettings">
|
||||
<artifacts-to-build>
|
||||
<artifact name="MobilePayPrototype:war exploded" />
|
||||
</artifacts-to-build>
|
||||
</component>
|
||||
<component name="AutoImportSettings">
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="29d2b17e-3dd5-4f22-94a5-3da90e02a79c" name="更改" comment="" />
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Class" />
|
||||
<option value="Jsp File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="KubernetesApiPersistence">{}</component>
|
||||
<component name="KubernetesApiProvider">{
|
||||
"isMigrated": true
|
||||
}</component>
|
||||
<component name="LogFilters">
|
||||
<option name="FILTER_ERRORS" value="false" />
|
||||
<option name="FILTER_WARNINGS" value="false" />
|
||||
<option name="FILTER_INFO" value="true" />
|
||||
<option name="FILTER_DEBUG" value="true" />
|
||||
<option name="CUSTOM_FILTER" />
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
"associatedIndex": 3
|
||||
}</component>
|
||||
<component name="ProjectId" id="34KTet16frdjK92iA9fGK6TdnU3" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"ModuleVcsDetector.initialDetectionPerformed": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"Tomcat 服务器.Tomcat 10.1.47.executor": "Run",
|
||||
"kotlin-language-version-configured": "true",
|
||||
"last_opened_file_path": "C:/Users/87641/Downloads/MobilePayPrototype",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"project.structure.last.edited": "模块",
|
||||
"project.structure.proportion": "0.0",
|
||||
"project.structure.side.proportion": "0.2",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
}
|
||||
}</component>
|
||||
<component name="RunDashboard">
|
||||
<option name="configurationStatuses">
|
||||
<map>
|
||||
<entry key="#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory">
|
||||
<value>
|
||||
<map>
|
||||
<entry key="Tomcat 10.1.47" value="STOPPED" />
|
||||
</map>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<configuration name="Tomcat 10.1.47" type="#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory" factoryName="Local" APPLICATION_SERVER_NAME="Tomcat 10.1.47" ALTERNATIVE_JRE_ENABLED="false" nameIsGenerated="true">
|
||||
<option name="BROWSER_ID" value="98ca6316-2f89-46d9-a9e5-fa9e2b0625b3" />
|
||||
<option name="UPDATING_POLICY" value="restart-server" />
|
||||
<deployment>
|
||||
<artifact name="MobilePayPrototype:war exploded">
|
||||
<settings>
|
||||
<option name="CONTEXT_PATH" value="/MobilePayPrototype_war_exploded" />
|
||||
</settings>
|
||||
</artifact>
|
||||
</deployment>
|
||||
<server-settings>
|
||||
<option name="BASE_DIRECTORY_NAME" value="83ee14db-001f-45c9-801f-acd24919ac11" />
|
||||
</server-settings>
|
||||
<predefined_log_file enabled="true" id="Tomcat" />
|
||||
<predefined_log_file enabled="true" id="Tomcat Catalina" />
|
||||
<predefined_log_file id="Tomcat Manager" />
|
||||
<predefined_log_file id="Tomcat Host Manager" />
|
||||
<predefined_log_file id="Tomcat Localhost Access" />
|
||||
<RunnerSettings RunnerId="Debug">
|
||||
<option name="DEBUG_PORT" value="8809" />
|
||||
</RunnerSettings>
|
||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Cover">
|
||||
<option name="USE_ENV_VARIABLES" value="true" />
|
||||
<STARTUP>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</STARTUP>
|
||||
<SHUTDOWN>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</SHUTDOWN>
|
||||
</ConfigurationWrapper>
|
||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Debug">
|
||||
<option name="USE_ENV_VARIABLES" value="true" />
|
||||
<STARTUP>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</STARTUP>
|
||||
<SHUTDOWN>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</SHUTDOWN>
|
||||
</ConfigurationWrapper>
|
||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Profile">
|
||||
<option name="USE_ENV_VARIABLES" value="true" />
|
||||
<STARTUP>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</STARTUP>
|
||||
<SHUTDOWN>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</SHUTDOWN>
|
||||
</ConfigurationWrapper>
|
||||
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Run">
|
||||
<option name="USE_ENV_VARIABLES" value="true" />
|
||||
<STARTUP>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</STARTUP>
|
||||
<SHUTDOWN>
|
||||
<option name="USE_DEFAULT" value="true" />
|
||||
<option name="SCRIPT" value="" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
</SHUTDOWN>
|
||||
</ConfigurationWrapper>
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="BuildArtifacts" enabled="true">
|
||||
<artifact name="MobilePayPrototype:war exploded" />
|
||||
</option>
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
<set>
|
||||
<option value="bundled-jdk-9823dce3aa75-bf35d07a577b-intellij.indexing.shared.core-IU-252.26830.84" />
|
||||
<option value="bundled-js-predefined-d6986cc7102b-3aa1da707db6-JavaScript-IU-252.26830.84" />
|
||||
</set>
|
||||
</attachedChunks>
|
||||
</component>
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="默认任务">
|
||||
<changelist id="29d2b17e-3dd5-4f22-94a5-3da90e02a79c" name="更改" comment="" />
|
||||
<created>1760961364824</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1760961364824</updated>
|
||||
<workItem from="1760961365755" duration="97000" />
|
||||
<workItem from="1760961474830" duration="148000" />
|
||||
<workItem from="1760962006950" duration="1217000" />
|
||||
<workItem from="1761200575524" duration="627000" />
|
||||
<workItem from="1761202004904" duration="285000" />
|
||||
<workItem from="1761203404557" duration="18000" />
|
||||
<workItem from="1761295487704" duration="8022000" />
|
||||
<workItem from="1761483085466" duration="99000" />
|
||||
<workItem from="1761745663768" duration="2912000" />
|
||||
<workItem from="1761784691352" duration="1429000" />
|
||||
<workItem from="1761814006991" duration="565000" />
|
||||
<workItem from="1762047486066" duration="8669000" />
|
||||
<workItem from="1762152467619" duration="3073000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
||||
@ -0,0 +1,61 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
alias(libs.plugins.kotlin.compose)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.payment'
|
||||
compileSdk 36
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.payment"
|
||||
minSdk 24
|
||||
targetSdk 36
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '11'
|
||||
}
|
||||
buildFeatures {
|
||||
compose true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.9.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
|
||||
// Jetpack
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata:2.6.2'
|
||||
implementation 'androidx.fragment:fragment:1.6.1'
|
||||
|
||||
// 网络相关 - 必须添加这些
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
|
||||
|
||||
implementation 'com.squareup.okhttp3:mockwebserver:4.11.0'
|
||||
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.payment">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:name=".MyApplication"
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
|
||||
|
||||
<!-- 启动Activity -->
|
||||
<activity
|
||||
android:name=".user.LoginActivity"
|
||||
android:exported="true"
|
||||
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- 其他Activity -->
|
||||
<activity android:name=".ui.MainActivity" />
|
||||
<activity android:name=".user.RegisterActivity" />
|
||||
<activity android:name=".user.RealNameAuthActivity" />
|
||||
<activity android:name=".user.AuditStatusActivity" />
|
||||
<activity android:name=".asset.BalanceActivity" />
|
||||
<activity android:name=".asset.BankCardListActivity" />
|
||||
<activity android:name=".asset.AddBankCardActivity" />
|
||||
<activity android:name=".asset.RechargeWithdrawActivity" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@ -0,0 +1,19 @@
|
||||
package com.payment;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
public class MyApplication extends Application {
|
||||
private static Context context;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
context = getApplicationContext();
|
||||
}
|
||||
|
||||
// 提供全局上下文
|
||||
public static Context getContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
package com.payment.asset;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toast;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.payment.base.BaseActivity;
|
||||
import com.payment.R;
|
||||
|
||||
public class AddBankCardActivity extends BaseActivity {
|
||||
private TextInputEditText etCardNo, etBankName;
|
||||
private Button btnSubmit;
|
||||
private AssetViewModel assetViewModel;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_add_bank_card;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
etCardNo = findViewById(R.id.et_card_no);
|
||||
etBankName = findViewById(R.id.et_bank_name);
|
||||
btnSubmit = findViewById(R.id.btn_submit);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
assetViewModel = new ViewModelProvider(this).get(AssetViewModel.class);
|
||||
|
||||
// 观察添加银行卡结果 - 使用正确的方法名
|
||||
assetViewModel.getAddBankCardResult().observe(this, resultBean -> {
|
||||
if (resultBean != null && resultBean.isSuccess()) {
|
||||
showToast("添加银行卡成功");
|
||||
finish();
|
||||
} else {
|
||||
showToast("添加银行卡失败:" + (resultBean != null ? resultBean.getMsg() : "网络异常"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindEvent() {
|
||||
btnSubmit.setOnClickListener(v -> {
|
||||
String cardNo = etCardNo.getText().toString().trim();
|
||||
String bankName = etBankName.getText().toString().trim();
|
||||
|
||||
if (cardNo.isEmpty() || bankName.isEmpty()) {
|
||||
showToast("请完善银行卡信息");
|
||||
return;
|
||||
}
|
||||
|
||||
if (cardNo.length() < 16) {
|
||||
showToast("请输入正确的银行卡号");
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用添加银行卡接口
|
||||
assetViewModel.addBankCard(cardNo, bankName);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
package com.payment.asset;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import com.payment.base.BaseActivity;
|
||||
import com.payment.R;
|
||||
|
||||
public class BalanceActivity extends BaseActivity {
|
||||
private TextView tvBalance;
|
||||
// 移除 tvUpdateTime 的声明
|
||||
private AssetViewModel assetViewModel;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_balance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
tvBalance = findViewById(R.id.tv_balance);
|
||||
// 移除 tvUpdateTime 的初始化
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
assetViewModel = new ViewModelProvider(this).get(AssetViewModel.class);
|
||||
|
||||
// 查询余额
|
||||
assetViewModel.getBalance();
|
||||
|
||||
// 观察余额结果
|
||||
assetViewModel.getBalanceResult().observe(this, resultBean -> {
|
||||
if (resultBean != null && resultBean.isSuccess()) {
|
||||
String balance = resultBean.getData().getBalance();
|
||||
tvBalance.setText("¥ " + balance);
|
||||
// 移除更新时间显示
|
||||
} else {
|
||||
showToast("获取余额失败");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
package com.payment.asset;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.payment.R;
|
||||
import com.payment.network.ApiService;
|
||||
import java.util.List;
|
||||
|
||||
public class BankCardAdapter extends RecyclerView.Adapter<BankCardAdapter.ViewHolder> {
|
||||
private Context context;
|
||||
private List<ApiService.BankCardBean> cardList; // 修改为 ApiService.BankCardBean
|
||||
private OnItemActionListener listener;
|
||||
|
||||
public BankCardAdapter(Context context, List<ApiService.BankCardBean> cardList) {
|
||||
this.context = context;
|
||||
this.cardList = cardList;
|
||||
}
|
||||
|
||||
public void updateData(List<ApiService.BankCardBean> cardList) { // 修改参数类型
|
||||
this.cardList = cardList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setOnItemActionListener(OnItemActionListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(context).inflate(R.layout.item_bank_card, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
ApiService.BankCardBean card = cardList.get(position); // 修改类型
|
||||
holder.tvBankName.setText(card.getBankName());
|
||||
holder.tvCardNo.setText("**** **** **** " + card.getCardNo().substring(card.getCardNo().length() - 4));
|
||||
|
||||
if (card.isDefault()) {
|
||||
holder.btnSetDefault.setVisibility(View.GONE);
|
||||
holder.tvDefault.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
holder.btnSetDefault.setVisibility(View.VISIBLE);
|
||||
holder.tvDefault.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
holder.btnSetDefault.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onAction(card, "setDefault");
|
||||
}
|
||||
});
|
||||
|
||||
holder.btnDelete.setOnClickListener(v -> {
|
||||
if (listener != null) {
|
||||
listener.onAction(card, "delete");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return cardList == null ? 0 : cardList.size();
|
||||
}
|
||||
|
||||
static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView tvBankName, tvCardNo, tvDefault;
|
||||
Button btnSetDefault, btnDelete;
|
||||
|
||||
public ViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvBankName = itemView.findViewById(R.id.tv_bank_name);
|
||||
tvCardNo = itemView.findViewById(R.id.tv_card_no);
|
||||
tvDefault = itemView.findViewById(R.id.tv_default);
|
||||
btnSetDefault = itemView.findViewById(R.id.btn_set_default);
|
||||
btnDelete = itemView.findViewById(R.id.btn_delete);
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnItemActionListener {
|
||||
void onAction(ApiService.BankCardBean card, String action); // 修改参数类型
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.payment.model;
|
||||
|
||||
public class Balance {
|
||||
private double balance; // 账户余额
|
||||
private String updateTime; // 最后更新时间
|
||||
|
||||
// getter + setter
|
||||
public double getBalance() { return balance; }
|
||||
public void setBalance(double balance) { this.balance = balance; }
|
||||
public String getUpdateTime() { return updateTime; }
|
||||
public void setUpdateTime(String updateTime) { this.updateTime = updateTime; }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.payment.model;
|
||||
|
||||
public class BankCard {
|
||||
private int id; // 银行卡ID
|
||||
private String cardNo; // 银行卡号(脱敏)
|
||||
private String bankName; // 银行名称
|
||||
private boolean isDefault; // 是否默认卡
|
||||
|
||||
// getter + setter
|
||||
public int getId() { return id; }
|
||||
public void setId(int id) { this.id = id; }
|
||||
public String getCardNo() { return cardNo; }
|
||||
public void setCardNo(String cardNo) { this.cardNo = cardNo; }
|
||||
public String getBankName() { return bankName; }
|
||||
public void setBankName(String bankName) { this.bankName = bankName; }
|
||||
public boolean isDefault() { return isDefault; }
|
||||
public void setDefault(boolean aDefault) { isDefault = aDefault; }
|
||||
}
|
||||
@ -0,0 +1,21 @@
|
||||
package com.payment.model;
|
||||
|
||||
public class User {
|
||||
private int userId; // 用户ID
|
||||
private String userName; // 用户名
|
||||
private String token; // 登录令牌
|
||||
private String realName; // 真实姓名(实名认证后)
|
||||
private String idCard; // 身份证号(脱敏)
|
||||
|
||||
// getter + setter
|
||||
public int getUserId() { return userId; }
|
||||
public void setUserId(int userId) { this.userId = userId; }
|
||||
public String getUserName() { return userName; }
|
||||
public void setUserName(String userName) { this.userName = userName; }
|
||||
public String getToken() { return token; }
|
||||
public void setToken(String token) { this.token = token; }
|
||||
public String getRealName() { return realName; }
|
||||
public void setRealName(String realName) { this.realName = realName; }
|
||||
public String getIdCard() { return idCard; }
|
||||
public void setIdCard(String idCard) { this.idCard = idCard; }
|
||||
}
|
||||
@ -0,0 +1,464 @@
|
||||
package com.payment.network;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.POST;
|
||||
|
||||
/**
|
||||
* 网络请求接口服务类
|
||||
*/
|
||||
public interface ApiService {
|
||||
|
||||
// ------------------------ 用户模块接口 ------------------------
|
||||
/**
|
||||
* 用户登录
|
||||
*/
|
||||
@POST("user/login")
|
||||
Call<ResultBean<UserBean>> login(@Body LoginRequest loginRequest);
|
||||
|
||||
/**
|
||||
* 用户注册
|
||||
*/
|
||||
@POST("user/register")
|
||||
Call<ResultBean<BaseResponse>> register(@Body RegisterRequest registerRequest);
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*/
|
||||
@GET("user/info")
|
||||
Call<ResultBean<UserBean>> getUserInfo();
|
||||
|
||||
// ------------------------ 实名认证模块接口 ------------------------
|
||||
/**
|
||||
* 提交实名认证
|
||||
*/
|
||||
@POST("user/auth/submit")
|
||||
Call<ResultBean<BaseResponse>> submitRealNameAuth(@Body RealNameAuthRequest authRequest);
|
||||
|
||||
/**
|
||||
* 查询审核状态
|
||||
*/
|
||||
@GET("user/auth/status")
|
||||
Call<ResultBean<AuditStatusBean>> getAuditStatus();
|
||||
|
||||
// ------------------------ 银行卡模块接口 ------------------------
|
||||
/**
|
||||
* 获取银行卡列表
|
||||
*/
|
||||
@GET("bankCard/list")
|
||||
Call<ResultBean<BankCardListBean>> getBankCardList();
|
||||
|
||||
/**
|
||||
* 添加银行卡
|
||||
*/
|
||||
@POST("bankCard/add")
|
||||
Call<ResultBean<BaseResponse>> addBankCard(@Body AddBankCardRequest cardRequest);
|
||||
|
||||
/**
|
||||
* 设置默认银行卡
|
||||
*/
|
||||
@POST("bankCard/setDefault")
|
||||
Call<ResultBean<BaseResponse>> setDefaultBankCard(@Body DefaultBankCardRequest request);
|
||||
|
||||
/**
|
||||
* 删除银行卡
|
||||
*/
|
||||
@POST("bankCard/delete")
|
||||
Call<ResultBean<BaseResponse>> deleteBankCard(@Body DeleteBankCardRequest request);
|
||||
|
||||
// ------------------------ 资产模块接口 ------------------------
|
||||
/**
|
||||
* 获取余额
|
||||
*/
|
||||
@GET("asset/balance")
|
||||
Call<ResultBean<BalanceBean>> getBalance();
|
||||
|
||||
/**
|
||||
* 充值
|
||||
*/
|
||||
@POST("asset/recharge")
|
||||
Call<ResultBean<BaseResponse>> recharge(@Body RechargeWithdrawRequest request);
|
||||
|
||||
/**
|
||||
* 提现
|
||||
*/
|
||||
@POST("asset/withdraw")
|
||||
Call<ResultBean<BaseResponse>> withdraw(@Body RechargeWithdrawRequest request);
|
||||
|
||||
// ------------------------ 支付模块接口 ------------------------
|
||||
/**
|
||||
* 扫码支付
|
||||
*/
|
||||
@POST("payment/scan")
|
||||
Call<ResultBean<BaseResponse>> scanPayment(@Body ScanPaymentRequest request);
|
||||
|
||||
/**
|
||||
* 生成收款码
|
||||
*/
|
||||
@GET("payment/qrcode")
|
||||
Call<ResultBean<QRCodeBean>> generateQRCode();
|
||||
|
||||
/**
|
||||
* 确认支付
|
||||
*/
|
||||
@POST("payment/confirm")
|
||||
Call<ResultBean<BaseResponse>> confirmPayment(@Body ConfirmPaymentRequest request);
|
||||
|
||||
// ------------------------ 出行模块接口 ------------------------
|
||||
/**
|
||||
* 开通出行码
|
||||
*/
|
||||
@POST("travel/open")
|
||||
Call<ResultBean<BaseResponse>> openTravelCode();
|
||||
|
||||
/**
|
||||
* 获取出行码
|
||||
*/
|
||||
@GET("travel/code")
|
||||
Call<ResultBean<TravelCodeBean>> getTravelCode();
|
||||
|
||||
/**
|
||||
* 扫码进站
|
||||
*/
|
||||
@POST("travel/enter")
|
||||
Call<ResultBean<BaseResponse>> enterStation(@Body StationRequest request);
|
||||
|
||||
/**
|
||||
* 扫码出站
|
||||
*/
|
||||
@POST("travel/exit")
|
||||
Call<ResultBean<TravelFeeBean>> exitStation(@Body StationRequest request);
|
||||
|
||||
// ------------------------ 请求参数实体类 ------------------------
|
||||
/**
|
||||
* 登录请求参数
|
||||
*/
|
||||
class LoginRequest {
|
||||
private String phone;
|
||||
private String password;
|
||||
|
||||
public LoginRequest(String phone, String password) {
|
||||
this.phone = phone;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getPhone() { return phone; }
|
||||
public void setPhone(String phone) { this.phone = phone; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册请求参数
|
||||
*/
|
||||
class RegisterRequest {
|
||||
private String phone;
|
||||
private String verifyCode;
|
||||
private String password;
|
||||
|
||||
public RegisterRequest(String phone, String verifyCode, String password) {
|
||||
this.phone = phone;
|
||||
this.verifyCode = verifyCode;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getPhone() { return phone; }
|
||||
public void setPhone(String phone) { this.phone = phone; }
|
||||
public String getVerifyCode() { return verifyCode; }
|
||||
public void setVerifyCode(String verifyCode) { this.verifyCode = verifyCode; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 实名认证请求参数
|
||||
*/
|
||||
class RealNameAuthRequest {
|
||||
private String realName;
|
||||
private String idCard;
|
||||
|
||||
public RealNameAuthRequest(String realName, String idCard) {
|
||||
this.realName = realName;
|
||||
this.idCard = idCard;
|
||||
}
|
||||
|
||||
public String getRealName() { return realName; }
|
||||
public void setRealName(String realName) { this.realName = realName; }
|
||||
public String getIdCard() { return idCard; }
|
||||
public void setIdCard(String idCard) { this.idCard = idCard; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加银行卡请求参数
|
||||
*/
|
||||
class AddBankCardRequest {
|
||||
private String cardNo;
|
||||
private String bankName;
|
||||
|
||||
public AddBankCardRequest(String cardNo, String bankName) {
|
||||
this.cardNo = cardNo;
|
||||
this.bankName = bankName;
|
||||
}
|
||||
|
||||
public String getCardNo() { return cardNo; }
|
||||
public void setCardNo(String cardNo) { this.cardNo = cardNo; }
|
||||
public String getBankName() { return bankName; }
|
||||
public void setBankName(String bankName) { this.bankName = bankName; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认银行卡请求参数
|
||||
*/
|
||||
class DefaultBankCardRequest {
|
||||
private String cardId;
|
||||
|
||||
public DefaultBankCardRequest(String cardId) {
|
||||
this.cardId = cardId;
|
||||
}
|
||||
|
||||
public String getCardId() { return cardId; }
|
||||
public void setCardId(String cardId) { this.cardId = cardId; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除银行卡请求参数
|
||||
*/
|
||||
class DeleteBankCardRequest {
|
||||
private String cardId;
|
||||
|
||||
public DeleteBankCardRequest(String cardId) {
|
||||
this.cardId = cardId;
|
||||
}
|
||||
|
||||
public String getCardId() { return cardId; }
|
||||
public void setCardId(String cardId) { this.cardId = cardId; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 充值/提现请求参数
|
||||
*/
|
||||
class RechargeWithdrawRequest {
|
||||
private String amount;
|
||||
private String cardId;
|
||||
|
||||
public RechargeWithdrawRequest(String amount, String cardId) {
|
||||
this.amount = amount;
|
||||
this.cardId = cardId;
|
||||
}
|
||||
|
||||
public String getAmount() { return amount; }
|
||||
public void setAmount(String amount) { this.amount = amount; }
|
||||
public String getCardId() { return cardId; }
|
||||
public void setCardId(String cardId) { this.cardId = cardId; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫码支付请求参数
|
||||
*/
|
||||
class ScanPaymentRequest {
|
||||
private String qrCode;
|
||||
private String amount;
|
||||
|
||||
public ScanPaymentRequest(String qrCode, String amount) {
|
||||
this.qrCode = qrCode;
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public String getQrCode() { return qrCode; }
|
||||
public void setQrCode(String qrCode) { this.qrCode = qrCode; }
|
||||
public String getAmount() { return amount; }
|
||||
public void setAmount(String amount) { this.amount = amount; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认支付请求参数
|
||||
*/
|
||||
class ConfirmPaymentRequest {
|
||||
private String orderId;
|
||||
private String password;
|
||||
|
||||
public ConfirmPaymentRequest(String orderId, String password) {
|
||||
this.orderId = orderId;
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getOrderId() { return orderId; }
|
||||
public void setOrderId(String orderId) { this.orderId = orderId; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 站点请求参数
|
||||
*/
|
||||
class StationRequest {
|
||||
private String stationId;
|
||||
private String stationName;
|
||||
|
||||
public StationRequest(String stationId, String stationName) {
|
||||
this.stationId = stationId;
|
||||
this.stationName = stationName;
|
||||
}
|
||||
|
||||
public String getStationId() { return stationId; }
|
||||
public void setStationId(String stationId) { this.stationId = stationId; }
|
||||
public String getStationName() { return stationName; }
|
||||
public void setStationName(String stationName) { this.stationName = stationName; }
|
||||
}
|
||||
|
||||
// ------------------------ 响应结果实体类 ------------------------
|
||||
/**
|
||||
* 基础响应类
|
||||
*/
|
||||
class BaseResponse {
|
||||
private int code;
|
||||
private String message;
|
||||
|
||||
public int getCode() { return code; }
|
||||
public void setCode(int code) { this.code = code; }
|
||||
public String getMessage() { return message; }
|
||||
public void setMessage(String message) { this.message = message; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用结果包装类
|
||||
*/
|
||||
class ResultBean<T> {
|
||||
private int code;
|
||||
private String msg;
|
||||
private T data;
|
||||
private boolean success;
|
||||
|
||||
public int getCode() { return code; }
|
||||
public void setCode(int code) { this.code = code; }
|
||||
public String getMsg() { return msg; }
|
||||
public void setMsg(String msg) { this.msg = msg; }
|
||||
public T getData() { return data; }
|
||||
public void setData(T data) { this.data = data; }
|
||||
public boolean isSuccess() { return success; }
|
||||
public void setSuccess(boolean success) { this.success = success; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户信息实体类
|
||||
*/
|
||||
class UserBean {
|
||||
private String userId;
|
||||
private String phone;
|
||||
private String realName;
|
||||
private int authStatus;
|
||||
private String token;
|
||||
|
||||
public String getUserId() { return userId; }
|
||||
public void setUserId(String userId) { this.userId = userId; }
|
||||
public String getPhone() { return phone; }
|
||||
public void setPhone(String phone) { this.phone = phone; }
|
||||
public String getRealName() { return realName; }
|
||||
public void setRealName(String realName) { this.realName = realName; }
|
||||
public int getAuthStatus() { return authStatus; }
|
||||
public void setAuthStatus(int authStatus) { this.authStatus = authStatus; }
|
||||
public String getToken() { return token; }
|
||||
public void setToken(String token) { this.token = token; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 审核状态实体类
|
||||
*/
|
||||
class AuditStatusBean {
|
||||
private int status;
|
||||
private String desc;
|
||||
|
||||
public int getStatus() { return status; }
|
||||
public void setStatus(int status) { this.status = status; }
|
||||
public String getDesc() { return desc; }
|
||||
public void setDesc(String desc) { this.desc = desc; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 银行卡列表实体类
|
||||
*/
|
||||
class BankCardListBean {
|
||||
private BankCardBean[] cards;
|
||||
|
||||
public BankCardBean[] getCards() { return cards; }
|
||||
public void setCards(BankCardBean[] cards) { this.cards = cards; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 银行卡实体类
|
||||
*/
|
||||
class BankCardBean {
|
||||
private int id;
|
||||
private String cardNo;
|
||||
private String bankName;
|
||||
private boolean isDefault;
|
||||
|
||||
public int getId() { return id; }
|
||||
public void setId(int id) { this.id = id; }
|
||||
public String getCardNo() { return cardNo; }
|
||||
public void setCardNo(String cardNo) { this.cardNo = cardNo; }
|
||||
public String getBankName() { return bankName; }
|
||||
public void setBankName(String bankName) { this.bankName = bankName; }
|
||||
public boolean isDefault() { return isDefault; }
|
||||
public void setDefault(boolean isDefault) { this.isDefault = isDefault; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 余额实体类
|
||||
*/
|
||||
class BalanceBean {
|
||||
private String balance;
|
||||
private String updateTime;
|
||||
|
||||
public String getBalance() { return balance; }
|
||||
public void setBalance(String balance) { this.balance = balance; }
|
||||
public String getUpdateTime() { return updateTime; }
|
||||
public void setUpdateTime(String updateTime) { this.updateTime = updateTime; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 收款码实体类
|
||||
*/
|
||||
class QRCodeBean {
|
||||
private String qrCodeUrl;
|
||||
private String expireTime;
|
||||
|
||||
public String getQrCodeUrl() { return qrCodeUrl; }
|
||||
public void setQrCodeUrl(String qrCodeUrl) { this.qrCodeUrl = qrCodeUrl; }
|
||||
public String getExpireTime() { return expireTime; }
|
||||
public void setExpireTime(String expireTime) { this.expireTime = expireTime; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 出行码实体类
|
||||
*/
|
||||
class TravelCodeBean {
|
||||
private String code;
|
||||
private String status;
|
||||
private String expireTime;
|
||||
|
||||
public String getCode() { return code; }
|
||||
public void setCode(String code) { this.code = code; }
|
||||
public String getStatus() { return status; }
|
||||
public void setStatus(String status) { this.status = status; }
|
||||
public String getExpireTime() { return expireTime; }
|
||||
public void setExpireTime(String expireTime) { this.expireTime = expireTime; }
|
||||
}
|
||||
|
||||
/**
|
||||
* 出行费用实体类
|
||||
*/
|
||||
class TravelFeeBean {
|
||||
private String fee;
|
||||
private String distance;
|
||||
private String duration;
|
||||
|
||||
public String getFee() { return fee; }
|
||||
public void setFee(String fee) { this.fee = fee; }
|
||||
public String getDistance() { return distance; }
|
||||
public void setDistance(String distance) { this.distance = distance; }
|
||||
public String getDuration() { return duration; }
|
||||
public void setDuration(String duration) { this.duration = duration; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
package com.payment.ui;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RadioGroup;
|
||||
|
||||
import com.payment.R;
|
||||
import com.payment.ui.fragment.HomeFragment;
|
||||
import com.payment.ui.fragment.TravelCodeFragment;
|
||||
import com.payment.ui.fragment.BillFragment;
|
||||
import com.payment.ui.fragment.MineFragment;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private FrameLayout flContent;
|
||||
private RadioGroup rgBottomNav;
|
||||
private RadioButton rbHome, rbTravel, rbBill, rbMine;
|
||||
|
||||
// 碎片实例
|
||||
private Fragment homeFragment, travelFragment, billFragment, mineFragment;
|
||||
private Fragment currentFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// 初始化视图
|
||||
initView();
|
||||
// 初始化碎片
|
||||
initFragment();
|
||||
// 底部导航点击事件
|
||||
setNavClickListener();
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
flContent = findViewById(R.id.fl_content);
|
||||
rgBottomNav = findViewById(R.id.rg_bottom_nav);
|
||||
rbHome = findViewById(R.id.rb_home);
|
||||
rbTravel = findViewById(R.id.rb_travel);
|
||||
rbBill = findViewById(R.id.rb_bill);
|
||||
rbMine = findViewById(R.id.rb_mine);
|
||||
}
|
||||
|
||||
private void initFragment() {
|
||||
homeFragment = new HomeFragment();
|
||||
travelFragment = new TravelCodeFragment();
|
||||
billFragment = new BillFragment();
|
||||
mineFragment = new MineFragment();
|
||||
|
||||
// 默认显示首页
|
||||
currentFragment = homeFragment;
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.fl_content, homeFragment)
|
||||
.commit();
|
||||
}
|
||||
|
||||
private void setNavClickListener() {
|
||||
rgBottomNav.setOnCheckedChangeListener((group, checkedId) -> {
|
||||
Fragment targetFragment = null;
|
||||
// 用if-else替代switch-case
|
||||
if (checkedId == R.id.rb_home) {
|
||||
targetFragment = homeFragment;
|
||||
} else if (checkedId == R.id.rb_travel) {
|
||||
targetFragment = travelFragment;
|
||||
} else if (checkedId == R.id.rb_bill) {
|
||||
targetFragment = billFragment;
|
||||
} else if (checkedId == R.id.rb_mine) {
|
||||
targetFragment = mineFragment;
|
||||
}
|
||||
|
||||
// 切换碎片
|
||||
if (targetFragment != null && targetFragment != currentFragment) {
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
if (!targetFragment.isAdded()) {
|
||||
transaction.add(R.id.fl_content, targetFragment);
|
||||
}
|
||||
transaction.hide(currentFragment).show(targetFragment).commit();
|
||||
currentFragment = targetFragment;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.payment.ui.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.payment.R;
|
||||
|
||||
public class BillFragment extends Fragment {
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_bill, container, false);
|
||||
TextView tvTip = view.findViewById(R.id.tv_tip);
|
||||
tvTip.setText("账单功能暂未开放,敬请期待");
|
||||
return view;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
package com.payment.ui.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.payment.R;
|
||||
import com.payment.utils.IntentUtils;
|
||||
import com.payment.asset.BalanceActivity;
|
||||
import com.payment.asset.BankCardListActivity;
|
||||
|
||||
public class HomeFragment extends Fragment {
|
||||
private Button btnBalance, btnBankCard, btnRecharge, btnWithdraw;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_home, container, false);
|
||||
initView(view);
|
||||
bindEvent();
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initView(View view) {
|
||||
btnBalance = view.findViewById(R.id.btn_balance);
|
||||
btnBankCard = view.findViewById(R.id.btn_bank_card);
|
||||
btnRecharge = view.findViewById(R.id.btn_recharge);
|
||||
btnWithdraw = view.findViewById(R.id.btn_withdraw);
|
||||
}
|
||||
|
||||
private void bindEvent() {
|
||||
// 余额查询
|
||||
btnBalance.setOnClickListener(v -> {
|
||||
if (getActivity() != null) {
|
||||
IntentUtils.jumpTo(getActivity(), BalanceActivity.class, false);
|
||||
}
|
||||
});
|
||||
|
||||
// 银行卡管理
|
||||
btnBankCard.setOnClickListener(v -> {
|
||||
if (getActivity() != null) {
|
||||
IntentUtils.jumpTo(getActivity(), BankCardListActivity.class, false);
|
||||
}
|
||||
});
|
||||
|
||||
// 充值
|
||||
btnRecharge.setOnClickListener(v -> {
|
||||
if (getActivity() != null) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("type", "recharge");
|
||||
IntentUtils.jumpToWithBundle(getActivity(), com.payment.asset.RechargeWithdrawActivity.class, bundle, false);
|
||||
}
|
||||
});
|
||||
|
||||
// 提现
|
||||
btnWithdraw.setOnClickListener(v -> {
|
||||
if (getActivity() != null) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString("type", "withdraw");
|
||||
IntentUtils.jumpToWithBundle(getActivity(), com.payment.asset.RechargeWithdrawActivity.class, bundle, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package com.payment.ui.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import com.payment.R;
|
||||
|
||||
public class TravelCodeFragment extends Fragment {
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.fragment_travel_code, container, false);
|
||||
TextView tvTip = view.findViewById(R.id.tv_tip);
|
||||
tvTip.setText("出行码功能暂未开放,敬请期待");
|
||||
return view;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.payment.user;
|
||||
|
||||
import com.payment.base.BaseActivity;
|
||||
import com.payment.R;
|
||||
import com.payment.network.ApiService;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class AuditStatusActivity extends BaseActivity {
|
||||
private TextView tvStatus, tvDesc;
|
||||
private UserViewModel userViewModel;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_audit_status;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
tvStatus = findViewById(R.id.tv_status);
|
||||
tvDesc = findViewById(R.id.tv_desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
|
||||
// 查询审核状态
|
||||
userViewModel.getAuditStatus();
|
||||
// 观察审核状态结果
|
||||
userViewModel.getAuditStatusResult().observe(this, resultBean -> {
|
||||
if (resultBean != null && resultBean.isSuccess()) {
|
||||
ApiService.AuditStatusBean statusBean = resultBean.getData();
|
||||
updateStatusUI(statusBean.getStatus(), statusBean.getDesc());
|
||||
} else {
|
||||
showToast("查询审核状态失败");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 更新审核状态UI
|
||||
private void updateStatusUI(int status, String desc) {
|
||||
tvStatus.setText(getStatusText(status));
|
||||
tvDesc.setText(desc);
|
||||
// 根据状态设置文字颜色
|
||||
switch (status) {
|
||||
case 0: // 未提交
|
||||
tvStatus.setTextColor(getResources().getColor(R.color.gray));
|
||||
break;
|
||||
case 1: // 审核中
|
||||
tvStatus.setTextColor(getResources().getColor(R.color.blue));
|
||||
break;
|
||||
case 2: // 审核通过
|
||||
tvStatus.setTextColor(getResources().getColor(R.color.green));
|
||||
break;
|
||||
case 3: // 驳回
|
||||
tvStatus.setTextColor(getResources().getColor(R.color.red));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 状态文字映射
|
||||
private String getStatusText(int status) {
|
||||
switch (status) {
|
||||
case 0: return "未提交实名认证";
|
||||
case 1: return "审核中";
|
||||
case 2: return "审核通过";
|
||||
case 3: return "审核驳回";
|
||||
default: return "未知状态";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,78 @@
|
||||
package com.payment.user;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.payment.R;
|
||||
import com.payment.utils.IntentUtils;
|
||||
import com.payment.utils.TokenUtils;
|
||||
import com.payment.ui.MainActivity;
|
||||
|
||||
public class LoginActivity extends AppCompatActivity {
|
||||
private EditText etPhone, etPassword;
|
||||
private Button btnLogin, btnRegister;
|
||||
private UserViewModel userViewModel;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_login);
|
||||
|
||||
// 移除或注释掉这行 - Mock服务器会在需要时自动启动
|
||||
// MockServerManager.startMockServer();
|
||||
|
||||
// 初始化视图
|
||||
initView();
|
||||
// 初始化ViewModel
|
||||
initViewModel();
|
||||
// 绑定点击事件
|
||||
setClickListeners();
|
||||
}
|
||||
|
||||
private void initView() {
|
||||
etPhone = findViewById(R.id.et_phone);
|
||||
etPassword = findViewById(R.id.et_password);
|
||||
btnLogin = findViewById(R.id.btn_login);
|
||||
btnRegister = findViewById(R.id.btn_register);
|
||||
}
|
||||
|
||||
private void initViewModel() {
|
||||
userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
|
||||
// 观察登录结果
|
||||
userViewModel.getLoginResult().observe(this, resultBean -> {
|
||||
if (resultBean != null && resultBean.isSuccess()) {
|
||||
// 保存Token
|
||||
TokenUtils.saveToken(this, resultBean.getData().getToken());
|
||||
Toast.makeText(this, "登录成功", Toast.LENGTH_SHORT).show();
|
||||
// 跳转到主页面
|
||||
IntentUtils.jumpTo(this, MainActivity.class, true);
|
||||
} else {
|
||||
Toast.makeText(this, "登录失败:" + (resultBean != null ? resultBean.getMsg() : "网络异常"), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setClickListeners() {
|
||||
// 登录按钮
|
||||
btnLogin.setOnClickListener(v -> {
|
||||
String phone = etPhone.getText().toString().trim();
|
||||
String password = etPassword.getText().toString().trim();
|
||||
if (phone.isEmpty() || password.isEmpty()) {
|
||||
Toast.makeText(this, "手机号和密码不能为空", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
// 调用ViewModel登录方法
|
||||
userViewModel.login(phone, password);
|
||||
});
|
||||
|
||||
// 注册按钮
|
||||
btnRegister.setOnClickListener(v -> {
|
||||
IntentUtils.jumpTo(this, RegisterActivity.class, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.payment.user;
|
||||
|
||||
import com.payment.base.BaseActivity;
|
||||
import com.payment.R;
|
||||
import com.payment.utils.ToastUtils;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
|
||||
public class RealNameAuthActivity extends BaseActivity {
|
||||
private EditText etRealName, etIdCard;
|
||||
private Button btnSubmit;
|
||||
private UserViewModel userViewModel;
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_real_name_auth;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initView() {
|
||||
etRealName = findViewById(R.id.et_real_name);
|
||||
etIdCard = findViewById(R.id.et_id_card);
|
||||
btnSubmit = findViewById(R.id.btn_submit);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initData() {
|
||||
userViewModel = new ViewModelProvider(this).get(UserViewModel.class);
|
||||
// 观察实名认证结果
|
||||
userViewModel.getRealNameResult().observe(this, resultBean -> {
|
||||
if (resultBean != null && resultBean.isSuccess()) {
|
||||
showToast(resultBean.getMsg());
|
||||
finish(); // 返回上一页
|
||||
} else {
|
||||
showToast("提交失败:" + (resultBean != null ? resultBean.getMsg() : "网络异常"));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindEvent() {
|
||||
btnSubmit.setOnClickListener(v -> {
|
||||
String realName = etRealName.getText().toString().trim();
|
||||
String idCard = etIdCard.getText().toString().trim();
|
||||
|
||||
if (realName.isEmpty() || idCard.isEmpty()) {
|
||||
showToast("请完善实名认证信息");
|
||||
return;
|
||||
}
|
||||
if (idCard.length() != 18) {
|
||||
showToast("请输入正确的身份证号");
|
||||
return;
|
||||
}
|
||||
// 提交实名认证
|
||||
userViewModel.submitRealNameAuth(realName, idCard);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
package com.payment.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class IntentUtils {
|
||||
/**
|
||||
* 页面跳转
|
||||
* @param context 上下文
|
||||
* @param targetClass 目标Activity
|
||||
* @param isFinish 是否关闭当前Activity
|
||||
*/
|
||||
public static void jumpTo(Context context, Class<?> targetClass, boolean isFinish) {
|
||||
Intent intent = new Intent(context, targetClass);
|
||||
context.startActivity(intent);
|
||||
if (isFinish && context instanceof android.app.Activity) {
|
||||
((android.app.Activity) context).finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 带参数跳转
|
||||
* @param context 上下文
|
||||
* @param targetClass 目标Activity
|
||||
* @param bundle 参数包
|
||||
* @param isFinish 是否关闭当前Activity
|
||||
*/
|
||||
public static void jumpToWithBundle(Context context, Class<?> targetClass, android.os.Bundle bundle, boolean isFinish) {
|
||||
Intent intent = new Intent(context, targetClass);
|
||||
if (bundle != null) {
|
||||
intent.putExtras(bundle);
|
||||
}
|
||||
context.startActivity(intent);
|
||||
if (isFinish && context instanceof android.app.Activity) {
|
||||
((android.app.Activity) context).finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.payment.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class ToastUtils {
|
||||
private static Toast toast;
|
||||
|
||||
// 显示短吐司
|
||||
public static void showToast(Context context, String msg) {
|
||||
if (toast == null) {
|
||||
toast = Toast.makeText(context.getApplicationContext(), msg, Toast.LENGTH_SHORT);
|
||||
} else {
|
||||
toast.setText(msg);
|
||||
toast.setDuration(Toast.LENGTH_SHORT);
|
||||
}
|
||||
toast.show();
|
||||
}
|
||||
|
||||
// 显示长吐司
|
||||
public static void showLongToast(Context context, String msg) {
|
||||
if (toast == null) {
|
||||
toast = Toast.makeText(context.getApplicationContext(), msg, Toast.LENGTH_LONG);
|
||||
} else {
|
||||
toast.setText(msg);
|
||||
toast.setDuration(Toast.LENGTH_LONG);
|
||||
}
|
||||
toast.show();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="添加银行卡"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_card_no"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入银行卡号"
|
||||
android:inputType="number" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_bank_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入银行名称" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_submit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="添加银行卡"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="审核状态"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="32dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="未知状态"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_desc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="状态描述"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#666" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="账户余额"
|
||||
android:textSize="18sp"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_balance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="¥ 0.00"
|
||||
android:textSize="32sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_add_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="添加银行卡"
|
||||
android:layout_margin="16dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_empty"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="暂无银行卡"
|
||||
android:gravity="center"
|
||||
android:textSize="16sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_bank_cards"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="32dp"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="用户登录"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="48dp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_phone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入手机号"
|
||||
android:inputType="phone" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入密码"
|
||||
android:inputType="textPassword" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_login"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="登录"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_register"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="注册"
|
||||
android:textSize="16sp"
|
||||
android:backgroundTint="@android:color/transparent"
|
||||
android:textColor="@color/blue" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<FrameLayout
|
||||
android:id="@+id/fl_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<!-- 底部导航 -->
|
||||
<RadioGroup
|
||||
android:id="@+id/rg_bottom_nav"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:background="#F5F5F5">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_home"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="首页"
|
||||
android:button="@null"
|
||||
android:drawableTop="@android:drawable/ic_menu_agenda"
|
||||
android:gravity="center"
|
||||
android:padding="8dp" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_travel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="出行码"
|
||||
android:button="@null"
|
||||
android:drawableTop="@android:drawable/ic_menu_directions"
|
||||
android:gravity="center"
|
||||
android:padding="8dp" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_bill"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="账单"
|
||||
android:button="@null"
|
||||
android:drawableTop="@android:drawable/ic_menu_manage"
|
||||
android:gravity="center"
|
||||
android:padding="8dp" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rb_mine"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="我的"
|
||||
android:button="@null"
|
||||
android:drawableTop="@android:drawable/ic_menu_my_calendar"
|
||||
android:gravity="center"
|
||||
android:padding="8dp" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="实名认证"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_real_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入真实姓名" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_id_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入身份证号"
|
||||
android:inputType="number" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_submit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="提交认证"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="充值"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_amount"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入金额"
|
||||
android:inputType="numberDecimal" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="选择银行卡"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner_bank_cards"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_confirm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="确认"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="32dp"
|
||||
android:gravity="center">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="用户注册"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:layout_marginBottom="48dp" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_phone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入手机号"
|
||||
android:inputType="phone" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_verify_code"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="请输入验证码"
|
||||
android:layout_marginEnd="8dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_get_code"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="获取验证码"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="32dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/et_password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="请输入密码"
|
||||
android:inputType="textPassword" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_register"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="注册"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_tip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="账单功能暂未开放,敬请期待"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#666" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:gravity="center">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_balance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="余额查询"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_bank_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="银行卡管理"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_recharge"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="充值"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_withdraw"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="提现"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_user_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="用户名"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_real_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="实名认证"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_audit_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="审核状态"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_logout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="退出登录"
|
||||
android:textColor="#FF0000"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_tip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="出行码功能暂未开放,敬请期待"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#666" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp"
|
||||
android:layout_margin="8dp"
|
||||
android:background="@android:color/white"
|
||||
android:elevation="2dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_bank_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="银行名称"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_default"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="默认"
|
||||
android:textColor="#FF4CAF50"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_card_no"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="**** **** **** 1234"
|
||||
android:textSize="14sp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="12dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_set_default"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="设为默认"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_delete"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="删除"
|
||||
android:textColor="#FFF44336"
|
||||
android:layout_marginStart="8dp"
|
||||
android:textSize="12sp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 982 B After Width: | Height: | Size: 982 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">PaymentApp</string>
|
||||
</resources>
|
||||
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">#2196F3</item>
|
||||
<item name="colorPrimaryDark">#1976D2</item>
|
||||
<item name="colorAccent">#FF4081</item>
|
||||
</style>
|
||||
</resources>
|
||||
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Theme.PaymentApp" parent="android:Theme.Material.Light.NoActionBar" />
|
||||
</resources>
|
||||
@ -1,4 +1,4 @@
|
||||
package com.example.myapplication
|
||||
package com.payment
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.kotlin.android) apply false
|
||||
alias(libs.plugins.kotlin.compose) apply false
|
||||
}
|
||||