提交 e0cc3ec1 编写于 作者: Shine-zwj's avatar Shine-zwj

update:更新表单逻辑

上级 b78dc23c
{{#each items as | formDetail |}}
{{#if (and (eq formDetail.detailType "BUTTON") (formDetail.psUIAction))}}
{{#formDetail.psUIAction}}
{{uIActionTag}}: { disabled: false, visible: true, noPrivDisplayMode: {{noPrivDisplayMode}}, dataAccessAction: '{{dataAccessAction}}', actionTarget: '{{actionTarget}}' },
{{/formDetail.psUIAction}}
{{/if}}
{{#if (and (eq formDetail.detailType "GROUPPANEL") (formDetail.psSUIActionGroup.psUIActionGroupDetails))}}
{{#each formDetail.psSUIActionGroup.psUIActionGroupDetails as | detail | }}
{{#detail.psUIAction}}
{{uIActionTag}}: { disabled: false, visible: true, noPrivDisplayMode: {{noPrivDisplayMode}}, dataAccessAction: '{{dataAccessAction}}', actionTarget: '{{actionTarget}}' },
{{/detail.psUIAction}}
{{/each}}
{{/if}}
{{#if formDetail.psDEFormDetails}}
{{>(lookup 'FORMACTIONMODEL') items=formDetail.psDEFormDetails}}
{{/if}}
{{/each}}
......@@ -2,6 +2,7 @@
<div style="flex-grow: {{#if item.psLayoutPos.grow}}{{item.psLayoutPos.grow}}{{else}}0{{/if}};">
<a-button
type="primary"
v-show="state.detailsModel.{{item.codeName}}.visible"
class="ibiz-form-button{{#if item.psSysCss}}{{item.psSysCss.cssName}}{{/if}}"
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}">
{{#if item.psSysImage}}
......@@ -19,6 +20,7 @@
{{> @macro/front-end/ctrl/common/layoutPos.hbs item=item.psLayoutPos}} >
<a-button
type="primary"
v-show="state.detailsModel.{{item.codeName}}.visible"
class="ibiz-form-button{{#if item.psSysCss}}{{item.psSysCss.cssName}}{{/if}}"
style="{{#if item.width}}width: {{item.width}}px;{{/if}}{{#if item.height}}height: {{item.height}}px;{{/if}}">
{{#if item.psSysImage}}
......
......@@ -9,6 +9,8 @@
showCaption: {{#if formDetail.showCaption}}true{{else}}false{{/if}},
{{#if (eq formDetail.detailType "FORMITEM")}}
dataType: '{{formDetail.dataType}}',
required: {{#if formDetail.allowEmpty}}false{{else}}true{{/if}},
enableCond: {{formDetail.enableCond}},
{{#if formDetail.resetItemName}}
resetItemName: '{{formDetail.resetItemName}}',
{{/if}}
......@@ -16,32 +18,38 @@
valueItemName: '{{formDetail.valueItemName}}',
{{/if}}
{{/if}}
{{#if (and (eq formDetail.detailType "BUTTON") formDetail.psUIAction)}}
{{#formDetail.psUIAction}}
uIAction: {
uIActionType: '{{uIActionType}}',
uIActionTag: '{{uIActionTag}}',
}
{{/formDetail.psUIAction}}
{{#if (and (eq formDetail.detailType "BUTTON") (formDetail.psUIAction))}}
uIActionTag: '{{formDetail.psUIAction.uIActionTag}}',
{{/if}}
{{#if (eq formDetail.detailType "GROUPPANEL")}}
{{/if}}
{{#each formDetail.psDEFDGroupLogics as | groupLogic |}}
groupLogics: {
name: '{{groupLogic.name}}',
groupOP: '{{groupLogic.groupOP}}',
relatedDetailNames: '{{groupLogic.relatedDetailNames}}',
logicCat: '{{groupLogic.logicCat}}',
logicType: '{{groupLogic.logicType}}',
notMode: '{{groupLogic.notMode}}',
Logics: [
{{#each groupLogic.psDEFDLogics as | logic |}}
{condOP: '{{logic.condOP}}',dEFDName: '{{logic.dEFDName}}',logicType: '{{logic.logicType}}',name: '{{logic.name}}'},
{{#if (and (eq formDetail.detailType "GROUPPANEL") (formDetail.psUIActionGroup))}}
uIActionGroup: {
extractMode: '{{formDetail.psUIActionGroup.actionGroupExtractMode}}',
details: [
{{#each formDetail.psUIActionGroup.psUIActionGroupDetails as | detail | }}
{ caption: '{{detail.caption}}', disabled: false, visible: true, uIActionTag: '{{detail.psUIAction.uIActionTag}}', showCaption: {{detail.showCaption}}, showIcon: {{detail.showIcon}}, {{#if detail.psUIAction.psSysImage}}{{#if detail.psUIAction.psSysImage.imagePath}} imgPath: "{{detail.psUIAction.psSysImage.imagePath}}",{{/if}}{{#if detail.psUIAction.psSysImage.cssClass}} iconClass: "{{detail.psUIAction.psSysImage.cssClass}}",{{/if}}{{/if}} },
{{/each}}
],
}
{{/each}}
},
{{/if}}
{{#if formDetail.psDEFDGroupLogics}}
groupLogics: [
{{#each formDetail.psDEFDGroupLogics as | groupLogic |}}
{
name: '{{groupLogic.name}}',
groupOP: '{{groupLogic.groupOP}}',
relatedDetailNames: '{{groupLogic.relatedDetailNames}}',
logicCat: '{{groupLogic.logicCat}}',
logicType: '{{groupLogic.logicType}}',
notMode: '{{groupLogic.notMode}}',
Logics: [
{{#each groupLogic.psDEFDLogics as | logic |}}
{condOP: '{{logic.condOP}}',dEFDName: '{{logic.dEFDName}}',logicType: '{{logic.logicType}}',name: '{{logic.name}}'},
{{/each}}
],
}
{{/each}}
],
{{/if}}
},
{{#if formDetail.psDEFormDetails}}
{{>(lookup 'FORMDETAILSMODEL') items=formDetail.psDEFormDetails}}
......
{{#eq item.psLayoutPos 'FLEX'}}
<div style="flex-grow: {{#if item.psLayoutPos.grow}}{{item.psLayoutPos.grow}}{{else}}0{{/if}};">
<IbizFormGroup name="{{item.codeName}}" title="{{item.caption}}">
<IbizFormGroup v-show="state.detailsModel.{{item.codeName}}.visible" name="{{item.codeName}}" title="{{item.caption}}">
{{#eq item.psLayout.layout "FLEX"}}
<div class="app-form-layout-flex" style="{{#if item.psLayout.dir}}flex-direction: {{item.psLayout.dir}};{{/if}}{{#if item.psLayout.align}}justify-content: {{item.psLayout.align}};{{/if}}{{#if item.psLayout.vAlign}}align-items: {{item.psLayout.vAlign}};{{/if}}">
{{#each item.psDEFormDetails as | formDetail |}}
......@@ -19,7 +19,7 @@
{{else}}
<a-col
{{> @macro/front-end/ctrl/common/layoutPos.hbs item=item.psLayoutPos}} >
<IbizFormGroup name="{{item.codeName}}" title="{{item.caption}}">
<IbizFormGroup v-show="state.detailsModel.{{item.codeName}}.visible" name="{{item.codeName}}" title="{{item.caption}}">
{{#eq item.psLayout.layout "FLEX"}}
<div class="app-form-layout-flex" style="{{#if item.psLayout.dir}}flex-direction: {{item.psLayout.dir}};{{/if}}{{#if item.psLayout.align}}justify-content: {{item.psLayout.align}};{{/if}}{{#if item.psLayout.vAlign}}align-items: {{item.psLayout.vAlign}};{{/if}}">
{{#each item.psDEFormDetails as | formDetail |}}
......
{{#eq item.psLayoutPos 'FLEX'}}
<div style="flex-grow: {{#if item.psLayoutPos.grow}}{{item.psLayoutPos.grow}}{{else}}0{{/if}};">
<div class="ibiz-form-iframe" style="{{#if item.contentHeight}}height: {{item.contentHeight}}px;{{/if}}{{#if item.contentWidth}}width: {{item.contentWidth}}px{{/if}}">
<div v-show="state.detailsModel.{{item.codeName}}.visible" class="ibiz-form-iframe" style="{{#if item.contentHeight}}height: {{item.contentHeight}}px;{{/if}}{{#if item.contentWidth}}width: {{item.contentWidth}}px{{/if}}">
<iframe src="{{item.iFrameUrl}}" style="height: 100%;width: 100%;border: 0"></iframe>
</div>
</div>
{{else}}
<a-col
{{> @macro/front-end/ctrl/common/layoutPos.hbs item=item.psLayoutPos}} >
<div class="ibiz-form-iframe" style="{{#if item.contentHeight}}height: {{item.contentHeight}}px;{{/if}}{{#if item.contentWidth}}width: {{item.contentWidth}}px{{/if}}">
<div v-show="state.detailsModel.{{item.codeName}}.visible" class="ibiz-form-iframe" style="{{#if item.contentHeight}}height: {{item.contentHeight}}px;{{/if}}{{#if item.contentWidth}}width: {{item.contentWidth}}px{{/if}}">
<iframe src="{{item.iFrameUrl}}" style="height: 100%;width: 100%;border: 0"></iframe>
</div>
</a-col>
......
{{>@macro/editor/include-editor.hbs}}
{{#eq item.psLayoutPos 'FLEX'}}
<div style="flex-grow: {{#if item.psLayoutPos.grow}}{{item.psLayoutPos.grow}}{{else}}0{{/if}};">
<IbizFormItem name="{{item.codeName}}" label="{{item.caption}}">
<IbizFormItem v-show="state.detailsModel.{{item.codeName}}.visible" name="{{item.codeName}}" label="{{item.caption}}">
{{#if item.psEditor}}
{{>(lookup . 'item.psEditor.editorType') item=item ctrlType="form"}}
{{/if}}
......@@ -10,7 +10,7 @@
{{else}}
<a-col
{{> @macro/front-end/ctrl/common/layoutPos.hbs item=item.psLayoutPos}} >
<IbizFormItem name="{{item.codeName}}" label="{{item.caption}}">
<IbizFormItem v-show="state.detailsModel.{{item.codeName}}.visible" name="{{item.codeName}}" label="{{item.caption}}">
{{#if item.psEditor}}
{{>(lookup . 'item.psEditor.editorType') item=item ctrlType="form"}}
{{/if}}
......
<a-tab-pane key="{{item.codeName}}" tab="{{item.caption}}">
<a-tab-pane v-show="state.detailsModel.{{item.codeName}}.visible" key="{{item.codeName}}" tab="{{item.caption}}">
{{#eq item.psLayout.layout "FLEX"}}
<div class="app-form-layout-flex" style="{{#if item.psLayout.dir}}flex-direction: {{item.psLayout.dir}};{{/if}}{{#if item.psLayout.align}}justify-content: {{item.psLayout.align}};{{/if}}{{#if item.psLayout.vAlign}}align-items: {{item.psLayout.vAlign}};{{/if}}">
{{#each item.psDEFormDetails as | formDetail |}}
......
{{#eq item.psLayoutPos 'FLEX'}}
<div style="flex-grow: {{#if item.psLayoutPos.grow}}{{item.psLayoutPos.grow}}{{else}}0{{/if}};">
<IbizRaw
{{#if item.psSysCss}}class="{{item.psSysCss.cssName}}"{{/if}}
{{#if item.psSysImage}}{{#if item.psSysImage.cssClass}}iconClass="{{item.psSysImage.cssClass}}"{{/if}}{{#if item.psSysImage.imagePath}}imgPath="{{item.psSysImage.imagePath}}"{{/if}}{{/if}}
contentType="{{item.contentType}}"
style="{{#if item.rawItemHeight}}height: {{item.rawItemHeight}}px;{{/if}}{{#if item.rawItemWidth}}width: {{item.rawItemWidth}}px{{/if}}"
{{#if (eq item.contentType 'RAW')}}value="{{item.rawContent}}"{{else if (eq item.contentType 'HTML')}}:value="`{{item.htmlContent}}`"{{/if}}/>
<IbizRaw
v-show="state.detailsModel.{{item.codeName}}.visible"
{{#if item.psSysCss}}class="{{item.psSysCss.cssName}}"{{/if}}
{{#if item.psSysImage}}{{#if item.psSysImage.cssClass}}iconClass="{{item.psSysImage.cssClass}}"{{/if}}{{#if item.psSysImage.imagePath}}imgPath="{{item.psSysImage.imagePath}}"{{/if}}{{/if}}
contentType="{{item.contentType}}"
style="{{#if item.rawItemHeight}}height: {{item.rawItemHeight}}px;{{/if}}{{#if item.rawItemWidth}}width: {{item.rawItemWidth}}px{{/if}}"
{{#if (eq item.contentType 'RAW')}}value="{{item.rawContent}}"{{else if (eq item.contentType 'HTML')}}:value="`{{item.htmlContent}}`"{{/if}}/>
</div>
{{else}}
<a-col
{{> @macro/front-end/ctrl/common/layoutPos.hbs item=item.psLayoutPos}} >
<IbizRaw
{{#if item.psSysCss}}class="{{item.psSysCss.cssName}}"{{/if}}
{{#if item.psSysImage}}{{#if item.psSysImage.cssClass}}iconClass="{{item.psSysImage.cssClass}}"{{/if}}{{#if item.psSysImage.imagePath}}imgPath="{{item.psSysImage.imagePath}}"{{/if}}{{/if}}
contentType="{{item.contentType}}"
style="{{#if item.rawItemHeight}}height: {{item.rawItemHeight}}px;{{/if}}{{#if item.rawItemWidth}}width: {{item.rawItemWidth}}px{{/if}}"
{{#if (eq item.contentType 'RAW')}}value="{{item.rawContent}}"{{else if (eq item.contentType 'HTML')}}:value="`{{item.htmlContent}}`"{{/if}}/>
</a-col>
<IbizRaw
v-show="state.detailsModel.{{item.codeName}}.visible"
{{#if item.psSysCss}}class="{{item.psSysCss.cssName}}"{{/if}}
{{#if item.psSysImage}}{{#if item.psSysImage.cssClass}}iconClass="{{item.psSysImage.cssClass}}"{{/if}}{{#if item.psSysImage.imagePath}}imgPath="{{item.psSysImage.imagePath}}"{{/if}}{{/if}}
contentType="{{item.contentType}}"
style="{{#if item.rawItemHeight}}height: {{item.rawItemHeight}}px;{{/if}}{{#if item.rawItemWidth}}width: {{item.rawItemWidth}}px{{/if}}"
{{#if (eq item.contentType 'RAW')}}value="{{item.rawContent}}"{{else if (eq item.contentType 'HTML')}}:value="`{{item.htmlContent}}`"{{/if}}/>
</a-col>
{{/eq}}
<a-tab-pane key="{{item.codeName}}" tab="{{item.caption}}">
<a-tab-pane v-show="state.detailsModel.{{item.codeName}}.visible" key="{{item.codeName}}" tab="{{item.caption}}">
{{#eq item.psLayout.layout "FLEX"}}
<div class="app-form-layout-flex" style="{{#if item.psLayout.dir}}flex-direction: {{item.psLayout.dir}};{{/if}}{{#if item.psLayout.align}}justify-content: {{item.psLayout.align}};{{/if}}{{#if item.psLayout.vAlign}}align-items: {{item.psLayout.vAlign}};{{/if}}">
{{#each item.psDEFormDetails as | formDetail |}}
......
......@@ -8,4 +8,5 @@
{{#*inline "FORMPART"}}{{>@macro/form-detail/form-formpart.hbs}}{{/inline}}
{{#*inline "TABPAGE"}}{{>@macro/form-detail/form-tabpage.hbs}}{{/inline}}
{{#*inline "DRUIPART"}}{{>@macro/form-detail/form-druipart.hbs}}{{/inline}}
{{#*inline "FORMDETAILSMODEL"}}{{>@macro/form-detail/form-details-model.hbs}}{{/inline}}
\ No newline at end of file
{{#*inline "FORMDETAILSMODEL"}}{{>@macro/form-detail/form-details-model.hbs}}{{/inline}}
{{#*inline "FORMACTIONMODEL"}}{{>@macro/form-detail/form-action-model.hbs}}{{/inline}}
\ No newline at end of file
......@@ -5,7 +5,7 @@
{{else if (eq item.columnType 'UAGRIDCOLUMN')}}
{{#each item.psDEUIActionGroup.psUIActionGroupDetails as | action |}}
{{#action}}
{ name: "{{name}}", caption: "{{psUIAction.caption}}", showIcon: {{showIcon}}, showCaption: {{showCaption}}, separator: {{addSeparator}}, uIActionTag: "{{psUIAction.uIActionTag}}", noPrivDisplayMode: {{#if psUIAction.noPrivDisplayMode}}{{psUIAction.noPrivDisplayMode}}{{else}}6{{/if}}, disabled: false, visible: true,{{#if psUIAction.psSysImage}}{{#if psUIAction.psSysImage.imagePath}} imgPath: "{{psUIAction.psSysImage.imagePath}}",{{/if}}{{#if psUIAction.psSysImage.cssClass}} iconClass: "{{psUIAction.psSysImage.cssClass}}",{{/if}}{{/if}} },
{ name: "{{name}}", caption: "{{psUIAction.caption}}", showIcon: {{showIcon}}, showCaption: {{showCaption}}, separator: {{addSeparator}}, uIActionTag: "{{psUIAction.uIActionTag}}", noPrivDisplayMode: {{psUIAction.noPrivDisplayMode}}, dataAccessAction: '{{psUIAction.dataAccessAction}}', actionTarget: '{{psUIAction.actionTarget}}', disabled: false, visible: true,{{#if psUIAction.psSysImage}}{{#if psUIAction.psSysImage.imagePath}} imgPath: "{{psUIAction.psSysImage.imagePath}}",{{/if}}{{#if psUIAction.psSysImage.cssClass}} iconClass: "{{psUIAction.psSysImage.cssClass}}",{{/if}}{{/if}} },
{{/action}}
{{/each}}
{{/if}}
\ No newline at end of file
......@@ -19,7 +19,7 @@ const emit = defineEmits<FormGroupEmit>();
:title="title"
:bordered="false">
<template #extra>
<a href="#">行为</a>
<!-- <a href="#">行为</a> -->
</template>
<slot></slot>
</a-card>
......
......@@ -35,4 +35,11 @@ export interface MainControlState extends ControlStateBase {
* @memberof MainControlState
*/
UIService: IParam;
/**
* @description 应用实体名称
* @type {string}
* @memberof MainControlState
*/
appDeCodeName: string;
}
\ No newline at end of file
......@@ -274,139 +274,4 @@ export class RouteUtil {
public static getIndexViewParam(): any {
return this.indexViewParam;
}
/**
* 计算界面行为项权限状态
*
* @static
* @param {*} [data] 传入数据
* @param {*} [ActionModel] 界面行为模型
* @param {*} [UIService] 界面行为服务
* @memberof RouteUtil
*/
public static calcActionItemAuthState(data: any, ActionModel: any, UIService: any) {
let result: any[] = [];
if (!UIService) return;
for (const key in ActionModel) {
if (!ActionModel.hasOwnProperty(key)) {
return result;
}
const _item = ActionModel[key];
let dataActionResult: any;
if (_item && _item['dataAccessAction']) {
if (Object.is(_item['actionTarget'], 'NONE') || Object.is(_item['actionTarget'], '')) {
dataActionResult = UIService.getAllOPPrivs(undefined, _item['dataAccessAction']);
} else {
if (data && Object.keys(data).length > 0) {
dataActionResult = UIService.getAllOPPrivs(data, _item['dataAccessAction']);
}
}
} else {
dataActionResult = 1;
}
// 无权限:0;有权限:1
if (dataActionResult === 0) {
// 禁用:1;隐藏:2;隐藏且默认隐藏:6
if (_item.getNoPrivDisplayMode === 1) {
_item.disabled = true;
}
if (_item.getNoPrivDisplayMode === 2 || _item.getNoPrivDisplayMode === 6) {
_item.visabled = false;
} else {
_item.visabled = true;
}
}
if (dataActionResult === 1) {
_item.visabled = true;
_item.disabled = false;
}
// 返回权限验证的结果
_item.dataActionResult = dataActionResult;
result.push(dataActionResult);
}
return result;
}
/**
* 计算界面行为项权限状态(树节点版本)
*
* @static
* @param {*} [data] 传入数据
* @param {*} [ActionModel] 界面行为模型
* @param {*} [UIService] 界面行为服务
* @memberof RouteUtil
*/
public static calcTreeActionItemAuthState(data: any, ActionModel: any, UIService: any) {
let result: any[] = [];
if (!UIService) return;
for (const key in ActionModel) {
if (!ActionModel.hasOwnProperty(key)) {
return result;
}
const _item = ActionModel[key];
let dataActionResult: any;
if (Object.is(_item['actiontarget'], 'NONE') || Object.is(_item['actiontarget'], '')) {
dataActionResult = UIService.getAllOPPrivs(undefined, _item['dataaccaction']);
} else {
if (_item && _item['dataaccaction'] && UIService.isEnableDEMainState) {
if (data && Object.keys(data).length > 0) {
dataActionResult = UIService.getAllOPPrivs(data, _item['dataaccaction']);
}
}
}
// 无权限:0;有权限:1
if (dataActionResult === 0) {
// 禁用:1;隐藏:2;隐藏且默认隐藏:6
if (_item.noprivdisplaymode === 1) {
_item.disabled = true;
}
if (_item.noprivdisplaymode === 2 || _item.noprivdisplaymode === 6) {
_item.visabled = false;
} else {
_item.visabled = true;
}
}
if (dataActionResult === 1) {
_item.visabled = true;
_item.disabled = false;
}
// 返回权限验证的结果
_item.dataActionResult = dataActionResult;
result.push(dataActionResult);
}
return result;
}
/**
* 计算重定向上下文
*
* @static
* @param {*} [tempContext] 上下文
* @param {*} [data] 传入数据
* @param {*} [redirectAppEntity] 应用实体对象
* @memberof RouteUtil
*/
public static async calcRedirectContext(tempContext: any, data: any, redirectAppEntity: any) {
if (
redirectAppEntity &&
redirectAppEntity.getMinorPSAppDERSs() &&
(redirectAppEntity.getMinorPSAppDERSs() as []).length > 0
) {
for (const item of redirectAppEntity.getMinorPSAppDERSs()) {
const parentPSAppDEFieldCodeName: string = item.M.getParentPSAppDEField?.codeName;
if (parentPSAppDEFieldCodeName) {
const curData: any = data;
if (curData && curData[parentPSAppDEFieldCodeName.toLowerCase()]) {
const majorAppEntity: any = item.getMajorPSAppDataEntity();
await majorAppEntity.fill();
if (!tempContext[majorAppEntity.codeName.toLowerCase()]) {
Object.assign(tempContext, {
[majorAppEntity.codeName.toLowerCase()]: curData[parentPSAppDEFieldCodeName.toLowerCase()],
});
}
}
}
}
}
}
}
......@@ -38,17 +38,17 @@ export class UIUtil {
// 无权限:0;有权限:1
if (dataActionResult === 0) {
// 禁用:1;隐藏:2;隐藏且默认隐藏:6
if (item.getNoPrivDisplayMode === 1) {
if (item.noPrivDisplayMode === 1) {
item.disabled = true;
}
if (item.getNoPrivDisplayMode === 2 || item.getNoPrivDisplayMode === 6) {
item.visabled = false;
if (item.noPrivDisplayMode === 2 || item.noPrivDisplayMode === 6) {
item.visible = false;
} else {
item.visabled = true;
item.visible = true;
}
}
if (dataActionResult === 1) {
item.visabled = true;
item.visible = true;
item.disabled = false;
}
// 返回权限验证的结果
......
......@@ -52,11 +52,16 @@ export const CtrlConfig = {
controlName: '{{ctrl.name}}',
controlService: new EditFormService<ControlVO>(ControlVO, new {{pascalCase ctrl.psAppDataEntity.codeName}}Service() ),
data: new ControlVO({}),
formDetails: {
detailsModel: {
{{#each ctrl.psDEFormPages as | FormPage | }}
{{>(lookup 'FORMDETAILSMODEL') items=FormPage.psDEFormDetails}}
{{/each}}
},
actionModel: {
{{#each ctrl.psDEFormPages as | FormPage | }}
{{>(lookup 'FORMACTIONMODEL') items=FormPage.psDEFormDetails}}
{{/each}}
},
rules: {
{{#each ctrl.psDEFormEditItemVRs as | ruleItem |}}
{{#neq ruleItem 2}}
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册