diff --git a/stallhelper/README.md b/stallhelper/README.md new file mode 100644 index 0000000..cc44aff --- /dev/null +++ b/stallhelper/README.md @@ -0,0 +1,4 @@ +# StallHelper +# 排档辅助管理工具 + +## LargeStall Stand Auxiliary Management Tool. diff --git a/stallhelper/app_update_description.txt b/stallhelper/app_update_description.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/stallhelper/app_update_description.txt @@ -0,0 +1 @@ + diff --git a/stallhelper/build.gradle b/stallhelper/build.gradle new file mode 100644 index 0000000..cd5975b --- /dev/null +++ b/stallhelper/build.gradle @@ -0,0 +1,80 @@ +apply plugin: 'com.android.application' +apply from: '../.winboll/winboll_app_build.gradle' +apply from: '../.winboll/winboll_lint_build.gradle' + +def genVersionName(def versionName){ + // 检查编译标志位配置 + assert (winbollBuildProps['stageCount'] != null) + assert (winbollBuildProps['baseVersion'] != null) + // 保存基础版本号 + winbollBuildProps.setProperty("baseVersion", "${versionName}"); + //保存编译标志配置 + FileOutputStream fos = new FileOutputStream(winbollBuildPropsFile) + winbollBuildProps.store(fos, "${winbollBuildPropsDesc}"); + fos.close(); + + // 返回编译版本号 + return "${versionName}." + winbollBuildProps['stageCount'] +} + +android { + compileSdkVersion 30 + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } + + defaultConfig { + applicationId "cc.winboll.studio.stallhelper" + minSdkVersion 26 + targetSdkVersion 30 + versionCode 1 + // versionName 更新后需要手动设置 + // .winboll/winbollBuildProps.properties 文件的 stageCount=0 + // Gradle编译环境下合起来的 versionName 就是 "${versionName}.0" + versionName "15.20" + if(true) { + versionName = genVersionName("${versionName}") + } + } +} + +dependencies { + // 下拉控件 + api 'com.baoyz.pullrefreshlayout:library:1.2.0' + // 拼音搜索 + // https://mvnrepository.com/artifact/com.github.open-android/pinyin4j + api 'com.github.open-android:pinyin4j:2.5.0' + // SSH + api 'com.jcraft:jsch:0.1.55' + // Html 解析 + api 'org.jsoup:jsoup:1.13.1' + // 二维码类库 + api 'com.google.zxing:core:3.4.1' + api 'com.journeyapps:zxing-android-embedded:3.6.0' + // 应用介绍页类库 + api 'io.github.medyo:android-about-page:2.0.0' + // 网络连接类库 + api 'com.squareup.okhttp3:okhttp:4.4.1' + // AndroidX 类库 + api 'androidx.appcompat:appcompat:1.1.0' + api 'androidx.cardview:cardview:1.0.0' + //api 'com.google.android.material:material:1.4.0' + //api 'androidx.viewpager:viewpager:1.0.0' + //api 'androidx.vectordrawable:vectordrawable:1.1.0' + //api 'androidx.vectordrawable:vectordrawable-animated:1.1.0' + //api 'androidx.fragment:fragment:1.1.0' + + //注意:以下5个库必须要引入 + //implementation 'androidx.appcompat:appcompat:1.4.1' + api 'androidx.recyclerview:recyclerview:1.0.0' + api 'com.google.code.gson:gson:2.8.5' + api 'com.github.bumptech.glide:glide:4.9.0' + //annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0' + + // WinBoLL库 nexus.winboll.cc 地址 + api 'cc.winboll.studio:libaes:15.20.3' + api 'cc.winboll.studio:libappbase:15.20.9' + + api fileTree(dir: 'libs', include: ['*.jar']) +} diff --git a/stallhelper/build.properties b/stallhelper/build.properties new file mode 100644 index 0000000..17c5765 --- /dev/null +++ b/stallhelper/build.properties @@ -0,0 +1,8 @@ +#Created by .winboll/winboll_app_build.gradle +#Wed May 13 02:22:06 HKT 2026 +stageCount=2 +libraryProject= +baseVersion=15.20 +publishVersion=15.20.1 +buildCount=0 +baseBetaVersion=15.20.2 diff --git a/stallhelper/proguard-rules.pro b/stallhelper/proguard-rules.pro new file mode 100644 index 0000000..855b18a --- /dev/null +++ b/stallhelper/proguard-rules.pro @@ -0,0 +1,143 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# ============================== 基础通用规则 ============================== +# 保留系统组件 +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class * extends android.app.backup.BackupAgentHelper +-keep public class * extends android.preference.Preference + +# 保留 WinBoLL 核心包及子类(合并简化规则) +-keep class cc.winboll.studio.** { *; } +-keepclassmembers class cc.winboll.studio.** { *; } + +# 保留所有类中的 public static final String TAG 字段(便于日志定位) +-keepclassmembers class * { + public static final java.lang.String TAG; +} + +# 保留序列化类(避免Parcelable/Gson解析异常) +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} +-keepclassmembers class * implements java.io.Serializable { + static final long serialVersionUID; + private static final java.io.ObjectStreamField[] serialPersistentFields; + private void writeObject(java.io.ObjectOutputStream); + private void readObject(java.io.ObjectInputStream); + java.lang.Object writeReplace(); + java.lang.Object readResolve(); +} + +# 保留 R 文件(避免资源ID混淆) +-keepclassmembers class **.R$* { + public static ; +} + +# 保留 native 方法(避免JNI调用失败) +-keepclasseswithmembernames class * { + native ; +} + +# 保留注解和泛型(避免反射/序列化异常) +-keepattributes *Annotation* +-keepattributes Signature + +# 屏蔽 Java 8+ 警告(适配 Java 7 语法) +-dontwarn java.lang.invoke.* +-dontwarn android.support.v8.renderscript.* +-dontwarn java.util.function.** + +# ============================== 第三方框架专项规则 ============================== +# OkHttp 4.4.1(米盟广告请求依赖,完善Lambda兼容) +-keep class okhttp3.** { *; } +-keep interface okhttp3.** { *; } +-keep class okhttp3.internal.** { *; } +-keep class okio.** { *; } +-dontwarn okhttp3.internal.platform.** +-dontwarn okio.** +# ============================== 必要补充规则 ============================== +# OkHttp 4.4.1 补充规则(Java 7 兼容) +-keep class okhttp3.internal.concurrent.** { *; } +-keep class okhttp3.internal.connection.** { *; } +-dontwarn okhttp3.internal.concurrent.TaskRunner +-dontwarn okhttp3.internal.connection.RealCall + +# Glide 4.9.0(米盟广告图片加载依赖) +-keep public class * implements com.bumptech.glide.module.GlideModule +-keep public class * extends com.bumptech.glide.module.AppGlideModule +-keep public enum com.bumptech.glide.load.ImageHeaderParser$ImageType { + **[] $VALUES; + public *; +} +-keepclassmembers class * implements com.bumptech.glide.module.AppGlideModule { + (); +} +-dontwarn com.bumptech.glide.** + +# Gson 2.8.5(米盟广告数据序列化依赖) +-keep class com.google.gson.** { *; } +-keep interface com.google.gson.** { *; } +-keepclassmembers class * { + @com.google.gson.annotations.SerializedName ; +} + +# 米盟 SDK(核心广告组件,完整保留避免加载失败) +-keep class com.miui.zeus.** { *; } +-keep interface com.miui.zeus.** { *; } +# 保留米盟日志字段(便于广告加载失败排查) +-keepclassmembers class com.miui.zeus.mimo.sdk.** { + public static final java.lang.String TAG; +} + +# RecyclerView 1.0.0(米盟广告布局渲染依赖) +-keep class androidx.recyclerview.** { *; } +-keep interface androidx.recyclerview.** { *; } +-keepclassmembers class androidx.recyclerview.widget.RecyclerView$Adapter { + public *; +} + +# 其他第三方框架(按引入依赖保留,无则可删除) +# XXPermissions 18.63 +-keep class com.hjq.permissions.** { *; } +-keep interface com.hjq.permissions.** { *; } + +# ZXing 二维码(核心解析组件) +-keep class com.google.zxing.** { *; } +-keep class com.journeyapps.zxing.** { *; } + +# Jsoup HTML解析 +-keep class org.jsoup.** { *; } + +# Pinyin4j 拼音搜索 +-keep class net.sourceforge.pinyin4j.** { *; } + +# JSch SSH组件 +-keep class com.jcraft.jsch.** { *; } + +# AndroidX 基础组件 +-keep class androidx.appcompat.** { *; } +-keep interface androidx.appcompat.** { *; } + +# ============================== 优化与调试配置 ============================== +# 优化级别(平衡混淆效果与性能) +-optimizationpasses 5 +-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/* + +# 调试辅助(保留行号便于崩溃定位) +-verbose +-dontpreverify +-dontusemixedcaseclassnames +-keepattributes SourceFile,LineNumberTable + diff --git a/stallhelper/src/beta/AndroidManifest.xml b/stallhelper/src/beta/AndroidManifest.xml new file mode 100644 index 0000000..1f53f3e --- /dev/null +++ b/stallhelper/src/beta/AndroidManifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/stallhelper/src/beta/res/values-zh/strings.xml b/stallhelper/src/beta/res/values-zh/strings.xml new file mode 100644 index 0000000..9df4507 --- /dev/null +++ b/stallhelper/src/beta/res/values-zh/strings.xml @@ -0,0 +1,6 @@ + + + + 排档辅助管理工具+ + + diff --git a/stallhelper/src/beta/res/values/strings.xml b/stallhelper/src/beta/res/values/strings.xml new file mode 100644 index 0000000..1f1dd73 --- /dev/null +++ b/stallhelper/src/beta/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + StallHelper+ + + diff --git a/stallhelper/src/main/AndroidManifest.xml b/stallhelper/src/main/AndroidManifest.xml new file mode 100644 index 0000000..4a32a9e --- /dev/null +++ b/stallhelper/src/main/AndroidManifest.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/App.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/App.java new file mode 100644 index 0000000..095c241 --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/App.java @@ -0,0 +1,34 @@ +package cc.winboll.studio.stallhelper; + +/** + * @Author ZhanGSKen@QQ.COM + * @Date 2025/01/22 00:11:41 + * @Describe 全局应用类 + */ +import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; +import cc.winboll.studio.libappbase.GlobalApplication; +import cc.winboll.studio.libappbase.ToastUtils; + +public class App extends GlobalApplication { + + public static final String TAG = "App"; + + @Override + public void onCreate() { + super.onCreate(); + + super.onCreate(); + setIsDebugging(BuildConfig.DEBUG); + //setIsDebugging(false); + WinBoLLActivityManager.init(this); + + // 初始化 Toast 框架 + ToastUtils.init(this); + } + + @Override + public void onTerminate() { + super.onTerminate(); + ToastUtils.release(); + } +} diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/MainActivity.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/MainActivity.java new file mode 100644 index 0000000..e59a874 --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/MainActivity.java @@ -0,0 +1,129 @@ +package cc.winboll.studio.stallhelper; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import androidx.appcompat.widget.Toolbar; +import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.stallhelper.R; +import cc.winboll.studio.stallhelper.activities.AboutActivity; +import cc.winboll.studio.stallhelper.activities.CompleteDiningTableActivity; +import cc.winboll.studio.stallhelper.activities.NoteRecordHelperActivity; +import cc.winboll.studio.stallhelper.activities.PreNullDiningTableActivity; +import cc.winboll.studio.stallhelper.activities.WinBoLLActivity; + +final public class MainActivity extends WinBoLLActivity { + + public static final String TAG = "MainActivity"; + + public static final int REQUEST_HOME_ACTIVITY = 0; + public static final int REQUEST_ABOUT_ACTIVITY = 1; + Context mContext; + private Toolbar mToolbar; + +// @Override +// protected boolean isEnableDisplayHomeAsUp() { +// return false; +// } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + mContext = getApplicationContext(); + + mToolbar = findViewById(R.id.toolbar); + setSupportActionBar(mToolbar); + } + + @Override + public String getTag() { + return TAG; + } + + +// @Override +// protected boolean isAddWinBoLLToolBar() { +// return true; +// } +// +// @Override +// protected Toolbar initToolBar() { +// return findViewById(R.id.activitymainToolbar1); +// } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.toolbar_main, menu); + return super.onCreateOptionsMenu(menu); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.action_about) { + startActivity(new Intent(this, AboutActivity.class)); + return true; + } + return super.onOptionsItemSelected(item); + } + + void openAboutActivity() { + Intent intent = new Intent(getApplicationContext(), AboutActivity.class); + startActivity(intent); + //App.getWinBoLLActivityManager().startWinBoLLActivity(getApplicationContext(), AboutActivity.class); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (resultCode) { + case REQUEST_HOME_ACTIVITY : { + LogUtils.d(TAG, "REQUEST_HOME_ACTIVITY"); + break; + } + case REQUEST_ABOUT_ACTIVITY : { + LogUtils.d(TAG, "REQUEST_ABOUT_ACTIVITY"); + break; + } + default : { + super.onActivityResult(requestCode, resultCode, data); + } + } + } + + public void onPreNullDiningTable(View view) { + //ToastUtils.show("onDiningTable"); + Intent intent = new Intent(getApplicationContext(), PreNullDiningTableActivity.class); + startActivity(intent); + //App.getWinBoLLActivityManager().startWinBoLLActivity(mContext, PreNullDiningTableActivity.class); +// try { +// WinBoLLActivity clazzActivity = PreNullDiningTableActivity.class.newInstance(); +// String tag = clazzActivity.getTag(); +// LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag); +// Intent intent = new Intent(getApplicationContext(), PreNullDiningTableActivity.class); +// startWinBoLLActivity(intent, tag); +// } catch (IllegalAccessException e) {} catch (InstantiationException e) {} + } + + public void onCompleteDiningTable(View view) { + //ToastUtils.show("onDiningTable"); + Intent intent = new Intent(getApplicationContext(), CompleteDiningTableActivity.class); + startActivity(intent); + //App.getWinBoLLActivityManager().startWinBoLLActivity(mContext, CompleteDiningTableActivity.class); +// try { +// WinBoLLActivity clazzActivity = CompleteDiningTableActivity.class.newInstance(); +// String tag = clazzActivity.getTag(); +// LogUtils.d(TAG, "String tag = clazzActivity.getTag(); tag " + tag); +// Intent intent = new Intent(getApplicationContext(), CompleteDiningTableActivity.class); +// startWinBoLLActivity(intent, tag); +// } catch (IllegalAccessException e) {} catch (InstantiationException e) {} + } + + public void onNoteRecordHelper(View view) { + Intent intent = new Intent(getApplicationContext(), NoteRecordHelperActivity.class); + startActivity(intent); + } +} diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/AboutActivity.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/AboutActivity.java new file mode 100644 index 0000000..303ee84 --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/AboutActivity.java @@ -0,0 +1,50 @@ +package cc.winboll.studio.stallhelper.activities; + +import android.os.Bundle; +import android.view.View; +import androidx.appcompat.widget.Toolbar; +import androidx.appcompat.app.AppCompatActivity; +import cc.winboll.studio.stallhelper.R; +import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.libappbase.models.APPInfo; +import cc.winboll.studio.libappbase.views.AboutView; + +/** + * @Author 豆包&ZhanGSKen + * @Date 2026/01/11 12:55 + * @Describe AboutActivity + */ +public class AboutActivity extends AppCompatActivity { + + public static final String TAG = "AboutActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_about); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + AboutView aboutView = findViewById(R.id.aboutview); + aboutView.setAPPInfo(genDefaultAppInfo()); + } + + private APPInfo genDefaultAppInfo() { + LogUtils.d(TAG, "genDefaultAppInfo() 调用"); + String branchName = "stallhelper"; + APPInfo appInfo = new APPInfo(); + appInfo.setAppName("StallHelper"); + appInfo.setAppIcon(R.drawable.ic_winboll); + appInfo.setAppDescription(getString(R.string.app_description)); + appInfo.setAppGitName("StallHelper"); + appInfo.setAppGitOwner("ZhanGSKen"); + appInfo.setAppGitAPPBranch(branchName); + appInfo.setAppGitAPPSubProjectFolder(branchName); + appInfo.setAppHomePage("http://10.8.0.4:9876/apks/index-manager.php?project=StallHelper"); + appInfo.setAppAPKName("StallHelper"); + appInfo.setAppAPKFolderName("StallHelper"); + LogUtils.d(TAG, "genDefaultAppInfo: 应用信息已生成"); + return appInfo; + } +} diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/CompleteDiningTableActivity.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/CompleteDiningTableActivity.java new file mode 100644 index 0000000..34ab03c --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/CompleteDiningTableActivity.java @@ -0,0 +1,371 @@ +package cc.winboll.studio.stallhelper.activities; + +/** + * @Author ZhanGSKen@QQ.COM + * @Date 2024/10/29 09:22:24 + * @Describe 餐桌表补全窗口 + */ +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; +import androidx.appcompat.widget.Toolbar; +import cc.winboll.studio.libappbase.ToastUtils; +import cc.winboll.studio.stallhelper.App; +import cc.winboll.studio.stallhelper.R; +import cc.winboll.studio.stallhelper.beans.DiningTableBean; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; + +public class CompleteDiningTableActivity extends WinBoLLActivity { + + public static final String TAG = "CompleteDiningTableActivity"; + + // 某一号晚上的餐桌预定补全列表 + ArrayList mCompleteTableInfoList; + // 原始预定信息内容输入框 + EditText metOriginBookText; + EditText metPreBookList; + EditText metCompleteDate; + ScrollView mScrollView; + + ArrayList mszOriginBookList; + + @Override + public String getTag() { + return TAG; + } + +// @Override +// protected boolean isEnableDisplayHomeAsUp() { +// return true; +// } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_completediningtable); + setTitle("餐桌表补全"); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + StringBuilder sbDateNow = new StringBuilder("当前日期:"); + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String timeString = sdf.format(now); + sbDateNow.append(timeString); + TextView tvDateNow = findViewById(R.id.activitycompletediningtableTextView2); + tvDateNow.setText(sbDateNow.toString()); + + + metOriginBookText = findViewById(R.id.activitycompletediningtableEditText1); + metPreBookList = findViewById(R.id.activitycompletediningtableEditText2); + metCompleteDate = findViewById(R.id.activitycompletediningtableEditText3); + mScrollView = findViewById(R.id.activitycompletediningtableScrollView1); + } + +// @Override +// protected Toolbar initToolBar() { +// return findViewById(R.id.activitycompletediningtableToolbar1); +// } +// +// @Override +// protected boolean isAddWinBoLLToolBar() { +// return false; +// } + + boolean isInCompleteRule(DiningTableBean item) { + String szCompleteDate = metCompleteDate.getText().toString() + "号"; + if (item.getDate().equals(szCompleteDate) && item.getDinnerType() == DiningTableBean.DinnerType.Evening) { + return true; + } + return false; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + WinBoLLActivityManager.getInstance().finish(this); + } + return super.onOptionsItemSelected(item); + } + + void createNullCompleteTableInfoList() { + mCompleteTableInfoList = new ArrayList(); + String szCompleteDate = metCompleteDate.getText().toString() + "号"; + + mCompleteTableInfoList.add(new DiningTableBean("201", 18, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("202", 8, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("203", 8, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("205", 10, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("206", 0, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("207", 0, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("208", 8, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("209", 10, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("210", 8, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("211", 12, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("212", 8, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("213", 9, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("666", 14, true, szCompleteDate)); + mCompleteTableInfoList.add(new DiningTableBean("888", 20, true, szCompleteDate)); + + for (int i = 1; i < 23; i++) { + DiningTableBean tempBean = new DiningTableBean(Integer.toString(i), 0, true, szCompleteDate); + tempBean.setDinnerType(DiningTableBean.DinnerType.Evening); + tempBean.setTableType(DiningTableBean.TableType.Table); + tempBean.setIsSelected(false); + mCompleteTableInfoList.add(tempBean); + } + + //DiningTableBean.saveBeanListToFile(getApplicationContext().getExternalFilesDir("temp") + "/1.json", mCompleteTableInfoList); + //ToastUtils.show("Test"); + } + + ArrayList getOriginBookList() { + //ToastUtils.show(metOriginBookText.getText().toString()); + ArrayList listReturn = new ArrayList(); + String[] szOriginBookText = metOriginBookText.getText().toString().split("\\r?\\n"); + for (String szTemp : szOriginBookText) { + String szTemp2 = szTemp.replace(" ", ""); + DiningTableBean bean = format2DiningTableBean(szTemp2); + if (bean != null) { + listReturn.add(bean); + // 更新补全列表 + updateCompleteTableInfoList(bean); + } + } + //ToastUtils.show("szOriginBookText : " + Integer.toString(szOriginBookText.length)); + //ToastUtils.show("listReturn : " + Integer.toString(listReturn.size())); + return listReturn; + } + + // + // 如果补全列表某一项时间和房号与指定项一致, + // 就把指定项信息更新至补全列表中。 + // + void updateCompleteTableInfoList(DiningTableBean beanNew) { + for (DiningTableBean completeTableInfo : mCompleteTableInfoList) { + if (completeTableInfo.getDate().equals(beanNew.getDate()) + && completeTableInfo.getDinnerType() == beanNew.getDinnerType() + && completeTableInfo.getTableNumber().equals(beanNew.getTableNumber())) { + completeTableInfo.setBookDesc(beanNew.getBookDesc()); + completeTableInfo.setIsSelected(true); + } + } + } + + // + // 检验每一个数据行的日期格式, + // 如果出现(x号/x月x号)以外的日期标注, + // 则提示有数据行日期标识不清晰的情况。 + // + boolean checkLinesDateValidAndShow() { + boolean checkResult = true; + String[] szLines = metOriginBookText.getText().toString().split("\\r?\\n"); + if (szLines.length < 1) { + ToastUtils.show("没有数据行。"); + checkResult = false; + } else { + StringBuilder sb = new StringBuilder("日期标识不清晰,在"); + for (int i = 0; i < szLines.length; i++) { + Pattern pattern = Pattern.compile("(\\d*[月]{0,1}\\d+号)\\s*([晚|午]{0,1}).*"); + Matcher matcher = pattern.matcher(szLines[i]); + if (!matcher.find()) { + sb.append("("); + sb.append(Integer.toString(i + 1)); + sb.append(")"); + checkResult = false; + } + } + sb.append("行。"); + if (checkResult == false) { + ToastUtils.show(sb.toString()); + } + } + return checkResult; + } + + // + // 获取指定日期的第一条数据的位置 + // 返回 -1 表示所有数据都没有该日期 + // + int getFirstIndexOfDate(ArrayList originBookList, String szDate) { + int nResult = -1; + //ToastUtils.show("szDate " + szDate); + for (int i = originBookList.size() - 1 ; i > 0; i--) { + //LogUtils.d(TAG, "originBookList.get(i).getDate() " + originBookList.get(i).getDate()); + if (originBookList.get(i).isDiningTableBean()) { + if (originBookList.get(i).getDate().equals(szDate)) { + nResult = i; + continue; + } else { + return nResult; + } + } else { + nResult = i; + continue; + } + } + return nResult; + } + + DiningTableBean format2DiningTableBean(String szBookInfo) { + if (!szBookInfo.trim().equals("")) { + //String sz = "29号晚 201房 123456"; + // 定义正则表达式模式 + Pattern pattern = Pattern.compile("(\\d*[月]{0,1}\\d+号)\\s*([晚|午]{0,1})\\s*(\\d+)([房|桌])[-\\s]*(.*)"); + Matcher matcher = pattern.matcher(szBookInfo); + if (matcher.find()) { + String date = matcher.group(1); + String szDinnerType = matcher.group(2); + String tableNumber = matcher.group(3); + String szTableType = matcher.group(4); + String bookDesc = matcher.group(5); + + DiningTableBean.DinnerType dinnerType = DiningTableBean.DinnerType.Evening; + if (szDinnerType.equals("午")) { + dinnerType = DiningTableBean.DinnerType.Noon; + } + DiningTableBean.TableType tableType = DiningTableBean.TableType.Room; + if (szTableType.equals("桌")) { + tableType = DiningTableBean.TableType.Table; + } + return new DiningTableBean(tableNumber, 0, true, dinnerType, bookDesc, date, tableType); + } else { + return new DiningTableBean(true, false, szBookInfo); + } + } + return null; + } + + void checkAndAddCompleteTableInfoList(ArrayList originBookList) { + boolean isAddCompleteTableInfoList = false; + for (int i = 0; i < originBookList.size(); i++) { + DiningTableBean item = originBookList.get(i); + // 循环读取原始 Bean 列表, + // 如果遇到第一个匹配指定日期号, + // 就不显示 item 项,并且添加预制好的补全表(一次性添加,后续再遇到同类 item 项则不添加补全表。)。 + if (isInCompleteRule(item)) { + // 设置不显示 item 项 + item.setIsSelected(false); + + // 添加补全列表(一次性添加,后续再遇到同类 item 项则不添加补全表。) + if (isAddCompleteTableInfoList == false) { + originBookList.addAll(i, mCompleteTableInfoList); + // 设置后续遇到同类项时,不再添加补全列表 + isAddCompleteTableInfoList = true; + i = i + mCompleteTableInfoList.size(); + } + } + + } + + // 如果遍历完原始 Bean 表后还未添加补全表, + // 就添加一次补全表 + if (isAddCompleteTableInfoList == false) { + int nInsertPost = getFirstIndexOfDate(originBookList, metCompleteDate.getText().toString() + "号"); + //ToastUtils.show("nInsertPost " + Integer.toString(nInsertPost)); + if (nInsertPost == -1) { + originBookList.addAll(mCompleteTableInfoList); + } else { + originBookList.addAll(nInsertPost, mCompleteTableInfoList); + } + // 设置后续遇到同类项时,不再添加补全列表 + isAddCompleteTableInfoList = true; + } + } + + public void onCopyResultText(View view) { + // Gets a handle to the clipboard service. + ClipboardManager clipboard = (ClipboardManager) getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE); + // Creates a new text clip to put on the clipboard + ClipData clip = ClipData.newPlainText("simple text", metPreBookList.getText()); + // Set the clipboard's primary clip. + clipboard.setPrimaryClip(clip); + Toast.makeText(getApplicationContext(), "Copy to clipboard.", Toast.LENGTH_SHORT).show(); + } + + public void onCleanResultText(View view) { + metPreBookList.setText(""); + } + + public void onCreatePreBookList(View view) { + if(metCompleteDate.getText().toString().trim().equals("")) { + ToastUtils.show("没有填写补全日期"); + return; + } + + //checkLinesDateValidAndShow(); + createNullCompleteTableInfoList(); + ArrayList originBookList = getOriginBookList(); + checkAndAddCompleteTableInfoList(originBookList); + + StringBuilder sbPreBookList = new StringBuilder(); + for (int i = 0; i < originBookList.size(); i++) { + DiningTableBean item = originBookList.get(i); + if (item.isDiningTableBean()) { + if (item.getIsSelected()) { + String szDinnerTyp = ""; + if (item.getDinnerType() == DiningTableBean.DinnerType.Evening) { + szDinnerTyp = "晚"; + } + + if (item.getDinnerType() == DiningTableBean.DinnerType.Noon) { + szDinnerTyp = "午"; + } + + String szTableType = ""; + if (item.getTableType() == DiningTableBean.TableType.Room) { + szTableType = "房"; + } + + if (item.getTableType() == DiningTableBean.TableType.Table) { + szTableType = "桌"; + } + + sbPreBookList.append(item.getDate()); + //sbPreBookList.append("号"); + sbPreBookList.append(szDinnerTyp); + //sbPreBookList.append(" "); + sbPreBookList.append(item.getTableNumber()); + sbPreBookList.append(szTableType); + sbPreBookList.append("-"); + sbPreBookList.append(item.getBookDesc()); + sbPreBookList.append("\n"); + } + } else { + sbPreBookList.append(item.getOriginDesc()); + sbPreBookList.append("\n"); + } + + // 不同日期间隔行排版 + if (i + 1 != originBookList.size()) { + if (!originBookList.get(i + 1).getDate().equals(originBookList.get(i).getDate())) { + sbPreBookList.append("\n"); + } + } + } + + //metPreBookList.append("\n"); + metPreBookList.append(sbPreBookList.toString()); + + mScrollView.post(new Runnable() { + @Override + public void run() { + mScrollView.fullScroll(ScrollView.FOCUS_DOWN); + } + }); + } + +} diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/NoteRecordHelperActivity.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/NoteRecordHelperActivity.java new file mode 100644 index 0000000..2b4f836 --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/NoteRecordHelperActivity.java @@ -0,0 +1,226 @@ +package cc.winboll.studio.stallhelper.activities; + +import android.graphics.Color; +import android.os.Bundle; +import android.text.Spannable; +import android.text.SpannableStringBuilder; +import android.text.style.BackgroundColorSpan; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.stallhelper.R; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Author 豆包&ZhanGSKen + * @CreateTime 2026-03-31 00:20:00 + * @ModifyTime 2026-03-31 14:47:00 + * @Describe 订单笔录辅助窗口,支持房号、桌号、多房间号(含"号"字)、手机号尾4位及'-'后文本高亮,原文完整输出 + */ +public class NoteRecordHelperActivity extends AppCompatActivity { + + public static final String TAG = "NoteRecordHelperActivity"; + + // 高亮颜色数组 + private final int[] highlightColors = { + Color.parseColor("#4CAF50"), + Color.parseColor("#FF9800"), + Color.parseColor("#E91E63"), + Color.parseColor("#F44336"), + Color.parseColor("#FFC107"), + Color.parseColor("#2196F3") + }; + + // 正则匹配 + // 匹配多房间号(包含后面的"号"字):11-16-17号 + private final Pattern PATTERN_MULTI_ROOM = Pattern.compile("(\\d+(?:-\\d+)+\\s*号)"); + // 匹配手机号(连续11位或带分隔符) + private final Pattern PATTERN_PHONE = Pattern.compile("(?:\\d{11}|(?:\\d{3,4}[\\s-]?){3,4})"); + + // 控件 + private EditText etContent; + private Button btnHighlight; + private TextView tvHighlightResult; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_noterecordhelper); + LogUtils.i(TAG, "onCreate: 页面初始化"); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + setTitle("订单笔录辅助"); + + initViews(); + } + + /** + * 初始化控件 + */ + private void initViews() { + etContent = findViewById(R.id.et_content); + btnHighlight = findViewById(R.id.btn_highlight); + tvHighlightResult = findViewById(R.id.tv_highlight_result); + + btnHighlight.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + LogUtils.i(TAG, "onClick: 点击高亮按钮"); + highlightContent(); + } + }); + } + + /** + * 解析并高亮内容 + */ + private void highlightContent() { + LogUtils.i(TAG, "highlightContent: 开始处理高亮"); + + String raw = etContent.getText().toString(); + if (raw.isEmpty()) { + LogUtils.i(TAG, "highlightContent: 输入内容为空,直接返回"); + return; + } + + String[] lines = raw.split("\\n"); + SpannableStringBuilder ssb = new SpannableStringBuilder(); + + for (int i = 0; i < lines.length; i++) { + String line = lines[i]; + // 空行也完整保留 + if (line.isEmpty()) { + ssb.append("\n"); + continue; + } + + int colorIndex = i % highlightColors.length; + int color = highlightColors[colorIndex]; + + LogUtils.d(TAG, "highlightContent: 处理第" + (i + 1) + "行,颜色索引=" + colorIndex); + processLine(line, ssb, color); + + if (i != lines.length - 1) { + ssb.append("\n"); + } + } + + tvHighlightResult.setText(ssb); + LogUtils.i(TAG, "highlightContent: 高亮处理完成"); + } + + /** + * 处理单行高亮(原文完整保留) + * @param line 单行文本 + * @param ssb 富文本构建器 + * @param color 高亮颜色 + */ + private void processLine(String line, SpannableStringBuilder ssb, int color) { + LogUtils.d(TAG, "processLine: line=" + line + ", color=" + Integer.toHexString(color)); + + // 1. 先把原文完整追加到 ssb,不会丢失任何字符 + int start = ssb.length(); + ssb.append(line); + + // 2. 高亮多房间号(包含"号"字):11-16-17号 + Matcher mMulti = PATTERN_MULTI_ROOM.matcher(line); + if (mMulti.find()) { + int s = start + mMulti.start(1); + int e = start + mMulti.end(1); + ssb.setSpan(new BackgroundColorSpan(color), s, e, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + + // 3. 高亮房号 / 桌号 + int roomIdx = line.indexOf("房"); + int tableIdx = line.indexOf("号桌"); + + if (roomIdx != -1) { + int s = findNumberStart(line, roomIdx); + int e = roomIdx + 1; + ssb.setSpan(new BackgroundColorSpan(color), start + s, start + e, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } else if (tableIdx != -1) { + int s = findNumberStart(line, tableIdx); + int e = tableIdx + 2; + ssb.setSpan(new BackgroundColorSpan(color), start + s, start + e, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + + // 4. 处理'-'后的内容:优先高亮手机号尾4位,否则高亮全部文本 + int dashIndex = line.indexOf("-"); + if (dashIndex != -1) { + String afterDash = line.substring(dashIndex + 1); + Matcher phoneMatcher = PATTERN_PHONE.matcher(afterDash); + boolean foundPhone = false; + + // 尝试匹配手机号并高亮尾4位 + while (phoneMatcher.find()) { + String phone = phoneMatcher.group(); + if (phone != null) { + foundPhone = true; + // 提取纯数字 + String pureNumber = phone.replaceAll("[^0-9]", ""); + if (pureNumber.length() >= 4) { + String last4 = pureNumber.substring(pureNumber.length() - 4); + // 在原行中定位尾4位(从 dashIndex+1 开始查找,避免匹配前面的数字) + int tailStart = line.indexOf(last4, dashIndex + 1); + if (tailStart != -1) { + int s = start + tailStart; + int e = s + 4; + ssb.setSpan(new BackgroundColorSpan(color), s, e, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + } + } + + // 没有手机号,则高亮'-'后的全部文本 + if (!foundPhone) { + int s = start + dashIndex + 1; + int e = start + line.length(); + ssb.setSpan(new BackgroundColorSpan(color), s, e, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } else { + // 无'-'的行,尝试匹配并高亮手机号尾4位 + Matcher phoneMatcher = PATTERN_PHONE.matcher(line); + while (phoneMatcher.find()) { + String phone = phoneMatcher.group(); + if (phone != null) { + String pureNumber = phone.replaceAll("[^0-9]", ""); + if (pureNumber.length() >= 4) { + String last4 = pureNumber.substring(pureNumber.length() - 4); + int tailStart = line.indexOf(last4); + if (tailStart != -1) { + int s = start + tailStart; + int e = s + 4; + ssb.setSpan(new BackgroundColorSpan(color), s, e, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); + } + } + } + } + } + } + + /** + * 查找数字起始位置 + * @param line 文本行 + * @param endIdx 结束位置 + * @return 数字起始下标 + */ + private int findNumberStart(String line, int endIdx) { + LogUtils.d(TAG, "findNumberStart: endIdx=" + endIdx); + + for (int i = endIdx - 1; i >= 0; i--) { + char c = line.charAt(i); + if (!Character.isDigit(c) && c != ' ') { + return i + 1; + } + } + return 0; + } + +} + diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/PreNullDiningTableActivity.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/PreNullDiningTableActivity.java new file mode 100644 index 0000000..90c5ee4 --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/PreNullDiningTableActivity.java @@ -0,0 +1,264 @@ +package cc.winboll.studio.stallhelper.activities; + +/** + * @Author ZhanGSKen@QQ.COM + * @Date 2024/10/16 05:13:42 + * @Describe 餐桌空白预定表生成窗口 + */ +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.RadioButton; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; +import androidx.appcompat.widget.Toolbar; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; +import cc.winboll.studio.libappbase.ToastUtils; +import cc.winboll.studio.stallhelper.R; +import cc.winboll.studio.stallhelper.beans.DiningTableBean; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Date; + +public class PreNullDiningTableActivity extends WinBoLLActivity { + + public static final String TAG = "DiningTableActivity"; + + ArrayList mListTableInfo; + DiningTableBeanListAdapter mDiningTableBeanListAdapter; + EditText metPreBookList; + ScrollView mScrollView; + RadioButton mrbDinnerTypeNoon; + RadioButton mrbDinnerTypeEvening; + + + @Override + public String getTag() { + return TAG; + } + +// @Override +// protected boolean isEnableDisplayHomeAsUp() { +// return true; +// } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_prenulldiningtable); + setTitle("餐桌空白预定表制作"); + + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + StringBuilder sbDateNow = new StringBuilder("当前日期:"); + Date now = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String timeString = sdf.format(now); + sbDateNow.append(timeString); + TextView tvDateNow = findViewById(R.id.activityprenulldiningtableTextView2); + tvDateNow.setText(sbDateNow.toString()); + + LocalDate currentDate = LocalDate.now(); + int dayOfMonth = currentDate.getDayOfMonth(); + EditText etDateNow = findViewById(R.id.activityprenulldiningtableEditText1); + etDateNow.setText(Integer.toString(dayOfMonth)); + + + mListTableInfo = new ArrayList(); + addTable(); + RecyclerView recyclerView = findViewById(R.id.activityprenulldiningtableRecyclerView1); + recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.HORIZONTAL, false)); + mDiningTableBeanListAdapter = new DiningTableBeanListAdapter(mListTableInfo); + // 设置 RecyclerView 的适配器 + recyclerView.setAdapter(mDiningTableBeanListAdapter); + + metPreBookList = findViewById(R.id.activityprenulldiningtableEditText2); + mScrollView = findViewById(R.id.activityprenulldiningtableScrollView1); + + mrbDinnerTypeNoon = findViewById(R.id.activityprenulldiningtableRadioButton1); + mrbDinnerTypeEvening = findViewById(R.id.activityprenulldiningtableRadioButton2); + mrbDinnerTypeEvening.setChecked(true); + + } + + +// +// @Override +// protected Toolbar initToolBar() { +// return findViewById(R.id.activityprenulldiningtableToolbar1); +// } +// +// @Override +// protected boolean isAddWinBoLLToolBar() { +// return false; +// } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + WinBoLLActivityManager.getInstance().finish(this); + } + return super.onOptionsItemSelected(item); + } + + void addTable() { + mListTableInfo.add(new DiningTableBean("201", 18, false)); + mListTableInfo.add(new DiningTableBean("202", 8, false)); + mListTableInfo.add(new DiningTableBean("203", 8, false)); + mListTableInfo.add(new DiningTableBean("205", 10, false)); + mListTableInfo.add(new DiningTableBean("206", 0, false)); + mListTableInfo.add(new DiningTableBean("207", 0, false)); + mListTableInfo.add(new DiningTableBean("208", 8, false)); + mListTableInfo.add(new DiningTableBean("209", 10, false)); + mListTableInfo.add(new DiningTableBean("210", 8, false)); + mListTableInfo.add(new DiningTableBean("211", 12, false)); + mListTableInfo.add(new DiningTableBean("212", 8, false)); + mListTableInfo.add(new DiningTableBean("213", 9, false)); + mListTableInfo.add(new DiningTableBean("666", 14, false)); + mListTableInfo.add(new DiningTableBean("888", 20, false)); + } + + public void onDinnerType(View view) { + RadioButton rb = (RadioButton)view; + if (rb.getId() == mrbDinnerTypeNoon.getId()) { + ToastUtils.show("午餐"); + mrbDinnerTypeEvening.setChecked(false); + } else { + ToastUtils.show("晚餐"); + mrbDinnerTypeNoon.setChecked(false); + } + } + + public void onCopyResultText(View view) { + // Gets a handle to the clipboard service. + ClipboardManager clipboard = (ClipboardManager) getApplicationContext().getSystemService(Context.CLIPBOARD_SERVICE); + // Creates a new text clip to put on the clipboard + ClipData clip = ClipData.newPlainText("simple text", metPreBookList.getText()); + // Set the clipboard's primary clip. + clipboard.setPrimaryClip(clip); + Toast.makeText(getApplicationContext(), "Copy to clipboard.", Toast.LENGTH_SHORT).show(); + } + + public void onCleanResultText(View view) { + metPreBookList.setText(""); + } + + public void onCreatePreBookList(View view) { + String szDinnerTyp = mrbDinnerTypeEvening.isChecked() ?"晚": "午"; + + EditText etDate = findViewById(R.id.activityprenulldiningtableEditText1); + + StringBuilder sbPreBookList = new StringBuilder(); + for (DiningTableBean item : mListTableInfo) { + if (item.getIsSelected()) { + /*sbPreBookList.append(etDate.getText()); + sbPreBookList.append("号 "); + sbPreBookList.append(szDinnerTyp); + sbPreBookList.append(" "); + sbPreBookList.append(item.getTableNumber()); + sbPreBookList.append("房-\n");*/ + + + String szTableType = ""; + if (item.getTableType() == DiningTableBean.TableType.Room) { + szTableType = "房"; + } + + if (item.getTableType() == DiningTableBean.TableType.Table) { + szTableType = "桌"; + } + + sbPreBookList.append(etDate.getText()); + sbPreBookList.append("号 "); + sbPreBookList.append(szDinnerTyp); + sbPreBookList.append(" "); + sbPreBookList.append(item.getTableNumber()); + sbPreBookList.append(szTableType); + sbPreBookList.append("-"); + sbPreBookList.append(item.getBookDesc()); + sbPreBookList.append("\n"); + } + } + + //metPreBookList.append("\n"); + metPreBookList.append(sbPreBookList.toString()); + + mScrollView.post(new Runnable() { + @Override + public void run() { + mScrollView.fullScroll(ScrollView.FOCUS_DOWN); + } + }); + } + + public void onSelectALLTable(View view) { + boolean isSelectAll =((CheckBox)findViewById(R.id.activityprenulldiningtableCheckBox1)).isChecked(); + for (DiningTableBean item : mListTableInfo) { + item.setIsSelected(isSelectAll); + } + //ToastUtils.show(Boolean.toString(isSelectAll)); + mDiningTableBeanListAdapter.notifyDataSetChanged(); + + } + + class DiningTableBeanListAdapter extends RecyclerView.Adapter { + + ArrayList mDataList; + public DiningTableBeanListAdapter(ArrayList listInfo) { + mDataList = listInfo; + } + @Override + public int getItemCount() { + return mDataList.size(); + } + + @Override + public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) { + final DiningTableBean item = mDataList.get(position); + if (holder.getItemViewType() == 0) { + final SimpleViewHolder viewHolder = (SimpleViewHolder) holder; + viewHolder.mcbTable.setText(item.getTableNumber() + "房(" + Integer.toString(item.getMaxPersonCount()) + "人)"); + viewHolder.mcbTable.setChecked(item.getIsSelected()); + viewHolder.mcbTable.setOnClickListener(new View.OnClickListener(){ + @Override + public void onClick(View v) { + item.setIsSelected(viewHolder.mcbTable.isChecked()); + } + }); + + + } + } + + @Override + public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if (viewType == 0) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.listview_tableinfo, parent, false); + return new SimpleViewHolder(view); + } + return null; + } + + class SimpleViewHolder extends RecyclerView.ViewHolder { + CheckBox mcbTable; + SimpleViewHolder(View itemView) { + super(itemView); + mcbTable = itemView.findViewById(R.id.listviewtableinfoCheckBox1); + } + } + + } +} diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/WinBoLLActivity.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/WinBoLLActivity.java new file mode 100644 index 0000000..9e90701 --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/activities/WinBoLLActivity.java @@ -0,0 +1,82 @@ +package cc.winboll.studio.stallhelper.activities; + +/** + * @Author ZhanGSKen@AliYun.Com + * @Date 2025/03/28 15:34:16 + * @Describe 应用活动窗口基类 + */ +import android.app.Activity; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.view.MenuItem; +import androidx.appcompat.app.AppCompatActivity; +import cc.winboll.studio.libaes.dialogs.YesNoAlertDialog; +import cc.winboll.studio.libaes.interfaces.IWinBoLLActivity; +import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; +import cc.winboll.studio.libappbase.GlobalApplication; +import cc.winboll.studio.stallhelper.App; +import cc.winboll.studio.stallhelper.R; + +public class WinBoLLActivity extends AppCompatActivity implements IWinBoLLActivity { + + public static final String TAG = "WinBoLLActivityBase"; + + @Override + public Activity getActivity() { + return this; + } + + @Override + public String getTag() { + return TAG; + } + + WinBoLLActivityManager getWinBoLLActivityManager() { + return WinBoLLActivityManager.getInstance(); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWinBoLLActivityManager().add(this); + } + + @Override + public void onPostCreate(Bundle savedInstanceState, PersistableBundle persistentState) { + super.onPostCreate(savedInstanceState, persistentState); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { +// if (item.getItemId() == cc.winboll.studio.appbase.R.id.item_log) { +// GlobalApplication.getWinBoLLActivityManager().startLogActivity(this); +// return true; +// } else if(item.getItemId() == cc.winboll.studio.appbase.R.id.item_minimal) { +// //moveTaskToBack(true); +// exit(); +// } + // 在switch语句中处理每个ID,并在处理完后返回true,未处理的情况返回false。 + return super.onOptionsItemSelected(item); + } + + void exit() { + YesNoAlertDialog.show(this, "Exit " + getString(R.string.app_name), "Close all activity and exit?", new YesNoAlertDialog.OnDialogResultListener(){ + + @Override + public void onYes() { + WinBoLLActivityManager.getInstance().finishAll(); + } + + @Override + public void onNo() { + } + }); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + getWinBoLLActivityManager().registeRemove(this); + } +} diff --git a/stallhelper/src/main/java/cc/winboll/studio/stallhelper/beans/DiningTableBean.java b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/beans/DiningTableBean.java new file mode 100644 index 0000000..8bab983 --- /dev/null +++ b/stallhelper/src/main/java/cc/winboll/studio/stallhelper/beans/DiningTableBean.java @@ -0,0 +1,216 @@ +package cc.winboll.studio.stallhelper.beans; + +/** + * @Author ZhanGSKen@QQ.COM + * @Date 2024/10/16 06:09:54 + * @Describe 餐桌 + */ +import android.util.JsonReader; +import android.util.JsonWriter; +import cc.winboll.studio.libappbase.BaseBean; +import java.io.IOException; + +public class DiningTableBean extends BaseBean { + + public static final String TAG = "AuthenticationBean"; + + public enum DinnerType { Noon, Evening }; + public enum TableType { Room, Table }; + + // 餐桌号 + String tableNumber; + // 最大就餐人数 + int maxPersonCount; + // 是否选取了这张桌号 + boolean isSelected; + // 预定时间类型 + DinnerType dinnerType; + // 预定信息 + String bookDesc; + // 预定时间 + String date; + // 餐桌类型 + TableType tableType; + // 是否被识别为 DiningTableBean + boolean isDiningTableBean; + // 或者是无法识别为 DiningTableBean 的原始信息。 + String originDesc; + + public DiningTableBean(String tableNumber, int maxPersonCount, boolean isSelected) { + this.tableNumber = tableNumber; + this.maxPersonCount = maxPersonCount; + this.isSelected = isSelected; + this.dinnerType = DinnerType.Evening; + this.bookDesc = ""; + this.date = ""; + this.tableType = TableType.Room; + this.isDiningTableBean = true; + this.originDesc = ""; + } + + public DiningTableBean(String tableNumber, int maxPersonCount, boolean isSelected, String date) { + this.tableNumber = tableNumber; + this.maxPersonCount = maxPersonCount; + this.isSelected = isSelected; + this.dinnerType = DinnerType.Evening; + this.bookDesc = ""; + this.date = date; + this.tableType = TableType.Room; + this.isDiningTableBean = true; + this.originDesc = ""; + } + + public DiningTableBean(String tableNumber, int maxPersonCount, boolean isSelected, DinnerType dinnerType, String bookDesc, String date, TableType tableType) { + this.tableNumber = tableNumber; + this.maxPersonCount = maxPersonCount; + this.isSelected = isSelected; + this.dinnerType = dinnerType; + this.bookDesc = bookDesc; + this.date = date; + this.tableType = tableType; + this.isDiningTableBean = true; + this.originDesc = ""; + } + + public DiningTableBean(boolean isSelected, boolean isDiningTableBean, String originDesc) { + this.tableNumber = ""; + this.maxPersonCount = 0; + this.isSelected = isSelected; + this.dinnerType = DinnerType.Evening; + this.bookDesc = ""; + this.date = ""; + this.tableType = TableType.Room; + this.isDiningTableBean = isDiningTableBean; + this.originDesc = originDesc; + } + + public void setOriginDesc(String originDesc) { + this.originDesc = originDesc; + } + + public String getOriginDesc() { + return originDesc; + } + + public void setIsDiningTableBean(boolean isDiningTableBean) { + this.isDiningTableBean = isDiningTableBean; + } + + public boolean isDiningTableBean() { + return isDiningTableBean; + } + + public void setTableType(TableType tableType) { + this.tableType = tableType; + } + + public TableType getTableType() { + return tableType; + } + + public void setDate(String date) { + this.date = date; + } + + public String getDate() { + return date; + } + + public void setDinnerType(DinnerType dinnerType) { + this.dinnerType = dinnerType; + } + + public DinnerType getDinnerType() { + return dinnerType; + } + + + public void setBookDesc(String bookDesc) { + this.bookDesc = bookDesc; + } + + public String getBookDesc() { + return bookDesc; + } + + public void setIsSelected(boolean isSelected) { + this.isSelected = isSelected; + } + + public boolean getIsSelected() { + return isSelected; + } + + public void setTableNumber(String tableNumber) { + this.tableNumber = tableNumber; + } + + public String getTableNumber() { + return tableNumber; + } + + public void setMaxPersonCount(int maxPersonCount) { + this.maxPersonCount = maxPersonCount; + } + + public int getMaxPersonCount() { + return maxPersonCount; + } + + @Override + public String getName() { + return DiningTableBean.class.getName(); + } + + @Override + public void writeThisToJsonWriter(JsonWriter jsonWriter) throws IOException { + super.writeThisToJsonWriter(jsonWriter); + DiningTableBean bean = this; + jsonWriter.name("tableNumber").value(bean.getTableNumber()); + jsonWriter.name("maxPersonCount").value(bean.getMaxPersonCount()); + jsonWriter.name("isSelected").value(bean.getTableNumber()); + jsonWriter.name("dinnerType").value(bean.getDinnerType().ordinal()); + jsonWriter.name("bookDesc").value(bean.getBookDesc()); + jsonWriter.name("date").value(bean.getDate()); + jsonWriter.name("tableType").value(bean.getTableType().ordinal()); + } + + @Override + public boolean initObjectsFromJsonReader(JsonReader jsonReader, String name) throws IOException { + if (super.initObjectsFromJsonReader(jsonReader, name)) { return true; } else { + if (name.equals("tableNumber")) { + setTableNumber(jsonReader.nextString()); + } else if (name.equals("maxPersonCount")) { + setMaxPersonCount(jsonReader.nextInt()); + } else if (name.equals("isSelected")) { + setIsSelected(jsonReader.nextBoolean()); + } else if (name.equals("dinnerType")) { + setDinnerType(DinnerType.values()[jsonReader.nextInt()]); + } else if (name.equals("bookDesc")) { + setBookDesc(jsonReader.nextString()); + } else if (name.equals("date")) { + setDate(jsonReader.nextString()); + } else if (name.equals("tableType")) { + setTableType(TableType.values()[jsonReader.nextInt()]); + } else { + return false; + } + } + return true; + } + + @Override + public BaseBean readBeanFromJsonReader(JsonReader jsonReader) throws IOException { + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + String name = jsonReader.nextName(); + if (!initObjectsFromJsonReader(jsonReader, name)) { + jsonReader.skipValue(); + } + } + // 结束 JSON 对象 + jsonReader.endObject(); + return this; + } + +} diff --git a/stallhelper/src/main/res/drawable/bg_frame.xml b/stallhelper/src/main/res/drawable/bg_frame.xml new file mode 100644 index 0000000..75b2b94 --- /dev/null +++ b/stallhelper/src/main/res/drawable/bg_frame.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + diff --git a/stallhelper/src/main/res/drawable/bg_frame_black.xml b/stallhelper/src/main/res/drawable/bg_frame_black.xml new file mode 100644 index 0000000..cfe4379 --- /dev/null +++ b/stallhelper/src/main/res/drawable/bg_frame_black.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + diff --git a/stallhelper/src/main/res/drawable/bg_frame_white.xml b/stallhelper/src/main/res/drawable/bg_frame_white.xml new file mode 100644 index 0000000..002ffe1 --- /dev/null +++ b/stallhelper/src/main/res/drawable/bg_frame_white.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + diff --git a/stallhelper/src/main/res/drawable/bg_shadow.xml b/stallhelper/src/main/res/drawable/bg_shadow.xml new file mode 100644 index 0000000..6d3d898 --- /dev/null +++ b/stallhelper/src/main/res/drawable/bg_shadow.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + diff --git a/stallhelper/src/main/res/drawable/diningtable.xml b/stallhelper/src/main/res/drawable/diningtable.xml new file mode 100644 index 0000000..23c6217 --- /dev/null +++ b/stallhelper/src/main/res/drawable/diningtable.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + diff --git a/stallhelper/src/main/res/drawable/ic_launcher.xml b/stallhelper/src/main/res/drawable/ic_launcher.xml new file mode 100644 index 0000000..d4d1eaf --- /dev/null +++ b/stallhelper/src/main/res/drawable/ic_launcher.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/stallhelper/src/main/res/drawable/ic_launcher_background.xml b/stallhelper/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..9486190 --- /dev/null +++ b/stallhelper/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/stallhelper/src/main/res/drawable/ic_launcher_foreground.xml b/stallhelper/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..872b04e --- /dev/null +++ b/stallhelper/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,10 @@ + + + + diff --git a/stallhelper/src/main/res/drawable/ic_noterecordhelper.png b/stallhelper/src/main/res/drawable/ic_noterecordhelper.png new file mode 100644 index 0000000..ba5cd57 Binary files /dev/null and b/stallhelper/src/main/res/drawable/ic_noterecordhelper.png differ diff --git a/stallhelper/src/main/res/drawable/ic_stall.png b/stallhelper/src/main/res/drawable/ic_stall.png new file mode 100644 index 0000000..24c3d2c Binary files /dev/null and b/stallhelper/src/main/res/drawable/ic_stall.png differ diff --git a/stallhelper/src/main/res/drawable/ic_stall_beta.png b/stallhelper/src/main/res/drawable/ic_stall_beta.png new file mode 100644 index 0000000..9d94066 Binary files /dev/null and b/stallhelper/src/main/res/drawable/ic_stall_beta.png differ diff --git a/stallhelper/src/main/res/drawable/shape_gradient.xml b/stallhelper/src/main/res/drawable/shape_gradient.xml new file mode 100644 index 0000000..c164fe9 --- /dev/null +++ b/stallhelper/src/main/res/drawable/shape_gradient.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/stallhelper/src/main/res/layout/activity_about.xml b/stallhelper/src/main/res/layout/activity_about.xml new file mode 100644 index 0000000..8057fc6 --- /dev/null +++ b/stallhelper/src/main/res/layout/activity_about.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/stallhelper/src/main/res/layout/activity_completediningtable.xml b/stallhelper/src/main/res/layout/activity_completediningtable.xml new file mode 100644 index 0000000..73d461a --- /dev/null +++ b/stallhelper/src/main/res/layout/activity_completediningtable.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + +