Commit 2a51cd02 authored by hywang's avatar hywang

保定架项目三期flutter

parents
Pipeline #340 failed with stages
# anchor_collect_flutter
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "com.phlx.anchor_collect_flutter"
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "uni.UNIBFB8315"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21
// minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
signingConfigs {
release {
keyAlias 'anchorkeystore'
keyPassword '111111'
storeFile file('key0.jks')
storePassword '111111'
}
}
}
flutter {
source '../..'
}
dependencies {
implementation files('libs\\uhf.jar')
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
<manifest xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
package="uni.UNIBFB8315">
<uses-feature
android:name="android.hardware.telephony"
android:required="false" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Permissions options for the `contacts` group -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<!-- Permissions options for the `storage` group -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- Permissions options for the `camera` group -->
<uses-permission android:name="android.permission.CAMERA"/>
<!-- Permissions options for the `sms` group -->
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH"/>
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
<!-- Permissions options for the `phone` group -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ADD_VOICEMAIL"/>
<uses-permission android:name="android.permission.USE_SIP"/>
<uses-permission android:name="android.permission.READ_CALL_LOG"/>
<uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
<uses-permission android:name="android.permission.BIND_CALL_REDIRECTION_SERVICE"
tools:ignore="ProtectedPermissions" />
<!-- Permissions options for the `calendar` group -->
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<!-- Permissions options for the `location` group -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- Permissions options for the `microphone` or `speech` group -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- Permissions options for the `sensors` group -->
<uses-permission android:name="android.permission.BODY_SENSORS" />
<!-- Permissions options for the `accessMediaLocation` group -->
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<!-- Permissions options for the `activityRecognition` group -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<!-- Permissions options for the `ignoreBatteryOptimizations` group -->
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
<!-- Permissions options for the `bluetooth` group -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Permissions options for the `manage external storage` group -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<!-- Permissions options for the `system alert windows` group -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<!-- Permissions options for the `request install packages` group -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!--(静默安装需要添加这个权限,并且需要系统应用-->
<uses-permission android:name="android.permission.INSTALL_PACKAGES" tools:ignore="ProtectedPermissions"/>
<!-- Permissions options for the `access notification policy` group -->
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY"/>
<application
android:label="良种肉牛追溯系统"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true"
>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
package com.phlx.anchor_collect_flutter;
import io.flutter.embedding.android.FlutterActivity;
import android.content.Intent;
import android.os.Bundle;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.embedding.engine.FlutterEngine;
public class MainActivity extends FlutterActivity {
// 通道名称
protected String channel = "通道名称";
// 获取推送,发给flutter
protected String payLoad = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取自定义透传参数值
Intent intent = getIntent();
if (intent != null) {
payLoad = intent.getStringExtra("payload");
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 获取自定义透传参数值
if (intent != null) {
payLoad = intent.getStringExtra("payload");
}
}
@Override
public void configureFlutterEngine(FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
payLoad = getIntent().getStringExtra("payload");
try {
// 通过MethodChannel调用通知flutter开启参数
new MethodChannel(
flutterEngine.getDartExecutor().getBinaryMessenger(),
channel
).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if (call.method.equals("getIntentData")) {
result.success(payLoad);
}
}
});
} catch (Exception err) {}
}
}
package com.phlx.anchor_collect_flutter;
import androidx.annotation.NonNull;
import com.uhf.linkage.Linkage;
import com.uhf.structures.InventoryData;
import com.uhf.structures.OnBluetoothListener;
import com.uhf.structures.OnInventoryListener;
import com.uhf.structures.Rfid_Value;
import java.util.HashMap;
import java.util.Map;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
/**
* rfid插件
*/
public class RfidPlugin implements FlutterPlugin, MethodChannel.MethodCallHandler
, OnBluetoothListener, OnInventoryListener {
private MethodChannel _methodChannel;
private Linkage link;
// 事件派发对象
private EventChannel.EventSink _eventSink;
private EventChannel.StreamHandler _streamHandler = new EventChannel.StreamHandler() {
@Override
public void onListen(Object arguments, EventChannel.EventSink events) {
_eventSink = events;
}
@Override
public void onCancel(Object arguments) {
_eventSink = null;
}
};
@Override
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
_methodChannel = new MethodChannel(binding.getBinaryMessenger(), "flutter_rfid_plugin");
_methodChannel.setMethodCallHandler(this);
EventChannel channel = new EventChannel(binding.getBinaryMessenger(), "flutter_rfid_plugin/event");
channel.setStreamHandler(_streamHandler);
}
@Override
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
_methodChannel.setMethodCallHandler(null);
}
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
switch (call.method) {
case "init_rfid":
initModule();
break;
case "get_version":
Rfid_Value version_value = new Rfid_Value();
byte[] versionData = getLinkage().getVersion(version_value);
String version = "";
if (version_value.value == 0) {
version = new String(versionData);
} else {
version = "" + version_value.value;
}
result.success(version);
break;
case "start_inventory":
/**
* 下发盘点指令
*
* @param mode 盘点模式:0-单次盘点,1-高速盘点,2-低功耗盘点 默认高速盘点
* @param status 掩码状态 0-禁用,1-启用
*/
getLinkage().startInventory(1, 0);
break;
case "stop_inventory":
getLinkage().stopInventory();
break;
case "push_data":
getLinkage().pushRemoteRFIDData(call.argument("value"));
break;
}
}
private void initModule() {
getLinkage().setRFModuleType(2);
/**设置设备连接方式为蓝牙连接*/
getLinkage().setRFConnectMode(2);
}
public Linkage getLinkage() {
if (link == null) {
link = new Linkage();
link.initRFID();
}
return link;
}
@Override
public void getBluetoothData(byte[] bytes) {
Map<String, byte[]> result = new HashMap<>();
result.put("BluetoothData", bytes);
_eventSink.success(result);
}
@Override
public void getInventoryData(InventoryData inventoryData) {
Map<String, String> result = new HashMap<>();
String epc = TextUtil.byteToHexString(inventoryData.getEPC_Data(), inventoryData.getEpcLength()).substring(1);
String tid = TextUtil.byteToHexString(inventoryData.getData(), inventoryData.getDataLength());
result.put("InventoryData", epc + "," + tid);
_eventSink.success(result);
}
}
package com.phlx.anchor_collect_flutter;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.Log;
/**
* <pre>
* author : lei
* e-mail : 18600395998@163.com
* time : 2020/04/23
* desc :
* version: 1.0
* </pre>
*/
public class TextUtil {
// public static String getSimplePinyin(String s){
//
// String pinyin = Pinyin.toPinyin(s, ",");
// String[] arrayStr = pinyin.split(",");
// String result="";
// for (String item : arrayStr){
// if (!TextUtils.isEmpty(item)){
// result = result+item.substring(0,1);
// }
// }
// Log.e("lei", "getSimplePinyin: "+result );
// return result;
// }
// public static String getPinyin(String s){
//
// return Pinyin.toPinyin(s,"");
// }
public static String byteToHexString(byte[] b, int length) {
String ret = "";
for (int i = 0; i < length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
ret += hex.toUpperCase();
}
return ret;
}
/**
* 判断字符串是否为null或全为空白字符
*
* @param s 待校验字符串
* @return {@code true}: null或全空白字符<br> {@code false}: 不为null且不全空白字符
*/
public static boolean isSpace(final String s) {
if (s == null)
return true;
for (int i = 0, len = s.length(); i < len; ++i) {
if (!Character.isWhitespace(s.charAt(i))) {
return false;
}
}
return true;
}
public static String packageName(Context context) {
PackageManager manager = context.getPackageManager();
String name = null;
try {
PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);
name = info.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return name;
}
/**
* 将一个字符串中的所有字母均转换为大写
*
* @param devicesAddress
* @return
*/
public static String formatTheString(String devicesAddress) {
StringBuffer newDevicesAddress = new StringBuffer("");
for (int i = 0; i < devicesAddress.length(); i++) {
char chars = devicesAddress.charAt(i);
String childString = "" + chars;
childString = childString.toUpperCase();
newDevicesAddress.append(childString);
}
return newDevicesAddress.toString().substring(0, 17);
// return newDevicesAddress.toString();
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
// maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' }
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
// maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
maven { url 'https://maven.aliyun.com/repository/public/' }
maven { url 'https://maven.aliyun.com/repository/central' }
maven { url 'https://maven.aliyun.com/repository/google' }
maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
jcenter()
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
#org.gradle.java.home=C:\\Program Files\\Java\\jdk-11.0.20
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
include ":app"
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"
{
"id": "4150819",
"name": "herd",
"font_family": "iconfont",
"css_prefix_text": "hred-",
"description": "",
"glyphs": [
{
"icon_id": "13719920",
"name": "待诊疗",
"font_class": "daizhenliao1",
"unicode": "e601",
"unicode_decimal": 58881
},
{
"icon_id": "2980618",
"name": "待诊疗",
"font_class": "daizhenliao",
"unicode": "e653",
"unicode_decimal": 58963
},
{
"icon_id": "22942743",
"name": "采收重量",
"font_class": "caishouzhongliang",
"unicode": "e9fb",
"unicode_decimal": 59899
},
{
"icon_id": "13210287",
"name": "重量",
"font_class": "canshuiconyouhua-",
"unicode": "e60e",
"unicode_decimal": 58894
},
{
"icon_id": "14995479",
"name": "宠物免疫",
"font_class": "chongwumianyi",
"unicode": "e616",
"unicode_decimal": 58902
},
{
"icon_id": "27477695",
"name": "死亡记录",
"font_class": "siwangjilu",
"unicode": "e60b",
"unicode_decimal": 58891
},
{
"icon_id": "24185802",
"name": "搜索",
"font_class": "search",
"unicode": "e60c",
"unicode_decimal": 58892
},
{
"icon_id": "6537253",
"name": "已出售",
"font_class": "yichushou",
"unicode": "e69c",
"unicode_decimal": 59036
},
{
"icon_id": "12655486",
"name": "养殖",
"font_class": "yangzhi",
"unicode": "e61e",
"unicode_decimal": 58910
},
{
"icon_id": "12353865",
"name": "超期",
"font_class": "chaoqi",
"unicode": "e784",
"unicode_decimal": 59268
},
{
"icon_id": "6015247",
"name": "总览-乏情牛",
"font_class": "zonglan-faqingniu",
"unicode": "e6ea",
"unicode_decimal": 59114
},
{
"icon_id": "16241768",
"name": "摄氏度",
"font_class": "sheshidu",
"unicode": "eb97",
"unicode_decimal": 60311
},
{
"icon_id": "1753964",
"name": "诊疗记录",
"font_class": "zhenliaojilu",
"unicode": "e667",
"unicode_decimal": 58983
},
{
"icon_id": "11327629",
"name": "养殖档案",
"font_class": "yangzhidangan",
"unicode": "e9aa",
"unicode_decimal": 59818
},
{
"icon_id": "11327631",
"name": "种植档案",
"font_class": "zhongzhidangan",
"unicode": "e9ac",
"unicode_decimal": 59820
},
{
"icon_id": "12726885",
"name": "爱情与浪漫类图标40",
"font_class": "icon-test",
"unicode": "e76b",
"unicode_decimal": 59243
},
{
"icon_id": "17084946",
"name": "猪只淘汰记录",
"font_class": "zhuzhitaotaijilu",
"unicode": "e7b8",
"unicode_decimal": 59320
},
{
"icon_id": "29850801",
"name": "淘汰",
"font_class": "taotai",
"unicode": "e659",
"unicode_decimal": 58969
},
{
"icon_id": "21666443",
"name": "初检",
"font_class": "chujian",
"unicode": "e65a",
"unicode_decimal": 58970
},
{
"icon_id": "21666552",
"name": "初检",
"font_class": "chujian1",
"unicode": "e65b",
"unicode_decimal": 58971
},
{
"icon_id": "10490161",
"name": "面向公牛的权利",
"font_class": "mianxianggongniudequanli",
"unicode": "e640",
"unicode_decimal": 58944
},
{
"icon_id": "32678539",
"name": "牛-成母牛",
"font_class": "chengmuniu",
"unicode": "e6ba",
"unicode_decimal": 59066
},
{
"icon_id": "3948313",
"name": "日报月报",
"font_class": "yuebao",
"unicode": "e697",
"unicode_decimal": 59031
},
{
"icon_id": "7085902",
"name": "超期天数",
"font_class": "chaoqitianshu",
"unicode": "e624",
"unicode_decimal": 58916
},
{
"icon_id": "2886018",
"name": "猪只断奶",
"font_class": "duannai",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "27690807",
"name": "小牛牛",
"font_class": "xiaoniu",
"unicode": "e6b1",
"unicode_decimal": 59057
},
{
"icon_id": "30351750",
"name": "业务_发情",
"font_class": "faqing",
"unicode": "e632",
"unicode_decimal": 58930
},
{
"icon_id": "32869969",
"name": "配种",
"font_class": "peizhong",
"unicode": "e62f",
"unicode_decimal": 58927
}
]
}
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
#include "Generated.xcconfig"
#include "Generated.xcconfig"
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
# Launch Screen Assets
You can customize the launch screen with your own desired assets by replacing the image files in this directory.
You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
<viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
</resources>
</document>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
</dependencies>
<scenes>
<!--Flutter View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Anchor Collect Flutter</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>良种肉牛追溯系统</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>需要使用您的相机来拍摄照片</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要使用您的麦克风来录制音频</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>我们需要访问您的相册来选择图片。</string>
</dict>
</plist>
#import "GeneratedPluginRegistrant.h"
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}
import 'package:dio/dio.dart';
import 'api_response.dart';
class ApiException implements Exception {
static const unknownException = "未知错误";
final String? message;
final int? code;
String? stackInfo;
ApiException([this.code, this.message]);
factory ApiException.fromDioError(DioException error) {
switch (error.type) {
case DioExceptionType.cancel:
return BadRequestException(-1, "请求取消");
case DioExceptionType.connectionTimeout:
return BadRequestException(-1, "连接超时");
case DioExceptionType.sendTimeout:
return BadRequestException(-1, "请求超时");
case DioExceptionType.receiveTimeout:
return BadRequestException(-1, "响应超时");
case DioExceptionType.connectionError:
return BadRequestException(-1, "网络不可用");
case DioExceptionType.unknown:
try {
/// http错误码带业务错误信息
ApiResponse apiResponse = ApiResponse.fromJson(error.response?.data);
return ApiException(apiResponse.code, apiResponse.msg);
} on Exception {
return ApiException(-1, unknownException);
}
default:
return ApiException(-1, error.message);
}
}
factory ApiException.from(dynamic exception) {
if (exception is DioExceptionType) {
return ApiException.fromDioError(exception as DioException);
}
if(exception is DioException){
return ApiException.fromDioError(exception);
}
if (exception is ApiException) {
return exception;
} else {
var apiException = ApiException(-1, unknownException);
apiException.stackInfo = exception?.toString();
return apiException;
}
}
}
/// 请求错误
class BadRequestException extends ApiException {
BadRequestException([super.code, super.message]);
}
/// 未认证异常
class UnauthorisedException extends ApiException {
UnauthorisedException([int super.code = -1, String super.message = '']);
}
import 'package:get/get.dart';
class ApiService extends GetxService{
// Future<BannerModel?> banner(Map params, {onError}) async{
// return await RequestClient().post<BannerModel>(APIS.banner, data: params, onError: onError);
// }
//
}
\ No newline at end of file
import 'dart:convert';
import 'package:anchor_collect_flutter/utils/dialog_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import '../utils/loading.dart' as loading;
import 'ApiException.dart';
import 'NetWorkConfig.dart';
import 'TokenInterceptor.dart';
import 'api_response.dart';
class HttpUtils<T> {
late Dio _dio;
String? url;
String method = 'POST';
String contentType = '';
FormData? formData;
bool isList = false;
Map<dynamic, dynamic> params = {};
Map<String, dynamic> queryParameters = {};
Map<String, dynamic>? headers = {};
bool isShow = false;
Function(String, int)? errorCallback;
Function(T?)? responseCallback;
Function(List<T?>)? responseListCallback;
List<dynamic>? mList;
HttpUtils._internal() {
var options = BaseOptions(
baseUrl: NetWorkConfig.baseUrl,
connectTimeout:
const Duration(milliseconds: NetWorkConfig.connectTimeOut),
receiveTimeout: const Duration(milliseconds: NetWorkConfig.readTimeOut),
sendTimeout: const Duration(milliseconds: NetWorkConfig.writeTimeOut));
_dio = Dio(options);
_dio.interceptors.add(TokenInterceptor());
_dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseHeader: true,
responseBody: true));
}
factory HttpUtils() {
return HttpUtils._internal();
}
void post() {
method = 'POST';
url = '';
isShow = false;
params = {};
queryParameters = {};
contentType = 'application/json';
}
void get() {
method = 'Get';
url = '';
isShow = false;
params = {};
queryParameters = {};
contentType = '';
}
void setContentType(String contentType) {
this.contentType = contentType;
}
void showLoading() {
isShow = true;
}
void setUrl(String url) {
this.url = url;
}
void setMethod(String method) {
this.method = method;
}
void setmListParam(List<dynamic> mList) {
this.mList = mList;
}
void setIsList() {
this.isList = true;
}
void addParam(String key, dynamic value) {
params[key] = value;
}
void setParams(Map<dynamic, dynamic> params) {
this.params = params;
}
void addQueryParameters(String key, dynamic value) {
queryParameters[key] = value;
}
void setQueryParameters(Map<String, dynamic> queryParameters) {
this.queryParameters = queryParameters;
}
void setFormData(FormData formData) {
this.formData = formData;
}
void setHeaders(Map<String, dynamic> headers) {
this.headers = headers;
}
void addHeader(String key, String value) {
headers?.putIfAbsent(key, () => value);
}
void onError(void Function(String msg, int code) errorCallback) {
this.errorCallback = errorCallback;
}
void onResponse(void Function(T? response) onResponseCallback) {
this.responseCallback = onResponseCallback;
}
void onResponseList(void Function(List<T?> list) onResponseListCallback) {
this.responseListCallback = onResponseListCallback;
}
Future<void> build() async {
if (isShow) {
loading.showLoading();
}
Options options = Options(
method: method,
headers: headers,
);
if (contentType != '') {
options.contentType = contentType;
}
try {
Response response = await _dio.request(url!,
data: mList != null
? _convertRequestData(mList)
: formData ?? _convertRequestData(params),
queryParameters: queryParameters,
options: options);
_handleResponse(response);
} catch (e) {
var exception = ApiException.from(e);
DialogUtils.dismissDialog();
if (errorCallback != null) {
errorCallback!(e.toString(), exception.code ?? -1);
}
// EasyLoading.showError(exception.message ?? '服务器异常');
DialogUtils.showWarningDialog(exception.message ?? '服务器异常');
}
}
void _handleResponse(Response response) {
if (response.statusCode == 200) {
ApiResponse<T> apiResponse;
if (isList) {
apiResponse = ApiResponse<T>.fromJsonList(response.data);
} else {
apiResponse = ApiResponse<T>.fromJson(response.data);
}
if (apiResponse.code == NetWorkConfig.successCode) {
loading.dismissLoading();
if (isList) {
responseListCallback?.call(apiResponse.list);
} else {
if (apiResponse.data != null) {
responseCallback?.call(apiResponse.data);
}
}
} else {
loading.dismissLoading();
interceptToken(apiResponse.msg, apiResponse.code);
// EasyLoading.showError(apiResponse.message);
}
} else {
loading.dismissLoading();
var exception =
ApiException(response.statusCode, ApiException.unknownException);
errorCallback!(exception.message ?? '服务器异常', exception.code ?? -1);
EasyLoading.showError(exception.message ?? '服务器异常');
}
}
interceptToken(String msg, int code) {
print('code:$code -- msg:$msg');
switch (code) {
case 403:
// print('网络请求 拦截到400');
// NetWorkUtils.getVisitorToken();
break;
default:
EasyLoading.showError(msg);
errorCallback!(msg, code ?? -1);
break;
}
}
_convertRequestData(data) {
if (data != null) {
data = jsonDecode(jsonEncode(data));
}
return data;
}
}
import 'package:anchor_collect_flutter/api/apis.dart';
class NetWorkConfig {
static String baseUrl =
APIS.baseUrl;
static const int connectTimeOut = 10000;
static const int readTimeOut = 10000;
static const int writeTimeOut = 10000;
static const int successCode = 0;
}
\ No newline at end of file
import 'dart:convert';
import 'dart:io';
import 'package:anchor_collect_flutter/api/ApiException.dart';
import 'package:anchor_collect_flutter/api/NetWorkConfig.dart';
import 'package:anchor_collect_flutter/api/TokenInterceptor.dart';
import 'package:anchor_collect_flutter/api/api_response.dart';
import 'package:anchor_collect_flutter/utils/loading.dart';
import 'package:dio/dio.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
class RequestClient {
late Dio _dio;
static final RequestClient _singletonRequestClient =
RequestClient._internal();
factory RequestClient() {
return _singletonRequestClient;
}
RequestClient._internal() {
///初始化 dio 配置
var options = BaseOptions(
baseUrl: NetWorkConfig.baseUrl,
connectTimeout: Duration(milliseconds: NetWorkConfig.connectTimeOut),
receiveTimeout: Duration(milliseconds: NetWorkConfig.readTimeOut),
sendTimeout: Duration(milliseconds: NetWorkConfig.writeTimeOut));
_dio = Dio(options);
_dio.interceptors.add(TokenInterceptor());
_dio.interceptors.add(PrettyDioLogger(
requestHeader: true,
requestBody: true,
responseHeader: true,
responseBody: true));
}
/// dio 本身提供了get 、post 、put 、delete 等一系列 http 请求方法,最终都是调用request,直接封装request就行
Future<T?> request<T>(
String url, {
required String method,
Map<String, dynamic>? queryParameters,
dynamic data,
Map<String, dynamic>? headers,
bool isshowLoading = false,
bool Function(ApiException)? onError, //用于错误信息处理的回调
Function(T)? onResponse,
}) async {
try {
if (isshowLoading) {
showLoading();
}
Options options = Options()
..method = method
..headers = headers;
data = _convertRequestData(data);
Response response = await _dio.request(url,
queryParameters: queryParameters, data: data, options: options);
dismissLoading();
T? mdata = _handleResponse<T>(response) as T;
if (onResponse == null) {
} else {
onResponse(mdata as T);
}
return mdata;
} catch (e) {
print('errcode e-->${e.toString()}');
var exception = ApiException.from(e);
dismissLoading();
if (onError?.call(exception) != true) {
EasyLoading.showError(exception.message ?? '服务器异常');
throw exception;
}
}
dismissLoading();
return null;
}
///获取游客令牌
///
///将请求 data 数据先使用 jsonEncode 转换为字符串,再使用 jsonDecode 方法将字符串转换为 Map。
_convertRequestData(data) {
if (data != null) {
data = jsonDecode(jsonEncode(data));
}
return data;
}
///请求响应内容处理e
T? _handleResponse<T>(Response response) {
if (response.statusCode == 200) {
ApiResponse<T> apiResponse = ApiResponse<T>.fromJson(response.data);
return _handleBusinessResponse<T>(apiResponse);
} else {
dismissLoading();
var exception =
ApiException(response.statusCode, ApiException.unknownException);
throw exception;
}
}
Future<T?> get<T>(String url,
{Map<String, dynamic>? queryParameters,
Map<String, dynamic>? headers,
bool showLoading = false,
bool Function(ApiException)? onError,
Function(T)? onResponse}) {
return request(
url,
method: "Get",
queryParameters: queryParameters,
headers: headers,
onError: onError,
onResponse: onResponse,
isshowLoading: showLoading,
);
}
Future<T?> post<T>(String url,
{Map<String, dynamic>? queryParameters,
data,
Map<String, dynamic>? headers,
bool showLoading = false,
bool Function(ApiException)? onError,
Function(T)? onResponse}) {
return request(url,
method: "POST",
queryParameters: queryParameters,
data: data,
headers: headers,
isshowLoading: showLoading,
onError: onError,
onResponse: onResponse);
}
Future<T?> delete<T>(
String url, {
Map<String, dynamic>? queryParameters,
data,
Map<String, dynamic>? headers,
bool showLoading = false,
bool Function(ApiException)? onError,
}) {
return request(url,
method: "DELETE",
queryParameters: queryParameters,
data: data,
isshowLoading: showLoading,
headers: headers,
onError: onError);
}
Future<T?> put<T>(
String url, {
Map<String, dynamic>? queryParameters,
data,
Map<String, dynamic>? headers,
bool showLoading = false,
bool Function(ApiException)? onError,
Function(T)? onResponse,
}) {
return request(url,
method: "PUT",
queryParameters: queryParameters,
data: data,
isshowLoading: showLoading,
headers: headers,
onError: onError,
onResponse: onResponse);
}
///业务内容处理
T? _handleBusinessResponse<T>(ApiResponse<T> response) {
if (response.code == NetWorkConfig.successCode) {
print("errcode errcode: 200200200");
return response.data;
} else {
var exception = ApiException(response.code, response.msg);
// if (response.code == 403) {
// // mGet.Get.toNamed(RouterPath.bsiDetailsPage);
// print("errcode errcode: 403403403");
// return null;
// }
throw exception;
}
}
}
import 'dart:io';
import 'dart:math';
import 'package:anchor_collect_flutter/utils/sp_helper.dart';
import 'package:device_info/device_info.dart';
import 'package:dio/dio.dart' as dio;
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import '../congifs.dart';
class TokenInterceptor extends Interceptor{
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
String uuidStr = SpHelper.getStorage(Config.SP_UUID)??getUUid();
///todo get token from cache
// options.headers["Authorization"] = "Basic ZHhtaF93ZWI6ZHhtaF93ZWJfc2VjcmV0";
// options.headers["token"] = "YToyOntzOjY6InVzZXJpZCI7czo5OiI3eVVnamVnc2UiO3M6OToidGltZXN0YW1wIjtpOjE2OTk0MDc0MTQ7fQ\$\$#M2YxODdhZWNiZDdjMGE2NWRiNzI3NjJhNmNkNWEyZDA\$ ";
options.headers["token"] = SpHelper.getStorage(Config.SP_STR_TOKEN);
options.headers["deptid"] = SpHelper.getStorage(Config.SP_DEPT_ID);
options.headers["imei"] = uuidStr;
// options.headers["imei"] = '8743174844301820';
// options.headers["type"] = 'app';
// options.headers["response-status"] = 401;
print('token:${options.headers["token"]},imei:${options.headers["imei"]}');
super.onRequest(options, handler);
}
@override
void onResponse(dio.Response response, ResponseInterceptorHandler handler) {
super.onResponse(response, handler);
}
static Future<String?> getDeviceId() async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
if (kDebugMode) {
print('设备 ID: ${androidInfo.androidId}');
}
return androidInfo.androidId;
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
if (kDebugMode) {
print('设备 ID: ${iosInfo.identifierForVendor}');
} // 在 iOS 中,我们使用 identifierForVendor 作为设备 ID
return iosInfo.identifierForVendor;
}
}
//获取随机4位+时间戳
String getUUid() {
String randomStr = Random().nextInt(10).toString();
for (var i = 0; i < 1; i++) {
var str = Random().nextInt(10);
randomStr = "$randomStr$str";
}
var timeNumber = DateTime.now().millisecondsSinceEpoch;//时间
var uuid = "$randomStr$timeNumber";
if (kDebugMode) {
print(uuid);
}
SpHelper.putStorage(Config.SP_UUID, uuid);
return uuid;
}
}
\ No newline at end of file
import 'dart:convert';
import '../generated/json/base/json_field.dart';
import 'api_response.g.dart';
@JsonSerializable()
class ApiResponse<T> {
late int code;
late String msg;
T? data;
late List<T?> list;
ApiResponse();
factory ApiResponse.fromJson(Map<String, dynamic> json) =>
$ApiResponseFromJson<T>(json);
factory ApiResponse.fromJsonList(Map<String, dynamic> json) =>
$ApiResponseFromJsonList<T>(json);
Map<String, dynamic> toJson() => $ApiResponseToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
@JsonSerializable()
class ApiResponseData {
ApiResponseData();
factory ApiResponseData.fromJson(Map<String, dynamic> json) =>
$ApiResponseDataFromJson(json);
Map<String, dynamic> toJson() => $ApiResponseDataToJson(this);
@override
String toString() {
return jsonEncode(this);
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment