Merge branch 'master' of gitee.com:starlock-cn/app-starlock

# Conflicts:
#	star_lock/lib/main/lockDetail/lockDetail/lockDetail_page.dart
#	star_lock/lib/network/api.dart
This commit is contained in:
Daisy 2024-01-29 18:01:02 +08:00
commit 842fcbf557
156 changed files with 1002 additions and 3461 deletions

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main_dev.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="buildFlavor" value="dev"/>
<option name="filePath" value="$PROJECT_DIR$/lib/main_dev.dart"/>
<method v="2"/>
</configuration>
</component>

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main_pre.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="buildFlavor" value="pre"/>
<option name="filePath" value="$PROJECT_DIR$/lib/main_pre.dart"/>
<method v="2"/>
</configuration>
</component>

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main_sky.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="buildFlavor" value="sky"/>
<option name="filePath" value="$PROJECT_DIR$/lib/main_sky.dart"/>
<method v="2"/>
</configuration>
</component>

View File

@ -0,0 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main_xhj.dart" type="FlutterRunConfigurationType" factoryName="Flutter">
<option name="buildFlavor" value="xhj"/>
<option name="filePath" value="$PROJECT_DIR$/lib/main_xhj.dart"/>
<method v="2"/>
</configuration>
</component>

View File

@ -1,16 +1,72 @@
# star_lock
# 星锁APP
A new Flutter project.
星云项目组旗下的智能锁应用,其中锁相关数据接入星云平台,业务数据接入星锁自有后台。
## Getting Started
基于Flutter技术架构支持Android和iOS平台。
This project is a starting point for a Flutter application.
## 开发步骤
A few resources to get you started if this is your first Flutter project:
### 安装Flutter
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
参阅 [安装 - Flutter](https://docs.flutter.dev/get-started/install)
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.
然后 `flutter doctor` 检查环境
### 禁用不需要的平台
```bash
flutter config --no-enable-macos-desktop --no-enable-windows-desktop --no-enable-linux-desktop --no-enable-web
```
### 安装依赖
```bash
flutter pub get
```
### 运行
```bash
# 运行sky渠道
flutter run --flavor sky -t lib/main_sky.dart
```
## 配置签名
参阅 [构建和发布 Android 应用 - 创建上载密钥库 - Flutter](https://docs.flutter.dev/deployment/android#create-an-upload-keystore)
为发布渠道创建JAVA密钥储存(密钥库)文件 `.jks`,或者 `.keystore` 文件。
```bash
keytool -genkey -v -keystore android/app/sky.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
```
请记住你输入的主密码和键密码
因为本项目将会发布2个以上的渠道所以密钥库也会有2个以上请注意区分 同一个发布渠道必须使用同一个密钥库,不要生成多个。
为了编译管理方便,我们将密钥库文件放在了项目代码内。
`key.properties` 文件用于存放密钥库的相关信息,但是我们不用这个文件,而是直接在 `build.gradle` 中写入密钥库的相关信息。
因为我们将密钥库文件本身都已经储存在git中了也就没必要再单独存放密钥信息了。
## 编译
```bash
flutter build apk --split-per-abi --release --flavor sky -t lib/main_sky.dart
```
## 获取编译包的签名
用于APP备案国内商店上架等
需要使用到`apksigner`工具对于Windows来说它在`C:\Users\myUser\AppData\Local\Android\Sdk\build-tools\34.0.0\lib`
`git bash` 中我需要使用 `apksigner.bat` 来使用它;在其它系统中应该可以直接使用 `apksigner` 命令即可。
参阅:[How to find signature of apk file?](https://stackoverflow.com/questions/38558623/how-to-find-signature-of-apk-file)
```bash
apksigner verify --print-certs -v build/app/outputs/flutter-apk/app-sky-release.apk
```

View File

@ -8,6 +8,8 @@ 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
# 因为我们要管理多个项目所以这里不要忽略keystore
# 而且我们的代码库是私有的,不存在泄露问题
#key.properties
#**/*.keystore
#**/*.jks

View File

@ -28,7 +28,59 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
signingConfigs {
pre {
storeFile file("starlock.keystore")
storePassword '123456'
keyAlias = 'starlock'
keyPassword '123456'
}
sky {
// CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
storeFile file("sky.jks")
storePassword 'sky2028'
keyAlias = 'upload'
keyPassword 'sky2028'
}
xhj {
storeFile file("xhj.jks")
storePassword 'xhj8872'
keyAlias = 'upload'
keyPassword 'xhj8872'
}
}
// ----- BEGIN flavorDimensions (autogenerated by flutter_flavorizr) -----
flavorDimensions "flavor-type"
productFlavors {
dev {
dimension "flavor-type"
applicationId "com.starlock.lock.dev"
resValue "string", "app_name", "星锁-dev"
}
pre {
dimension "flavor-type"
applicationId "com.starlock.lock.pre"
resValue "string", "app_name", "星锁"
}
sky {
dimension "flavor-type"
applicationId "com.skychip.lock"
signingConfig signingConfigs.sky
resValue "string", "app_name", "锁通通"
}
xhj {
dimension "flavor-type"
applicationId "com.xhjcn.lock"
signingConfig signingConfigs.xhj
resValue "string", "app_name", "鑫锁"
}
}
// ----- END flavorDimensions (autogenerated by flutter_flavorizr) -----
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
lintOptions{
@ -52,7 +104,6 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "cn.starlock.lock"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
@ -63,37 +114,28 @@ android {
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
signingConfig signingConfigs.pre
// 使 flutter build apk --split-per-abi
// ndk在同一个个包中包含多个架构
ndk {
//SO库架构so
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64"
}
}
signingConfigs {
release {
storeFile file("starlock.keystore")
storePassword '123456'
keyAlias = 'starlock'
keyPassword '123456'
}
debug {
storeFile file("starlock.keystore")
storePassword '123456'
keyAlias = 'starlock'
keyPassword '123456'
splits {
abi {
include "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64"
}
}
}
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.release
productFlavors.dev.signingConfig signingConfigs.pre
productFlavors.pre.signingConfig signingConfigs.pre
productFlavors.sky.signingConfig signingConfigs.sky
productFlavors.xhj.signingConfig signingConfigs.xhj
}
debug {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --debug` works.
signingConfig signingConfigs.debug
signingConfig signingConfigs.pre
}
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,110 +1,78 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.star_lock">
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />-->
<!--允许访问网络,必选权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!--允许获取精确位置,精准定位必选-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--允许获取粗略位置,粗略定位必选-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--允许获取设备和运营商信息用于问题排查和网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS" />
<!--允许获取网络状态用于网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--允许获取wifi网络信息用于网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--允许获取wifi状态改变用于网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<!--后台获取位置信息,若需后台定位则必选-->
<!-- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />-->
<!--用于申请调用A-GPS模块,卫星定位加速-->
<!-- <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />-->
<!--允许写设备缓存,用于问题排查-->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!--允许写入扩展存储,用于写入缓存定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--允许读设备等信息,用于问题排查-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!--允许麦克风权限,用于录音发送-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.REORDER_TASKS" />
<application
android:label="星锁"
android:name="${applicationName}"
android:icon="@mipmap/ic_logo">
<!-- 配置定位Service -->
<service android:name="com.amap.api.location.APSService"/>
<activity
android:name="cn.starlock.lock.MainActivity"
android:exported="true"
android:screenOrientation="portrait"
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
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.star_lock">
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" android:usesPermissionFlags="neverForLocation"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<!-- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:maxSdkVersion="30" />-->
<!-- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="30" />-->
<!--允许访问网络,必选权限-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--允许获取精确位置,精准定位必选-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!--允许获取粗略位置,粗略定位必选-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!--允许获取设备和运营商信息用于问题排查和网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<!--允许获取网络状态用于网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--允许获取wifi网络信息用于网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!--允许获取wifi状态改变用于网络定位无gps情况下的定位若需网络定位功能则必选-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!--后台获取位置信息,若需后台定位则必选-->
<!-- <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />-->
<!--用于申请调用A-GPS模块,卫星定位加速-->
<!-- <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />-->
<!--允许写设备缓存,用于问题排查-->
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<!--允许写入扩展存储,用于写入缓存定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--允许读设备等信息,用于问题排查-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<!--允许麦克风权限,用于录音发送-->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.REORDER_TASKS"/>
<application android:label="@string/app_name" android:name="${applicationName}" android:icon="@mipmap/ic_launcher">
<!-- 配置定位Service -->
<service android:name="com.amap.api.location.APSService"/>
<activity android:name="cn.starlock.lock.MainActivity" android:exported="true" android:screenOrientation="portrait" 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.
<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" />
<meta-data android:name="com.amap.api.v2.apikey" android:value="11d49b3f4fc09c04a02bbb7500925ba2"> </meta-data>
<!-- 请填写你自己的- appKey -->
<meta-data android:name="com.alibaba.app.appkey" android:value="333904040"/>
<!-- 请填写你自己的appSecret -->
<meta-data android:name="com.alibaba.app.appsecret" android:value="c316965fe0a74fc9a481a5c44a535dc2"/>
<!-- 消息接收监听器 (用户可自主扩展) -->
<receiver
android:name="cn.starlock.lock.MyMessageReceiver"
android:exported="false" > <!-- 为保证receiver安全建议设置不可导出如需对其他应用开放可通过androidpermission进行限制 -->
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.intent.MESSAGE" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE" />
</intent-filter>
</receiver>
</application>
<meta-data android:name="flutterEmbedding" android:value="2"/>
<meta-data android:name="com.amap.api.v2.apikey" android:value="11d49b3f4fc09c04a02bbb7500925ba2"></meta-data>
<!-- 请填写你自己的- appKey -->
<meta-data android:name="com.alibaba.app.appkey" android:value="333904040"/>
<!-- 请填写你自己的appSecret -->
<meta-data android:name="com.alibaba.app.appsecret" android:value="c316965fe0a74fc9a481a5c44a535dc2"/>
<!-- 消息接收监听器 (用户可自主扩展) -->
<receiver android:name="cn.starlock.lock.MyMessageReceiver" android:exported="false">
<!-- 为保证receiver安全建议设置不可导出如需对其他应用开放可通过androidpermission进行限制 -->
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.intent.MESSAGE"/>
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED"/>
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED"/>
</intent-filter>
<intent-filter>
<action android:name="com.alibaba.sdk.android.push.RECEIVE"/>
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -7,6 +7,6 @@
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_logo" />
android:src="@mipmap/ic_launcher" />
</item>
</layer-list>

View File

@ -7,6 +7,6 @@
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_logo" />
android:src="@mipmap/ic_launcher" />
</item>
</layer-list>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

59
star_lock/flavorizr.yaml Normal file
View File

@ -0,0 +1,59 @@
# 用于编译出不同的APPID
# 生成:意思是将本文件定义的配置,生成对应的代码,或者原生的配置、构建过程、文件资源等
# 风味用法dart run flutter_flavorizr -p <processor_1>,<processor_2>
# 以下行为都是覆盖,所以如果不是很清楚自己在做什么,请不要随意运行,以免覆盖有用的文件
# 安卓图标dart run flutter_flavorizr -p android:icons
# 安卓构建参数集配置dart run flutter_flavorizr -p android:androidManifest
# 安卓构建目标配置dart run flutter_flavorizr -p android:buildGradle
# iOS图标dart run flutter_flavorizr -
# iOS构建参数集配置dart run flutter_flavorizr -
# iOS构建目标配置dart run flutter_flavorizr -
# 项目运行说明添加不同风味后不能再使用flutter默认的运行方式`flutter run`,而是需要指定运行的风味
# flutter run --flavor <flavor> -t lib/main_<flavor>.dart
# 注意,这里有 入口文件(main_<flavor>.dart) 和 口味(<flavor>) 两个参数
# 其中入口文件在代码中指定运行时的差异,例如 页面上的名称、颜色、API请求的域名等
# 而 口味 指定 构建差异,例如 APPID、Logo、应用名称等
# 下面是4个运行示例
# flutter run --flavor dev -t lib/main_dev.dart
# flutter run --flavor pre -t lib/main_pre.dart
# flutter run --flavor sky -t lib/main_sky.dart
# flutter run --flavor xhj -t lib/main_xhj.dart
app:
android:
flavorDimensions: "flavor-type"
flavors:
dev:
app:
name: "星锁-dev"
icon: "assets/icon/dev.png"
android:
applicationId: "com.starlock.lock.dev"
pre:
app:
name: "星锁"
icon: "assets/icon/pre.png"
android:
applicationId: "com.starlock.lock.pre"
sky:
app:
name: "锁通通"
icon: "assets/icon/sky.png"
android:
applicationId: "com.skychip.lock"
customConfig:
signingConfig: signingConfigs.sky
xhj:
app:
name: "鑫锁"
icon: "assets/icon/xhj.png"
android:
applicationId: "com.xhjcn.lock"
customConfig:
signingConfig: signingConfigs.xhj
ide: idea

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

177
star_lock/lib/app.dart Normal file
View File

@ -0,0 +1,177 @@
import 'package:aliyun_push/aliyun_push.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/tools/app_manager.dart';
import 'package:star_lock/tools/bindings/app_binding.dart';
import 'package:star_lock/tools/storage.dart';
import 'package:star_lock/tools/xs_aliyunPush.dart';
import 'package:star_lock/translations/app_dept.dart';
import 'package:star_lock/translations/trans_lib.dart';
import 'appRouters.dart';
import 'baseWidget.dart';
import 'tools/appRouteObserver.dart';
import 'dart:io';
import 'package:flutter/services.dart';
class MyApp extends StatefulWidget {
const MyApp({GlobalKey? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
// RouteObserver navigation observer.
// final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(585, 1265),
builder: (w, a) => _initMaterialApp());
}
GetMaterialApp _initMaterialApp() => GetMaterialApp(
title: 'Star Lock',
navigatorObservers: [AppRouteObserver().routeObserver],
translations: TranslationMessage(),
supportedLocales: appDept.deptSupportedLocales,
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
localeResolutionCallback: (locale, supportedLocales) {
if (!supportedLocales.contains(locale)) {
int idx = appSupportedLocales.indexWhere(
(element) => element.languageCode == locale!.languageCode);
if (idx != -1) {
locale = appSupportedLocales[idx];
} else {
locale = const Locale('zh', 'CN');
}
}
// print("localelocalelocalelocalelocale locale:${locale} locale.languageCode:${locale.languageCode} locale.countryCode:${locale.countryCode} supportedLocales:${supportedLocales}");
AppManager()
.setLanCode(code: '${locale!.languageCode}_${locale.countryCode}');
return locale;
},
// locale: StoreService.to.getLanguageCode().isNotEmpty ? appDept.deptSupportedLocales.where((element) => element.languageCode == StoreService.to.getLanguageCode()).first : Get.deviceLocale,
locale: Get.deviceLocale,
fallbackLocale: const Locale('zh', 'CN'),
theme: ThemeData(
scaffoldBackgroundColor: const Color(0xFFF6F6F6),
backgroundColor: const Color(0xFFF6F6F6),
primaryColor: const Color(0xFFFFFFFF),
textTheme: TextTheme(
//Material组件上的文字显示,
bodyText1:
TextStyle(fontSize: 28.sp, color: const Color(0xff2E2B2B)),
//Material组件上的文字显示
bodyText2:
TextStyle(fontSize: 28.sp, color: const Color(0xff2E2B2B)),
button: TextStyle(fontSize: 28.sp)),
iconTheme: IconThemeData(size: 28.sp, color: const Color(0xff2E2B2B)),
appBarTheme: AppBarTheme(
backgroundColor: const Color(0xFFFFFFFF),
elevation: 0,
centerTitle: true,
iconTheme: IconThemeData(color: const Color(0xff333333), size: 36.sp),
titleTextStyle: TextStyle(
color: const Color(0xff333333),
fontWeight: FontWeight.w400,
fontSize: 36.sp),
),
splashColor: Colors.transparent, //
highlightColor: Colors.transparent,
),
debugShowCheckedModeBanner: false,
getPages: AppRouters.routePages,
builder: EasyLoading.init(),
initialBinding: AppBindings(),
initialRoute: '/');
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
openBlueScan();
initAliyunPush();
}
//
void initAliyunPush() {
final aliyunPush = AliyunPush();
XSAliyunPushProvider().init(aliyunPush);
XSAliyunPushProvider().initAliyunPush();
if (Platform.isAndroid) {
XSAliyunPushProvider().initAliyunThirdPush();
}
//使DeviceID推送
aliyunPush.getDeviceId().then((deviceId) async {
// print('得到的DeviceId$deviceId');
final data = await Storage.getString(saveUserLoginData);
if (data!.isNotEmpty && deviceId.isNotEmpty) {
XSAliyunPushProvider()
.pushBindDeviceID(deviceId, Platform.isAndroid ? 10 : 20);
}
});
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
void openBlueScan() {
if (Platform.isIOS) {
print("有蓝牙权限开始扫描");
// startScanAction();
} else {
getMicrophonePermission().then((value) {
if (value) {
//
print("有蓝牙权限开始扫描");
// startScanAction();
} else {
//
openAppSettings(); //app系统设置
}
});
}
}
// void startScanAction() {
// BlueManage().startScan();
// }
///
Future<bool> getMicrophonePermission() async {
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetoothScan,
Permission.bluetoothConnect,
Permission.location,
].request();
//granted denied permanentlyDenied
if (statuses[Permission.bluetoothScan]!.isGranted &&
statuses[Permission.bluetoothConnect]!.isGranted &&
statuses[Permission.location]!.isGranted) {
return true;
}
return false;
}

View File

@ -130,4 +130,6 @@ class AppColors {
static Color openPassageModeColor = const Color(0xFFEB2A3B);// ()
static Color listTimeYellowColor = const Color(0xFFF3BA37);// ()
static Color get lockDetailBottomBtnUneable => const Color(0xFF808080);// ()
}

View File

@ -1,8 +1,8 @@
import 'package:star_lock/network/api.dart';
import '../../flavors.dart';
class XSConstantMacro {
//
static String baseWebURL = Api.baseAddress; //base地址
static String baseWebURL = F.apiPrefix; //base地址
static String introduceURL = '$baseWebURL/app/introduce'; //
static String userAgreementURL = '$baseWebURL/app/userAgreement'; //
static String privacyPolicyURL = '$baseWebURL/app/privacy'; //

View File

@ -0,0 +1,43 @@
enum Flavor {
dev,
pre,
sky,
xhj,
}
class F {
static Flavor? appFlavor;
static String get name => appFlavor?.name ?? '';
static String get title {
switch (appFlavor) {
case Flavor.dev:
return '星锁-dev';
case Flavor.pre:
return '星锁-pre';
case Flavor.sky:
return '锁通通';
case Flavor.xhj:
return '鑫锁';
default:
throw Exception('flavor[$name] title not found');
}
}
static String get apiPrefix {
switch (appFlavor) {
case Flavor.dev:
return 'https://dev.lock.star-lock.cn';
case Flavor.pre:
return 'https://pre.lock.star-lock.cn';
case Flavor.sky:
return 'https://lock.skychip.top';
case Flavor.xhj:
return 'https://lock.xhjcn.ltd';
default:
// "http://192.168.1.15:8022"; //
// "https://ge.lock.star-lock.cn"; //
throw Exception('flavor[$name] apiPrefix not found');
}
}
}

View File

@ -1,28 +1,16 @@
import 'package:aliyun_push/aliyun_push.dart';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:star_lock/tools/app_manager.dart';
import 'package:star_lock/tools/bindings/app_binding.dart';
import 'package:flutter/services.dart';
import 'package:star_lock/translations/trans_lib.dart';
import 'app.dart';
import 'package:star_lock/tools/device_info_service.dart';
import 'package:star_lock/tools/platform_info_services.dart';
import 'package:star_lock/tools/storage.dart';
import 'package:star_lock/tools/xs_aliyunPush.dart';
import 'package:star_lock/translations/app_dept.dart';
import 'package:star_lock/translations/trans_lib.dart';
import 'appRouters.dart';
import 'baseWidget.dart';
import 'blue/blue_manage.dart';
import 'tools/appRouteObserver.dart';
import 'app_settings/app_settings.dart';
import 'tools/store_service.dart';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
void main() async {
// flavorizr.yaml
FutureOr<void> main() async {
await _setCommonServices();
//
@ -30,135 +18,19 @@ void main() async {
runApp(MyApp());
if (Platform.isAndroid) {
if (AppPlatform.isAndroid) {
SystemUiOverlayStyle systemUiOverlayStyle =
const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
}
}
class MyApp extends StatefulWidget {
const MyApp({GlobalKey? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
// RouteObserver navigation observer.
// final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
class _MyAppState extends State<MyApp> with WidgetsBindingObserver, BaseWidget {
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(585, 1265),
builder: (w, a) => _initMaterialApp());
}
GetMaterialApp _initMaterialApp() => GetMaterialApp(
title: 'Star Lock',
navigatorObservers: [AppRouteObserver().routeObserver],
translations: TranslationMessage(),
supportedLocales: appDept.deptSupportedLocales,
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
localeResolutionCallback: (locale, supportedLocales) {
if (!supportedLocales.contains(locale)) {
int idx = appSupportedLocales.indexWhere(
(element) => element.languageCode == locale!.languageCode);
if (idx != -1) {
locale = appSupportedLocales[idx];
} else {
locale = const Locale('zh', 'CN');
}
}
// print("localelocalelocalelocalelocale locale:${locale} locale.languageCode:${locale.languageCode} locale.countryCode:${locale.countryCode} supportedLocales:${supportedLocales}");
AppManager()
.setLanCode(code: '${locale!.languageCode}_${locale.countryCode}');
return locale;
},
// locale: StoreService.to.getLanguageCode().isNotEmpty ? appDept.deptSupportedLocales.where((element) => element.languageCode == StoreService.to.getLanguageCode()).first : Get.deviceLocale,
locale: Get.deviceLocale,
fallbackLocale: const Locale('zh', 'CN'),
theme: ThemeData(
scaffoldBackgroundColor: const Color(0xFFF6F6F6),
backgroundColor: const Color(0xFFF6F6F6),
primaryColor: const Color(0xFFFFFFFF),
textTheme: TextTheme(
//Material组件上的文字显示,
bodyText1:
TextStyle(fontSize: 28.sp, color: const Color(0xff2E2B2B)),
//Material组件上的文字显示
bodyText2:
TextStyle(fontSize: 28.sp, color: const Color(0xff2E2B2B)),
button: TextStyle(fontSize: 28.sp)),
iconTheme: IconThemeData(size: 28.sp, color: const Color(0xff2E2B2B)),
appBarTheme: AppBarTheme(
backgroundColor: const Color(0xFFFFFFFF),
elevation: 0,
centerTitle: true,
iconTheme: IconThemeData(color: const Color(0xff333333), size: 36.sp),
titleTextStyle: TextStyle(
color: const Color(0xff333333),
fontWeight: FontWeight.w400,
fontSize: 36.sp),
),
splashColor: Colors.transparent, //
highlightColor: Colors.transparent,
),
debugShowCheckedModeBanner: false,
getPages: AppRouters.routePages,
builder: EasyLoading.init(),
initialBinding: AppBindings(),
initialRoute: '/');
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
openBlueScan();
initAliyunPush();
}
//
void initAliyunPush() {
final aliyunPush = AliyunPush();
XSAliyunPushProvider().init(aliyunPush);
XSAliyunPushProvider().initAliyunPush();
if (Platform.isAndroid) {
XSAliyunPushProvider().initAliyunThirdPush();
}
//使DeviceID推送
aliyunPush.getDeviceId().then((deviceId) async {
// print('得到的DeviceId$deviceId');
final data = await Storage.getString(saveUserLoginData);
if (data!.isNotEmpty && deviceId.isNotEmpty) {
XSAliyunPushProvider()
.pushBindDeviceID(deviceId, Platform.isAndroid ? 10 : 20);
}
});
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
}
//
Future _initTranslation() async => TranslationLoader.loadTranslation(
zhSource: "images/lan/lan_zh.json",
enSource: "images/lan/lan_en.json",
keySource: "images/lan/lan_keys.json",
);
zhSource: "images/lan/lan_zh.json",
enSource: "images/lan/lan_en.json",
keySource: "images/lan/lan_keys.json",
);
//
Future _setCommonServices() async {
@ -167,43 +39,3 @@ Future _setCommonServices() async {
await Get.putAsync(() => DeviceInfoService().init());
// Get.log(PlatformInfoService.to.info.version);
}
void openBlueScan() {
if (Platform.isIOS) {
print("有蓝牙权限开始扫描");
// startScanAction();
} else {
getMicrophonePermission().then((value) {
if (value) {
//
print("有蓝牙权限开始扫描");
// startScanAction();
} else {
//
openAppSettings(); //app系统设置
}
});
}
}
// void startScanAction() {
// BlueManage().startScan();
// }
///
Future<bool> getMicrophonePermission() async {
// You can request multiple permissions at once.
Map<Permission, PermissionStatus> statuses = await [
Permission.bluetoothScan,
Permission.bluetoothConnect,
Permission.location,
].request();
//granted denied permanentlyDenied
if (statuses[Permission.bluetoothScan]!.isGranted &&
statuses[Permission.bluetoothConnect]!.isGranted &&
statuses[Permission.location]!.isGranted) {
return true;
}
return false;
}

View File

@ -1,8 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_native_contact_picker/flutter_native_contact_picker.dart';
// import 'package:flutter_pickers/pickers.dart';
// import 'package:flutter_pickers/time_picker/model/date_mode.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:star_lock/network/api_repository.dart';
@ -340,7 +339,7 @@ class _AuthorizedAdminPageState extends State<AuthorizedAdminPage> {
//
Widget getTFWidget(bool isHaveBtn, String tfStr, int lineIndex) {
return SizedBox(
height: 50.h,
height: 65.h,
width: 300.w,
child: Row(
children: [
@ -348,6 +347,10 @@ class _AuthorizedAdminPageState extends State<AuthorizedAdminPage> {
child: TextField(
//
maxLines: 1,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.deny('\n'),
LengthLimitingTextInputFormatter(30),
],
controller: lineIndex == 1
? state.emailOrPhoneController
: state.keyNameController,
@ -355,13 +358,24 @@ class _AuthorizedAdminPageState extends State<AuthorizedAdminPage> {
textAlign: TextAlign.end,
decoration: InputDecoration(
//
contentPadding: const EdgeInsets.only(top: 12.0, bottom: 8.0),
// contentPadding: const EdgeInsets.only(top: 12.0, bottom: 8.0),
hintText: tfStr,
hintStyle: TextStyle(
color: AppColors.placeholderTextColor, fontSize: 22.sp),
//线
border: InputBorder.none,
hintStyle: TextStyle(fontSize: 22.sp),
focusedBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),
disabledBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),
enabledBorder: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),
border: const OutlineInputBorder(borderSide: BorderSide(width: 0, color: Colors.transparent)),
contentPadding: const EdgeInsets.symmetric(vertical: 0),
),
// decoration: InputDecoration(
// //
// contentPadding: const EdgeInsets.only(top: 12.0, bottom: 8.0),
// hintText: tfStr,
// hintStyle: TextStyle(
// color: AppColors.placeholderTextColor, fontSize: 22.sp),
// //线
// border: InputBorder.none,
// ),
),
),
SizedBox(

View File

@ -9,16 +9,16 @@ class AuthorizedAdminListLogic extends BaseGetXController {
//
Future<List<ElectronicKeyListItem>> mockNetworkDataRequest() async {
ElectronicKeyListEntity entity = await ApiRepository.to.electronicKeyList(
'0',
state.keyInfo.value.keyId.toString(),
'',
state.keyInfo.value.lockId.toString(),
'',
state.pageNum.toString(),
state.pageSize.toString(),
'0',
'0',
state.searchStr.value);
endDate: '0',
keyId: state.keyInfo.value.keyId.toString(),
keyStatus: '',
lockId: state.keyInfo.value.lockId.toString(),
operatorUid: '',
pageNo: pageNo.toString(),
pageSize: pageSize.toString(),
startDate: '0',
keyRight: '0',
searchStr:state.searchStr.value);
List<ElectronicKeyListItem> dataList = [];
if (entity.errorCode!.codeIsSuccessful) {
print("电子钥匙列表成功:${entity.data?.itemList}");

View File

@ -36,6 +36,7 @@ class _CheckingInListPageState extends State<CheckingInListPage> {
haveBack: true,
backgroundColor: AppColors.mainColor,
actionsList: [
(state.getKeyInfosData.value.isLockOwner == 1 && state.getKeyInfosData.value.keyRight == 1) ?
GestureDetector(
onTap: () async {
var isDemoMode = await Storage.getBool(ifIsDemoModeOrNot);
@ -48,7 +49,7 @@ class _CheckingInListPageState extends State<CheckingInListPage> {
logic.showToast("演示模式");
}
},
child: Image.asset('images/main/icon_lockDetail_checkIn_set.png', width: 36.w, height: 36.w,)),
child: Image.asset('images/main/icon_lockDetail_checkIn_set.png', width: 36.w, height: 36.w,)) : Container(),
SizedBox(width: 30.w),
],
),

View File

@ -115,17 +115,20 @@ class _CheckingInSetPageState extends State<CheckingInSetPage> {
SizedBox(
height: 30.h,
),
SubmitBtn(
btnName:
"${TranslationLoader.lanKeys!.delete!.tr}${TranslationLoader.lanKeys!.company!.tr}",
borderRadius: 20.w,
fontSize: 32.sp,
isDelete: true,
margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 20.w),
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
onClick: () {
showDeletCompanyAlertDialog(context);
}),
Visibility(
visible: state.getKeyInfosData.value.isLockOwner == 1,
child: SubmitBtn(
btnName:
"${TranslationLoader.lanKeys!.delete!.tr}${TranslationLoader.lanKeys!.company!.tr}",
borderRadius: 20.w,
fontSize: 32.sp,
isDelete: true,
margin: EdgeInsets.only(left: 30.w, right: 30.w, top: 20.w),
padding: EdgeInsets.only(top: 20.w, bottom: 20.w),
onClick: () {
showDeletCompanyAlertDialog(context);
}),
),
],
),
);

View File

@ -5,6 +5,8 @@ import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import '../../../../../tools/eventBusEventManage.dart';
class ElectronicKeyDetailLogic extends BaseGetXController {
final ElectronicKeyDetailState state = ElectronicKeyDetailState();
@ -15,8 +17,10 @@ class ElectronicKeyDetailLogic extends BaseGetXController {
state.changeNameController.text, '');
if (entity.errorCode!.codeIsSuccessful) {
print("修改要是名称成功啦啦啦啦啦");
showToast("修改成功");
Get.back();
showToast("修改成功", something: (){
eventBus.fire(ElectronicKeyListRefreshUI());
Get.back();
});
}
}
@ -26,8 +30,10 @@ class ElectronicKeyDetailLogic extends BaseGetXController {
.deleteElectronicKey(state.itemData.value.keyId.toString());
if (entity.errorCode!.codeIsSuccessful) {
print("删除电子钥匙成功");
showToast("删除成功");
Get.back();
showToast("删除成功", something: (){
eventBus.fire(ElectronicKeyListRefreshUI());
Get.back();
});
}
}
}

View File

@ -5,6 +5,8 @@ import 'package:star_lock/main/lockDetail/passwordKey/passwordKey_perpetual/pass
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import '../../../../../tools/eventBusEventManage.dart';
class ElectronicKeyDetailChangeDateLogic extends BaseGetXController {
final ElectronicKeyDetailChangeDateState state =
ElectronicKeyDetailChangeDateState();
@ -23,8 +25,10 @@ class ElectronicKeyDetailChangeDateLogic extends BaseGetXController {
hoursEnd: state.hoursEnd.value,
isCoerced: state.isCoerced.value);
if (entity.errorCode!.codeIsSuccessful) {
showToast("修改成功");
Get.back();
showToast("修改成功", something: (){
eventBus.fire(ElectronicKeyListRefreshUI());
Get.back();
});
}
}
@ -40,8 +44,10 @@ class ElectronicKeyDetailChangeDateLogic extends BaseGetXController {
state.startDay.value,
state.weekDays.value);
if (entity.errorCode!.codeIsSuccessful) {
showToast("修改成功");
Get.back();
showToast("修改成功", something: (){
eventBus.fire(ElectronicKeyListRefreshUI());
Get.back();
});
}
}
}

View File

@ -1,24 +1,28 @@
import 'dart:async';
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/electronicKeyList_state.dart';
import 'package:star_lock/main/lockDetail/electronicKey/electronicKeyList/entity/ElectronicKeyListEntity.dart';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import '../../../../tools/eventBusEventManage.dart';
class ElectronicKeyListLogic extends BaseGetXController {
final ElectronicKeyListState state = ElectronicKeyListState();
//
Future<ElectronicKeyListEntity> mockNetworkDataRequest() async {
ElectronicKeyListEntity entity = await ApiRepository.to.electronicKeyList(
'0',
state.keyInfo.value.keyId.toString(),
'',
state.keyInfo.value.lockId.toString(),
'',
pageNo.toString(),
pageSize.toString(),
'0',
'0',
state.searchController.text);
endDate: '0',
keyId: state.keyInfo.value.keyId.toString(),
keyStatus: '',
lockId: state.keyInfo.value.lockId.toString(),
operatorUid: '',
pageNo: pageNo.toString(),
pageSize: pageSize.toString(),
startDate: '0',
keyRight: '0',
searchStr: state.searchController.text);
if (entity.errorCode!.codeIsSuccessful) {
if (pageNo == 1) {
state.itemDataList.value = entity.data!.itemList!;
@ -40,6 +44,7 @@ class ElectronicKeyListLogic extends BaseGetXController {
if (entity.errorCode!.codeIsSuccessful) {
print("重置电子钥匙成功啦啦啦啦啦");
showToast("重置成功");
pageNo = 1;
mockNetworkDataRequest();
}
}
@ -51,14 +56,27 @@ class ElectronicKeyListLogic extends BaseGetXController {
if (entity.errorCode!.codeIsSuccessful) {
print("删除电子钥匙成功");
showToast("删除成功");
pageNo = 1;
mockNetworkDataRequest();
}
}
///
StreamSubscription? _getElectronicKeyListRefreshUIEvent;
void _getElectronicKeyListRefreshUIAction() {
// eventBus
_getElectronicKeyListRefreshUIEvent = eventBus.on<ElectronicKeyListRefreshUI>().listen((event) {
pageNo = 1;
mockNetworkDataRequest();
});
}
@override
void onReady() {
// TODO: implement onReady
super.onReady();
_getElectronicKeyListRefreshUIAction();
}
@override
@ -70,5 +88,8 @@ class ElectronicKeyListLogic extends BaseGetXController {
@override
void onClose() {
// TODO: implement onClose
super.onClose();
_getElectronicKeyListRefreshUIEvent?.cancel();
}
}

View File

@ -121,63 +121,64 @@ class _ElectronicKeyListPageState extends State<ElectronicKeyListPage> {
Widget _buildMainUI() {
return Obx(() => state.itemDataList.value.isEmpty
? NoData(noDataHeight: 1.sh - ScreenUtil().statusBarHeight - ScreenUtil().bottomBarHeight - 190.h - 64.h)
: ListView.separated(
: SlidableAutoCloseBehavior(
child: ListView.separated(
shrinkWrap: true,
itemCount: state.itemDataList.value.length,
itemBuilder: (c, index) {
ElectronicKeyListItem indexEntity = state.itemDataList.value[index];
String useDateStr = ''; //使
String keyStatus = ''; //
ElectronicKeyListItem indexEntity = state.itemDataList.value[index];
String useDateStr = ''; //使
String keyStatus = ''; //
//使
useDateStr = getUseDateStr(indexEntity);
//使
useDateStr = getUseDateStr(indexEntity);
//
keyStatus = getKeyStatus(indexEntity.keyStatus);
//
keyStatus = getKeyStatus(indexEntity.keyStatus);
//
bool isAdminKey = false;
if (indexEntity.keyRight == 1) {
isAdminKey = true;
} else {
isAdminKey = false;
}
//
bool isAdminKey = false;
if (indexEntity.keyRight == 1) {
isAdminKey = true;
} else {
isAdminKey = false;
}
return Slidable(
key:ValueKey(indexEntity.keyId),
endActionPane: ActionPane(
extentRatio: 0.2,
motion: const ScrollMotion(),
children: [
SlidableAction(
onPressed: (BuildContext context){
showIosTipViewDialog(context, indexEntity.keyId!.toString());
},
backgroundColor: Colors.red,
foregroundColor: Colors.white,
label: '删除',
),
],
),
child: _electronicKeyItem('images/controls_user.png',
indexEntity.keyName!, useDateStr, keyStatus, isAdminKey, () {
Navigator.pushNamed(context, Routers.electronicKeyDetailPage,
arguments: {"itemData": indexEntity}).then((val) {
if (val != null) {
logic.mockNetworkDataRequest();
setState(() {});
}
});
}),
);
return Slidable(
key:ValueKey(indexEntity.keyId),
endActionPane: ActionPane(
extentRatio: 0.2,
motion: const ScrollMotion(),
children: [
SlidableAction(
onPressed: (BuildContext context){
showIosTipViewDialog(context, indexEntity.keyId!.toString());
},
backgroundColor: Colors.red,
foregroundColor: Colors.white,
label: '删除',
),
],
),
child: _electronicKeyItem('images/controls_user.png', indexEntity.keyName!, useDateStr, keyStatus, isAdminKey, () {
Navigator.pushNamed(context, Routers.electronicKeyDetailPage,
arguments: {"itemData": indexEntity}).then((val) {
if (val != null) {
logic.mockNetworkDataRequest();
setState(() {});
}
});
}),
);
},
separatorBuilder: (BuildContext context, int index) {
return const Divider(
height: 1,
color: AppColors.greyLineColor,
);
return const Divider(
height: 1,
color: AppColors.greyLineColor,
);
},
));
),
));
}
Widget _buildDeleteBtn(String keyId) {
@ -269,6 +270,9 @@ class _ElectronicKeyListPageState extends State<ElectronicKeyListPage> {
} else if (keyStatusFlag == 110410) {
//
keyStatus = '已重置';
} else if (keyStatusFlag == 110412) {
//
keyStatus = '已过期';
}
return keyStatus;

View File

@ -6,6 +6,7 @@ import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import 'package:star_lock/main/lockDetail/electronicKey/sendElectronicKey/sendElectronicKey/sendElectronicKey_state.dart';
import 'package:star_lock/network/api_repository.dart';
import 'package:star_lock/tools/baseGetXController.dart';
import 'package:star_lock/tools/eventBusEventManage.dart';
import 'package:star_lock/translations/trans_lib.dart';
class SendElectronicKeyLogic extends BaseGetXController {
@ -62,6 +63,9 @@ class SendElectronicKeyLogic extends BaseGetXController {
if (entity.errorCode!.codeIsSuccessful) {
print('发送电子钥匙成功');
state.isSendSuccess.value = true;
state.sendSucceedType.value = int.parse(state.type.value);
resetData();
eventBus.fire(ElectronicKeyListRefreshUI());
} else {
if (entity.errorCode == 425) {
//
@ -162,4 +166,11 @@ class SendElectronicKeyLogic extends BaseGetXController {
},
);
}
void resetData(){
state.emailOrPhoneController.text = "";
state.keyNameController.text = "";
state.selectEffectiveDate = '${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} ${DateTime.now().hour}:${DateTime.now().minute}'.obs; //
state.selectFailureDate = '${DateTime.now().year}-${DateTime.now().month}-${DateTime.now().day} ${DateTime.now().hour}:${DateTime.now().minute}'.obs; //
}
}

View File

@ -53,7 +53,7 @@ class _SendElectronicKeyPageState extends State<SendElectronicKeyPage> {
}
Widget indexChangeWidget() {
if (state.isSendSuccess.value == true) {
if (state.isSendSuccess.value == true && state.sendSucceedType.value.toString() == widget.type) {
return sendElectronicKeySucceed();
} else {
switch (int.parse(widget.type)) {
@ -281,8 +281,7 @@ class _SendElectronicKeyPageState extends State<SendElectronicKeyPage> {
state.failureDateTime.value.hour,
state.failureDateTime.value.minute);
//
if (state.emailOrPhoneController.text.isNotEmpty &&
state.keyNameController.text.isNotEmpty) {
if (state.emailOrPhoneController.text.isNotEmpty && state.keyNameController.text.isNotEmpty) {
if (int.parse(widget.type) == 0) {
if (!startDateTime.isBefore(endDateTime) ||
startDateTime.isAtSameMomentAs(endDateTime)) {
@ -372,7 +371,7 @@ class _SendElectronicKeyPageState extends State<SendElectronicKeyPage> {
btnName: '完成',
onClick: () {
state.isSendSuccess.value = false;
Navigator.pop(context, true);
logic.resetData();
}),
SizedBox(
height: 10.h,
@ -443,7 +442,7 @@ class _SendElectronicKeyPageState extends State<SendElectronicKeyPage> {
maxLines: 1,
inputFormatters: <TextInputFormatter>[
FilteringTextInputFormatter.deny('\n'),
LengthLimitingTextInputFormatter(18),
LengthLimitingTextInputFormatter(30),
],
// controller: _controller,
autofocus: false,
@ -508,17 +507,20 @@ class _SendElectronicKeyPageState extends State<SendElectronicKeyPage> {
//
Widget remoteUnlockingWidget() {
return Column(
children: [
CommonItem(
leftTitel: TranslationLoader.lanKeys!.remoteUnlockingAllowed!.tr,
rightTitle: "",
isHaveRightWidget: true,
rightWidget:
SizedBox(width: 60.w, height: 50.h, child: _remoteSwitch(true)),
action: () {}),
Container(height: 10.h),
],
return Visibility(
visible: state.keyInfo.value.lockSetting!.remoteUnlock == 1 ? true : false,
child: Column(
children: [
CommonItem(
leftTitel: TranslationLoader.lanKeys!.remoteUnlockingAllowed!.tr,
rightTitle: "",
isHaveRightWidget: true,
rightWidget:
SizedBox(width: 60.w, height: 50.h, child: _remoteSwitch(true)),
action: () {}),
Container(height: 10.h),
],
),
);
}

View File

@ -35,6 +35,8 @@ class SendElectronicKeyState {
var weekdaysList = [].obs;
var isCreateUser = false.obs; //1 0
final sendSucceedType = 0.obs;
SendElectronicKeyState() {
Map map = Get.arguments;
keyInfo.value = map["keyInfo"];

View File

@ -38,6 +38,13 @@ class _SendElectronicKeyManageTabbarState
vsync: this,
length: _itemTabs.length,
initialIndex: widget.initialIndex);
_tabController.addListener(() {
// print("_tabController.animation!.value:${_tabController.animation!.value} _tabController.index:${_tabController.index}");
if (_tabController.animation!.value==_tabController.index){
FocusScope.of(context).requestFocus(FocusNode());
}
});
}
@override
@ -54,6 +61,9 @@ class _SendElectronicKeyManageTabbarState
TabBar _tabBar() {
return TabBar(
controller: _tabController,
onTap: (index){
FocusScope.of(context).requestFocus(FocusNode());
},
tabs: _itemTabs.map((ItemView item) => _tab(item)).toList(),
isScrollable: true,
indicatorColor: Colors.red,

View File

@ -137,7 +137,10 @@ class LockDetailLogic extends BaseGetXController {
case 0x16:
// ...
print("${reply.commandType}正在开锁中...");
showToast("正在开锁中...");
state.openLockBtnState.value = 0;
showToast("正在开锁中...", something: (){
cancelBlueConnetctToastTimer();
});
break;
default:
//
@ -317,7 +320,7 @@ class LockDetailLogic extends BaseGetXController {
} else {
getLockNetToken();
}
// clickPushBtnAction();
break;
case 0x06:
//
@ -598,38 +601,45 @@ class LockDetailLogic extends BaseGetXController {
}
}
// 0 1 2 3 4 5 6 7 8 9 10
clickItemBtnAction(int type){
state.clickNextType = type;
if (state.lockUserNo == 0) {
// lockUserNo为0
addUserConnectBlue();
} else {
clickPushBtnAction();
}
}
clickPushBtnAction(){
// 0 1 2 3 4 5 6 7 8 9 10
switch(state.clickNextType){
case 0:
//
startOpenLock();
break;
case 1:
//
startUnLock();
break;
case 2:
//
Get.toNamed(Routers.passwordKeyListPage, arguments: {"keyInfo": state.keyInfos.value});
break;
case 3:
//
Get.toNamed(Routers.passwordKeyListPage, arguments: {"keyInfo": state.keyInfos.value});
break;
}
}
// // 0 1 2 3 4 5 6 7 8 9 10
// clickItemBtnAction(int type){
// state.clickNextType = type;
// if (state.lockUserNo == 0) {
// // lockUserNo为0
// addUserConnectBlue();
// } else {
// clickPushBtnAction();
// }
// }
//
// clickPushBtnAction(){
// // 0 1 2 3 4 5 6 7 8 9 10
// switch(state.clickNextType){
// case 0:
// //
// startOpenLock();
// break;
// case 1:
// //
// startUnLock();
// break;
// case 2:
// //
// Get.toNamed(Routers.passwordKeyListPage, arguments: {"keyInfo": state.keyInfos.value});
// break;
// case 3:
// //
// Get.toNamed(Routers.passwordKeyListPage, arguments: {"keyInfo": state.keyInfos.value});
// break;
// case 10:
// //
// Get.toNamed(Routers.lockSetPage, arguments: {
// "lockId": state.keyInfos.value.lockId,
// "isOnlyOneData": state.isOnlyOneData,
// });
// break;
// }
// }
// token
void getLockNetToken() async {
@ -648,6 +658,8 @@ class LockDetailLogic extends BaseGetXController {
lockUserNo: state.lockUserNo.toString());
if (entity.errorCode!.codeIsSuccessful) {
if (state.isOpenLockNeedOnline.value == 0) {
state.bottomBtnisUneable.value = false;
eventBus.fire(RefreshLockListInfoDataEvent());
openDoorAction(1);
} else {
getLockNetToken();

View File

@ -38,12 +38,15 @@ class _LockDetailPageState extends State<LockDetailPage>
void initState() {
// TODO: implement initState
super.initState();
Get.log("LockDetailPage initState1111");
// Get.log("LockDetailPage initState1111");
print("LockDetailPage isOnlyOneData==${widget.isOnlyOneData}");
state.keyInfos.value = widget.lockListInfoItemEntity;
state.lockUserNo = state.keyInfos.value.lockUserNo!;
print("state.lockUserNo==${state.lockUserNo}");
if (state.lockUserNo == 0) {
state.bottomBtnisUneable.value = true;
}
state.isOnlyOneData = widget.isOnlyOneData;
// print("state.lockUserNo==${state.lockUserNo}");
state.senderUserId = state.keyInfos.value.senderUserId!;
state.isAttendance.value = state.keyInfos.value.lockSetting!.attendance!;
state.isOpenLockNeedOnline.value =
@ -153,7 +156,6 @@ class _LockDetailPageState extends State<LockDetailPage>
}
Widget topWidget() {
// KeyInfos keyInfo = widget.lockMainEntity.data!.keyInfos![0];
return Column(
children: [
SizedBox(height: 50.h),
@ -439,24 +441,35 @@ class _LockDetailPageState extends State<LockDetailPage>
//
List<Widget> getNormalWidget() {
var showWidgetArr = [
//
bottomItem('images/main/icon_main_operatingRecord.png',
TranslationLoader.lanKeys!.operatingRecord!.tr, () {
Get.toNamed(Routers.lockOperatingRecordPage,
arguments: {"keyInfo": state.keyInfos.value});
}),
var showWidgetArr = <Widget>[];
//
if (state.isAttendance.value == 1) {
showWidgetArr.add(bottomItem(
'images/main/icon_main_clockingIn.png',
TranslationLoader.lanKeys!.checkingIn!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.checkingInListPage,
arguments: state.keyInfos.value);
}));
}
//
showWidgetArr.add(bottomItem(
'images/main/icon_main_operatingRecord.png',
TranslationLoader.lanKeys!.operatingRecord!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.lockOperatingRecordPage,
arguments: {"keyInfo": state.keyInfos.value});
}));
//
showWidgetArr.add(bottomItem('images/main/icon_main_set.png',
TranslationLoader.lanKeys!.set!.tr, state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.lockSetPage, arguments: {
"lockId": state.keyInfos.value.lockId,
"isOnlyOneData": state.isOnlyOneData
});
}));
//
bottomItem(
'images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr,
() {
Get.toNamed(Routers.lockSetPage, arguments: {
"lockId": state.keyInfos.value.lockId,
"isOnlyOneData": widget.isOnlyOneData,
});
}),
];
return showWidgetArr;
}
@ -465,31 +478,39 @@ class _LockDetailPageState extends State<LockDetailPage>
var showWidgetArr = <Widget>[];
//
if (state.isAttendance.value == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_clockingIn.png',
TranslationLoader.lanKeys!.checkingIn!.tr, () {
showWidgetArr.add(bottomItem(
'images/main/icon_main_clockingIn.png',
TranslationLoader.lanKeys!.checkingIn!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.checkingInListPage,
arguments: state.keyInfos.value);
}));
}
//
showWidgetArr.add(bottomItem('images/main/icon_main_electronicKey.png',
TranslationLoader.lanKeys!.electronicKey!.tr, () {
showWidgetArr.add(bottomItem(
'images/main/icon_main_electronicKey.png',
TranslationLoader.lanKeys!.electronicKey!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.electronicKeyListPage,
arguments: {"keyInfo": state.keyInfos.value});
}));
//
showWidgetArr.add(bottomItem('images/main/icon_main_password.png',
TranslationLoader.lanKeys!.password!.tr, () {
showWidgetArr.add(bottomItem(
'images/main/icon_main_password.png',
TranslationLoader.lanKeys!.password!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.passwordKeyListPage,
arguments: {"keyInfo": state.keyInfos.value});
}));
// ic卡
if (state.keyInfos.value.lockFeature!.icCard == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_icCard.png',
TranslationLoader.lanKeys!.card!.tr, () {
showWidgetArr.add(bottomItem(
'images/main/icon_main_icCard.png',
TranslationLoader.lanKeys!.card!.tr,
state.bottomBtnisUneable.value, () {
// logic.showToast("普通用户第一次需要在锁旁边操作哦。", something: () {
// logic.showEasyLoading();
// });
@ -501,8 +522,10 @@ class _LockDetailPageState extends State<LockDetailPage>
//
if (state.keyInfos.value.lockFeature!.fingerprint == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_fingerprint.png',
TranslationLoader.lanKeys!.fingerprint!.tr, () {
showWidgetArr.add(bottomItem(
'images/main/icon_main_fingerprint.png',
TranslationLoader.lanKeys!.fingerprint!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.fingerprintListPage, arguments: {
"lockId": state.keyInfos.value.lockId,
});
@ -511,8 +534,10 @@ class _LockDetailPageState extends State<LockDetailPage>
//
if (state.keyInfos.value.lockFeature!.bluetoothRemoteControl == 1) {
showWidgetArr.add(bottomItem('images/main/icon_main_remoteControl.png',
TranslationLoader.lanKeys!.remoteControl!.tr, () {
showWidgetArr.add(bottomItem(
'images/main/icon_main_remoteControl.png',
TranslationLoader.lanKeys!.remoteControl!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.remoteControlListPage);
}));
}
@ -520,8 +545,10 @@ class _LockDetailPageState extends State<LockDetailPage>
//->
if (state.keyInfos.value.lockFeature!.d3Face == 1) {
showWidgetArr.add(
bottomItem('images/main/icon_face.png',
TranslationLoader.lanKeys!.humanFace!.tr, () {
bottomItem(
'images/main/icon_face.png',
TranslationLoader.lanKeys!.humanFace!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.faceList, arguments: {
"lockId": state.keyInfos.value.lockId,
}); // Toast.show(msg: "功能暂未开放");
@ -532,8 +559,10 @@ class _LockDetailPageState extends State<LockDetailPage>
//->
if (state.keyInfos.value.lockFeature!.videoIntercom == 1) {
showWidgetArr.add(
bottomItem('images/main/icon_catEyes.png',
TranslationLoader.lanKeys!.monitoring!.tr, () {
bottomItem(
'images/main/icon_catEyes.png',
TranslationLoader.lanKeys!.monitoring!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.realTimePicturePage, arguments: {
"lockName": state.keyInfos.value.lockName,
"isMonitoring": true
@ -542,40 +571,56 @@ class _LockDetailPageState extends State<LockDetailPage>
);
}
var endWiddget = [
//
bottomItem('images/main/icon_main_authorizedAdmin.png',
TranslationLoader.lanKeys!.authorizedAdmin!.tr, () {
//
if (state.keyInfos.value.isLockOwner == 1) {
showWidgetArr.add(bottomItem(
'images/main/icon_main_authorizedAdmin.png',
TranslationLoader.lanKeys!.authorizedAdmin!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.authorizedAdminListPage,
arguments: {"keyInfo": state.keyInfos.value});
}),
}));
}
// bottomItem('images/main/icon_main_authorizedAdmin.png', TranslationLoader.lanKeys!.authorizedAdmin!.tr, state.bottomBtnisUneable.value, () {
// Get.toNamed(Routers.authorizedAdminListPage,
// arguments: {"keyInfo": state.keyInfos.value});
// })
var endWiddget = [
//
bottomItem('images/main/icon_main_operatingRecord.png',
TranslationLoader.lanKeys!.operatingRecord!.tr, () {
bottomItem(
'images/main/icon_main_operatingRecord.png',
TranslationLoader.lanKeys!.operatingRecord!.tr,
state.bottomBtnisUneable.value, () {
// Get.toNamed(Routers.lockOperatingRecordPage,
// arguments: {"keyInfo": state.keyInfos.value});
Get.toNamed(Routers.doorLockLogPage,
arguments: {"keyInfo": state.keyInfos.value});
}),
//
bottomItem('images/main/icon_lockDetail_videoLog.png',
TranslationLoader.lanKeys!.videoLog!.tr, () {
bottomItem(
'images/main/icon_lockDetail_videoLog.png',
TranslationLoader.lanKeys!.videoLog!.tr,
state.bottomBtnisUneable.value, () {
//
Get.toNamed(Routers.videoLogPage);
}),
//
bottomItem('images/main/icon_lockDetail_messageReminding.png',
TranslationLoader.lanKeys!.messageReminding!.tr, () {
bottomItem(
'images/main/icon_lockDetail_messageReminding.png',
TranslationLoader.lanKeys!.messageReminding!.tr,
state.bottomBtnisUneable.value, () {
Get.toNamed(Routers.msgNotificationPage);
}),
//
bottomItem(
'images/main/icon_main_set.png', TranslationLoader.lanKeys!.set!.tr,
() {
// BlueManage().stopScan();
'images/main/icon_main_set.png',
TranslationLoader.lanKeys!.set!.tr,
state.bottomBtnisUneable.value, () {
// logic.clickItemBtnAction(10);
Get.toNamed(Routers.lockSetPage, arguments: {
"lockId": state.keyInfos.value.lockId,
"isOnlyOneData": widget.isOnlyOneData,
"isOnlyOneData": state.isOnlyOneData,
});
}),
];
@ -583,11 +628,17 @@ class _LockDetailPageState extends State<LockDetailPage>
return showWidgetArr;
}
Widget bottomItem(String iconUrl, String name, Function() onClick) {
//
Widget bottomItem(
String iconUrl, String name, bool isForbidden, Function() onClick) {
var width = 42.w;
var height = 42.h;
return GestureDetector(
onTap: onClick,
onTap: isForbidden
? () {
logic.showToast("请在锁旁边完成第一次开锁");
}
: onClick,
child: Container(
// height: 300.h,
color: Colors.white,
@ -596,15 +647,24 @@ class _LockDetailPageState extends State<LockDetailPage>
children: [
SizedBox(
width: width,
height: height,
height:
height, // isForbidden ? "${iconUrl}_uneable.png" :"${iconUrl}.png"
child: Image.asset(iconUrl,
width: width, height: height, fit: BoxFit.fitWidth),
width: width,
height: height,
color: isForbidden
? AppColors.lockDetailBottomBtnUneable
: AppColors.mainColor,
fit: BoxFit.fitWidth),
),
SizedBox(height: 10.w),
Expanded(
child: Text(name,
style: TextStyle(
fontSize: 20.sp, color: AppColors.blackColor),
fontSize: 20.sp,
color: isForbidden
? AppColors.lockDetailBottomBtnUneable
: AppColors.blackColor),
textAlign: TextAlign.center))
],
)),
@ -685,7 +745,7 @@ class _LockDetailPageState extends State<LockDetailPage>
child: Column(
children: [
Text(
widget.lockListInfoItemEntity.lockAlias!,
state.keyInfos.value.lockAlias!,
style: TextStyle(
color: AppColors.placeholderTextColor, fontSize: 24.sp),
),

View File

@ -21,6 +21,7 @@ class LockDetailState {
String lockNetToken = "";
var lockUserNo = 0;
var senderUserId = 0;
var isOnlyOneData = false;
var isAttendance = 0.obs;//
var isOpenLockNeedOnline = 0.obs; // APP开锁时是否需联网
@ -35,8 +36,7 @@ class LockDetailState {
var iSOpenLock = true.obs; //
Timer? closedUnlockSuccessfulTimer;
// 0 1 2 3 4 5 6 7 8 9 10
var clickNextType = 0;
var bottomBtnisUneable = false.obs; //
//
late AnimationController animationController;

View File

@ -34,7 +34,8 @@ class _LockOperatingRecordPageState extends State<LockOperatingRecordPage> {
haveBack: true,
backgroundColor: AppColors.mainColor,
actionsList: [
IconButton(
(state.keyInfos.value.isLockOwner == 1 || state.keyInfos.value.keyRight == 1)
? IconButton(
icon: Image.asset(
'images/icon_bar_more.png',
height: 30.h,
@ -63,7 +64,8 @@ class _LockOperatingRecordPageState extends State<LockOperatingRecordPage> {
logic.showToast("演示模式");
}
},
),
)
: Container(),
],
),
body: Column(

View File

@ -91,6 +91,7 @@ class _BasicInformationPageState extends State<BasicInformationPage> {
if (data != null) {
setState(() {
state.lockBasicInfo.value = data["lockBasicInfo"];
print("state.lockBasicInfo.value.lockAlias:${state.lockBasicInfo.value.lockAlias}");
});
}
})),
@ -111,8 +112,7 @@ class _BasicInformationPageState extends State<BasicInformationPage> {
});
})),
Visibility(
visible: (state.lockBasicInfo.value.isLockOwner == 1 ||
state.lockBasicInfo.value.keyRight == 1)
visible: state.lockBasicInfo.value.isLockOwner == 1
? true
: false,
child: CommonItem(

View File

@ -16,8 +16,8 @@ class EditLockNameLogic extends BaseGetXController{
lockId: state.lockSetInfoData.value.lockId.toString(),
lockName:state.changeLockNameController.text);
if (entity.errorCode!.codeIsSuccessful) {
state.lockBasicInfo.value.lockAlias = state.changeLockNameController.text;
showToast("修改成功", something: (){
state.lockBasicInfo.value.lockAlias = state.changeLockNameController.text;
eventBus.fire(LockSetChangeSetRefreshLockDetailWithType(3, state.lockBasicInfo.value.lockAlias!));
eventBus.fire(RefreshLockListInfoDataEvent());
});

View File

@ -330,7 +330,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
}))),
//
Obx(() => Visibility(
visible: state.lockFeature.value.resetSwitch == 1 ? true : false,
visible: (state.lockBasicInfo.value.isLockOwner == 1 && state.lockFeature.value.resetSwitch == 1) ? true : false,
child: CommonItem(
leftTitel: TranslationLoader.lanKeys!.resetButton!.tr,
rightTitle: (state.lockSettingInfo.value.resetSwitch ?? 0) == 1
@ -470,7 +470,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
//
Obx(
() => Visibility(
visible: state.lockFeature.value.attendance == 1 ? true : false,
visible: (state.lockBasicInfo.value.isLockOwner == 1 && state.lockFeature.value.attendance == 1) ? true : false,
child: CommonItem(
leftTitel: TranslationLoader.lanKeys!.checkingIn!.tr,
rightTitle: "",
@ -481,7 +481,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
//
Obx(
() => Visibility(
visible: state.lockFeature.value.unlockReminder == 1 ? true : false,
visible: state.lockBasicInfo.value.isLockOwner == 1 && state.lockFeature.value.unlockReminder == 1 ? true : false,
child: CommonItem(
leftTitel: TranslationLoader.lanKeys!.unlockReminder!.tr,
rightTitle: "",
@ -492,7 +492,7 @@ class _LockSetPageState extends State<LockSetPage> with RouteAware {
// APP开锁时是否需联网
Obx(
() => Visibility(
visible: state.lockFeature.value.appUnlockOnline == 1 ? true : false,
visible: state.lockBasicInfo.value.isLockOwner == 1 && state.lockFeature.value.appUnlockOnline == 1 ? true : false,
child: CommonItem(
leftTitel: TranslationLoader
.lanKeys!.whetherInternetRequiredWhenUnlocking!.tr,

View File

@ -23,13 +23,13 @@ class RemoteUnlockingLogic extends BaseGetXController{
remoteUnlock:state.remoteEnable.value == 1 ? 0 : 1
);
if(entity.errorCode!.codeIsSuccessful){
eventBus.fire(RefreshLockListInfoDataEvent());
state.remoteEnable.value = state.remoteEnable.value == 1 ? 0 : 1;
state.lockSetInfoData.value.lockSettingInfo!.remoteUnlock = state.remoteEnable.value;
print("state.remoteEnable.value:${state.remoteEnable.value} state.getKeyInfosData.value.remoteEnable:${state.lockSetInfoData.value.lockSettingInfo!.remoteUnlock}");
eventBus.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
showToast("操作成功");
showToast("操作成功", something: (){
eventBus.fire(RefreshLockListInfoDataEvent());
state.remoteEnable.value = state.remoteEnable.value == 1 ? 0 : 1;
state.lockSetInfoData.value.lockSettingInfo!.remoteUnlock = state.remoteEnable.value;
print("state.remoteEnable.value:${state.remoteEnable.value} state.getKeyInfosData.value.remoteEnable:${state.lockSetInfoData.value.lockSettingInfo!.remoteUnlock}");
eventBus.fire(PassCurrentLockInformationEvent(state.lockSetInfoData.value));
});
}
}

View File

@ -41,6 +41,7 @@ class PasswordKeyListLogic extends BaseGetXController {
if (entity.errorCode!.codeIsSuccessful) {
print("重置电子钥匙成功啦啦啦啦啦");
showToast("重置成功");
pageNo = 1;
mockNetworkDataRequest();
}
}
@ -52,6 +53,7 @@ class PasswordKeyListLogic extends BaseGetXController {
.deleteKeyboardPwd(lockId, keyboardPwdId, deleteType);
if (entity.errorCode!.codeIsSuccessful) {
showToast("删除成功");
pageNo = 1;
mockNetworkDataRequest();
}
}
@ -146,6 +148,7 @@ class PasswordKeyListLogic extends BaseGetXController {
void _getPasswordListRefreshUIAction() {
// eventBus
_getPasswordListRefreshUIEvent = eventBus.on<GetPasswordListRefreshUI>().listen((event) {
pageNo = 1;
mockNetworkDataRequest();
});
}

View File

@ -0,0 +1,8 @@
import 'flavors.dart';
import 'main.dart' as runner;
Future<void> main() async {
F.appFlavor = Flavor.dev;
await runner.main();
}

View File

@ -0,0 +1,8 @@
import 'flavors.dart';
import 'main.dart' as runner;
Future<void> main() async {
F.appFlavor = Flavor.pre;
await runner.main();
}

View File

@ -0,0 +1,8 @@
import 'flavors.dart';
import 'main.dart' as runner;
Future<void> main() async {
F.appFlavor = Flavor.sky;
await runner.main();
}

View File

@ -0,0 +1,8 @@
import 'flavors.dart';
import 'main.dart' as runner;
Future<void> main() async {
F.appFlavor = Flavor.xhj;
await runner.main();
}

View File

@ -5,6 +5,7 @@ import 'package:star_lock/appRouters.dart';
import 'package:star_lock/common/XSConstantMacro/XSConstantMacro.dart';
import '../../app_settings/app_colors.dart';
import '../../flavors.dart';
import '../../tools/commonItem.dart';
import '../../tools/titleAppBar.dart';
import '../../translations/trans_lib.dart';
@ -38,12 +39,12 @@ class _AboutPageState extends State<AboutPage> {
),
SizedBox(height: 20.h),
Text(
"星锁 1.0.0.09(preRelease-20240126-1)",
"${F.title} 1.0.0.09(preRelease-20240126-1)",
style: TextStyle(fontSize: 24.sp, color: AppColors.blackColor),
),
SizedBox(height: 20.h),
Text(
Api.baseAddress,
F.apiPrefix,
style: TextStyle(fontSize: 24.sp, color: AppColors.blackColor),
),
SizedBox(

View File

@ -1,4 +1,3 @@
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
@ -6,7 +5,6 @@ import 'package:star_lock/tools/noData.dart';
import '../../../appRouters.dart';
import '../../../app_settings/app_colors.dart';
import '../../../network/api_repository.dart';
import '../../../tools/EasyRefreshTool.dart';
import '../../../tools/dateTool.dart';
import '../../../tools/titleAppBar.dart';
@ -79,7 +77,7 @@ class _MessageListPageState extends State<MessageListPage> with TickerProviderSt
),
],
),
child: _selectGatewayListListItem(messageItemEntity, () {
child: _messageListItem(messageItemEntity, () {
Get.toNamed(Routers.messageDetailPage, arguments: {"messageItemEntity": messageItemEntity});
}),
);
@ -90,51 +88,51 @@ class _MessageListPageState extends State<MessageListPage> with TickerProviderSt
);
}
Widget _selectGatewayListListItem(MessageItemEntity messageItemEntity, Function() action) {
Widget _messageListItem(MessageItemEntity messageItemEntity, Function() action) {
return GestureDetector(
onTap: action,
child: Container(
height: 90.h,
width: 1.sw,
margin: EdgeInsets.only(bottom: 2.h),
// padding:
// EdgeInsets.only(left: 10.w, right: 20.w, top: 20.h, bottom: 20.h),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10.w),
),
child: Row(
children: [
SizedBox(
width: 20.w,
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
child: Container(
width: 1.sw,
margin: EdgeInsets.only(left: 20.w, right: 20.w),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
SizedBox(
width: 1.sw - 20.w*2,
child: Flexible(
child: Text(
messageItemEntity.data!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 22.sp, color: messageItemEntity.readAt! == 0 ? AppColors.blackColor : AppColors.placeholderTextColor),
),
],
),
),
SizedBox(height: 10.h),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
// Image.asset('images/mine/icon_mine_gatewaySignal_strong.png', width: 40.w, height: 40.w,),
// SizedBox(width: 10.w,),
Text(DateTool().dateToYMDHNString(messageItemEntity.createdAt!.toString()), style: TextStyle(fontSize: 18.sp, color: messageItemEntity.readAt! == 0 ? AppColors.blackColor : AppColors.placeholderTextColor)),
],
),
SizedBox(width: 20.h),
],
),
)
],
SizedBox(height: 10.h),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
// Image.asset('images/mine/icon_mine_gatewaySignal_strong.png', width: 40.w, height: 40.w,),
// SizedBox(width: 10.w,),
Text(DateTool().dateToYMDHNString(messageItemEntity.createdAt!.toString()), style: TextStyle(fontSize: 18.sp, color: messageItemEntity.readAt! == 0 ? AppColors.blackColor : AppColors.placeholderTextColor)),
],
),
SizedBox(width: 20.h),
],
),
),
),
);

View File

@ -1,11 +1,4 @@
abstract class Api {
// static String baseAddress = "https://pre.lock.star-lock.cn"; //
static String baseAddress = "https://dev.lock.star-lock.cn"; //
// static String baseAddress = "http://192.168.1.15:8022"; //
// static String baseAddress = "https://ge.lock.star-lock.cn"; //
final String baseUrl = "$baseAddress/api";
//
final String getVerificationCodeUrl = '/user/sendValidationCode';
final String registerUrl = '/user/register';

View File

@ -2,6 +2,7 @@ import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get.dart';
import '../appRouters.dart';
import '../flavors.dart';
import 'api.dart';
import 'request_interceptor.dart';
import 'request_interceptor_log.dart';
@ -11,7 +12,7 @@ import 'response_interceptor_log.dart';
class BaseProvider extends GetConnect with Api {
@override
void onInit() {
httpClient.baseUrl = baseUrl;
httpClient.baseUrl = '${F.apiPrefix}/api';
httpClient.addRequestModifier(requestInterceptor);
httpClient.addResponseModifier(responseInterceptor);
httpClient.addRequestModifier(requestLogInterceptor);
@ -32,7 +33,7 @@ class BaseProvider extends GetConnect with Api {
// print("post: url:${url} body:${body} contentType:${contentType} headers:${headers} query:${query}");
if (isUnShowLoading == false) EasyLoading.show();
// print('请求url======>$url');
// print('请求body体======>$body');
print('请求body体======>$body');
var res = await super.post(url, body,
contentType: contentType,
headers: headers,

View File

@ -125,16 +125,18 @@ class ApiRepository {
//
Future<ElectronicKeyListEntity> electronicKeyList(
String endDate,
String keyId,
String keyStatus,
String lockId,
String operatorUid,
String pageNo,
String pageSize,
String startDate,
String keyRight,
String searchStr) async {
{
required String endDate,
required String keyId,
required String keyStatus,
required String lockId,
required String operatorUid,
required String pageNo,
required String pageSize,
required String startDate,
required String keyRight,
required String searchStr
}) async {
final res = await apiProvider.electronicKeyList(endDate, keyId, keyStatus,
lockId, operatorUid, pageNo, pageSize, startDate, keyRight, searchStr);
return ElectronicKeyListEntity.fromJson(res.body);

View File

@ -89,3 +89,8 @@ class GetPasswordListRefreshUI {
class ReadMessageRefreshUI {
ReadMessageRefreshUI();
}
///
class ElectronicKeyListRefreshUI {
ElectronicKeyListRefreshUI();
}

View File

@ -1 +0,0 @@
flutter/ephemeral

View File

@ -1,138 +0,0 @@
# Project-level configuration.
cmake_minimum_required(VERSION 3.10)
project(runner LANGUAGES CXX)
# The name of the executable created for the application. Change this to change
# the on-disk name of your application.
set(BINARY_NAME "star_lock")
# The unique GTK application identifier for this application. See:
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
set(APPLICATION_ID "com.example.star_lock")
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
# versions of CMake.
cmake_policy(SET CMP0063 NEW)
# Load bundled libraries from the lib/ directory relative to the binary.
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
# Root filesystem for cross-building.
if(FLUTTER_TARGET_PLATFORM_SYSROOT)
set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
# Define build configuration options.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Debug" CACHE
STRING "Flutter build mode" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Profile" "Release")
endif()
# Compilation settings that should be applied to most targets.
#
# Be cautious about adding new options here, as plugins use this function by
# default. In most cases, you should add new options to specific targets instead
# of modifying this function.
function(APPLY_STANDARD_SETTINGS TARGET)
target_compile_features(${TARGET} PUBLIC cxx_std_14)
target_compile_options(${TARGET} PRIVATE -Wall -Werror)
target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
endfunction()
# Flutter library and tool build rules.
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
add_subdirectory(${FLUTTER_MANAGED_DIR})
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
# Define the application target. To change its name, change BINARY_NAME above,
# not the value here, or `flutter run` will no longer work.
#
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
# Apply the standard set of build settings. This can be removed for applications
# that need different build settings.
apply_standard_settings(${BINARY_NAME})
# Add dependency libraries. Add any application-specific dependencies here.
target_link_libraries(${BINARY_NAME} PRIVATE flutter)
target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
# Run the Flutter tool portions of the build. This must not be removed.
add_dependencies(${BINARY_NAME} flutter_assemble)
# Only the install-generated bundle's copy of the executable will launch
# correctly, since the resources must in the right relative locations. To avoid
# people trying to run the unbundled copy, put it in a subdirectory instead of
# the default top-level location.
set_target_properties(${BINARY_NAME}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
)
# Generated plugin build rules, which manage building the plugins and adding
# them to the application.
include(flutter/generated_plugins.cmake)
# === Installation ===
# By default, "installing" just makes a relocatable bundle in the build
# directory.
set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
endif()
# Start with a clean build bundle directory every time.
install(CODE "
file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
" COMPONENT Runtime)
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
COMPONENT Runtime)
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
COMPONENT Runtime)
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
install(FILES "${bundled_library}"
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endforeach(bundled_library)
# Fully re-copy the assets directory on each build to avoid having stale files
# from a previous install.
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
install(CODE "
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
" COMPONENT Runtime)
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
# Install the AOT library on non-Debug builds only.
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)
endif()

View File

@ -1,88 +0,0 @@
# This file controls Flutter-level build steps. It should not be edited.
cmake_minimum_required(VERSION 3.10)
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
# Configuration provided via flutter tool.
include(${EPHEMERAL_DIR}/generated_config.cmake)
# TODO: Move the rest of this into files in ephemeral. See
# https://github.com/flutter/flutter/issues/57146.
# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
# which isn't available in 3.10.
function(list_prepend LIST_NAME PREFIX)
set(NEW_LIST "")
foreach(element ${${LIST_NAME}})
list(APPEND NEW_LIST "${PREFIX}${element}")
endforeach(element)
set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
endfunction()
# === Flutter Library ===
# System-level dependencies.
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
# Published to parent scope for install step.
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
list(APPEND FLUTTER_LIBRARY_HEADERS
"fl_basic_message_channel.h"
"fl_binary_codec.h"
"fl_binary_messenger.h"
"fl_dart_project.h"
"fl_engine.h"
"fl_json_message_codec.h"
"fl_json_method_codec.h"
"fl_message_codec.h"
"fl_method_call.h"
"fl_method_channel.h"
"fl_method_codec.h"
"fl_method_response.h"
"fl_plugin_registrar.h"
"fl_plugin_registry.h"
"fl_standard_message_codec.h"
"fl_standard_method_codec.h"
"fl_string_codec.h"
"fl_value.h"
"fl_view.h"
"flutter_linux.h"
)
list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
add_library(flutter INTERFACE)
target_include_directories(flutter INTERFACE
"${EPHEMERAL_DIR}"
)
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
target_link_libraries(flutter INTERFACE
PkgConfig::GTK
PkgConfig::GLIB
PkgConfig::GIO
)
add_dependencies(flutter flutter_assemble)
# === Flutter tool backend ===
# _phony_ is a non-existent file to force this command to run every time,
# since currently there's no way to get a full input/output list from the
# flutter tool.
add_custom_command(
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
${CMAKE_CURRENT_BINARY_DIR}/_phony_
COMMAND ${CMAKE_COMMAND} -E env
${FLUTTER_TOOL_ENVIRONMENT}
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
VERBATIM
)
add_custom_target(flutter_assemble DEPENDS
"${FLUTTER_LIBRARY}"
${FLUTTER_LIBRARY_HEADERS}
)

View File

@ -1,27 +0,0 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
#include <aj_captcha_flutter/aj_captcha_flutter_plugin.h>
#include <audioplayers_linux/audioplayers_linux_plugin.h>
#include <file_selector_linux/file_selector_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) aj_captcha_flutter_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "AjCaptchaFlutterPlugin");
aj_captcha_flutter_plugin_register_with_registrar(aj_captcha_flutter_registrar);
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
}

View File

@ -1,15 +0,0 @@
//
// Generated file. Do not edit.
//
// clang-format off
#ifndef GENERATED_PLUGIN_REGISTRANT_
#define GENERATED_PLUGIN_REGISTRANT_
#include <flutter_linux/flutter_linux.h>
// Registers Flutter plugins.
void fl_register_plugins(FlPluginRegistry* registry);
#endif // GENERATED_PLUGIN_REGISTRANT_

View File

@ -1,27 +0,0 @@
#
# Generated file, do not edit.
#
list(APPEND FLUTTER_PLUGIN_LIST
aj_captcha_flutter
audioplayers_linux
file_selector_linux
url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
)
set(PLUGIN_BUNDLED_LIBRARIES)
foreach(plugin ${FLUTTER_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)

View File

@ -1,6 +0,0 @@
#include "my_application.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}

View File

@ -1,104 +0,0 @@
#include "my_application.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
// Implements GApplication::activate.
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
// Use a header bar when running in GNOME as this is the common style used
// by applications and is the setup most users will be using (e.g. Ubuntu
// desktop).
// If running on X and not using GNOME then just use a traditional title bar
// in case the window manager does more exotic layout, e.g. tiling.
// If running on Wayland assume the header bar will work (may need changing
// if future cases occur).
gboolean use_header_bar = TRUE;
#ifdef GDK_WINDOWING_X11
GdkScreen* screen = gtk_window_get_screen(window);
if (GDK_IS_X11_SCREEN(screen)) {
const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
use_header_bar = FALSE;
}
}
#endif
if (use_header_bar) {
GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
gtk_widget_show(GTK_WIDGET(header_bar));
gtk_header_bar_set_title(header_bar, "star_lock");
gtk_header_bar_set_show_close_button(header_bar, TRUE);
gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
} else {
gtk_window_set_title(window, "star_lock");
}
gtk_window_set_default_size(window, 1280, 720);
gtk_widget_show(GTK_WIDGET(window));
g_autoptr(FlDartProject) project = fl_dart_project_new();
fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
FlView* view = fl_view_new(project);
gtk_widget_show(GTK_WIDGET(view));
gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
fl_register_plugins(FL_PLUGIN_REGISTRY(view));
gtk_widget_grab_focus(GTK_WIDGET(view));
}
// Implements GApplication::local_command_line.
static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
MyApplication* self = MY_APPLICATION(application);
// Strip out the first argument as it is the binary name.
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr;
if (!g_application_register(application, nullptr, &error)) {
g_warning("Failed to register: %s", error->message);
*exit_status = 1;
return TRUE;
}
g_application_activate(application);
*exit_status = 0;
return TRUE;
}
// Implements GObject::dispose.
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
}
static void my_application_init(MyApplication* self) {}
MyApplication* my_application_new() {
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID,
"flags", G_APPLICATION_NON_UNIQUE,
nullptr));
}

Some files were not shown because too many files have changed in this diff Show More