Merge branch 'dev' of codeup.aliyun.com:61c14a7efa282c88e103c23f/oak-general-business into dev

This commit is contained in:
Xu Chang 2022-08-10 14:22:37 +08:00
commit 5c4efc3486
8 changed files with 288 additions and 145 deletions

View File

@ -13,7 +13,7 @@ export default function render() {
theme="primary"
icon={<ChevronUpIcon />}
style={{
position: 'absolute',
position: 'fixed',
bottom: 0,
right: '45vw',
...style,

View File

@ -1,4 +1,8 @@
{
"ptrActivate": "松开刷新",
"ptrDeactivate": "下拉刷新",
"ptrRelease": "正在刷新...",
"ptrFinish": "刷新完成",
"action": {
"create": "创建",
"update": "更新",

View File

@ -1,3 +1,4 @@
/** index.wxss **/
@import "../../../config/styles/_base.less";
@import "../../../config/styles/_mixins.less";
@ -14,19 +15,111 @@
.safe-area-inset-bottom();
}
.t-tabs {
&__nav {
.loginbox-main {
height: 100vh;
display: flex;
flex: 1;
align-items: center;
flex-direction: column;
justify-content: center;
}
.loginbox-wrap {
width: 400px;
display: block;
background: #fff;
border-radius: 4px;
overflow: hidden;
box-shadow: 0 2px 4px rgb(0 0 0 / 8%), 0 0 4px rgb(0 0 0 / 8%);
}
.loginbox-hd {
padding: 32px;
&__tab {
width: 100%;
height: 38px;
background-color: rgba(0, 0, 0, .04) !important;
}
&__nav-wrap {
&__tabcon {
width: 100%;
}
&__nav-item {
width: 50%;
display: flex;
justify-content: center;
}
}
.loginbox-bd {
height: 310px;
}
.tabPanel {
padding-top: 16px;
.loginbox-only {
padding-top: 32px !important;
}
.loginbox-mobile {
position: relative;
padding: 0 32px;
}
.loginbox-password {
position: relative;
padding: 0 32px;
}
.loginbox-qrcode {
padding: 0 32px;
font-size: 14px;
&__sociallogin {
margin-bottom: 15px;
text-align: center;
color: #999;
}
&__refresh {
color: var(--td-text-color-brand);
margin-left: 10px;
cursor: pointer;
&-icon {
color: var(--td-text-color-brand)
}
}
&__iframe {
position: relative;
width: 160px;
height: 160px;
margin: 0 auto;
border: #999 solid 1px;
}
}
.current {
color: var(--td-text-color-brand) !important;
cursor: default;
background-color: #fff;
border-radius: 4px;
}
.loginbox-input {
.t-input {
background-color: rgba(0, 0, 0, .04) !important;
}
}
.loginbox-ft {
height: 54px;
border-top: 1px solid #f2f3f5;
font-size: 14px;
&__btn {
}
}
.loginbox-protocal {
padding: 20px 32px;
}

View File

@ -4,8 +4,9 @@ import {
isPassword,
isCaptcha,
} from 'oak-domain/lib/utils/validator';
import { DesktopIcon, LockOnIcon, MobileIcon } from 'tdesign-icons-react';
import { Form, Input, Button, Checkbox, Tabs } from 'tdesign-react';
import { DesktopIcon, LockOnIcon, MobileIcon, Icon } from 'tdesign-icons-react';
import { Form, Input, Button, Checkbox, Tabs, Radio } from 'tdesign-react';
import classNames from 'classnames';
const { TabPanel } = Tabs;
const { FormItem } = Form;
@ -13,7 +14,7 @@ const { FormItem } = Form;
export default function render() {
const { t } = this;
const { onlyCaptcha, onlyPassword, width } = this.props;
const { mobile, captcha, password, counter } = this.state;
const { mobile, captcha, password, counter, tabValue = 1} = this.state;
const validMobile = isMobile(mobile);
const validCaptcha = isCaptcha(captcha);
const validPassword = isPassword(password);
@ -29,13 +30,14 @@ export default function render() {
data-attr="mobile"
maxlength={11}
prefixIcon={<MobileIcon />}
placeholder="Mobile"
placeholder={t('placeholder.Mobile')}
size="large"
onChange={(value, context) => {
this.setState({
mobile: value,
});
}}
className="loginbox-input"
/>
</FormItem>
<FormItem name="password">
@ -45,18 +47,16 @@ export default function render() {
data-attr="password"
prefixIcon={<LockOnIcon />}
type="password"
placeholder="Password"
placeholder={t('placeholder.Password')}
size="large"
onChange={(value, context) => {
this.setState({
password: value,
});
}}
className="loginbox-input"
/>
</FormItem>
<FormItem>
<Checkbox>{t('Remember me')}</Checkbox>
</FormItem>
<FormItem>
<Button
@ -82,13 +82,14 @@ export default function render() {
type="tel"
maxlength={11}
prefixIcon={<MobileIcon />}
placeholder="Mobile"
placeholder={t('placeholder.Mobile')}
size="large"
onChange={(value, context) => {
this.setState({
mobile: value,
});
}}
className="loginbox-input"
/>
</FormItem>
<FormItem name="captcha">
@ -96,24 +97,28 @@ export default function render() {
clearable
value={captcha}
data-attr="captcha"
type="number"
// type="number"
maxlength={4}
placeholder="Captcha"
placeholder={t('placeholder.Captcha')}
size="large"
onChange={(value, context) => {
this.setState({
captcha: value,
});
}}
className="loginbox-input"
suffix={
<Button
variant="text"
size="small"
theme="primary"
disabled={!validMobile || counter > 0}
onClick={() => this.sendCaptcha()}
>
{counter > 0 ? `${counter}秒后可重发` : t('Send')}
</Button>
}
/>
<Button
size="large"
theme="primary"
disabled={!validMobile || counter > 0}
onClick={() => this.sendCaptcha()}
>
{counter > 0 ? counter : t('Send')}
</Button>
</FormItem>
<FormItem>
@ -130,87 +135,122 @@ export default function render() {
</FormItem>
</Form>
);
if (onlyCaptcha) {
return (
<div className="page-body">
<div
style={{
flex: 2,
}}
/>
{LoginCaptcha}
<div
style={{
flex: 3,
}}
/>
</div>
);
return (
<div className="loginbox-main">
<div className="loginbox-wrap">
<div className="loginbox-bd">
<div className="loginbox-mobile loginbox-only">
{LoginCaptcha}
</div>
</div>
</div>
</div>
);
} else if (onlyPassword) {
return (
<div className="page-body">
<div
style={{
flex: 2,
}}
/>
{LoginPassword}
<div
style={{
flex: 3,
}}
/>
</div>
);
return (
<div className="loginbox-main">
<div className="loginbox-wrap">
<div className="loginbox-bd">
<div className="loginbox-password loginbox-only">
{LoginPassword}
</div>
</div>
</div>
</div>
);
}
return (
<div className="page-body">
<div
style={{
flex: 2,
}}
/>
<div
style={{
minHeight: 500,
lineHeight: 22,
width: width === 'xs' ? 320 : 400,
}}
>
<Tabs
theme="normal"
placement="top"
defaultValue="1"
size="medium"
onChange={(value) => {
this.setState({
tabValue: value,
});
}}
>
<TabPanel
className="tabPanel"
key="tab_1"
label={t('in Password')}
value="1"
<div className="loginbox-main">
<div className="loginbox-wrap">
<div className="loginbox-hd">
<Radio.Group
variant="default-filled"
defaultValue={tabValue}
onChange={(value) => {
this.setState({
tabValue: value,
});
}}
className="loginbox-hd__tab"
>
<Radio.Button
value={1}
className={classNames('loginbox-hd__tabcon', {
current: tabValue === 1,
})}
>
{t('in Password')}
</Radio.Button>
<Radio.Button
value={2}
className={classNames('loginbox-hd__tabcon', {
current: tabValue === 2,
})}
>
{t('in Captcha')}
</Radio.Button>
<Radio.Button
value={3}
className={classNames('loginbox-hd__tabcon', {
current: tabValue === 3,
})}
>
{t('in QrCode')}
</Radio.Button>
</Radio.Group>
</div>
<div className="loginbox-bd">
<div
className="loginbox-password"
style={tabValue === 1 ? {} : { display: 'none' }}
>
{LoginPassword}
</TabPanel>
<TabPanel
className="tabPanel"
key="tab_2"
label={t('in Captcha')}
value="2"
</div>
<div
className="loginbox-mobile"
style={tabValue === 2 ? {} : { display: 'none' }}
>
{LoginCaptcha}
</TabPanel>
</Tabs>
</div>
<div
className="loginbox-qrcode"
style={tabValue === 3 ? {} : { display: 'none' }}
>
<div className="loginbox-qrcode__sociallogin">
使
<span
className="loginbox-qrcode__refresh"
onClick={() => {
this.setMessage({
type: 'success',
content: '刷新二维码'
})
}}
>
<Icon
name="refresh"
className="loginbox-qrcode__refresh-icon"
/>
</span>
</div>
<div className="loginbox-qrcode__iframe"></div>
</div>
</div>
<div className="loginbox-ft">
<div className="loginbox-ft__btn">
<div className="loginbox-protocal">
<Checkbox
label={
<div> </div>
}
/>
</div>
</div>
</div>
</div>
<div
style={{
flex: 3,
}}
/>
</div>
);
}

View File

@ -3,5 +3,11 @@
"Remember me": "记住账号",
"in Password": "账号登录",
"in Captcha": "手机号登录",
"Send": "发送验证码"
"in QrCode": "扫码登录",
"Send": "发送验证码",
"placeholder": {
"Captcha": "输入4位短信验证码",
"Mobile": "请输入手机号",
"Password": "请输入密码"
}
}

View File

@ -6,7 +6,7 @@ export default function render() {
const { t } = this;
const { event } = this.props;
const { userArr = [], oakLoading, stateColor, pagination } = this.state;
const { step } = pagination || {};
const { pageSize, total, currentPage } = pagination || {};
return (
<div style={{ padding: 16 }}>
@ -118,11 +118,11 @@ export default function render() {
},
]}
pagination={{
total: 30,
pageSize: step,
total: total,
pageSize: pageSize,
current: currentPage,
onPageSizeChange: (pageSize: number) => {
this.setPageSize(pageSize)
this.setPageSize(pageSize);
},
}}
/>

View File

@ -133,26 +133,50 @@ export default OakPage({
},
},
methods: {
onAdd() {
if (process.env.OAK_PLATFORM === 'web') {
this.goUpsert();
} else {
this.setState({
visible: true,
});
}
},
goUpsert() {
const { entity, entityId, relations } = this.props;
this.navigateTo(
{
url: '/userRelation/upsert',
entity,
entityId,
relations,
},
{
relations,
}
);
},
goUserEntityGrantWithGrant() {
const { entity, entityId, relations } = this.props;
this.navigateTo(
{
url: '/userEntityGrant/grant',
entity,
entityId,
},
{
relations,
}
);
},
onActionSelect(e: any) {
const { index, selected } = e.detail;
const { entity, entityId, relations } = this.props;
switch (index) {
case 0: {
this.navigateTo({
url: '/userEntityGrant/grant',
entity,
entityId,
relations,
});
this.goUserEntityGrantWithGrant();
}
case 1: {
this.navigateTo({
url: '/userRelation/upsert',
entity,
entityId,
relations,
});
this.goUpsert();
}
}
},
@ -178,30 +202,6 @@ export default OakPage({
entityId,
});
},
goUpsert() {
const { entity, entityId, relations } = this.props;
if (process.env.OAK_PLATFORM === 'web') {
this.navigateTo({
url: '/userRelation/upsert',
entity,
entityId,
relations,
});
} else {
this.setState({
visible: true,
});
}
},
goUserEntityGrantWithGrant() {
const { entity, entityId, relations } = this.props;
this.navigateTo({
url: '/userEntityGrant/grant',
entity,
entityId,
relations,
});
},
async searchChange(event: any) {
const { value } = this.resolveInput(event);
this.addNamedFilter({

View File

@ -19,6 +19,6 @@
</view>
</t-cell>
</block>
<t-fab style="right: 0; bottom: 32px" icon="add" bind:click="goUpsert" />
<t-fab style="right: 0; bottom: 32px" icon="add" bind:click="onAdd" />
</view>
<t-action-sheet id="t-action-sheet" items="{{btnItems}}" visible="{{visible}}" bind:selected="onActionSelect" bind:cancel="onActionCancel" bind:close="onActionClose" />