提交 404d3658 编写于 作者: Q qiang

Merge branch 'alpha'

......@@ -12,5 +12,5 @@
"message": "chore(release): publish %s"
}
},
"version": "2.0.0-alpha-28420200805004"
"version": "2.0.0-28720200819002"
}
{
"name": "@dcloudio/uni-app-plus-nvue",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app app-plus-nvue",
"main": "dist/index.js",
"repository": {
......
......@@ -1147,10 +1147,10 @@ function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || [];
);
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])));
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])));
}
});
}
......
{
"name": "@dcloudio/uni-app-plus",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app app-plus",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-automator",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app automator",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-cli-shared",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-cli-shared",
"main": "lib/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-h5-ui",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app h5 ui",
"main": "dist/index.umd.min.js",
"repository": {
......
{
"name": "@dcloudio/uni-h5",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app h5",
"main": "dist/index.umd.min.js",
"repository": {
......
{
"name": "@dcloudio/uni-migration",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app migration",
"main": "lib/index.js",
"repository": {
......
......@@ -1626,10 +1626,10 @@ function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || [];
);
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])));
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])));
}
});
}
......
{
"name": "@dcloudio/uni-mp-alipay",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app mp-alipay",
"main": "dist/index.js",
"repository": {
......
......@@ -1289,10 +1289,10 @@ function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || [];
);
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])));
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])));
}
});
}
......
{
"name": "@dcloudio/uni-mp-baidu",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app mp-baidu",
"main": "dist/index.js",
"repository": {
......
......@@ -1205,10 +1205,10 @@ function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || [];
);
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])));
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])));
}
});
}
......
{
"name": "@dcloudio/uni-mp-qq",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app mp-qq",
"main": "dist/index.js",
"repository": {
......
......@@ -1297,10 +1297,10 @@ function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || [];
);
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])));
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])));
}
});
}
......
{
"name": "@dcloudio/uni-mp-toutiao",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app mp-toutiao",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-mp-vue",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "@dcloudio/uni-mp-vue",
"main": "dist/vue.runtime.esm.js",
"module": "dist/vue.runtime.esm.js",
......
......@@ -1162,10 +1162,10 @@ function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || [];
);
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])));
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])));
}
});
}
......
{
"name": "@dcloudio/uni-mp-weixin",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app mp-weixin",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-quickapp-native",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app quickapp-native",
"main": "dist/vue.prod.js",
"repository": {
......
......@@ -1147,10 +1147,10 @@ function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || [];
);
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])));
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])));
}
});
}
......
{
"name": "@dcloudio/uni-quickapp-webview",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app quickapp-webview",
"main": "dist/index.js",
"repository": {
......
{
"name": "@dcloudio/uni-stat",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "",
"main": "dist/index.js",
"repository": {
......
......@@ -327,6 +327,16 @@ describe('mp:compiler-extra', () => {
'<view><view class="item" v-for="i in 5" :key="i" @click="func(i)"></view></view>',
'<view><block wx:for="{{5}}" wx:for-item="i" wx:for-index="__i0__" wx:key="*this"><view data-event-opts="{{[[\'tap\',[[\'func\',[\'$0\'],[[[5,\'\',__i0__]]]]]]]}}" class="item" bindtap="__e"></view></block></view>'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view @click="$test.test(item,item.length)"></view></view>',
'<block wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><view data-event-opts="{{[[\'tap\',[[\'e0\',[\'$event\']]]]]}}" data-event-params="{{({item})}}" bindtap="__e"></view></view></block>',
'with(this){if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return $test.test(item,item.length)}}}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view @click="$test.test(item,item.length,undefined)"></view></view>',
'<block wx:for="{{list}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><view data-event-opts="{{[[\'tap\',[[\'e0\',[\'$event\']]]]]}}" data-event-params="{{({item})}}" bindtap="__e"></view></view></block>',
'with(this){if(!_isMounted){e0=function($event,item){var _temp=arguments[arguments.length-1].currentTarget.dataset,_temp2=_temp.eventParams||_temp["event-params"],item=_temp2.item;var _temp,_temp2;return $test.test(item,item.length,undefined)}}}'
)
})
it('generate class binding', () => {
......@@ -687,10 +697,45 @@ describe('mp:compiler-extra', () => {
'<block wx:if="{{$root.m0}}"><view>{{$root.m1}}</view></block>',
'with(this){var m0=getValue(key);var m1=m0?getValue(key):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1}})}'
)
assertCodegen(
'<view v-if="test1(key)&&test2(key)">{{getValue(key)}}</view>',
'<block wx:if="{{$root.m0&&$root.m1}}"><view>{{$root.m2}}</view></block>',
'with(this){var m0=test1(key);var m1=test2(key);var m2=m0&&m1?getValue(key):null;$mp.data=Object.assign({},{$root:{m0:m0,m1:m1,m2:m2}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="item">{{getValue(item)}}</view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{item.$orig}}"><view>{{item.m0}}</view></block></view></block>',
'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);var m0=item?getValue(item):null;return{$orig:$orig,m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="item.length">{{getValue(item)}}</view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{item.$orig.length}}"><view>{{item.m0}}</view></block></view></block>',
'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);var m0=item.length?getValue(item):null;return{$orig:$orig,m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="item.length>0">{{getValue(item)}}</view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{item.$orig.length>0}}"><view>{{item.m0}}</view></block></view></block>',
'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);var m0=item.length>0?getValue(item):null;return{$orig:$orig,m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="item.length>0">{{test(\'item\')}}</view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{item.$orig.length>0}}"><view>{{item.m0}}</view></block></view></block>',
'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);var m0=item.length>0?test("item"):null;return{$orig:$orig,m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="test(item)">{{test(\'item\')}}</view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{item.m0}}"><view>{{item.m1}}</view></block></view></block>',
'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);var m0=test(item);var m1=m0?test("item"):null;return{$orig:$orig,m0:m0,m1:m1}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="test(item.id)"><view v-if="test(item.type)">{{test(\'item\')}}</view></view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{item.m0}}"><view><block wx:if="{{item.m1}}"><view>{{item.m2}}</view></block></view></block></view></block>',
'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);var m0=test(item.id);var m1=m0?test(item.type):null;var m2=m0&&m1?test("item"):null;return{$orig:$orig,m0:m0,m1:m1,m2:m2}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
assertCodegen(
'<view v-for="(item,index) in list" :key="index"><view v-if="Object.values(item.list).length">{{test(item.list)}}</view></view>',
'<block wx:for="{{$root.l0}}" wx:for-item="item" wx:for-index="index" wx:key="index"><view><block wx:if="{{item.g0.length}}"><view>{{item.m0}}</view></block></view></block>',
'with(this){var l0=__map(list,function(item,index){var $orig=__get_orig(item);var g0=Object.values(item.list);var m0=g0.length?test(item.list):null;return{$orig:$orig,g0:g0,m0:m0}});$mp.data=Object.assign({},{$root:{l0:l0}})}'
)
})
})
......@@ -131,6 +131,11 @@ describe('mp:compiler-mp-weixin', () => {
'<block wx:for="{{({list1,list2})}}" wx:for-item="item" wx:for-index="key"></block>'
)
assertCodegen('<test :obj="{x:0}"></test>', '<test vue-id="551070e6-1" obj="{{({x:0})}}" bind:__l="__l"></test>')
assertCodegen('<test :obj="{\'x\':0}"></test>', '<test vue-id="551070e6-1" obj="{{$root.a0}}" bind:__l="__l"></test>', 'with(this){var a0={"x":0};$mp.data=Object.assign({},{$root:{a0:a0}})}')
assertCodegen(
'<test :obj="{x:{x:0}}"></test>', '<test vue-id="551070e6-1" obj="{{$root.a0}}" bind:__l="__l"></test>',
'with(this){var a0={x:{x:0}};$mp.data=Object.assign({},{$root:{a0:a0}})}'
)
})
it('generate v-show directive', () => {
......
// const {
// IDENTIFIER_ATTR
// } = require('../../../constants')
const t = require('@babel/types')
// const getMemberExpr = require('../member-expr')
const {
IDENTIFIER_ATTR
} = require('../../../constants')
const getMemberExpr = require('../member-expr')
module.exports = function processAttrs (paths, path, state, isComponent, tagName) {
// 不再单独处理ObjectExpression,改为在转换temlplte时用()包裹(微信、QQ)
// const attrsPath = paths.attrs
// if (attrsPath) {
// attrsPath.get('value.properties').forEach(propertyPath => {
// const valuePath = propertyPath.get('value')
// if (valuePath.isObjectExpression()) {
// valuePath.replaceWith(getMemberExpr(null, IDENTIFIER_ATTR, valuePath.node, state))
// }
// })
// }
const attrsPath = paths.attrs
if (attrsPath) {
attrsPath.get('value.properties').forEach(propertyPath => {
const valuePath = propertyPath.get('value')
// 对于普通的ObjectExpression不再单独处理,改为在转换temlplte时用()包裹(微信、QQ)
if (valuePath.isObjectExpression() && valuePath.node.properties.find(({ key, value }) => !t.isIdentifier(key) || !(t.isIdentifier(value) || t.isStringLiteral(value) || t.isBooleanLiteral(value) || t.isNumericLiteral(value) || t.isNullLiteral(value)))) {
valuePath.replaceWith(getMemberExpr(path, IDENTIFIER_ATTR, valuePath.node, state))
}
})
}
return []
}
......@@ -335,7 +335,7 @@ function parseEvent (keyPath, valuePath, state, isComponent, isNativeOn = false,
const scope = path.scope
const node = path.node
const name = node.name
if (path.key !== 'key' && (path.key !== 'property' || path.parent.computed) && scope && !scope.hasOwnBinding(name) && scope.hasBinding(name)) {
if (path.key !== 'key' && (path.key !== 'property' || path.parent.computed) && scope && !scope.hasOwnBinding(name) && scope.hasBinding(name) && !params.includes(name) && name !== 'undefined') {
params.push(name)
}
}
......
......@@ -2,14 +2,17 @@ const t = require('@babel/types')
const traverse = require('@babel/traverse').default
const {
VAR_ROOT
VAR_ROOT,
IDENTIFIER_METHOD,
IDENTIFIER_FILTER,
IDENTIFIER_GLOBAL
} = require('../../constants')
function isMatch (name, forItem, forIndex) {
return name === forItem || name === forIndex
}
function findScoped (path, state) {
function findScoped (path, test, state) {
if (!path) {
return state
}
......@@ -30,6 +33,20 @@ function findScoped (path, state) {
}
}
})
if (!match && test) {
traverse(t.arrayExpression([test]), {
noScope: true,
Identifier (path) {
if (!match && path.key !== 'key' && (path.key !== 'property' || path.parent.computed)) {
const node = path.node
match = isMatch(node.name, forItem, forIndex) || scoped.declarationArray.find(({ declarations }) => declarations.find(({ id }) => id === node))
if (match) {
path.stop()
}
}
}
})
}
return match
})
if (!scoped && state.scoped.length > 1) {
......@@ -40,34 +57,46 @@ function findScoped (path, state) {
function findTest (path, state) {
let tests
while (path.parentPath && path.key !== 'body') {
if (path.key === 'consequent' || path.key === 'alternate') {
let test = t.arrayExpression([t.clone(path.container.test)])
traverse(test, {
noScope: true,
MemberExpression (path) {
const names = state.scoped.map(scoped => scoped.forItem)
const node = path.node
const objectName = node.object.name
if (objectName === VAR_ROOT || names.includes(objectName)) {
path.replaceWith(node.property)
if (path) {
while (path.parentPath && path.key !== 'body') {
if (path.key === 'consequent' || path.key === 'alternate') {
const testOrig = path.container.test
let test = t.arrayExpression([t.cloneDeep(testOrig)])
traverse(test, {
noScope: true,
MemberExpression (memberExpressionPath) {
const names = state.scoped.map(scoped => scoped.forItem)
const node = memberExpressionPath.node
const objectName = node.object.name
const property = node.property
const propertyName = property.name
if (objectName === VAR_ROOT || (names.includes(objectName) && (propertyName === IDENTIFIER_METHOD || propertyName === IDENTIFIER_FILTER || propertyName === IDENTIFIER_GLOBAL))) {
const array = []
let tempPath = memberExpressionPath
while (tempPath.parentPath) {
const key = tempPath.key
array.unshift(typeof key === 'number' ? `[${key}]` : `.${key}`)
tempPath = tempPath.parentPath
}
memberExpressionPath.replaceWith(path.parentPath.get('test' + array.join('')).node.property)
}
}
})
test = test.elements[0]
if (path.key === 'alternate') {
test = t.unaryExpression('!', test)
}
})
test = test.elements[0]
if (path.key === 'alternate') {
test = t.unaryExpression('!', test)
tests = tests ? t.logicalExpression('&&', test, tests) : test
}
tests = tests ? t.logicalExpression('&&', test, tests) : test
path = path.parentPath
}
path = path.parentPath
}
return tests
}
module.exports = function getMemberExpr (path, name, init, state, variableDeclaration = true) {
const scoped = findScoped(path, state)
const test = findTest(path, state)
const scoped = findScoped(path, test, state)
if (!variableDeclaration) {
scoped.declarationArray.push(t.expressionStatement(init))
......
{
"name": "@dcloudio/uni-template-compiler",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-template-compiler",
"main": "lib/index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-hbuilderx",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "HBuilderX plugin for vue-cli 3",
"main": "index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-uni-optimize",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app optimize plugin for vue-cli 3",
"main": "index.js",
"repository": {
......
{
"name": "@dcloudio/vue-cli-plugin-uni",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app plugin for vue-cli 3",
"main": "index.js",
"repository": {
......@@ -17,7 +17,7 @@
"author": "fxy060608",
"license": "Apache-2.0",
"dependencies": {
"@dcloudio/uni-stat": "^2.0.0-alpha-28420200805004",
"@dcloudio/uni-stat": "^2.0.0-28720200819002",
"buffer-json": "^2.0.0",
"copy-webpack-plugin": "^5.1.1",
"cross-env": "^5.2.0",
......
{
"name": "@dcloudio/webpack-uni-mp-loader",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "webpack-uni-mp-loader",
"main": "index.js",
"repository": {
......
{
"name": "@dcloudio/webpack-uni-pages-loader",
"version": "2.0.0-alpha-28420200805004",
"version": "2.0.0-28720200819002",
"description": "uni-app pages.json loader",
"main": "lib/index.js",
"repository": {
......@@ -21,7 +21,7 @@
"strip-json-comments": "^2.0.1"
},
"uni-app": {
"compilerVersion": "2.8.4"
"compilerVersion": "2.8.7"
},
"gitHead": "e62f0398362f2f9de0bf5726046d7951c88d6b1d"
}
......@@ -549,10 +549,10 @@ export function handleEvent (event) {
eventArray[2],
isCustom,
methodName
) || []
)
// 参数尾部增加原始事件对象用于复杂表达式内获取额外数据
// eslint-disable-next-line no-sparse-arrays
ret.push(handler.apply(handlerCtx, params.concat([, , , , , , , , , , event])))
ret.push(handler.apply(handlerCtx, (Array.isArray(params) ? params : []).concat([, , , , , , , , , , event])))
}
})
}
......
......@@ -21,6 +21,7 @@ class RewardedVideoAd {
}
})
this._preload = options.preload !== undefined ? options.preload : true
this._isLoad = false
this._adError = ''
this._loadPromiseResolve = null
......@@ -30,8 +31,8 @@ class RewardedVideoAd {
const rewardAd = this._rewardAd = plus.ad.createRewardedVideoAd(options)
rewardAd.onLoad((e) => {
this._isLoad = true
this._dispatchEvent('load', {})
this._lastLoadTime = Date.now()
this._dispatchEvent('load', {})
if (this._loadPromiseResolve != null) {
this._loadPromiseResolve()
......@@ -39,7 +40,9 @@ class RewardedVideoAd {
}
})
rewardAd.onClose((e) => {
this._loadAd()
if (this._preload) {
this._loadAd()
}
this._dispatchEvent('close', { isEnded: e.isEnded })
})
rewardAd.onVerify && rewardAd.onVerify((e) => {
......@@ -59,11 +62,14 @@ class RewardedVideoAd {
this._loadPromiseReject = null
}
})
this._loadAd()
if (this._preload) {
this._loadAd()
}
}
get isExpired () {
return (Math.abs(Date.now() - this._lastLoadTime) > EXPIRED_TIME)
return (this._lastLoadTime !== 0 && (Math.abs(Date.now() - this._lastLoadTime) > EXPIRED_TIME))
}
load () {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册