From eb171a063423a83a29345307d36072dd70ac18d4 Mon Sep 17 00:00:00 2001 From: shixianjie Date: Mon, 4 Aug 2025 16:28:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=A7=E6=A8=A1=E5=9E=8B=E6=89=B9=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/hjx/parent/JudgeActivity.java | 39 +++++++++++++++ app/src/main/java/com/hjx/parent/api/ChatApi.java | 9 +++- .../main/java/com/hjx/parent/api/ChatMessage.java | 3 +- .../main/java/com/hjx/parent/api/ChatRequest.java | 6 +++ .../main/java/com/hjx/parent/api/ContentItem.java | 4 ++ .../java/com/hjx/parent/api/JudgeRepository.java | 55 +++++++++++++++++++++ .../main/java/com/hjx/parent/utils/CutUtil.java | 15 ++++++ app/src/main/res/drawable/png_ic_judge_wrong.png | Bin 0 -> 1149 bytes .../main/java/com/prws/common/net/NetWorks.java | 4 +- .../java/com/prws/common/net/SignInterceptor.java | 18 +++---- 10 files changed, 141 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/com/hjx/parent/api/JudgeRepository.java create mode 100644 app/src/main/res/drawable/png_ic_judge_wrong.png diff --git a/app/src/main/java/com/hjx/parent/JudgeActivity.java b/app/src/main/java/com/hjx/parent/JudgeActivity.java index c87cfde..ec203e2 100644 --- a/app/src/main/java/com/hjx/parent/JudgeActivity.java +++ b/app/src/main/java/com/hjx/parent/JudgeActivity.java @@ -4,8 +4,10 @@ import android.annotation.SuppressLint; import android.graphics.Bitmap; import android.graphics.Rect; import android.os.Bundle; +import android.util.Log; import com.bumptech.glide.Glide; +import com.hjx.parent.api.JudgeRepository; import com.hjx.parent.databinding.ActivityJudgeBinding; import com.hjx.parent.databinding.LayoutJudgeRectBinding; import com.hjx.parent.rx.BaseRxActivity; @@ -15,6 +17,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import io.reactivex.Observable; import io.reactivex.Single; import top.zibin.luban.Luban; @@ -62,6 +65,41 @@ public class JudgeActivity extends BaseRxActivity { LayoutJudgeRectBinding vb = showRect(rect); mList.add(new JudgeCut(i, bitmap, rect, vb)); } + + judge(); + } + + @SuppressLint("CheckResult") + private void judge() { + showLoadingDialog(""); + Observable.fromIterable(mList) + .map(it -> { + if (it.url != null && !it.url.isEmpty()) return it; + String base64 = CutUtil.bitmapToBase64(it.bitmap, true); + it.url = base64; + return it; + }) + .flatMap(it -> JudgeRepository.singleJudge(it.url) + .map(result -> { + it.correctResult = result; + return it; + }) + .toObservable() + ) + .compose(transform()) + .subscribe(it -> { + if (it.correctResult == 1) { + it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct); + it.vb.getRoot().setSelected(false); + } else if (it.correctResult == 2) { + it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong); + it.vb.getRoot().setSelected(true); + } + }, th -> { + cancelLoadingDialog(); + Log.e(getClass().getName(), "", th); + }, this::cancelLoadingDialog) + ; } private LayoutJudgeRectBinding showRect(Rect rect) { @@ -111,6 +149,7 @@ public class JudgeActivity extends BaseRxActivity { final Rect rect; final LayoutJudgeRectBinding vb; + String url; int correctResult = 0; public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) { diff --git a/app/src/main/java/com/hjx/parent/api/ChatApi.java b/app/src/main/java/com/hjx/parent/api/ChatApi.java index 418e55b..562e71b 100644 --- a/app/src/main/java/com/hjx/parent/api/ChatApi.java +++ b/app/src/main/java/com/hjx/parent/api/ChatApi.java @@ -1,10 +1,17 @@ package com.hjx.parent.api; +import io.reactivex.Single; +import retrofit2.http.Body; import retrofit2.http.Header; import retrofit2.http.POST; import retrofit2.http.Url; public interface ChatApi { @POST - void aiChat(@Url String url, @Header("Authorization") String token); + Single aiChat( + @Url String url, + @Header("Authorization") String token, + @Body ChatRequest body + ); + } diff --git a/app/src/main/java/com/hjx/parent/api/ChatMessage.java b/app/src/main/java/com/hjx/parent/api/ChatMessage.java index 3c98e91..f8f2273 100644 --- a/app/src/main/java/com/hjx/parent/api/ChatMessage.java +++ b/app/src/main/java/com/hjx/parent/api/ChatMessage.java @@ -21,7 +21,8 @@ public class ChatMessage { items.add(new ContentItem(ContentItem.TYPE_TEXT, text)); } for (String it: urls) { - items.add(new ContentItem(ContentItem.TYPE_IMAGE, it)); + ContentItem.ContentImage image = new ContentItem.ContentImage(it); + items.add(new ContentItem(ContentItem.TYPE_IMAGE, image)); } return new ChatMessage(role, items); } diff --git a/app/src/main/java/com/hjx/parent/api/ChatRequest.java b/app/src/main/java/com/hjx/parent/api/ChatRequest.java index 62aace3..9421e50 100644 --- a/app/src/main/java/com/hjx/parent/api/ChatRequest.java +++ b/app/src/main/java/com/hjx/parent/api/ChatRequest.java @@ -6,4 +6,10 @@ public class ChatRequest { public String model; public List messages; public boolean stream; + + public ChatRequest(String model, List messages) { + this.model = model; + this.messages = messages; + this.stream = false; + } } diff --git a/app/src/main/java/com/hjx/parent/api/ContentItem.java b/app/src/main/java/com/hjx/parent/api/ContentItem.java index 5f78f0f..92f0508 100644 --- a/app/src/main/java/com/hjx/parent/api/ContentItem.java +++ b/app/src/main/java/com/hjx/parent/api/ContentItem.java @@ -25,6 +25,10 @@ public class ContentItem { public ContentImage imageUrl; public static class ContentImage { + public ContentImage(String url) { + this.url = url; + } + public String url; } diff --git a/app/src/main/java/com/hjx/parent/api/JudgeRepository.java b/app/src/main/java/com/hjx/parent/api/JudgeRepository.java new file mode 100644 index 0000000..fc16952 --- /dev/null +++ b/app/src/main/java/com/hjx/parent/api/JudgeRepository.java @@ -0,0 +1,55 @@ +package com.hjx.parent.api; + +import android.annotation.SuppressLint; + +import com.google.gson.Gson; +import com.prws.common.net.NetWorks; + +import java.util.ArrayList; +import java.util.List; + +import io.reactivex.Single; +import retrofit2.Retrofit; + +public class JudgeRepository { + private static final Gson gson = new Gson(); + private static final ChatApi api; + static { + Retrofit retrofit = NetWorks.retrofit; + api = retrofit.create(ChatApi.class); + } + + + public static Single singleJudge(String url) { + List messages = new ArrayList<>(); + messages.add(ChatMessage.fromImage("system", setting, url)); + + return api.aiChat(JudgeRepository.url, token, new ChatRequest(model, messages)) + .map(response -> { + if (response.choices == null) return null; + return response.choices.stream().findFirst() + .map(it -> it.message) + .map(ChatMessage::getTextContent) + .orElse(null); + }) + .map(json -> { + JudgeResult result = gson.fromJson(json, JudgeResult.class); + return result.result; + }) + ; + } + + + private static final String model = "doubao-1-5-thinking-vision-pro-250428"; + private static final String url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions"; + private static final String token = "Bearer a877087e-bb74-471b-8f2a-01e6b2220699"; + private static final String setting = + "批改图片中的题目, 判断作答是否正确,并以Json格式返回结果,需要包含以下字段: \n" + + "result(批改结果, 枚举 0:不确定; 1:正确; 2:错误; 3:未作答).\n" + + "Json示例(供参考,无需复制): {\"result\": 1}\n" + + "一个图片中一般只会有一个题目, 返回一个结果即可."; + + private static class JudgeResult { + public int result; + } +} diff --git a/app/src/main/java/com/hjx/parent/utils/CutUtil.java b/app/src/main/java/com/hjx/parent/utils/CutUtil.java index f2ebe9b..9c1187c 100644 --- a/app/src/main/java/com/hjx/parent/utils/CutUtil.java +++ b/app/src/main/java/com/hjx/parent/utils/CutUtil.java @@ -5,6 +5,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.util.Base64; import android.view.View; import android.view.ViewTreeObserver; @@ -12,6 +13,8 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool; import com.hjx.parent.function.Function1; +import java.io.ByteArrayOutputStream; + public class CutUtil { public static float[] measureBitmap(View view, Bitmap bitmap) { @@ -72,4 +75,16 @@ public class CutUtil { } ); } + + public static byte[] bitmapToByteArray(Bitmap bitmap) { + ByteArrayOutputStream output = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output); + return output.toByteArray(); + } + + public static String bitmapToBase64(Bitmap bitmap, Boolean usePrefix) { + String base64 = Base64.encodeToString(bitmapToByteArray(bitmap), Base64.NO_WRAP); + if (usePrefix) return "data:image/jpeg;base64," + base64; + else return base64; + } } diff --git a/app/src/main/res/drawable/png_ic_judge_wrong.png b/app/src/main/res/drawable/png_ic_judge_wrong.png new file mode 100644 index 0000000000000000000000000000000000000000..a7301b0e8c64d37c18ebf652f9d6b553b108954a GIT binary patch literal 1149 zcmV-@1cLjCP)Px(H%UZ6R7gvOm1%5LRTRhn|NExxylJ5 zrnGv$y|etza^E?Z7~}NLo>Esoe$qo)p+f|7NK6xe1kMBaO|p(s>6iB`^6ZZWT;9Og*L220wGCX7>8@)mKjMb{Qc3=AJ z$jtj%BP{`PXUTrZ=_fN`-(3NA;;{n&=0lL9=w(omL2BHXdU_YmqE zA?vRPlpkfldm?n;*k2`Ze>}F9z@}lNB^0kpXmppHL{iSR!T6+u$FI1p;SQnk6^N>` zDn8M~yGpPVBAsT^ev22{V&iH>P7$0y!P~)PdaW#Mp6mwXFo0=g@I8w1zKGf`M0HUv zBJYKg_A1wkt`f47KwnLNzL8Em@+6=>{bIKXr2IVcf-8D0_`po2 zpDlD3FkCBo2IN!2R%So4+u$PwW`mM-jQawk=w{)!7 z2@p-9u{_k1{(L0FiAT2pTv?f^WP)1Hs(`T%q+|e|_ zHET|Ts1>bOhkA~7`pd`>{7ztE!FPBFigB`wZkuWt)n5Xbt_HlNH3u?(6q6y~4me(8 zVY@k2^J}2ITG$gF?+pHO#O_-Zo*htXE5O0v6=N||scR$K?XOtBLf4uV76yI=Fiu1^ zhLZLx1+d(UfSZpV0@(uK6lHKpFnKKV|Mv#C@$f7WV~;-z1kyFV-dtuf`O-cv7{J&I z;8sE|d%)UI!v4t5XtV(SYtkQ&K4pNL1ehp-^8*;XtA044ibd}(h|H9L>IM-Rg2^#} zp91)S@J>R6!ayT{`yg0evJ=T%gZE$&>U-YsG@YH-5SmzBw*la4e#|gGW&_ZIoK$Hls5=;qYx8(ENYY(10HyYy~wcFp2Y*pB_ P00000NkvXXu0mjfp=KlB literal 0 HcmV?d00001 diff --git a/libs/common/src/main/java/com/prws/common/net/NetWorks.java b/libs/common/src/main/java/com/prws/common/net/NetWorks.java index 0986e8e..44b58c5 100644 --- a/libs/common/src/main/java/com/prws/common/net/NetWorks.java +++ b/libs/common/src/main/java/com/prws/common/net/NetWorks.java @@ -38,6 +38,7 @@ import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; +import retrofit2.Retrofit; import retrofit2.http.Body; import retrofit2.http.GET; import retrofit2.http.Header; @@ -58,7 +59,8 @@ import retrofit2.http.Url; */ public class NetWorks extends RetrofitUtils { //服务器路径 - public static final NetService service_url = getMachineRetrofit(BuildConfig.SERVER_URL).create(NetService.class); + public static final Retrofit retrofit = getMachineRetrofit(BuildConfig.SERVER_URL); + public static final NetService service_url = retrofit.create(NetService.class); //设缓存有效期为1天 protected static final long CACHE_STALE_SEC = 60 * 60 * 24 * 1; diff --git a/libs/common/src/main/java/com/prws/common/net/SignInterceptor.java b/libs/common/src/main/java/com/prws/common/net/SignInterceptor.java index 3daee25..a55b47d 100644 --- a/libs/common/src/main/java/com/prws/common/net/SignInterceptor.java +++ b/libs/common/src/main/java/com/prws/common/net/SignInterceptor.java @@ -1,5 +1,8 @@ package com.prws.common.net; +import androidx.annotation.NonNull; + +import com.prws.common.BuildConfig; import com.prws.common.utils.SharedPreferencesUtil; import org.apache.commons.codec.binary.Hex; @@ -14,23 +17,20 @@ import okhttp3.Request; import okhttp3.Response; public class SignInterceptor implements Interceptor { + @NonNull @Override public Response intercept(Chain chain) throws IOException { -// String appId = "1"; -// String APP_SECRET = "a839c40e04477d43705a64ba9db23b0dba969df360c3e428add85a6f5b8d0622"; -// String timestamp = String.valueOf(new Date().getTime()); -// String nonce = String.valueOf(new Random().nextInt(10000)); -// String sign = DigestUtils.md5Hex(appId + APP_SECRET + timestamp + nonce); // yidao板子报错 采用如下代码 -// byte[] signBytes = DigestUtils.md5(appId + APP_SECRET + timestamp + nonce); -// String sign = new String(Hex.encodeHex(signBytes)); + String host = BuildConfig.SERVER_URL; + if (!chain.request().url().toString().startsWith(host)) { + return chain.proceed(chain.request()); + } + String token = (String) SharedPreferencesUtil.getData("token",""); Request.Builder requestBuilder = chain.request().newBuilder(); if (token != null && token.length() > 0) { requestBuilder = chain.request().newBuilder() .header("Authorization", token); } -// .header("Content-Type","application/json"); - return chain.proceed(requestBuilder.build()); } } -- 1.9.0