Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
德宏大魔王
uni-starter
提交
a67f4778
U
uni-starter
项目概览
德宏大魔王
/
uni-starter
与 Fork 源项目一致
Fork自
DCloud / uni-starter
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
uni-starter
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
a67f4778
编写于
4月 12, 2021
作者:
L
linju
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
123
上级
fa27cd1f
变更
16
展开全部
隐藏空白更改
内联
并排
Showing
16 changed file
with
323 addition
and
102 deletion
+323
-102
js_sdk/request.js
js_sdk/request.js
+21
-16
pages.json
pages.json
+11
-11
pages/test/test.vue
pages/test/test.vue
+13
-4
pages/ucenter/edit/uploadCutImageToUnicloud.vue
pages/ucenter/edit/uploadCutImageToUnicloud.vue
+1
-1
uni_modules/uni-config-center/changelog.md
uni_modules/uni-config-center/changelog.md
+2
-0
uni_modules/uni-config-center/package.json
uni_modules/uni-config-center/package.json
+80
-0
uni_modules/uni-config-center/readme.md
uni_modules/uni-config-center/readme.md
+93
-0
uni_modules/uni-id/changelog.md
uni_modules/uni-id/changelog.md
+18
-2
uni_modules/uni-id/package.json
uni_modules/uni-id/package.json
+2
-2
uni_modules/uni-id/readme.md
uni_modules/uni-id/readme.md
+32
-32
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/config.json
.../uni-id/uniCloud/cloudfunctions/common/uni-id/config.json
+1
-1
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
...les/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
+1
-1
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
...uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
+2
-2
uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
...dules/uni-list/components/uni-list-item/uni-list-item.vue
+1
-1
uni_modules/uni-login-page/components/login-short-code/login-short-code.vue
...gin-page/components/login-short-code/login-short-code.vue
+44
-28
uni_modules/uni-quick-login/components/uni-quick-login/uni-quick-login.vue
...uick-login/components/uni-quick-login/uni-quick-login.vue
+1
-1
未找到文件。
js_sdk/request.js
浏览文件 @
a67f4778
...
...
@@ -6,7 +6,7 @@
3.2 处理因token过期等问题自动更新本地token,或token无效跳转至登陆页面
*/
const
debug
=
true
;
//开启后,会alert错误信息
export
default
function
request
(
name
,
params
,
callback
,{
showLoading
=
false
,
loadText
=
''
,
fail
=
()
=>
{}}
=
{}){
export
default
function
request
(
name
,
params
,
callback
=
false
,{
showLoading
=
false
,
loadText
=
''
,
fail
=
()
=>
{}}
=
{}){
console
.
log
(
'
request
'
);
showLoading
||
loadText
?
uni
.
showLoading
({
title
:
loadText
}):
''
;
...
...
@@ -16,21 +16,26 @@ export default function request(name,params,callback,{showLoading=false,loadText
name
=
routers
[
0
]
action
=
routers
[
1
]
}
console
.
log
({
name
,
data
:
{
action
,
params
}})
return
uniCloud
.
callFunction
({
name
,
data
:
{
action
,
params
},
success
(
e
){
console
.
log
(
e
);
if
(
showLoading
||
loadText
)
uni
.
hideLoading
()
const
res
=
e
.
result
if
(
res
.
code
===
0
)
{
return
callback
(
res
.
data
,
e
.
result
,
e
)
// console.log({name,data: {action,params}})
return
new
Promise
((
resolve
,
reject
)
=>
{
uniCloud
.
callFunction
({
name
,
data
:
{
action
,
params
},
success
(
e
){
// console.log(e);
if
(
showLoading
||
loadText
)
uni
.
hideLoading
()
const
{
result
:{
data
,
code
}}
=
e
console
.
log
(
data
,
code
);
if
(
code
===
0
)
{
resolve
(
e
)
return
callback
(
data
,
e
.
result
,
e
)
}
debug
?
uni
.
showModal
({
content
:
JSON
.
stringify
(
e
)})
:
''
;
},
fail
(
err
){
reject
(
err
)
console
.
log
(
err
);
debug
?
uni
.
showModal
({
content
:
JSON
.
stringify
(
err
)})
:
''
;
fail
(
err
)
}
debug
?
uni
.
showModal
({
content
:
JSON
.
stringify
(
e
)})
:
''
;
},
fail
(
err
){
console
.
log
(
err
);
debug
?
uni
.
showModal
({
content
:
JSON
.
stringify
(
err
)})
:
''
;
fail
(
err
)
}
})
})
}
\ No newline at end of file
pages.json
浏览文件 @
a67f4778
...
...
@@ -207,17 +207,17 @@
"navigationBarBackgroundColor"
:
"#FFFFFF"
,
"backgroundColor"
:
"#F8F8F8"
},
"condition"
:
{
"list"
:
[
{
"path"
:
"uni_modules/uni-login-page/pages/index/index"
},
{
"path"
:
"pages/test/test"
}
],
"current"
:
0
},
//
"condition"
:
{
//
"list"
:
[
//
{
//
"path"
:
"uni_modules/uni-login-page/pages/index/index"
//
},
//
{
//
"path"
:
"pages/test/test"
//
}
//
],
//
"current"
:
0
//
},
"tabBar"
:
{
"color"
:
"#7A7E83"
,
"selectedColor"
:
"#007AFF"
,
...
...
pages/test/test.vue
浏览文件 @
a67f4778
<
template
>
<view>
test
<button
type=
"default"
@
click=
"fn1"
>
1
</button>
<button
type=
"default"
@
click=
"fn2"
>
2
</button>
</view>
</
template
>
...
...
@@ -12,12 +14,19 @@
}
},
onLoad
()
{
this
.
request
(
'
user-center/login_by_
'
,{},
e
=>
{
console
.
log
(
e
);
})
},
methods
:
{
fn1
(){
let
res
=
this
.
request
(
'
user-center/login_by_
'
).
then
(
e
=>
{
console
.
log
(
'
then--1
'
,
e
);
})
},
fn2
(){
this
.
request
(
'
user-center/login_by_
'
,{},
e
=>
{
console
.
log
(
'
222
'
,
e
);
})
}
}
}
</
script
>
...
...
pages/ucenter/edit/uploadCutImageToUnicloud.vue
浏览文件 @
a67f4778
<
template
>
<view
class=
"content"
>
<limeClipper
:width=
"options.width"
:scale-ratio=
"2"
:is
LockWidth=
"true"
:isLockH
eight=
"true"
:height=
"options.height"
:image-url=
"path"
<limeClipper
:width=
"options.width"
:scale-ratio=
"2"
:is
-lock-width=
"true"
:is-lock-h
eight=
"true"
:height=
"options.height"
:image-url=
"path"
@
success=
"successFn"
@
cancel=
"cancel"
/>
</view>
</
template
>
...
...
uni_modules/uni-config-center/changelog.md
0 → 100644
浏览文件 @
a67f4778
## 0.0.1(2021-03-15)
-
初始化项目
uni_modules/uni-config-center/package.json
0 → 100644
浏览文件 @
a67f4778
{
"id"
:
"uni-config-center"
,
"displayName"
:
"uni-config-center"
,
"version"
:
"0.0.1"
,
"description"
:
"uniCloud 配置中心"
,
"keywords"
:
[
"配置"
,
"配置中心"
],
"repository"
:
""
,
"engines"
:
{
"HBuilderX"
:
"^3.1.0"
},
"dcloudext"
:
{
"category"
:
[
"uniCloud"
,
"云函数模板"
],
"sale"
:
{
"regular"
:
{
"price"
:
0
},
"sourcecode"
:
{
"price"
:
0
}
},
"contact"
:
{
"qq"
:
""
},
"declaration"
:
{
"ads"
:
"无"
,
"data"
:
"无"
,
"permissions"
:
"无"
},
"npmurl"
:
""
},
"directories"
:
{
"example"
:
"../../../scripts/dist"
},
"uni_modules"
:
{
"dependencies"
:
[],
"encrypt"
:
[],
"platforms"
:
{
"cloud"
:
{
"tcb"
:
"y"
,
"aliyun"
:
"y"
},
"client"
:
{
"App"
:
{
"app-vue"
:
"u"
,
"app-nvue"
:
"u"
},
"H5-mobile"
:
{
"Safari"
:
"u"
,
"Android Browser"
:
"u"
,
"微信浏览器(Android)"
:
"u"
,
"QQ浏览器(Android)"
:
"u"
},
"H5-pc"
:
{
"Chrome"
:
"u"
,
"IE"
:
"u"
,
"Edge"
:
"u"
,
"Firefox"
:
"u"
,
"Safari"
:
"u"
},
"小程序"
:
{
"微信"
:
"u"
,
"阿里"
:
"u"
,
"百度"
:
"u"
,
"字节跳动"
:
"u"
,
"QQ"
:
"u"
},
"快应用"
:
{
"华为"
:
"u"
,
"联盟"
:
"u"
}
}
}
}
}
uni_modules/uni-config-center/readme.md
0 → 100644
浏览文件 @
a67f4778
# 为什么使用uni-config-center
实际开发中很多插件需要配置文件才可以正常运行,如果每个插件都单独进行配置的话就会产生下面这样的目录结构
```
bash
cloudfunctions
└─────common 公共模块
├─plugin-a // 插件A对应的目录
│ ├─index.js
│ ├─config.json // plugin-a对应的配置文件
│ └─other-file.cert // plugin-a依赖的其他文件
└─plugin-b // plugin-b对应的目录
├─index.js
└─config.json // plugin-b对应的配置文件
```
假设插件作者要发布一个项目模板,里面使用了很多需要配置的插件,无论是作者发布还是用户使用都是一个大麻烦。
uni-config-center就是用了统一管理这些配置文件的,使用uni-config-center后的目录结构如下
```
bash
cloudfunctions
└─────common 公共模块
├─plugin-a // 插件A对应的目录
│ └─index.js
├─plugin-b // plugin-b对应的目录
│ └─index.js
└─uni-config-center
├─index.js // config-center入口文件
├─plugin-a
│ ├─config.json // plugin-a对应的配置文件
│ └─other-file.cert // plugin-a依赖的其他文件
└─plugin-b
└─config.json // plugin-b对应的配置文件
```
使用uni-config-center后的优势
-
配置文件统一管理,对插件作者来说发布插件更简单了,对用户来说使用也更简单了
-
支持对config.json设置schema,插件使用者在HBuilderX内编写config.json文件时会有更好的提示(后续HBuilderX会提供支持)
# 用法
在要使用uni-config-center的公共模块或云函数内引入uni-config-center依赖,请参考:
[
使用公共模块
](
https://uniapp.dcloud.net.cn/uniCloud/cf-common
)
```
js
const
createConfig
=
require
(
'
uni-config-center
'
)
const
uniIdConfig
=
createConfig
({
pluginId
:
'
uni-id
'
,
// 插件id
defaultConfig
:
{
// 默认配置
tokenExpiresIn
:
7200
,
tokenExpiresThreshold
:
600
,
},
customMerge
:
function
(
defaultConfig
,
userConfig
)
{
// 自定义默认配置和用户配置的合并规则,不设置的情况侠会对默认配置和用户配置进行深度合并
// defaudltConfig 默认配置
// userConfig 用户配置
return
Object
.
assign
(
defaultConfig
,
userConfig
)
}
})
// 以如下配置为例
// {
// "tokenExpiresIn": 7200,
// "passwordErrorLimit": 6,
// "bindTokenToDevice": false,
// "passwordErrorRetryTime": 3600,
// "app-plus": {
// "tokenExpiresIn": 2592000
// },
// "service": {
// "sms": {
// "codeExpiresIn": 300
// }
// }
// }
// 获取配置
uniIdConfig
.
config
()
// 获取全部配置,注意:uni-config-center内不存在对应插件目录时会返回空对象
uniIdConfig
.
config
(
'
tokenExpiresIn
'
)
// 指定键值获取配置,返回:7200
uniIdConfig
.
config
(
'
service.sms.codeExpiresIn
'
)
// 指定键值获取配置,返回:300
uniIdConfig
.
config
(
'
tokenExpiresThreshold
'
,
600
)
// 指定键值获取配置,如果不存在则取传入的默认值,返回:600
// 获取文件绝对路径
uniIdConfig
.
resolve
(
'
custom-token.js
'
)
// 获取uni-config-center/uni-id/custom-token.js文件的路径
// 引用文件(require)
uniIDConfig
.
requireFile
(
'
custom-token.js
'
)
// 使用require方式引用uni-config-center/uni-id/custom-token.js文件。文件不存在时返回undefined,文件内有其他错误导致require失败时会抛出错误。
// 判断是否包含某文件
uniIDConfig
.
hasFile
(
'
custom-token.js
'
)
// 配置目录是否包含某文件,true: 文件存在,false: 文件不存在
```
\ No newline at end of file
uni_modules/uni-id/changelog.md
浏览文件 @
a67f4778
## 3.0.5(2021-02-03)
-
调整为uni_modules目录规范
## 3.0.11(2021-04-12)
-
修复3.0.7版本引出的多个用户访问时可能出现30201报错的Bug
## 3.0.10(2021-04-08)
-
优化错误提示
## 3.0.9(2021-04-08)
-
bindMobile接口支持通过一键登录的方式绑定
-
优化错误提示
## 3.0.8(2021-03-19)
-
修复 3.0.7版本某些情况下生成token报错的Bug
## 3.0.7(2021-03-19)
-
新增 支持uni-config-center,更新uni-id无须再担心配置被覆盖
[
详情
](
https://uniapp.dcloud.io/uniCloud/uni-id?id=uni-config-center
)
-
新增 自定义token内容,可以缓存角色权限之外的更多信息到客户端
[
详情
](
https://uniapp.dcloud.io/uniCloud/uni-id?id=custom-token
)
-
新增 支持传入context获取uni-id实例,防止单实例多并发时全局context混乱
[
详情
](
https://uniapp.dcloud.io/uniCloud/uni-id?id=create-instance
)
## 3.0.6(2021-03-05)
-
新增
[
uniID.wxBizDataCrypt
](
https://uniapp.dcloud.io/uniCloud/uni-id?id=%e5%be%ae%e4%bf%a1%e6%95%b0%e6%8d%ae%e8%a7%a3%e5%af%86
)
方法
-
优化loginByApple方法,提高接口响应速度
## 3.0.5(2021-02-03)
-
调整为uni_modules目录规范
uni_modules/uni-id/package.json
浏览文件 @
a67f4778
{
"id"
:
"uni-id"
,
"displayName"
:
"uni-id"
,
"version"
:
"3.0.
5
"
,
"version"
:
"3.0.
11
"
,
"description"
:
"简单、统一、可扩展的用户中心"
,
"keywords"
:
[
"uniid"
,
...
...
@@ -38,7 +38,7 @@
"npmurl"
:
""
},
"uni_modules"
:
{
"dependencies"
:
[],
"dependencies"
:
[
"uni-config-center"
],
"encrypt"
:
[],
"platforms"
:
{
"cloud"
:
{
...
...
uni_modules/uni-id/readme.md
浏览文件 @
a67f4778
**文档已移至[uni-id文档](https://uniapp.dcloud.net.cn/uniCloud/uni-id)**
> 一般uni-id升级大版本时为不兼容更新,从低版本迁移到高版本请参考:[uni-id迁移指南](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=migration)
## 重要升级说明
**uni-id 3.x版本,搭配的uniCloud admin版本需大于1.2.10。**
### 缓存角色权限
自
`uni-id 3.0.0`
起,支持在token内缓存用户的角色权限,默认开启此功能,各登录接口的needPermission参数不再生效。如需关闭请在config内配置
`"removePermissionAndRoleFromToken": true`
。
为什么要缓存角色权限?要知道云数据库是按照读写次数来收取费用的,并且读写数据库会拖慢接口响应速度。未配置
`"removePermissionAndRoleFromToken": true`
的情况下,可以在调用checkToken接口时不查询数据库获取用户角色权限。
详细checkToken流程如下:
![](
https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/ed45d350-5a4d-11eb-b997-9918a5dda011.jpg
)
可以看出,旧版token(removePermissionAndRoleFromToken为true时生成的)在checkToken时如需返回权限需要进行两次数据库查询。新版token不需要查库即可返回权限信息。
**注意**
-
由于角色权限缓存在token内,可能会存在权限已经更新但是用户token未过期之前依然是旧版角色权限的情况。可以调短一些token过期时间来减少这种情况的影响。
-
admin角色token内不包含permission,如需自行判断用户是否有某个权限,要注意admin角色需要额外判断一下,写法如下
```
js
const
{
role
,
permission
}
=
await
uniID
.
checkToken
(
event
.
uniIdToken
)
if
(
role
.
includes
(
'
admin
'
)
||
permission
.
includes
(
'
your permission id
'
))
{
// 当前角色拥有'your permission id'对应的权限
}
**文档已移至[uni-id文档](https://uniapp.dcloud.net.cn/uniCloud/uni-id)**
> 一般uni-id升级大版本时为不兼容更新,从低版本迁移到高版本请参考:[uni-id迁移指南](https://uniapp.dcloud.net.cn/uniCloud/uni-id?id=migration)
## 重要升级说明
**uni-id 3.x版本,搭配的uniCloud admin版本需大于1.2.10。**
### 缓存角色权限
自
`uni-id 3.0.0`
起,支持在token内缓存用户的角色权限,默认开启此功能,各登录接口的needPermission参数不再生效。如需关闭请在config内配置
`"removePermissionAndRoleFromToken": true`
。
为什么要缓存角色权限?要知道云数据库是按照读写次数来收取费用的,并且读写数据库会拖慢接口响应速度。未配置
`"removePermissionAndRoleFromToken": true`
的情况下,可以在调用checkToken接口时不查询数据库获取用户角色权限。
详细checkToken流程如下:
![](
https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/ed45d350-5a4d-11eb-b997-9918a5dda011.jpg
)
可以看出,旧版token(removePermissionAndRoleFromToken为true时生成的)在checkToken时如需返回权限需要进行两次数据库查询。新版token不需要查库即可返回权限信息。
**注意**
-
由于角色权限缓存在token内,可能会存在权限已经更新但是用户token未过期之前依然是旧版角色权限的情况。可以调短一些token过期时间来减少这种情况的影响。
-
admin角色token内不包含permission,如需自行判断用户是否有某个权限,要注意admin角色需要额外判断一下,写法如下
```
js
const
{
role
,
permission
}
=
await
uniID
.
checkToken
(
event
.
uniIdToken
)
if
(
role
.
includes
(
'
admin
'
)
||
permission
.
includes
(
'
your permission id
'
))
{
// 当前角色拥有'your permission id'对应的权限
}
```
\ No newline at end of file
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/config.json
浏览文件 @
a67f4778
...
...
@@ -44,7 +44,7 @@
"smsSecret"
:
"d6c424b702d73baa3b6e1a1452469213"
},
"univerify"
:{
"appid"
:
"
__UNI__BC54A00
"
,
"appid"
:
"
Du9ZOTSzHO9vutboF6UYa3
"
,
"apiKey"
:
"d1e36bcd497b3795434d900dcfdd44dc"
,
"apiSecret"
:
"2feb378ff1114362b20ac179b572293e"
}
...
...
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/index.js
浏览文件 @
a67f4778
此差异已折叠。
点击以展开。
uni_modules/uni-id/uniCloud/cloudfunctions/common/uni-id/package.json
浏览文件 @
a67f4778
{
"name"
:
"uni-id"
,
"version"
:
"3.0.
8
"
,
"version"
:
"3.0.
11
"
,
"description"
:
"uni-id for uniCloud"
,
"main"
:
"index.js"
,
"homepage"
:
"https://uniapp.dcloud.io/uniCloud/uni-id"
,
...
...
@@ -13,4 +13,4 @@
"dependencies"
:
{
"uni-config-center"
:
"file:../../../../../uni-config-center/uniCloud/cloudfunctions/common/uni-config-center"
}
}
}
\ No newline at end of file
uni_modules/uni-list/components/uni-list-item/uni-list-item.vue
浏览文件 @
a67f4778
...
...
@@ -370,7 +370,7 @@ $list-item-pd: $uni-spacing-col-lg $uni-spacing-row-lg;
/* #endif */
height
:
$uni-img-size-base
;
width
:
$uni-img-size-base
;
marin-right
:
10px
;
mar
g
in-right
:
10px
;
}
.uni-icon-wrapper
{
...
...
uni_modules/uni-login-page/components/login-short-code/login-short-code.vue
浏览文件 @
a67f4778
...
...
@@ -64,36 +64,52 @@
if
(
!
reg_phone
.
test
(
this
.
phone
))
return
uni
.
showToast
({
title
:
'
手机号格式错误
'
,
icon
:
'
none
'
});
uniCloud
.
callFunction
({
"
name
"
:
"
user-center
"
,
"
data
"
:
{
"
action
"
:
"
sendSmsCode
"
,
"
params
"
:
{
"
mobile
"
:
this
.
phone
,
"
type
"
:
"
login
"
}
},
success
:
(
e
)
=>
{
uni
.
showToast
({
title
:
"
短信验证码发送成功
"
,
icon
:
'
none
'
});
this
.
request
(
'
user-center/sendSmsCode
'
,
{
"
mobile
"
:
this
.
phone
,
"
type
"
:
"
login
"
},(
data
,
result
)
=>
{
console
.
log
(
data
,
result
);
uni
.
showToast
({
title
:
"
短信验证码发送成功
"
,
icon
:
'
none
'
});
this
.
reverseNumber
=
Number
(
this
.
count
);
this
.
getCode
();
this
.
$emit
(
'
getCode
'
);
},
fail
:
(
err
)
=>
{
console
.
log
(
err
);
uni
.
showToast
({
title
:
'
短信验证码发送失败
'
,
icon
:
'
none
'
});
},
complete
:
()
=>
{
uni
.
hideLoading
()
}
})
this
.
getCode
();
this
.
$emit
(
'
getCode
'
);
})
// uniCloud.callFunction({
// "name": "user-center",
// "data": {
// "action": "sendSmsCode",
// "params": {
// "mobile": this.phone,
// "type": "login"
// }
// },
// success: (e) => {
// uni.showToast({
// title: "短信验证码发送成功",
// icon: 'none'
// });
// this.reverseNumber = Number(this.count);
// this.getCode();
// this.$emit('getCode');
// },
// fail: (err) => {
// console.log(err);
// uni.showToast({
// title: '短信验证码发送失败',
// icon: 'none'
// });
// },
// complete: () => {
// uni.hideLoading()
// }
// })
},
getCode
()
{
if
(
this
.
reverseNumber
==
0
)
{
...
...
uni_modules/uni-quick-login/components/uni-quick-login/uni-quick-login.vue
浏览文件 @
a67f4778
...
...
@@ -139,7 +139,7 @@
uni
.
setStorageSync
(
'
uni_id_uid
'
,
result
.
uid
)
uni
.
setStorageSync
(
'
uni_id_token
'
,
result
.
token
)
uni
.
setStorageSync
(
'
uni_id_token_expired
'
,
result
.
tokenExpired
)
delete
result
.
userInfo
.
token
this
.
setUserInfo
(
result
.
userInfo
)
if
(
type
==
'
univerify
'
){
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录