Browse Source

集成数据库和打印机(未完结)

周素华 10 months ago
parent
commit
241da78369

+ 9 - 0
android/app/build.gradle

@@ -32,6 +32,12 @@ android {
32 32
         targetCompatibility JavaVersion.VERSION_1_8
33 33
     }
34 34
 
35
+    sourceSets {
36
+        main {
37
+            jniLibs.srcDirs = ['jniLibs']
38
+        }
39
+    }
40
+
35 41
     defaultConfig {
36 42
         applicationId "com.szls.lszlgl"
37 43
         // You can update the following values to match your application needs.
@@ -95,6 +101,9 @@ android {
95 101
         implementation files('libs/LPAPI-2019-11-20-R.jar')
96 102
         implementation files('libs/image-1.8.4.6.aar')
97 103
 
104
+        // btp打印机库
105
+        implementation files('libs/LabelPrinterJavaSDK.jar')
106
+
98 107
         //权限库
99 108
         implementation 'com.guolindev.permissionx:permissionx:1.7.1'
100 109
     }

BIN
android/app/libs/LabelPrinterJavaSDK.jar


+ 32 - 110
android/app/src/main/java/io/flutter/plugins/BluetoothPlugin.java

@@ -50,6 +50,7 @@ import io.flutter.plugin.common.MethodChannel;
50 50
 import io.flutter.plugin.common.EventChannel.EventSink;
51 51
 import io.flutter.plugin.common.EventChannel.StreamHandler;
52 52
 import io.flutter.plugins.bean.BlueDeviceInfo;
53
+import io.flutter.plugins.utils.BTPPrintUtil;
53 54
 import io.flutter.plugins.utils.BluetoothUtils;
54 55
 import io.flutter.plugins.utils.PrintUtil;
55 56
 
@@ -152,27 +153,23 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
152 153
                 startBluetoothPair(methodCall, result);
153 154
                 break;
154 155
             case "startBluetoothConnect":
155
-                Log.d("ble", "startBluetoothConnect :"+methodCall.arguments);
156
+                Log.d("ble", "startBluetoothConnect :" + methodCall.arguments);
156 157
                 startBluetoothConnect(methodCall, result);
157 158
                 break;
158 159
             case "endBluetoothConnect":
159
-                Log.d("ble", "endBluetoothConnect :"+methodCall.arguments);
160
+                Log.d("ble", "endBluetoothConnect :" + methodCall.arguments);
160 161
                 endBluetoothConnect(methodCall, result);
161 162
                 break;
162 163
             case "hasBluetoothConnectDevice":
163
-                Log.d("ble", "hasBluetoothConnectDevice :"+methodCall.arguments);
164
+                Log.d("ble", "hasBluetoothConnectDevice :" + methodCall.arguments);
164 165
                 hasBluetoothConnectDevice(methodCall, result);
165 166
                 break;
166 167
             case "startBluetoothPrint":
167
-                Log.d("ble", "startBluetoothPrint :"+methodCall.arguments);
168
+                Log.d("ble", "startBluetoothPrint :" + methodCall.arguments);
168 169
                 startBluetoothPrint(methodCall, result);
169 170
                 break;
170 171
 
171 172
 
172
-
173
-
174
-
175
-
176 173
             case "autoLogin":
177 174
 
178 175
                 break;
@@ -245,10 +242,10 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
245 242
 
246 243
         String deviceInfo = methodCall.arguments.toString();
247 244
         String[] deviceInfoList = deviceInfo.split(delimiterStr);
248
-        for(int i =0; i < deviceInfoList.length ; i++) {
249
-            Log.d("ble", i+":"+deviceInfoList[i]);
245
+        for (int i = 0; i < deviceInfoList.length; i++) {
246
+            Log.d("ble", i + ":" + deviceInfoList[i]);
250 247
         }
251
-        Log.d("ble", "startBluetoothPair : ---"+deviceInfo + "----0:"+deviceInfoList[0]);
248
+        Log.d("ble", "startBluetoothPair : ---" + deviceInfo + "----0:" + deviceInfoList[0]);
252 249
         itemPosition = new BlueDeviceInfo(deviceInfoList[0], deviceInfoList[1], Integer.parseInt(deviceInfoList[2]));
253 250
         BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(itemPosition.getDeviceHardwareAddress());
254 251
 
@@ -275,18 +272,24 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
275 272
 
276 273
         String deviceInfo = methodCall.arguments.toString();
277 274
         String[] deviceInfoList = deviceInfo.split(delimiterStr);
278
-        for(int i =0; i < deviceInfoList.length ; i++){
279
-            Log.d("ble", i+":"+deviceInfoList[i]);
275
+        for (int i = 0; i < deviceInfoList.length; i++) {
276
+            Log.d("ble", i + ":" + deviceInfoList[i]);
280 277
         }
281
-        Log.d("ble", "startBluetoothConnect : ---"+deviceInfo + "----0:"+deviceInfoList[0]);
278
+        Log.d("ble", "startBluetoothConnect : ---" + deviceInfo + "----0:" + deviceInfoList[0]);
282 279
         itemPosition = new BlueDeviceInfo(deviceInfoList[0], deviceInfoList[1], Integer.parseInt(deviceInfoList[2]));
283 280
         BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(itemPosition.getDeviceHardwareAddress());
284 281
 
285 282
         executorService.submit(() -> {
286 283
             BlueDeviceInfo blueDeviceInfo = new BlueDeviceInfo(bluetoothDevice.getName(), bluetoothDevice.getAddress(), itemPosition.getConnectState());
287 284
             PrintUtil.setConnectedType(-1);
288
-            int connectResult = PrintUtil.connectBluetoothPrinter(blueDeviceInfo.getDeviceHardwareAddress());
289
-            Log.d("ble", "测试:连接结果 " + connectResult);
285
+            int connectResult = 1;
286
+            if (blueDeviceInfo.getDeviceName().contains("BTP")) {
287
+                BTPPrintUtil btpPrintUtil = new BTPPrintUtil();
288
+                connectResult = btpPrintUtil.connectBluetoothPrinter(blueDeviceInfo.getDeviceHardwareAddress());
289
+            } else {
290
+                connectResult = PrintUtil.connectBluetoothPrinter(blueDeviceInfo.getDeviceHardwareAddress());
291
+            }
292
+            Log.d("ble", "测试:连接结果 " + connectResult); // 0是成功
290 293
             result.success(connectResult);
291 294
         });
292 295
     }
@@ -297,11 +300,11 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
297 300
     }
298 301
 
299 302
     void hasBluetoothConnectDevice(@NonNull MethodCall methodCall, @NonNull MethodChannel.Result result) {
300
-        if (PrintUtil.isConnection() == 0 && PrintUtil.getConnectedType()==0) {
301
-            Log.d("ble", "测试:配对状态改变:判断连接状态 2" );
302
-             result.success(true);
303
-        }else {
304
-            Log.d("ble", "测试:配对状态改变:判断连接状态4 " );
303
+        if (PrintUtil.isConnection() == 0 && PrintUtil.getConnectedType() == 0) {
304
+            Log.d("ble", "测试:配对状态改变:判断连接状态 2");
305
+            result.success(true);
306
+        } else {
307
+            Log.d("ble", "测试:配对状态改变:判断连接状态4 ");
305 308
             result.success(false);
306 309
         }
307 310
     }
@@ -313,98 +316,17 @@ public class BluetoothPlugin implements FlutterPlugin, MethodChannel.MethodCallH
313 316
         Log.d("ble", "imageByte:" + imageByte);
314 317
         Bitmap bitmap = Bytes2Bimap(imageByte);
315 318
 
316
-        PrintUtil.getInstance().drawEmptyLabel(40, 60, 0, "");
317
-        if (PrintUtil.isConnection() != 0) {
318
-//            handler.post(() -> Toast.makeText(MyApplication.getInstance(), "未连接打印机", Toast.LENGTH_SHORT).show());
319
+        BluetoothDevice bluetoothDevice = mBluetoothAdapter.getRemoteDevice(itemPosition.getDeviceHardwareAddress());
320
+        if (ActivityCompat.checkSelfPermission(_applicationContext, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
319 321
             return;
320 322
         }
323
+        BlueDeviceInfo blueDeviceInfo = new BlueDeviceInfo(bluetoothDevice.getName(), bluetoothDevice.getAddress(), itemPosition.getConnectState());
324
+        if(blueDeviceInfo.getDeviceName().contains("BTP")) {
321 325
 
322
-//        fragment = new MyDialogLoadingFragment("打印中");
323
-//        fragment.show(getSupportFragmentManager(), "PRINT");
324
-
325
-
326
-        //重置错误状态变量
327
-        boolean isError = false;
328
-        //重置取消打印状态变量
329
-        boolean isCancel = false;
330
-
331
-        int orientation = 0;
332
-
333
-        int pageCount = 1;
334
-        int quantity = 1;
335
-        int printMultiple = 8;
336
-        final int[] generatedPrintDataPageCount = {0};
337
-        int totalQuantity = pageCount * quantity;
338
-
339
-        //setTotalQuantityOfPrints已废弃,使用方法含义更明确的setTotalPrintQuantity
340
-        PrintUtil.getInstance().setTotalPrintQuantity(totalQuantity);
341
-        /*
342
-         * 参数1:打印浓度 ,参数2:纸张类型 参数3:打印模式
343
-         * 打印浓度 B50/B50W/T6/T7/T8 建议设置6或8,Z401/B32建议设置8,B3S/B21/B203/B1建议设置3
344
-         */
345
-        PrintUtil.getInstance().startPrintJob(3, 3, 1, new PrintCallback() {
346
-            @Override
347
-            public void onProgress(int pageIndex, int quantityIndex, HashMap<String, Object> hashMap) {
348
-//                handler.post(() -> fragment.setStateStr("打印进度:已打印到第" + pageIndex + "页,第" + quantityIndex + "份"));
349
-                Log.d("ble", "测试:打印进度:已打印到第: " + pageIndex);
350
-                //打印进度回调
351
-                if (pageIndex == pageCount && quantityIndex == quantity) {
352
-                    Log.d("ble", "测试:onProgress: 结束打印");
353
-                    //endJob已废弃,使用方法含义更明确的endPrintJob
354
-                    if (PrintUtil.getInstance().endPrintJob()) {
355
-                        Log.d("ble", "结束打印成功");
356
-                    } else {
357
-                        Log.d("ble", "结束打印失败");
358
-                    }
359
-//                    handlePrintResult(fragment, "打印成功");
360
-                }
361
-            }
362
-
363
-            @Override
364
-            public void onError(int i) {
365
-
366
-            }
367
-
368
-
369
-            @Override
370
-            public void onError(int errorCode, int printState) {
371
-                Log.d("ble", "测试:onError");
372
-//                isError = true;
373
-//                String errorMsg = ERROR_MESSAGES.getOrDefault(errorCode, "");
374
-//                handlePrintResult(fragment, errorMsg);
375
-            }
376
-
377
-            @Override
378
-            public void onCancelJob(boolean isSuccess) {
379
-                //取消打印成功回调
380
-//                isCancel = true;
381
-            }
382
-
383
-            @Override
384
-            public void onBufferFree(int pageIndex, int bufferSize) {
385
-                if (isError || isCancel || pageIndex > pageCount) {
386
-                    return;
387
-                }
388
-
389
-                if (generatedPrintDataPageCount[0] < pageCount) {
390
-//                    ArrayList<Dish> dishList = new ArrayList<>();
391
-//                    dishList.add(new Dish("辣椒炒肉", "中辣", 29.9, 1));
392
-//                    dishList.add(new Dish("土豆牛腩", "中辣", 49.9, 1));
393
-//
394
-//                    Bitmap bitmap = ImgUtil.Companion.generatePosReceiptImage(dishList);
395
-
396
-                    int bitmapWidth = bitmap.getWidth();
397
-                    int bitmapHeight = bitmap.getHeight();
398
-                    Log.d("ble", "bitmapWidth:"+bitmapWidth+",bitmapHeight:"+bitmapHeight);
399
-                    PrintUtil.getInstance().commitImageData(orientation, bitmap, (int) (bitmapWidth / printMultiple), (int) (bitmapHeight / printMultiple), 1, 0, 0, 0, 0, "");
400
-
401
-
402
-                }
403
-
404
-
405
-            }
406
-        });
407
-
326
+            BTPPrintUtil.printBitMap(imageByte, bitmap.getWidth(), bitmap.getHeight(), result);
327
+        } else {
328
+            PrintUtil.printBitMap(bitmap, result);
329
+        }
408 330
     }
409 331
 
410 332
     public Bitmap Bytes2Bimap(byte[] b) {

+ 62 - 0
android/app/src/main/java/io/flutter/plugins/utils/BTPPrintUtil.java

@@ -0,0 +1,62 @@
1
+package io.flutter.plugins.utils;
2
+
3
+import android.graphics.Bitmap;
4
+import android.graphics.BitmapFactory;
5
+import android.util.Log;
6
+
7
+import androidx.annotation.NonNull;
8
+
9
+import com.snbc.sdk.LabelPrinter;
10
+
11
+import io.flutter.plugin.common.MethodChannel;
12
+
13
+public class BTPPrintUtil {
14
+
15
+
16
+    /**
17
+     * 单例实例,使用 volatile 保证多线程可见性和有序性
18
+     */
19
+    private static volatile LabelPrinter labelPrinter;
20
+
21
+    private static int nLang = 2;
22
+
23
+    /**
24
+     * 获取 LabelPrinter 单例实例
25
+     *
26
+     * @return LabelPrinter 实例
27
+     */
28
+    public  LabelPrinter getInstance() {
29
+        // 双重检查锁定以确保只初始化一次实例
30
+        if (labelPrinter == null) {
31
+            synchronized (BTPPrintUtil.class) {
32
+                if (labelPrinter == null) {
33
+                    labelPrinter = new LabelPrinter();
34
+                }
35
+            }
36
+        }
37
+
38
+        return labelPrinter;
39
+    }
40
+
41
+    /**
42
+     * 通过打印机mac地址进行蓝牙连接开启打印机(同步)
43
+     *
44
+     * @param address 打印机地址
45
+     * @return 成功与否
46
+     */
47
+    public  int connectBluetoothPrinter(String address) {
48
+        LabelPrinter   labelPrinter = new LabelPrinter();
49
+//        return 1;
50
+        // 获取单例实例以确保线程安全
51
+        return labelPrinter.ConnectPrinter(7, "04:7F:0E:AD:20:3A", 2);
52
+    }
53
+
54
+    public static void printBitMap(byte[] imageByte, int bitmapWidth, int bitmapHeight, @NonNull MethodChannel.Result result) {
55
+
56
+//        result.success(1);
57
+        Log.d("ble", "bitmapWidth:"+bitmapWidth+",bitmapHeight:"+bitmapHeight);
58
+//        int code = getInstance().PrintImageData(bitmapWidth, bitmapHeight, imageByte);
59
+//        result.success(code);
60
+    }
61
+
62
+}

+ 88 - 0
android/app/src/main/java/io/flutter/plugins/utils/PrintUtil.java

@@ -11,6 +11,8 @@ import android.graphics.Paint;
11 11
 import android.util.Log;
12 12
 import android.widget.Toast;
13 13
 
14
+import androidx.annotation.NonNull;
15
+
14 16
 import com.gengcon.www.jcprintersdk.JCPrintApi;
15 17
 import com.gengcon.www.jcprintersdk.callback.Callback;
16 18
 import com.gengcon.www.jcprintersdk.callback.PrintCallback;
@@ -19,8 +21,11 @@ import com.szls.lszlgl.app.MyApplication;
19 21
 import java.io.File;
20 22
 import java.io.InputStream;
21 23
 import java.util.ArrayList;
24
+import java.util.HashMap;
22 25
 import java.util.List;
23 26
 
27
+import io.flutter.plugin.common.MethodChannel;
28
+
24 29
 /**
25 30
  * 打印工具类
26 31
  *
@@ -210,5 +215,88 @@ public class PrintUtil {
210 215
         return localApi.isConnection();
211 216
     }
212 217
 
218
+    public static void printBitMap(Bitmap bitmap, @NonNull MethodChannel.Result result) {
219
+        if (PrintUtil.isConnection() != 0) {
220
+//            handler.post(() -> Toast.makeText(MyApplication.getInstance(), "未连接打印机", Toast.LENGTH_SHORT).show());
221
+            result.success(1);
222
+            return;
223
+        }
224
+
225
+//        fragment = new MyDialogLoadingFragment("打印中");
226
+//        fragment.show(getSupportFragmentManager(), "PRINT");
227
+
228
+
229
+        //重置错误状态变量
230
+        boolean isError = false;
231
+        //重置取消打印状态变量
232
+        boolean isCancel = false;
233
+
234
+        int orientation = 0;
235
+
236
+        int pageCount = 1;
237
+        int quantity = 1;
238
+        int printMultiple = 8;
239
+        final int[] generatedPrintDataPageCount = {0};
240
+        int totalQuantity = pageCount * quantity;
241
+
242
+        //setTotalQuantityOfPrints已废弃,使用方法含义更明确的setTotalPrintQuantity
243
+        PrintUtil.getInstance().setTotalPrintQuantity(totalQuantity);
244
+        /*
245
+         * 参数1:打印浓度 ,参数2:纸张类型 参数3:打印模式
246
+         * 打印浓度 B50/B50W/T6/T7/T8 建议设置6或8,Z401/B32建议设置8,B3S/B21/B203/B1建议设置3
247
+         */
248
+        PrintUtil.getInstance().startPrintJob(3, 3, 1, new PrintCallback() {
249
+            @Override
250
+            public void onProgress(int pageIndex, int quantityIndex, HashMap<String, Object> hashMap) {
251
+//                handler.post(() -> fragment.setStateStr("打印进度:已打印到第" + pageIndex + "页,第" + quantityIndex + "份"));
252
+                Log.d("ble", "测试:打印进度:已打印到第: " + pageIndex);
253
+                //打印进度回调
254
+                if (pageIndex == pageCount && quantityIndex == quantity) {
255
+                    Log.d("ble", "测试:onProgress: 结束打印");
256
+                    //endJob已废弃,使用方法含义更明确的endPrintJob
257
+                    if (PrintUtil.getInstance().endPrintJob()) {
258
+                        Log.d("ble", "结束打印成功");
259
+                    } else {
260
+                        Log.d("ble", "结束打印失败");
261
+                    }
262
+                    result.success(0);
263
+                }
264
+            }
265
+
266
+            @Override
267
+            public void onError(int i) {
268
+                result.success(i == 0 ? 1 : i);
269
+            }
270
+
271
+
272
+            @Override
273
+            public void onError(int errorCode, int printState) {
274
+                Log.d("ble", "测试:onError");
275
+                result.success(errorCode == 0 ? 1 : errorCode);
276
+            }
277
+
278
+            @Override
279
+            public void onCancelJob(boolean isSuccess) {
280
+                //取消打印成功回调
281
+                result.success(1);
282
+            }
283
+
284
+            @Override
285
+            public void onBufferFree(int pageIndex, int bufferSize) {
286
+                if (isError || isCancel || pageIndex > pageCount) {
287
+                    result.success(1);
288
+                }
289
+
290
+                if (generatedPrintDataPageCount[0] < pageCount) {
291
+
292
+                    int bitmapWidth = bitmap.getWidth();
293
+                    int bitmapHeight = bitmap.getHeight();
294
+                    Log.d("ble", "bitmapWidth:"+bitmapWidth+",bitmapHeight:"+bitmapHeight);
295
+                    PrintUtil.getInstance().commitImageData(orientation, bitmap, (int) (bitmapWidth / printMultiple), (int) (bitmapHeight / printMultiple), 1, 0, 0, 0, 0, "");
296
+                }
297
+            }
298
+        });
299
+    }
300
+
213 301
 
214 302
 }

+ 17 - 0
lib/drfit/dao/device_info_table_dao.dart

@@ -0,0 +1,17 @@
1
+import 'package:drift/drift.dart';
2
+import 'package:lszlgl/drfit/database.dart';
3
+import 'package:lszlgl/drfit/device_info_table.dart';
4
+
5
+part 'device_info_table_dao.g.dart';
6
+
7
+@DriftAccessor(tables: [DeviceInfoTable])
8
+class DeviceInfoTableDao extends DatabaseAccessor<MyDatabase> {
9
+  DeviceInfoTableDao(MyDatabase db) : super(db);
10
+
11
+  Future<int> addOneDeviceComp(DeviceInfoTableCompanion deviceInfoTableCompanion) async {
12
+    return into(db.deviceInfoTable).insert(deviceInfoTableCompanion);
13
+  }
14
+
15
+
16
+
17
+}

+ 8 - 0
lib/drfit/dao/device_info_table_dao.g.dart

@@ -0,0 +1,8 @@
1
+// GENERATED CODE - DO NOT MODIFY BY HAND
2
+
3
+part of 'device_info_table_dao.dart';
4
+
5
+// ignore_for_file: type=lint
6
+mixin _$DeviceInfoTableDaoMixin on DatabaseAccessor<MyDatabase> {
7
+  $DeviceInfoTableTable get deviceInfoTable => attachedDatabase.deviceInfoTable;
8
+}

+ 40 - 0
lib/drfit/database.dart

@@ -0,0 +1,40 @@
1
+import 'dart:io';
2
+
3
+import 'package:drift/drift.dart';
4
+import 'package:drift/native.dart';
5
+import 'package:lszlgl/main.dart';
6
+import 'package:path_provider/path_provider.dart';
7
+import 'package:path/path.dart' as p;
8
+
9
+import 'dao/device_info_table_dao.dart';
10
+import 'device_info_table.dart';
11
+
12
+
13
+part 'database.g.dart';
14
+
15
+@DriftDatabase(tables: [DeviceInfoTable], daos: [DeviceInfoTableDao])
16
+class MyDatabase extends _$MyDatabase {
17
+  MyDatabase() : super(_openConnection());
18
+  // MyDatabase(super.e);
19
+
20
+
21
+  @override
22
+  int get schemaVersion => 1;
23
+}
24
+
25
+LazyDatabase _openConnection() {
26
+
27
+  getApplicationDocumentsDirectory().then((value) {
28
+    logger.d('==============zhouzhou 111 ${value.path}');
29
+  });
30
+
31
+
32
+  return LazyDatabase(() async {
33
+    logger.d('==============zhouzhou');
34
+
35
+    final documentsDir = await getApplicationDocumentsDirectory();
36
+    final file = File(p.join(documentsDir.path, 'db.sqlite'));
37
+
38
+    return NativeDatabase.createInBackground(file);
39
+  });
40
+}

+ 419 - 0
lib/drfit/database.g.dart

@@ -0,0 +1,419 @@
1
+// GENERATED CODE - DO NOT MODIFY BY HAND
2
+
3
+part of 'database.dart';
4
+
5
+// ignore_for_file: type=lint
6
+class $DeviceInfoTableTable extends DeviceInfoTable
7
+    with TableInfo<$DeviceInfoTableTable, DeviceInfo> {
8
+  @override
9
+  final GeneratedDatabase attachedDatabase;
10
+  final String? _alias;
11
+  $DeviceInfoTableTable(this.attachedDatabase, [this._alias]);
12
+  static const VerificationMeta _usernameMeta =
13
+      const VerificationMeta('username');
14
+  @override
15
+  late final GeneratedColumn<String> username = GeneratedColumn<String>(
16
+      'username', aliasedName, false,
17
+      type: DriftSqlType.string, requiredDuringInsert: true);
18
+  static const VerificationMeta _phoneMeta = const VerificationMeta('phone');
19
+  @override
20
+  late final GeneratedColumn<String> phone = GeneratedColumn<String>(
21
+      'phone', aliasedName, false,
22
+      type: DriftSqlType.string, requiredDuringInsert: true);
23
+  static const VerificationMeta _bleMacMeta = const VerificationMeta('bleMac');
24
+  @override
25
+  late final GeneratedColumn<String> bleMac = GeneratedColumn<String>(
26
+      'ble_mac', aliasedName, false,
27
+      type: DriftSqlType.string, requiredDuringInsert: true);
28
+  static const VerificationMeta _bleNameMeta =
29
+      const VerificationMeta('bleName');
30
+  @override
31
+  late final GeneratedColumn<String> bleName = GeneratedColumn<String>(
32
+      'ble_name', aliasedName, false,
33
+      type: DriftSqlType.string, requiredDuringInsert: true);
34
+  @override
35
+  List<GeneratedColumn> get $columns => [username, phone, bleMac, bleName];
36
+  @override
37
+  String get aliasedName => _alias ?? actualTableName;
38
+  @override
39
+  String get actualTableName => $name;
40
+  static const String $name = 'device_info_table';
41
+  @override
42
+  VerificationContext validateIntegrity(Insertable<DeviceInfo> instance,
43
+      {bool isInserting = false}) {
44
+    final context = VerificationContext();
45
+    final data = instance.toColumns(true);
46
+    if (data.containsKey('username')) {
47
+      context.handle(_usernameMeta,
48
+          username.isAcceptableOrUnknown(data['username']!, _usernameMeta));
49
+    } else if (isInserting) {
50
+      context.missing(_usernameMeta);
51
+    }
52
+    if (data.containsKey('phone')) {
53
+      context.handle(
54
+          _phoneMeta, phone.isAcceptableOrUnknown(data['phone']!, _phoneMeta));
55
+    } else if (isInserting) {
56
+      context.missing(_phoneMeta);
57
+    }
58
+    if (data.containsKey('ble_mac')) {
59
+      context.handle(_bleMacMeta,
60
+          bleMac.isAcceptableOrUnknown(data['ble_mac']!, _bleMacMeta));
61
+    } else if (isInserting) {
62
+      context.missing(_bleMacMeta);
63
+    }
64
+    if (data.containsKey('ble_name')) {
65
+      context.handle(_bleNameMeta,
66
+          bleName.isAcceptableOrUnknown(data['ble_name']!, _bleNameMeta));
67
+    } else if (isInserting) {
68
+      context.missing(_bleNameMeta);
69
+    }
70
+    return context;
71
+  }
72
+
73
+  @override
74
+  Set<GeneratedColumn> get $primaryKey => {bleMac};
75
+  @override
76
+  DeviceInfo map(Map<String, dynamic> data, {String? tablePrefix}) {
77
+    final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
78
+    return DeviceInfo(
79
+      username: attachedDatabase.typeMapping
80
+          .read(DriftSqlType.string, data['${effectivePrefix}username'])!,
81
+      phone: attachedDatabase.typeMapping
82
+          .read(DriftSqlType.string, data['${effectivePrefix}phone'])!,
83
+      bleMac: attachedDatabase.typeMapping
84
+          .read(DriftSqlType.string, data['${effectivePrefix}ble_mac'])!,
85
+      bleName: attachedDatabase.typeMapping
86
+          .read(DriftSqlType.string, data['${effectivePrefix}ble_name'])!,
87
+    );
88
+  }
89
+
90
+  @override
91
+  $DeviceInfoTableTable createAlias(String alias) {
92
+    return $DeviceInfoTableTable(attachedDatabase, alias);
93
+  }
94
+}
95
+
96
+class DeviceInfo extends DataClass implements Insertable<DeviceInfo> {
97
+  /// 登录用户名
98
+  final String username;
99
+
100
+  /// 登录手机型号
101
+  final String phone;
102
+
103
+  /// 登录蓝牙mac地址
104
+  final String bleMac;
105
+
106
+  /// 登录蓝牙名称
107
+  final String bleName;
108
+  const DeviceInfo(
109
+      {required this.username,
110
+      required this.phone,
111
+      required this.bleMac,
112
+      required this.bleName});
113
+  @override
114
+  Map<String, Expression> toColumns(bool nullToAbsent) {
115
+    final map = <String, Expression>{};
116
+    map['username'] = Variable<String>(username);
117
+    map['phone'] = Variable<String>(phone);
118
+    map['ble_mac'] = Variable<String>(bleMac);
119
+    map['ble_name'] = Variable<String>(bleName);
120
+    return map;
121
+  }
122
+
123
+  DeviceInfoTableCompanion toCompanion(bool nullToAbsent) {
124
+    return DeviceInfoTableCompanion(
125
+      username: Value(username),
126
+      phone: Value(phone),
127
+      bleMac: Value(bleMac),
128
+      bleName: Value(bleName),
129
+    );
130
+  }
131
+
132
+  factory DeviceInfo.fromJson(Map<String, dynamic> json,
133
+      {ValueSerializer? serializer}) {
134
+    serializer ??= driftRuntimeOptions.defaultSerializer;
135
+    return DeviceInfo(
136
+      username: serializer.fromJson<String>(json['username']),
137
+      phone: serializer.fromJson<String>(json['phone']),
138
+      bleMac: serializer.fromJson<String>(json['bleMac']),
139
+      bleName: serializer.fromJson<String>(json['bleName']),
140
+    );
141
+  }
142
+  @override
143
+  Map<String, dynamic> toJson({ValueSerializer? serializer}) {
144
+    serializer ??= driftRuntimeOptions.defaultSerializer;
145
+    return <String, dynamic>{
146
+      'username': serializer.toJson<String>(username),
147
+      'phone': serializer.toJson<String>(phone),
148
+      'bleMac': serializer.toJson<String>(bleMac),
149
+      'bleName': serializer.toJson<String>(bleName),
150
+    };
151
+  }
152
+
153
+  DeviceInfo copyWith(
154
+          {String? username, String? phone, String? bleMac, String? bleName}) =>
155
+      DeviceInfo(
156
+        username: username ?? this.username,
157
+        phone: phone ?? this.phone,
158
+        bleMac: bleMac ?? this.bleMac,
159
+        bleName: bleName ?? this.bleName,
160
+      );
161
+  @override
162
+  String toString() {
163
+    return (StringBuffer('DeviceInfo(')
164
+          ..write('username: $username, ')
165
+          ..write('phone: $phone, ')
166
+          ..write('bleMac: $bleMac, ')
167
+          ..write('bleName: $bleName')
168
+          ..write(')'))
169
+        .toString();
170
+  }
171
+
172
+  @override
173
+  int get hashCode => Object.hash(username, phone, bleMac, bleName);
174
+  @override
175
+  bool operator ==(Object other) =>
176
+      identical(this, other) ||
177
+      (other is DeviceInfo &&
178
+          other.username == this.username &&
179
+          other.phone == this.phone &&
180
+          other.bleMac == this.bleMac &&
181
+          other.bleName == this.bleName);
182
+}
183
+
184
+class DeviceInfoTableCompanion extends UpdateCompanion<DeviceInfo> {
185
+  final Value<String> username;
186
+  final Value<String> phone;
187
+  final Value<String> bleMac;
188
+  final Value<String> bleName;
189
+  final Value<int> rowid;
190
+  const DeviceInfoTableCompanion({
191
+    this.username = const Value.absent(),
192
+    this.phone = const Value.absent(),
193
+    this.bleMac = const Value.absent(),
194
+    this.bleName = const Value.absent(),
195
+    this.rowid = const Value.absent(),
196
+  });
197
+  DeviceInfoTableCompanion.insert({
198
+    required String username,
199
+    required String phone,
200
+    required String bleMac,
201
+    required String bleName,
202
+    this.rowid = const Value.absent(),
203
+  })  : username = Value(username),
204
+        phone = Value(phone),
205
+        bleMac = Value(bleMac),
206
+        bleName = Value(bleName);
207
+  static Insertable<DeviceInfo> custom({
208
+    Expression<String>? username,
209
+    Expression<String>? phone,
210
+    Expression<String>? bleMac,
211
+    Expression<String>? bleName,
212
+    Expression<int>? rowid,
213
+  }) {
214
+    return RawValuesInsertable({
215
+      if (username != null) 'username': username,
216
+      if (phone != null) 'phone': phone,
217
+      if (bleMac != null) 'ble_mac': bleMac,
218
+      if (bleName != null) 'ble_name': bleName,
219
+      if (rowid != null) 'rowid': rowid,
220
+    });
221
+  }
222
+
223
+  DeviceInfoTableCompanion copyWith(
224
+      {Value<String>? username,
225
+      Value<String>? phone,
226
+      Value<String>? bleMac,
227
+      Value<String>? bleName,
228
+      Value<int>? rowid}) {
229
+    return DeviceInfoTableCompanion(
230
+      username: username ?? this.username,
231
+      phone: phone ?? this.phone,
232
+      bleMac: bleMac ?? this.bleMac,
233
+      bleName: bleName ?? this.bleName,
234
+      rowid: rowid ?? this.rowid,
235
+    );
236
+  }
237
+
238
+  @override
239
+  Map<String, Expression> toColumns(bool nullToAbsent) {
240
+    final map = <String, Expression>{};
241
+    if (username.present) {
242
+      map['username'] = Variable<String>(username.value);
243
+    }
244
+    if (phone.present) {
245
+      map['phone'] = Variable<String>(phone.value);
246
+    }
247
+    if (bleMac.present) {
248
+      map['ble_mac'] = Variable<String>(bleMac.value);
249
+    }
250
+    if (bleName.present) {
251
+      map['ble_name'] = Variable<String>(bleName.value);
252
+    }
253
+    if (rowid.present) {
254
+      map['rowid'] = Variable<int>(rowid.value);
255
+    }
256
+    return map;
257
+  }
258
+
259
+  @override
260
+  String toString() {
261
+    return (StringBuffer('DeviceInfoTableCompanion(')
262
+          ..write('username: $username, ')
263
+          ..write('phone: $phone, ')
264
+          ..write('bleMac: $bleMac, ')
265
+          ..write('bleName: $bleName, ')
266
+          ..write('rowid: $rowid')
267
+          ..write(')'))
268
+        .toString();
269
+  }
270
+}
271
+
272
+abstract class _$MyDatabase extends GeneratedDatabase {
273
+  _$MyDatabase(QueryExecutor e) : super(e);
274
+  _$MyDatabaseManager get managers => _$MyDatabaseManager(this);
275
+  late final $DeviceInfoTableTable deviceInfoTable =
276
+      $DeviceInfoTableTable(this);
277
+  late final DeviceInfoTableDao deviceInfoTableDao =
278
+      DeviceInfoTableDao(this as MyDatabase);
279
+  @override
280
+  Iterable<TableInfo<Table, Object?>> get allTables =>
281
+      allSchemaEntities.whereType<TableInfo<Table, Object?>>();
282
+  @override
283
+  List<DatabaseSchemaEntity> get allSchemaEntities => [deviceInfoTable];
284
+}
285
+
286
+typedef $$DeviceInfoTableTableInsertCompanionBuilder = DeviceInfoTableCompanion
287
+    Function({
288
+  required String username,
289
+  required String phone,
290
+  required String bleMac,
291
+  required String bleName,
292
+  Value<int> rowid,
293
+});
294
+typedef $$DeviceInfoTableTableUpdateCompanionBuilder = DeviceInfoTableCompanion
295
+    Function({
296
+  Value<String> username,
297
+  Value<String> phone,
298
+  Value<String> bleMac,
299
+  Value<String> bleName,
300
+  Value<int> rowid,
301
+});
302
+
303
+class $$DeviceInfoTableTableTableManager extends RootTableManager<
304
+    _$MyDatabase,
305
+    $DeviceInfoTableTable,
306
+    DeviceInfo,
307
+    $$DeviceInfoTableTableFilterComposer,
308
+    $$DeviceInfoTableTableOrderingComposer,
309
+    $$DeviceInfoTableTableProcessedTableManager,
310
+    $$DeviceInfoTableTableInsertCompanionBuilder,
311
+    $$DeviceInfoTableTableUpdateCompanionBuilder> {
312
+  $$DeviceInfoTableTableTableManager(
313
+      _$MyDatabase db, $DeviceInfoTableTable table)
314
+      : super(TableManagerState(
315
+          db: db,
316
+          table: table,
317
+          filteringComposer:
318
+              $$DeviceInfoTableTableFilterComposer(ComposerState(db, table)),
319
+          orderingComposer:
320
+              $$DeviceInfoTableTableOrderingComposer(ComposerState(db, table)),
321
+          getChildManagerBuilder: (p) =>
322
+              $$DeviceInfoTableTableProcessedTableManager(p),
323
+          getUpdateCompanionBuilder: ({
324
+            Value<String> username = const Value.absent(),
325
+            Value<String> phone = const Value.absent(),
326
+            Value<String> bleMac = const Value.absent(),
327
+            Value<String> bleName = const Value.absent(),
328
+            Value<int> rowid = const Value.absent(),
329
+          }) =>
330
+              DeviceInfoTableCompanion(
331
+            username: username,
332
+            phone: phone,
333
+            bleMac: bleMac,
334
+            bleName: bleName,
335
+            rowid: rowid,
336
+          ),
337
+          getInsertCompanionBuilder: ({
338
+            required String username,
339
+            required String phone,
340
+            required String bleMac,
341
+            required String bleName,
342
+            Value<int> rowid = const Value.absent(),
343
+          }) =>
344
+              DeviceInfoTableCompanion.insert(
345
+            username: username,
346
+            phone: phone,
347
+            bleMac: bleMac,
348
+            bleName: bleName,
349
+            rowid: rowid,
350
+          ),
351
+        ));
352
+}
353
+
354
+class $$DeviceInfoTableTableProcessedTableManager extends ProcessedTableManager<
355
+    _$MyDatabase,
356
+    $DeviceInfoTableTable,
357
+    DeviceInfo,
358
+    $$DeviceInfoTableTableFilterComposer,
359
+    $$DeviceInfoTableTableOrderingComposer,
360
+    $$DeviceInfoTableTableProcessedTableManager,
361
+    $$DeviceInfoTableTableInsertCompanionBuilder,
362
+    $$DeviceInfoTableTableUpdateCompanionBuilder> {
363
+  $$DeviceInfoTableTableProcessedTableManager(super.$state);
364
+}
365
+
366
+class $$DeviceInfoTableTableFilterComposer
367
+    extends FilterComposer<_$MyDatabase, $DeviceInfoTableTable> {
368
+  $$DeviceInfoTableTableFilterComposer(super.$state);
369
+  ColumnFilters<String> get username => $state.composableBuilder(
370
+      column: $state.table.username,
371
+      builder: (column, joinBuilders) =>
372
+          ColumnFilters(column, joinBuilders: joinBuilders));
373
+
374
+  ColumnFilters<String> get phone => $state.composableBuilder(
375
+      column: $state.table.phone,
376
+      builder: (column, joinBuilders) =>
377
+          ColumnFilters(column, joinBuilders: joinBuilders));
378
+
379
+  ColumnFilters<String> get bleMac => $state.composableBuilder(
380
+      column: $state.table.bleMac,
381
+      builder: (column, joinBuilders) =>
382
+          ColumnFilters(column, joinBuilders: joinBuilders));
383
+
384
+  ColumnFilters<String> get bleName => $state.composableBuilder(
385
+      column: $state.table.bleName,
386
+      builder: (column, joinBuilders) =>
387
+          ColumnFilters(column, joinBuilders: joinBuilders));
388
+}
389
+
390
+class $$DeviceInfoTableTableOrderingComposer
391
+    extends OrderingComposer<_$MyDatabase, $DeviceInfoTableTable> {
392
+  $$DeviceInfoTableTableOrderingComposer(super.$state);
393
+  ColumnOrderings<String> get username => $state.composableBuilder(
394
+      column: $state.table.username,
395
+      builder: (column, joinBuilders) =>
396
+          ColumnOrderings(column, joinBuilders: joinBuilders));
397
+
398
+  ColumnOrderings<String> get phone => $state.composableBuilder(
399
+      column: $state.table.phone,
400
+      builder: (column, joinBuilders) =>
401
+          ColumnOrderings(column, joinBuilders: joinBuilders));
402
+
403
+  ColumnOrderings<String> get bleMac => $state.composableBuilder(
404
+      column: $state.table.bleMac,
405
+      builder: (column, joinBuilders) =>
406
+          ColumnOrderings(column, joinBuilders: joinBuilders));
407
+
408
+  ColumnOrderings<String> get bleName => $state.composableBuilder(
409
+      column: $state.table.bleName,
410
+      builder: (column, joinBuilders) =>
411
+          ColumnOrderings(column, joinBuilders: joinBuilders));
412
+}
413
+
414
+class _$MyDatabaseManager {
415
+  final _$MyDatabase _db;
416
+  _$MyDatabaseManager(this._db);
417
+  $$DeviceInfoTableTableTableManager get deviceInfoTable =>
418
+      $$DeviceInfoTableTableTableManager(_db, _db.deviceInfoTable);
419
+}

+ 17 - 0
lib/drfit/device_info_table.dart

@@ -0,0 +1,17 @@
1
+import 'package:drift/drift.dart';
2
+
3
+@DataClassName('DeviceInfo')
4
+class DeviceInfoTable extends Table {
5
+
6
+  /// 登录用户名
7
+  TextColumn get username => text()();
8
+  /// 登录手机型号
9
+  TextColumn get phone => text()();
10
+  /// 登录蓝牙mac地址
11
+  TextColumn get bleMac => text()();
12
+  /// 登录蓝牙名称
13
+  TextColumn get bleName => text()();
14
+
15
+  @override
16
+  Set<Column<Object>>? get primaryKey => {bleMac};
17
+}

+ 21 - 0
lib/drfit/model_factory.dart

@@ -0,0 +1,21 @@
1
+
2
+
3
+import 'package:drift/drift.dart';
4
+import 'package:lszlgl/drfit/database.dart';
5
+
6
+import '../model/rsp/user_rsp.dart';
7
+import '../service/user_service.dart';
8
+
9
+class ModelFactory {
10
+  static DeviceInfoTableCompanion convertToTSlideComp(String bleMac, String bleName) {
11
+    UserRsp? userRsp =  UserService.get().getUser();
12
+    var tsc = DeviceInfoTableCompanion(
13
+      username: Value.absentIfNull(userRsp?.username),
14
+      phone: const Value.absentIfNull(''),
15
+      bleMac: Value(bleMac),
16
+      bleName: Value(bleName),
17
+    );
18
+    return tsc;
19
+  }
20
+
21
+}

+ 12 - 0
lib/main.dart

@@ -1,4 +1,7 @@
1 1
 import 'dart:async';
2
+import 'dart:io';
3
+import 'package:drift/drift.dart' as drift;
4
+import 'package:drift/native.dart';
2 5
 import 'package:flutter/foundation.dart';
3 6
 import 'package:flutter/material.dart';
4 7
 import 'package:flutter/services.dart';
@@ -6,18 +9,27 @@ import 'package:flutter_localizations/flutter_localizations.dart';
6 9
 import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
7 10
 import 'package:logger/logger.dart';
8 11
 import 'package:lszlgl/config/colors.dart';
12
+import 'package:lszlgl/drfit/database.dart';
9 13
 import 'package:lszlgl/router/my_navigator.dart';
14
+import 'package:path_provider/path_provider.dart';
15
+import 'package:path/path.dart' as p;
10 16
 
11 17
 late Logger logger;
18
+late MyDatabase database;
12 19
 
13 20
 void main() async {
14 21
   logger = Logger(printer: PrettyPrinter(methodCount: 0));
22
+
23
+  database = MyDatabase();
24
+  // database = MyDatabase(NativeDatabase.memory());
25
+
15 26
   initReportException(() async {
16 27
     SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light.copyWith(statusBarColor: Colors.transparent));
17 28
     SystemChrome.setPreferredOrientations([
18 29
       DeviceOrientation.portraitUp,
19 30
       DeviceOrientation.portraitDown,
20 31
     ]);
32
+
21 33
     runApp(const MyApp());
22 34
   });
23 35
 }

+ 1 - 1
lib/model/req/login_req.g.dart

@@ -9,7 +9,7 @@ part of 'login_req.dart';
9 9
 LoginReq _$LoginReqFromJson(Map<String, dynamic> json) => LoginReq(
10 10
       username: json['username'] as String?,
11 11
       password: json['password'] as String?,
12
-      platform: json['platform'] as int? ?? 1,
12
+      platform: (json['platform'] as num?)?.toInt() ?? 1,
13 13
     );
14 14
 
15 15
 Map<String, dynamic> _$LoginReqToJson(LoginReq instance) => <String, dynamic>{

+ 5 - 5
lib/model/req/sample_task_list_req.g.dart

@@ -8,13 +8,13 @@ part of 'sample_task_list_req.dart';
8 8
 
9 9
 SampleTaskListReq _$SampleTaskListReqFromJson(Map<String, dynamic> json) =>
10 10
     SampleTaskListReq(
11
-      pageNo: json['pageNo'] as int? ?? 1,
12
-      pageSize: json['pageSize'] as int? ?? 10,
13
-      deliveryStatus: json['deliveryStatus'] as int?,
14
-      rwlx: json['rwlx'] as int?,
11
+      pageNo: (json['pageNo'] as num?)?.toInt() ?? 1,
12
+      pageSize: (json['pageSize'] as num?)?.toInt() ?? 10,
13
+      deliveryStatus: (json['deliveryStatus'] as num?)?.toInt(),
14
+      rwlx: (json['rwlx'] as num?)?.toInt(),
15 15
       cypzName: json['cypzName'] as String?,
16 16
       jyzb: json['jyzb'] as String?,
17
-      ypdj: json['ypdj'] as int?,
17
+      ypdj: (json['ypdj'] as num?)?.toInt(),
18 18
       qydq: json['qydq'] as String?,
19 19
     );
20 20
 

+ 1 - 1
lib/page/login/login_page.dart

@@ -83,7 +83,7 @@ class _LoginPageState extends BaseLifecycleState<LoginPage> {
83 83
 
84 84
   @override
85 85
   void onFirstShow(Duration timeStamp) async {
86
-    MyNavigator.showLoading();
86
+    // MyNavigator.showLoading();
87 87
 
88 88
     /// 初始化基础库 start
89 89
     BaseDio.get().init();

+ 12 - 0
lib/page/print/connect_print_page.dart

@@ -1,6 +1,7 @@
1 1
 import 'package:flutter/material.dart';
2 2
 import 'package:flutter/services.dart';
3 3
 import 'package:lszlgl/base/base_lifecycle_state.dart';
4
+import 'package:lszlgl/drfit/model_factory.dart';
4 5
 import 'package:lszlgl/main.dart';
5 6
 import 'package:lszlgl/service/print_service.dart';
6 7
 import 'package:lszlgl/widget/loading_widget.dart';
@@ -8,6 +9,7 @@ import 'package:lszlgl/widget/page_widget.dart';
8 9
 import 'package:signature/signature.dart';
9 10
 import 'package:lszlgl/widget/button.dart';
10 11
 
12
+import '../../drfit/database.dart';
11 13
 import '../../plugin/bluetooth_plugin.dart';
12 14
 import '../home/home_page.dart';
13 15
 
@@ -70,6 +72,11 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
70 72
     await PrintService.startBluetoothDiscovery();
71 73
   }
72 74
 
75
+  Future<int> savaToSqlite(BlueDeviceInfo deviceInfo) async {
76
+    DeviceInfoTableCompanion tableCompanion = ModelFactory.convertToTSlideComp(deviceInfo.deviceMac, deviceInfo.deviceName);
77
+    return await database.deviceInfoTableDao.addOneDeviceComp(tableCompanion);
78
+  }
79
+
73 80
   /// 去连接
74 81
   Future<void> startConnect(BlueDeviceInfo deviceInfo) async {
75 82
     if(deviceInfo.connectStateStr == '未配对') {
@@ -82,6 +89,8 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
82 89
         MyNavigator.dismiss();
83 90
         MyNavigator.showToast('连接成功');
84 91
         deviceInfo.connectSuccess();
92
+        //addOneSlideComp
93
+
85 94
         if(deviceMacList.contains(deviceInfo.deviceMac)) {
86 95
           setState(() {
87 96
             deviceMacList.removeWhere((element) => element == deviceInfo.deviceMac);
@@ -92,6 +101,7 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
92 101
           PrintService.connectedDeviceMacList.add(deviceInfo.deviceMac);
93 102
           PrintService.connectedDeviceList.add(deviceInfo);
94 103
         });
104
+        await savaToSqlite(deviceInfo); // 保存记录到数据库
95 105
       } else {
96 106
         MyNavigator.dismiss();
97 107
         MyNavigator.showToast('连接失败');
@@ -114,6 +124,8 @@ class _ConnectPrintPageState extends BaseLifecycleState<ConnectPrintPage> {
114 124
     }
115 125
   }
116 126
 
127
+
128
+
117 129
   @override
118 130
   void onInit() {
119 131
 

+ 1 - 0
pubspec.yaml

@@ -107,6 +107,7 @@ dev_dependencies:
107 107
   build_runner: '>=2.3.0 <4.0.0'
108 108
   # JSON转实体类
109 109
   json_serializable: ^6.6.2
110
+  drift_dev: ^2.2.0
110 111
 
111 112
 # For information on the generic Dart part of this file, see the
112 113
 # following page: https://dart.dev/tools/pub/pubspec