Browse Source

image or other file message send use qiniu, and only send fileUrl.

wr_202303
zsw 4 months ago
parent
commit
56ad10156c
  1. 15
      lib/constant.dart
  2. 56
      lib/im/SocketClient.dart
  3. 24
      lib/im/chat_details_page.dart
  4. 4
      lib/main.dart
  5. 2
      lib/retrofit/data/address.dart
  6. 4
      lib/retrofit/min_api.dart
  7. 11
      lib/retrofit/retrofit_api.dart
  8. 23
      lib/retrofit/retrofit_api.g.dart
  9. 3
      lib/setting/about_page.dart
  10. 80
      lib/utils/qiniu.dart
  11. 50
      pubspec.lock
  12. 8
      pubspec.yaml

15
lib/constant.dart

@ -1,4 +1,19 @@
import 'package:flutter/foundation.dart';
const String chatImageHost = "http://skk8mlm5b.hn-bkt.clouddn.com/";
//47.93.216.24:9090 线 192.168.10.129:9090
const String socketHost = kDebugMode ? '192.168.10.129' : '47.93.216.24';
const num socketPort = 9090;
const ipBaseUrl = "http://whois.pconline.com.cn";
const localMiniBaseUrl = "http://192.168.10.54:8765/app/";///
const serviceMiniBaseUrl = "https://pos.api.lotus-wallet.com/app/";///线
const localBaseUrl = "http://192.168.10.54:8766/app/";///
const serviceBaseUrl = "https://pos.platform.lotus-wallet.com/app/";///线
Map<S, List<T>> groupBy<S, T>(Iterable<T> values, S Function(T) key) {

56
lib/im/SocketClient.dart

@ -1,11 +1,12 @@
import 'dart:async';
import 'dart:convert';
import 'dart:core';
import 'dart:core';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/constant.dart';
import 'package:huixiang/im/Proto.dart';
import 'package:huixiang/im/database/message.dart';
import 'package:huixiang/im/out/auth.pb.dart';
@ -17,9 +18,6 @@ import 'package:shared_preferences/shared_preferences.dart';
class SocketClient {
//47.93.216.24:9090 线 192.168.10.129:9090
final String ip = kDebugMode ? '192.168.10.129' : '47.93.216.24';
final num port = 9090;
Socket _socket;
SharedPreferences _shared;
Timer timer;
@ -34,8 +32,8 @@ class SocketClient {
}
showDebugToast("socket-connect .... ");
await Socket.connect(ip, port).then((value) {
debugPrint("socket-connect-$ip");
await Socket.connect(socketHost, socketPort).then((value) {
debugPrint("socket-connect-$socketHost");
_socket = value;
_socket.listen((data) {
print(data);
@ -77,34 +75,18 @@ class SocketClient {
}
Future<Map<String, dynamic>> receiveInsertMessage(MsgData dataResult) async {
String content = "";
String attach = "";
Uint8List dataBytes = dataResult.data;
String content = utf8.decode(dataBytes);
String attach = "";
MsgType type = MsgType.values[dataResult.type.value];
if (type == MsgType.TEXT) {
content = utf8.decode(dataBytes);
} else if (type == MsgType.IMAGE || type == MsgType.VIDEO) {
Map<String, dynamic> result = await ImageGallerySaver.saveImage(
dataBytes,
isReturnImagePathOfIOS: true,
);
if (type == MsgType.IMAGE || type == MsgType.VIDEO || type == MsgType.AUDIO) {
String filePath = await qiniu.downloadFile(content);
Map<String, dynamic> result = await ImageGallerySaver.saveFile(filePath).catchError((error){});
bool isSuccess = result["isSuccess"] != null && result["isSuccess"];
if (isSuccess) {
attach = result["filePath"];
}
} else if (type == MsgType.AUDIO) {
Directory dir = await getTemporaryDirectory();
File file = File("${dir.path}/hx_${DateTime.now().millisecondsSinceEpoch}.wav");
try {
IOSink ioSink = file.openWrite();
ioSink.write(dataBytes);
ioSink.close();
attach = file.path;
} catch (e) {
debugPrint("${file.path} write fail");
}
} else {
content = "暂不支持的消息格式";
attach = filePath;
}
Map<String, dynamic> messageMap = createMessage(userId, content, attach: attach, msgType: type.value, fromId: dataResult.from);
@ -210,19 +192,13 @@ class SocketClient {
Future<Message> sendMessage(String toId, String content, {String attach, int msgType = 1, replyId}) async {
MsgType type = MsgType.values[msgType];
Uint8List data;
if (type == MsgType.TEXT) {
data = utf8.encode(content);
} else if (type == MsgType.IMAGE || type == MsgType.VIDEO || type == MsgType.AUDIO) {
Uint8List data = utf8.encode(content);
if (type == MsgType.IMAGE || type == MsgType.VIDEO || type == MsgType.AUDIO) {
File file = File(attach);
Directory dir = await getTemporaryDirectory();
File newFile = await file.copy("${dir.path}/hx_${DateTime.now().millisecondsSinceEpoch}.${file.path.split(".")[1]}");
data = await file.readAsBytes();
File newFile = await file.copy("${dir.path}/hx_${attach.split('/').last}");
attach = newFile.path;
} else {
data = utf8.encode(content);
}
Map<String, dynamic> message = createMessage(toId, content, fromId: userId, attach: attach, msgType: msgType, replyId: replyId);
message["state"] = 1;
int id = await hxDatabase.insert(message).catchError((error) {

24
lib/im/chat_details_page.dart

@ -5,9 +5,7 @@ import 'dart:ui';
import 'package:dio/dio.dart';
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@ -15,17 +13,16 @@ import 'package:huixiang/im/database/message.dart';
import 'package:huixiang/main.dart';
import 'package:huixiang/retrofit/data/im_user.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:huixiang/utils/qiniu.dart';
import 'package:huixiang/view_widget/classic_header.dart';
import 'package:huixiang/view_widget/my_appbar.dart';
import 'package:flutter/cupertino.dart';
import 'package:huixiang/view_widget/my_footer.dart';
import 'package:image_pickers/image_pickers.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../community/release_dynamic.dart';
import '../../generated/l10n.dart';
import '../../utils/font_weight.dart';
import '../community/photo_view_gallery_screen.dart';
import '../retrofit/data/base_data.dart';
import '../retrofit/data/user_info.dart';
import '../utils/flutter_utils.dart';
@ -137,6 +134,8 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
///
queryUser() async {
final SharedPreferences value = await SharedPreferences.getInstance();
if (apiService == null)
apiService = ApiService(Dio(), context: context, token: value.getString("token"));
if (value.containsKey('user') &&
value.getString('user') != null &&
value.getString('user') != "") {
@ -146,9 +145,6 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
return;
}
}
if (apiService == null)
apiService =
ApiService(Dio(), context: context, token: value.getString("token"));
BaseData<UserInfo> baseData =
await apiService.queryInfo().catchError((onError) {});
if (baseData != null && baseData.isSuccess) {
@ -317,8 +313,9 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
}
List<String> filePath = mediaPaths.map((e) => e.path).toList();
filePath.forEach((path) {
socketClient.sendMessage(_toUser.mid, "", attach: path, msgType: galleryMode == GalleryMode.image ? 2 : 4);
Future.forEach(filePath.toSet(), (path) async {
String fileUrl = await qiniu.uploadFile(apiService, path);
socketClient.sendMessage(_toUser.mid, fileUrl, attach: path, msgType: galleryMode == GalleryMode.image ? 2 : 4);
});
}
@ -970,7 +967,6 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
return completer.future;
}
//
resizeImage(Size size) {
if (size.width > 180 || size.height > 200) {
if (size.width > size.height) {
@ -1063,9 +1059,9 @@ class _ChatDetailsPage extends State<ChatDetailsPage>
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
// _onMoreTap();
// jumpToBottom();
SmartDialog.showToast("暂不支持", alignment: Alignment.center);
_onMoreTap();
jumpToBottom();
// SmartDialog.showToast("暂不支持", alignment: Alignment.center);
},
child: Container(
padding: EdgeInsets.only(left: 8.w, right: 19.w),

4
lib/main.dart

@ -78,6 +78,7 @@ import 'package:huixiang/test_page.dart';
import 'package:huixiang/union/location_map_page.dart';
import 'package:huixiang/union/union_select_city.dart';
import 'package:huixiang/utils/ImgCachePath.dart';
import 'package:huixiang/utils/qiniu.dart';
import 'package:huixiang/vip/user_vip_service_page.dart';
import 'package:huixiang/web/web_page.dart';
@ -235,7 +236,8 @@ closeDatabase() async {
}
final SocketClient socketClient = new SocketClient();
EventBus eventBus = EventBus(sync: true);
final Qiniu qiniu = Qiniu();
final EventBus eventBus = EventBus(sync: true);
Route lastRoutePage;
class MyApp extends StatelessWidget {

2
lib/retrofit/data/address.dart

@ -20,7 +20,7 @@ class Address {
factory Address.fromJson(Map<String, dynamic> json) => Address()
..address = json['address'] as String
..area = json['area'] as String
..city = json['city'] as String
..city = (json['city'] is List<dynamic>) ? [] : json['city'] as String
..cityInfo = json['cityInfo'] as String
..id = json['id'] as String
..isDefault = json['isDefault'] as bool

4
lib/retrofit/min_api.dart

@ -4,6 +4,7 @@ import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:huixiang/constant.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/retrofit/data/address.dart';
import 'package:huixiang/retrofit/data/base_data.dart';
@ -27,9 +28,6 @@ import 'data/shopping_home_config.dart';
part 'min_api.g.dart';
const localBaseUrl = "http://192.168.10.54:8765/app/";///
// const localBaseUrl = "http://pos-test.api.lotus-wallet.com/app/";///
const serviceBaseUrl = "https://pos.api.lotus-wallet.com/app/";///线
///

11
lib/retrofit/retrofit_api.dart

@ -7,6 +7,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:huixiang/constant.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:huixiang/retrofit/data/activity.dart';
import 'package:huixiang/retrofit/data/article.dart';
@ -66,17 +67,10 @@ import 'data/vip_benefit_list.dart';
import 'data/vip_card.dart';
import 'data/vip_card_home.dart';
import 'data/vip_rule_details.dart';
import 'data/wx_pay.dart';
part 'retrofit_api.g.dart';
const localBaseUrl = "http://192.168.10.54:8766/app/";///
// const localBaseUrl = "http://platform.test.api.lotus-wallet.com/app/";///
const serviceBaseUrl = "https://pos.platform.lotus-wallet.com/app/";///线
const ipBaseUrl = "http://whois.pconline.com.cn";
///ip
@RestApi(baseUrl: localBaseUrl)
abstract class ApiService {
@ -664,4 +658,7 @@ abstract class ApiService {
Future<BaseData<List<ImUser>>> memberSearch(
@Path("keyword") String keyword);
@GET("/config/qiniuToken")
Future<BaseData<String>> getQiniuToken();
}

23
lib/retrofit/retrofit_api.g.dart

@ -2576,4 +2576,27 @@ class _ApiService implements ApiService {
.toList());
return value;
}
@override
Future<BaseData<String>> getQiniuToken() async {
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
final _result = await _dio.request<Map<String, dynamic>>(
'/config/qiniuToken',
queryParameters: queryParameters,
options: RequestOptions(
method: 'GET',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl,
),
data: _data,
);
final value = BaseData<String>.fromJson(
_result.data,
(json) => json);
return value;
}
}

3
lib/setting/about_page.dart

@ -4,6 +4,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:huixiang/constant.dart';
import 'package:huixiang/generated/l10n.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:huixiang/main.dart';
@ -87,7 +88,7 @@ class _AboutPage extends State<AboutPage> {
height: 20.h,
),
if (kDebugMode)
textItem("ip: ${socketClient.ip}\nport: ${socketClient.port}\nid: ${socketClient.userId}"),
textItem("ip: $socketHost\nport: $socketPort\nid: ${socketClient.userId}"),
GestureDetector(
onTap: (){
// updateApp();

80
lib/utils/qiniu.dart

@ -0,0 +1,80 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:huixiang/constant.dart';
import 'package:huixiang/retrofit/data/base_data.dart';
import 'package:huixiang/retrofit/retrofit_api.dart';
import 'package:path_provider/path_provider.dart';
import 'package:qiniu_flutter_sdk/qiniu_flutter_sdk.dart';
class Qiniu {
Storage storage = Storage(config: Config());
PutController putController = PutController();
progressListener() {
//
putController.addProgressListener((double percent) {
print('任务进度变化:已发送:$percent');
});
//
putController.addSendProgressListener((double percent) {
print('已上传进度变化:已发送:$percent');
});
//
putController.addStatusListener((StorageStatus status) {
print('状态变化: 当前任务状态:$status');
});
}
Future<String> uploadFile(ApiService apiService, String filePath) async {
String token = await _getToken(apiService);
File file = File(filePath);
PutResponse putResponse = await storage.putFile(file, token, options: PutOptions(
controller: putController,
key: filePath.split('/').last,
));
debugPrint("qiniuToken-result: ${putResponse.toJson()}");
return "$chatImageHost/${putResponse.key}";
}
Future<String> _getToken(ApiService apiService) async {
BaseData<String> baseData = await apiService.getQiniuToken()
.catchError((error){
debugPrint("getQiniuToken: $error");
});
if (baseData.isSuccess) {
return baseData.data;
} else {
debugPrint("get token fail, check network");
throw Error();
}
}
Dio dio = Dio();
Future<String> downloadFile(String urlPath) async {
Directory dir = await getTemporaryDirectory();
File newFile = File("${dir.path}/hx_${urlPath.split('/').last}");
Response response = await dio.download(urlPath, newFile.path);
if (response.statusCode == 200) {
return newFile.path;
}
return null;
}
}

50
pubspec.lock

@ -25,14 +25,6 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.4.2"
asn1lib:
dependency: transitive
description:
name: asn1lib
sha256: b74e3842a52c61f8819a1ec8444b4de5419b41a7465e69d4aa681445377398b0
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.1"
async:
dependency: transitive
description:
@ -141,18 +133,18 @@ packages:
dependency: transitive
description:
name: convert
sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592"
sha256: "3fa83bc417e26f1d55814443a603747d48e3cdf55b2f4fea27dea8e9224dcefd"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.1.1"
version: "2.1.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
sha256: "3ce628f3c6a7144be6c524dbb20ca5af52fa59c850c587bf5e52cd70ece8e7e8"
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.3"
version: "2.1.5"
csslib:
dependency: transitive
description:
@ -185,14 +177,6 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.1"
encrypt:
dependency: "direct main"
description:
name: encrypt
sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb"
url: "https://pub.flutter-io.cn"
source: hosted
version: "5.0.1"
equatable:
dependency: transitive
description:
@ -573,14 +557,6 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.8.0"
mqtt_client:
dependency: "direct main"
description:
name: mqtt_client
sha256: ba10ec490ded55dc4e77bbc992529d823fb15d0d5ec68c2895f960312060c541
url: "https://pub.flutter-io.cn"
source: hosted
version: "9.8.1"
nested:
dependency: transitive
description:
@ -761,10 +737,10 @@ packages:
dependency: transitive
description:
name: pointycastle
sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c"
sha256: a74ed4039c152dd319514f142768d93ad3973860b240d90160cec727c8155f65
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.7.3"
version: "3.0.1"
protobuf:
dependency: "direct main"
description:
@ -789,6 +765,20 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "2.0.0"
qiniu_flutter_sdk:
dependency: "direct main"
description:
path: "qiniu-dart-sdk/flutter"
relative: true
source: path
version: "0.2.0"
qiniu_sdk_base:
dependency: transitive
description:
path: "qiniu-dart-sdk/base"
relative: true
source: path
version: "0.2.2"
qr:
dependency: transitive
description:

8
pubspec.yaml

@ -63,7 +63,7 @@ dependencies:
visibility_detector: ^0.3.3
steel_crypt: ^3.0.0+1
encrypt: ^5.0.1
# encrypt: any
event_bus: ^2.0.0
intl: ^0.17.0
@ -115,18 +115,18 @@ dependencies:
emoji_picker_flutter: ^1.4.1
mqtt_client: ^9.6.8
shimmer: ^3.0.0
# 时间选择器
flutter_datetime_picker: ^1.5.1
qiniu_flutter_sdk:
path: qiniu-dart-sdk/flutter
widgetpicker: ^0.1.1
# floor: ^1.4.2
sqflite: ^2.2.2
syncfusion_flutter_datepicker: ^19.4.38
protobuf: ^3.1.0
dev_dependencies:

Loading…
Cancel
Save