提交 6e0c824f authored 作者: JarvanMo's avatar JarvanMo

create docs

上级 3555761d
## 2.0.0
* 代码重构,现在代码结构更清晰
* 所有图片由WeChatImage构建
* 现在iOS对分享微信小程序的高清图也会压缩
* 微信回调监听形式变更
* Android增加新的Action以防微信打开小程序出错不会返回原app的问题
## 1.2.1+2
* iOS的StringUtil重命名了
## 1.2.1+1
* Fix #178
## 1.2.1
* Fix #175
## 1.2.0
* 分享文件
* compileSdkVersion 29
## 1.1.4
* 注册微信时会对universal link进行简单校验
## 1.1.3
* Fix #146
## 1.1.2
* Fix #122
## 1.1.1+1
* Android CompileSDKVersion 提升到28
### 1.1.1
* registerWxApi
## 1.1.0
* iOS SDK升级至1.8.6.1,本版本开始支持universal link。
* Android SDK更换至without-mat:5.4.3
* Android配置升级
* 移除MTA选项
## 1.0.6
* Fix #110
## 1.0.5
* 增加分享内存图片
## 1.0.4
* 解决Android上打开小程序返回白屏问题(非官方解决方案)
## 1.0.3
* 修复一些小问题
## 1.0.2
* 修复无法Android上分享大图的问题
## 1.0.1
* 修复一些小问题
## 1.0.0
* ios不必再重写AppDelegate
## 0.6.3
* 免密支付
* 支持打开微信App了
* 升级了Android
## 0.6.2
* 对android进行了升级
## 0.6.1
* 支持二维码登录
## 0.6.0
* kotlin升级至1.3.21。
* ios SDK升级至1.8.4。
* android SDK升级至5.3.6。
## 0.5.7
* 修复问题43。
## 0.5.6
## 0.5.5
* 修复ios分享小程序标题不正确的问题。
## 0.5.4
* 增加一次性订阅消息功能。
## 0.5.3
* 修复唤起小程序返回值类型不一致的问题。
## 0.5.2
* 修复ios上sendAuth无返回的问题。
* kotlin升级至1.3.10
* android WeChatSDK升级到5.1.6
## 0.5.1
* Kotlin升级到了1.3.0
* 代码格化
## 0.5.0
* 增加了对拉起小程序的支持
* 删除了一些不必要的类
* 发送Auth验证Api调整
## 0.4.1
* 修复iOS与其他库共存时,会有重复的错误
## 0.4.0
* 移除WeChatPayModel
* 移除ios最小支持。
* 优化*Android*微信回调。
* *build.gradle*升级到了*3.2.1*
## 0.3.2
* *build.gradle*升级到了*3.2.0*
* *kotlin*升级到了*1.2.71*
## 0.3.1
* 修复了由于Flutter-dev-0.9.7-pre在android中添加了*@Nullable*注解而引起的编译问题
## 0.3.0
* 回调方式发生变化,由Map变更为实体类。
* iOS的WeChatSDK更换为内部依赖,并升级到了1.8.3。
* 修复iOS支付返回结果缺少*returnKey*的问题。
* API现在更加友善了。
* 对swift支持更友好了。
## 0.2.1
* 修复在Android处理网络图片后缀不对的问题。
## 0.2.0
* iOS支持Swift了。
## 0.1.9
* 修复了不传*thumbnail*在Android上会崩溃的bug。
## 0.1.8
* `WeChatPayModel`里的字段不再是`dynamic`
* 修复了iOS对支付功能中timestamp处理不正确的问题。
## 0.1.7
* 删除`Fluwx.registerApp(RegisterModel)`,现在使用`Fluwx.register()`
## 0.1.6
* 修复transitive dependencies。
## 0.1.5
* 增加了本地图片的支持
## 0.1.4
* 修复了iOS分享去处错误的问题
## 0.1.3
* `ResponseType` 更名为`WeChatResponseType`
## 0.1.2
* 修复iOS中FluwxShareHandler.h的导入问题
## 0.1.1
* 修复iOS分享去处错误的bug
## 0.1.0
* 增加了MTA选项
* Android部分的微信SDK提供方式由implementation更换为api
## 0.0.8
* 修复了iOS无法分享小程序的bug
* 修复了iOS分享音乐崩溃的问题
* 修复了iOS发送Auth偶尔会崩溃的问题
## 0.0.7
* 修复了iOS回调崩溃的bug
## 0.0.6
* 修复iOS拉起支付崩溃的问题
## 0.0.5
* 格式化代码
## 0.0.4
* 支付
* demo
## 0.0.3
* 发送Auth认证。
## 0.0.2
* 文本分享。
* 网站分享。
* 图片分享。
* 音乐分享。
* 视频分享。
* 小程序分享。
## 0.0.1
* TODO: Describe initial release.
* Android部分的分享已完成.
# fluwx
# Fluwx
![pub package](https://img.shields.io/pub/v/fluwx.svg)
[![Build status](https://img.shields.io/cirrus/github/OpenFlutter/fluwx/master)](https://cirrus-ci.com/github/OpenFlutter/fluwx)
======
![logo](https://github.com/JarvanMo/ImagesStore/blob/master/fluwx/fluwx_logo.png)
[中文请移步此处](./README_CN.md)
## What's Fluwx
`Fluwx` is flutter plugin for [WeChatSDK](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html) which allows developers to call
[WeChatSDK](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html) native APIs.
> Join QQ Group now: 892398530。
## Capability
- Share images, texts, music and so on to WeChat, including session, favorite and timeline.
- Payment with WeChat.
- Get auth code before you login in with WeChat.
- Launch mini program in WeChat.
- Subscribe Message.
- Just open WeChat app.
## Preparation
`Fluwx` is good but not God. You'd better read [official documents](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1) before
integrating `Fluwx`. Then you'll understand how to generate Android signature, what's universal link for iOS, how to add URL schema for iOS and so on.
[Watch Charged Video](https://study.163.com/course/introduction.htm?share=2&shareId=480000001896427&courseId=1209174838&_trace_c_p_k2_=e72467dc0df540579287a8ea996344a4)
## Install
Add the following dependencies in your `pubspec.yaml` file:
`Fluwx` with pay:
```yaml
dependencies:
fluwx: ^${latestVersion}
```
![pub package](https://img.shields.io/pub/v/fluwx.svg)
`Fluwx` without pay:
```yaml
dependencies:
fluwx_no_pay: ^${latestVersion}
```
![pub package](https://img.shields.io/pub/v/fluwx_no_pay.svg)
> NOTE: Never forget to replace ^${latestVersion} with actual version.
## Register WxAPI
Register your app via `fluwx` if necessary.
```dart
registerWxApi(appId: "wxd930ea5d5a228f5f",universalLink: "https://your.univerallink.com/link/");
```
The param `universalLink` only works with iOS. You can read [this document](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html) to learn
how to create universalLink. You can also learn how to add URL schema, how to add `LSApplicationQueriesSchemes` in your iOS project. This is essential.
For Android, you shall know to how generate signature for your app in [this page](https://developers.weixin.qq.com/doc/oplatform/Downloads/Android_Resource.html).
And you have to understand the difference between debug signature and release signature. Once the signature is incorrect, then you'll get `errCode = -1`.
## Capability Document
- [Basic knowledge](./docs/BASIC_KNOWLEDGE.md)
- [Share](./docs/SHARE.md)
- [Payment](./dosc/PAYMENT.md)
- [Auth](./docs/AUTH.md)
For more capabilities, you can read the public functions of `fluwx`.
### Donate
Buy the writer a cup of coffee。
<img src="https://github.com/JarvanMo/ImagesStore/blob/master/common/wx.jpeg" height="300"> <img src="https://github.com/JarvanMo/ImagesStore/blob/master/common/ali.jpeg" height="300">
### Subscribe Us On WeChat
![subscribe](https://github.com/JarvanMo/ImagesStore/blob/master/fluwx/wx_subscription.png)
## LICENSE
Copyright 2018 OpenFlutter Project
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
A new Flutter plugin.
## Getting Started
This project is a starting point for a Flutter
[plug-in package](https://flutter.dev/developing-packages/),
a specialized package that includes platform-specific implementation code for
Android and/or iOS.
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
# Fluwx
![pub package](https://img.shields.io/pub/v/fluwx.svg)
[![Build status](https://img.shields.io/cirrus/github/OpenFlutter/fluwx/master)](https://cirrus-ci.com/github/OpenFlutter/fluwx)
======
![logo](https://github.com/JarvanMo/ImagesStore/blob/master/fluwx/fluwx_logo.png)
## 什么是Fluwx
`Fluwx` 是一个[微信SDK](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html)插件,它允许开发者调用
[微信原生SDK ](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Resource_Center_Homepage.html).
> Join QQ Group now: 892398530。
## 能力
- 分享图片,文本,音乐,视频等。支持分享到会话,朋友圈以及收藏.
- 微信支付.
- 在微信登录时,获取Auth Code.
- 拉起小程序.
- 订阅消息.
- 打开微信.
## 准备
`Fluwx` 可以做很多工作但不是所有. 在集成之前,最好读一下[官方文档](https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1).
然后你才知道怎么生成签名,怎么使用universal link以及怎么添加URL schema等.
> [收费视频教程点这里](https://study.163.com/course/introduction.htm?share=2&shareId=480000001896427&courseId=1209174838&_trace_c_p_k2_=e72467dc0df540579287a8ea996344a4)
>
## 安装
`pubspec.yaml` 文件中添加`fluwx`依赖:
`Fluwx`,带支付:
```yaml
dependencies:
fluwx: ^${latestVersion}
```
![pub package](https://img.shields.io/pub/v/fluwx.svg)
`Fluwx`,不带支付:
```yaml
dependencies:
fluwx_no_pay: ^${latestVersion}
```
![pub package](https://img.shields.io/pub/v/fluwx_no_pay.svg)
> NOTE: 别忘记替换 ^${latestVersion} !!!!
## 注册 WxAPI
通过 `fluwx` 注册WxApi.
```dart
registerWxApi(appId: "wxd930ea5d5a228f5f",universalLink: "https://your.univerallink.com/link/");
```
参数 `universalLink` 只在iOS上有用. 查看[文档](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/iOS.html) 以便了解如何生成通用链接.
你也可以学习到怎么在iOS工程中添加URL schema,怎么添加`LSApplicationQueriesSchemes`。这很重要。
对于Android, 可以查看[本文](https://developers.weixin.qq.com/doc/oplatform/Downloads/Android_Resource.html)以便了解怎么获取app签名.
然后你需要知道release和debug时,app签名有什么区别。如果签名不对,你会得一个错误 `errCode = -1`.
## 能力文档
- [基础知识](./docs/BASIC_KNOWLEDGE_CN.md)
- [分享](./docs/SHARE_CN.md)
- [支付](./dosc/PAYMENT_CN.md)
- [登录](./docs/AUTH_CN.md)
对于更多功能,可以查看源码。
### 捐助
开源不易,请作者喝杯咖啡。
<img src="https://github.com/JarvanMo/ImagesStore/blob/master/common/wx.jpeg" height="300"> <img src="https://github.com/JarvanMo/ImagesStore/blob/master/common/ali.jpeg" height="300">
### 关注公众号
![subscribe](https://github.com/JarvanMo/ImagesStore/blob/master/fluwx/wx_subscription.png)
## LICENSE
Copyright 2018 OpenFlutter Project
Licensed to the Apache Software Foundation (ASF) under one or more contributor
license agreements. See the NOTICE file distributed with this work for
additional information regarding copyright ownership. The ASF licenses this
file to you under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
......@@ -4,6 +4,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application>
<activity
......
## AUTH
The purpose of `sendWeChatAuth` is to get auth code and then get information for WeChat login.
Getting `access_token` is not supported in `fluwx`. For `access_token`, please visit [official documents](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html).
```dart
sendWeChatAuth(scope: "snsapi_userinfo", state: "wechat_sdk_demo_test");
```
> WHY? I think we shall fetch access_token or user info at backend.
## 登录
`sendWeChatAuth`的目的是为了获取code,拿到了code才能进行微信登录,可以通过[官方文档](https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html)查看具体流程。
```dart
sendWeChatAuth(scope: "snsapi_userinfo", state: "wechat_sdk_demo_test");
```
> 为什么不支持获取用户信息? 我认为获取用户信息应该后端来做,即使没有后端,你也可以在dart层自己实现.
## Basic knowledge
### Response from WeChat
Actually, almost every result from functions like `shareToWeChat` or `payWithWeChat` which call `sendRequest` in native doesn't makes sense. The `bool` value is the result of `sendRequest`.
So if you want get the real result you shall do like this:
```dart
weChatResponseEventHandler.listen((res) {
if (res is WeChatPaymentResponse) {
// do something here
}
});
```
Take a look at subclasses of `BaseWeChatResponse` for help.
> NOTE: If you get `errCode = -1`, please read the WeChatSDK document for help. There are to many cases lead to that.
### Images in WeChat
The are four built-in types of `WeChatImage` in `fluwx`:
```dart
WeChatImage.network(String source, {String suffix});
WeChatImage.file(File source, {String suffix = ".jpeg"});
WeChatImage.asset(String source, {String suffix});
WeChatImage.binary(Uint8List source, {String suffix = ".jpeg"});
```
The suffix shall begins with `.`. The priority of `suffix` is highest, `fluwx` will try to read suffix from paths if `suffix` is blank.
The max size of image youcan share to WeChat is `10M`.`Fluwx` wil compress `WeChatImage` itself if it's used as `thumbnail` or `hdImagePath`,
otherwise, it doesn't. However, you'd better compress thumbnail yourself as the result of compression is unpredictable.
## 基础知识
### 微信回调
实际上,像`shareToWeChat` or `payWithWeChat`这种的函数,底层上是调用了原生SDK的`sendRequest`方法,所以他们的返回结果意义不大,他们的返回结果仅仅是`sendRequest`的返回值。
为了获取真实的回调,你应该这样做:
```dart
weChatResponseEventHandler.listen((res) {
if (res is WeChatPaymentResponse) {
// do something here
}
});
```
> 笔记: 如果你的 `errCode = -1`, 那请阅读微信官方文档,因为-1的原因数不胜数.
### 图片
有四种内置 `WeChatImage`:
```dart
WeChatImage.network(String source, {String suffix});
WeChatImage.file(File source, {String suffix = ".jpeg"});
WeChatImage.asset(String source, {String suffix});
WeChatImage.binary(Uint8List source, {String suffix = ".jpeg"});
```
其中, `suffix` 应该以`.`开头. `suffix` 优先级最高, 如果`suffix`是空白的,`fluwx` 将会尝试从文件路径中读取后缀.
在分享图片的功能,图片不能超过`10M`.如果图片被用作`thumbnail``hdImagePath``Fluwx` 会对进行 `WeChatImage` 进行压缩,
否则不会压缩. 但是,最好还是自己压缩,因为不保证`fluwx`压缩效果。
\ No newline at end of file
## Payment
Calling payment is easy but to make it work isn't not so easy:
```dart
payWithWeChat(
appId: result['appid'],
partnerId: result['partnerid'],
prepayId: result['prepayid'],
packageValue: result['package'],
nonceStr: result['noncestr'],
timeStamp: result['timestamp'],
sign: result['sign'],
);
```
Take a look at [payment document](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1#) for help.
## 支付
调用支付方法很简单,但想成功并不简单:
```dart
payWithWeChat(
appId: result['appid'],
partnerId: result['partnerid'],
prepayId: result['prepayid'],
packageValue: result['package'],
nonceStr: result['noncestr'],
timeStamp: result['timestamp'],
sign: result['sign'],
);
```
更多信息还查看[支付文档](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1#)吧.
## Share
Simple and easy:
```dart
shareToWeChat(WeChatShareTextModel("source text", scene: WeChatScene.SESSION));
```
The destination of sharing can be SESSION(default),TIMELINE or FAVORITE.However,mini-program only support SESSION.
```dart
///[WeChatScene.SESSION]会话
///[WeChatScene.TIMELINE]朋友圈
///[WeChatScene.FAVORITE]收藏
enum WeChatScene {
SESSION,
TIMELINE,
FAVORITE
}
```
You can share these models:
- WeChatShareTextModel
- WeChatShareMiniProgramModel
- WeChatShareImageModel
- WeChatShareMusicModel
- WeChatShareVideoModel
- WeChatShareWebPageModel
- WeChatShareFileModel
## 分享
简单:
```dart
shareToWeChat(WeChatShareTextModel("source text", scene: WeChatScene.SESSION));
```
绝大部分分享可以分享到会话,朋友圈,收藏(小程序目前只能分享到会话)。默认分享到会话。
```dart
///[WeChatScene.SESSION]会话
///[WeChatScene.TIMELINE]朋友圈
///[WeChatScene.FAVORITE]收藏
enum WeChatScene {
SESSION,
TIMELINE,
FAVORITE
}
```
支持的分享各类:
- WeChatShareTextModel
- WeChatShareMiniProgramModel
- WeChatShareImageModel
- WeChatShareMusicModel
- WeChatShareVideoModel
- WeChatShareWebPageModel
- WeChatShareFileModel
......@@ -25,12 +25,15 @@ class WeChatImage {
final ImageSchema schema;
final String suffix;
/// [source] must begin with http or https
WeChatImage.network(String source, {String suffix})
: assert(source != null && source.startsWith("http")),
this.source = source,
this.schema = ImageSchema.NETWORK,
this.suffix = source.readSuffix(suffix);
///[source] path of the image, like '/asset/image.jpeg?package=flutter',
///the query param package in [source] only available when you want to specify the package of image
WeChatImage.asset(String source, {String suffix})
: assert(source != null && source.trim().isNotEmpty),
this.source = source,
......@@ -50,7 +53,8 @@ class WeChatImage {
this.schema = ImageSchema.BINARY,
this.suffix = suffix;
Map toMap() => {"source": source, "schema": schema.index, "suffix": suffix};
Map toMap() => {"source": source, "schema": schema.index, "suffix": suffix ??
""};
}
///Types of image, usually there are for types listed below.
......
name: fluwx
description: The capability of implementing WeChat SDKs in flutter.
version: 2.0.0
homepage:
homepage: https://github.com/JarvanMo/fluwx
environment:
sdk: ">=2.6.0 <3.0.0"
......
......@@ -50,7 +50,7 @@ void main() {
test("shareImage", () async {
expect(
await fluwx.shareToWeChat(fluwx.WeChatShareImageModel(
fluwx.WeChatImage.fromNetwork("http://flutter.dev"))),
fluwx.WeChatImage.network("http://flutter.dev"))),
true);
});
});
......
......@@ -23,8 +23,8 @@ import 'package:fluwx/src/wechat_enums.dart';
void main() {
test("test create WeChatShareImageModel with thumbnail", () {
var image = WeChatImage.fromNetwork("http://openflutter.dev/fluwx.png");
var thumbnail = WeChatImage.fromNetwork("http://openflutter.dev/fluwx.png");
var image = WeChatImage.network("http://openflutter.dev/fluwx.png");
var thumbnail = WeChatImage.network("http://openflutter.dev/fluwx.png");
var model = WeChatShareImageModel(image,
scene: WeChatScene.FAVORITE, thumbnail: thumbnail);
expect(model.source, image);
......@@ -33,7 +33,7 @@ void main() {
});
test("test create WeChatShareImageModel without thumbnail", () {
var image = WeChatImage.fromNetwork("http://openflutter.dev/fluwx.png");
var image = WeChatImage.network("http://openflutter.dev/fluwx.png");
var model = WeChatShareImageModel(image, scene: WeChatScene.FAVORITE);
expect(model.source, image);
expect(model.scene, WeChatScene.FAVORITE);
......@@ -41,8 +41,8 @@ void main() {
});
test("test WeChatShareImageModel toMap", () {
var image = WeChatImage.fromNetwork("http://openflutter.dev/fluwx.png");
var thumbnail = WeChatImage.fromNetwork("http://openflutter.dev/fluwx.png");
var image = WeChatImage.network("http://openflutter.dev/fluwx.png");
var thumbnail = WeChatImage.network("http://openflutter.dev/fluwx.png");
var map = WeChatShareImageModel(image,
scene: WeChatScene.FAVORITE, thumbnail: thumbnail)
.toMap();
......
......@@ -25,7 +25,7 @@ void main() {
group("construct", () {
test("non default values", () {
var thumbnail =
WeChatImage.fromNetwork("http://openflutter.dev/fluwx.png");
WeChatImage.network("http://openflutter.dev/fluwx.png");
var model = WeChatShareMiniProgramModel(
webPageUrl: "http://openflutter.dev",
miniProgramType: WXMiniProgramType.PREVIEW,
......@@ -56,7 +56,7 @@ void main() {
group("toMap", () {
test("with thumbnail", () {
var thumbnail =
WeChatImage.fromNetwork("http://openflutter.dev/fluwx.png");
WeChatImage.network("http://openflutter.dev/fluwx.png");
var map = WeChatShareMiniProgramModel(
webPageUrl: "http://openflutter.dev",
miniProgramType: WXMiniProgramType.PREVIEW,
......
......@@ -24,19 +24,19 @@ void main() {
test("test WeChatImage.fromNetwork", () {
var withSuffixImage =
WeChatImage.fromNetwork("http://image.openflutter.dev/fluwx.png");
WeChatImage.network("http://image.openflutter.dev/fluwx.png");
expect(withSuffixImage.source, "http://image.openflutter.dev/fluwx.png");
expect(withSuffixImage.suffix, ".png");
expect(ImageSchema.NETWORK, withSuffixImage.schema);
var withNoSuffixNoUrlSuffixImage =
WeChatImage.fromNetwork("http://image.openflutter.dev/fluwx");
WeChatImage.network("http://image.openflutter.dev/fluwx");
expect("http://image.openflutter.dev/fluwx",
withNoSuffixNoUrlSuffixImage.source);
expect(withNoSuffixNoUrlSuffixImage.suffix, ".jpeg");
expect(ImageSchema.NETWORK, withSuffixImage.schema);
var withSpecifiedSuffixImage = WeChatImage.fromNetwork(
var withSpecifiedSuffixImage = WeChatImage.network(
"http://image.openflutter.dev/fluwx.jpeg",
suffix: ".png");
expect(withSpecifiedSuffixImage.source, "http://image.openflutter.dev/fluwx.jpeg");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论