oakicon 引用frontend

This commit is contained in:
Wang Kejun 2023-11-08 20:14:51 +08:00
parent 83559d4b17
commit 3004a5a6aa
95 changed files with 192 additions and 2996 deletions

View File

@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"oak-icon": "../../icon/index",
"oak-icon": "@oak-frontend-base/icon/index",
"l-badge": "@oak-frontend-base/miniprogram_npm/lin-ui/badge/index"
}
}

View File

@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"oak-icon": "../../icon/index",
"oak-icon": "@oak-frontend-base/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-icon": "@oak-frontend-base/miniprogram_npm/lin-ui/icon/index",
"l-grid": "@oak-frontend-base/miniprogram_npm/lin-ui/grid/index",

View File

@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"oak-icon": "../../icon/index",
"oak-icon": "@oak-frontend-base/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-arc-popup": "@oak-frontend-base/miniprogram_npm/lin-ui/arc-popup/index",
"l-dialog": "@oak-frontend-base/miniprogram_npm/lin-ui/dialog/index",

View File

@ -2,11 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
import React, { useState } from 'react';
import { Button, Space, Drawer, Modal, Tooltip } from 'antd';
import Style from './web.module.less';
import OakIcon from '../../icon';
import OakIcon from 'oak-frontend-base/es/components/icon';
import IconDemo from '../../icon';
export default function render(props) {
const { placement = 'bottom', style = {} } = props.data;
const { printCachedStore, printDebugStore, printRunningTree, resetInitialData, downloadEnv, resetEnv } = props.methods;
const [visible, setVisible] = useState(false);
const [iconOpen, setIconOpen] = useState(false);
return (_jsxs(React.Fragment, { children: [_jsx(Button, { type: "text", shape: "circle", icon: _jsx(OakIcon, { name: "packup" }), style: {
position: 'fixed',
bottom: 0,
@ -68,6 +70,13 @@ export default function render(props) {
},
});
}, children: "Reset" }) }), _jsx(Tooltip, { title: "\u67E5\u770BOakIcon", children: _jsx(Button, { size: "large", type: "primary", shape: "circle", onClick: () => {
window.open('/icon');
}, children: "Icon" }) })] })] })] }));
setIconOpen(true);
}, children: "Icon" }) })] })] }), _jsx(Modal, { width: 960, title: "oak-icon", footer: null, open: iconOpen, onCancel: () => {
setIconOpen(false);
}, styles: {
body: {
height: window.innerHeight - 200,
overflowY: 'auto'
}
}, children: _jsx(IconDemo, {}) })] }));
}

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,4 @@
/// <reference types="wechat-miniprogram" />
/// <reference types="react" />
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../oak-app-domain").EntityDict, keyof import("../../oak-app-domain").EntityDict, false, {
name: string;
size: number;
color: string;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../oak-app-domain").EntityDict, keyof import("../../oak-app-domain").EntityDict, true, WechatMiniprogram.Component.DataOption>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -1,11 +1,4 @@
export default OakComponent({
isList: false,
wechatMp: {
externalClasses: ['oak-class'],
},
properties: {
name: '',
size: 0,
color: '',
},
isList: true,
methods: {},
});

View File

@ -1,3 +1,4 @@
{
"component": true
"navigationBarTitleText": "OakIcon示例",
"usingComponents": {}
}

View File

@ -1,22 +1,6 @@
@import './iconfont.less';
@import '../../config/styles/mp/index.less';
.oak-icon__primary {
color: @oak-color-primary;
.page-body {
display: flex;
}
.oak-icon__error {
color: @oak-color-error;
}
.oak-icon__warning {
color: @oak-color-warning;
}
.oak-icon__success {
color: @oak-color-success;
}
.oak-icon__info {
color: @oak-color-info;
}

View File

@ -1 +1,4 @@
<view class="oak-icon {{ name === '' ? '' : 'oak-icon-' + name }} {{ color === '' || color === 'primary' || color === 'info' || color === 'error' || color === 'success' || color === 'warning' ? 'oak-icon__' + (color || 'primary') : ''}} oak-class" style="font-size: {{ size || 14 }}px; {{ color && color !== 'primary' && color !== 'info'&& color !== 'error'&& color !== 'success'&& color !== 'warning' ? 'color:' + color : '' }}"></view>
<!-- index.wxml -->
<view class="page-body">
未实现
</view>

View File

@ -1,11 +1,3 @@
import { WebComponentProps } from 'oak-frontend-base';
import React from 'react';
import { EntityDict } from '../../oak-app-domain';
import './web.less';
export default function Render(props: WebComponentProps<EntityDict, 'user', false, {
name: string;
color?: 'primary' | 'success' | 'error' | 'waring' | 'info' | string;
size?: string;
className?: string;
style?: React.CSSProperties;
}, {}>): import("react/jsx-runtime").JSX.Element;
import { WebComponentProps } from 'oak-frontend-base';
export default function Render(props: WebComponentProps<EntityDict, 'token', true, {}, {}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,15 +1,47 @@
import { jsx as _jsx } from "react/jsx-runtime";
import './web.less';
export default function Render(props) {
const { data } = props;
const { name, color = '', size, className, style = {}, } = data;
const isColor = ['primary', 'info', 'success', 'error', 'warning'].includes(color);
let class_name = 'oak-icon ' + 'oak-icon-' + name;
if (isColor || color === '') {
class_name += ' ' + 'oak-icon__' + (color || 'primary');
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import JsonData from './iconfont.json';
import OakIcon from 'oak-frontend-base/es/components/icon';
import Style from './web.module.less';
/**
* 复制文本到剪切板中
*
* @export
* @param {*} value 需要复制的文本
* @param {*} cb 复制成功后的回调
*/
function copy(value, cb) {
// 动态创建 textarea 标签
const textarea = document.createElement('textarea');
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly';
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
// 将要 copy 的值赋给 textarea 标签的 value 属性
// 网上有些例子是赋值给innerText,这样也会赋值成功,但是识别不了\r\n的换行符赋值给value属性就可以
textarea.value = value;
// 将 textarea 插入到 body 中
document.body.appendChild(textarea);
// 选中值并复制
textarea.select();
textarea.setSelectionRange(0, textarea.value.length);
document.execCommand('Copy');
document.body.removeChild(textarea);
if (cb && Object.prototype.toString.call(cb) === '[object Function]') {
cb();
}
if (className) {
class_name += ' ' + className;
}
return (_jsx("span", { className: class_name, style: Object.assign(style, size && { fontSize: size }, color && !isColor && { color }) }));
}
export default function Render(props) {
const { methods } = props;
const icons = JsonData.glyphs;
return (_jsx("div", { className: Style.container, children: _jsx("ul", { className: Style.dibBox, children: icons.map((ele) => {
return (_jsxs("li", { className: Style.dib, onClick: () => {
const content = `<OakIcon name='${ele.name}' />`;
copy(content, () => {
methods.setMessage({
type: 'success',
content,
});
});
}, children: [_jsx("div", { className: Style.iconBox, children: _jsx(OakIcon, { name: ele.name, size: 40 }) }), _jsx("div", { className: Style.name, children: ele.name })] }));
}) }) }));
}

View File

@ -1,21 +0,0 @@
@import './iconfont.less';
.oak-icon__primary {
color: var(--oak-color-primary);
}
.oak-icon__error {
color: var(--oak-color-error);
}
.oak-icon__warning {
color: var(--oak-color-warning);
}
.oak-icon__success {
color: var(--oak-color-success);
}
.oak-icon__info {
color: var(--oak-color-info);
}

View File

@ -1,7 +1,7 @@
.container {
display: flex;
padding: 30px 100px;
width: 960px;
width: 900px;
margin: 0 auto;
background-color: var(--oak-bg-color-page);
}

View File

@ -1,7 +1,7 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { Avatar } from 'antd';
import Styles from './web.module.less';
import OakIcon from '../../icon/index';
import OakIcon from 'oak-frontend-base/es/components/icon';
export default function Render(props) {
const { data: { avatarUrl, shape, size, iconColor, iconName, onClick } } = props;
return avatarUrl ? (_jsx(Avatar, { className: onClick ? Styles.avatar : undefined, src: avatarUrl, shape: shape, size: size, onClick: onClick })) : (_jsx(Avatar, { className: onClick ? Styles.avatar : undefined, icon: _jsx(OakIcon, { name: iconName, color: iconColor }), shape: shape, size: size, onClick: onClick }));

View File

@ -3,7 +3,7 @@ import { useState } from 'react';
import Styles from './web.pc.module.less';
import { Button, List, Popup, Tag, Input, Radio, Form, Space } from 'antd-mobile';
import MyAvatar from '../avatar';
import OakIcon from '../../icon';
import OakIcon from 'oak-frontend-base/es/components/icon';
const PrimaryColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-primary');
const WarningColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-warning');
const ErrorColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-error');

View File

@ -3,7 +3,7 @@ import { useState } from 'react';
import Styles from './web.pc.module.less';
import { Button, List, Modal, Tag, Input, Radio } from 'antd';
import MyAvatar from '../avatar';
import OakIcon from '../../icon';
import OakIcon from 'oak-frontend-base/es/components/icon';
const PrimaryColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-primary');
const WarningColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-warning');
const ErrorColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-error');

View File

@ -1,7 +1,7 @@
{
"navigationBarTitleText": "个人中心",
"usingComponents": {
"oak-icon": "../../../components/icon/index",
"oak-icon": "@oak-frontend-base/components/icon/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-avatar": "@oak-frontend-base/miniprogram_npm/lin-ui/avatar/index"

View File

@ -2,7 +2,7 @@
"navigationBarTitleText": "用户详情",
"usingComponents": {
"actionPanel": "../../../../components/func/actionPanel/index",
"oak-icon": "../../../../components/icon/index",
"oak-icon": "@oak-frontend-base/components/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-avatar": "@oak-frontend-base/miniprogram_npm/lin-ui/avatar/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",

View File

@ -1,6 +0,0 @@
/// <reference types="react" />
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../oak-app-domain").EntityDict, keyof import("../../oak-app-domain").EntityDict, false, {
showBack: boolean;
userId: string;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -1,38 +0,0 @@
import { OakUserInvisibleException } from 'oak-domain/lib/types';
export default OakComponent({
isList: false,
properties: {
showBack: false,
userId: '',
},
data: {
currentUserId: '',
},
lifetimes: {
attached() {
const { userId } = this.props;
const currentUserId = this.features.token.getUserId(true);
if (!currentUserId) {
this.setMessage({
type: 'error',
content: '您尚未登录',
});
this.navigateTo({
url: '/login',
}, undefined, true);
return;
}
if (userId && currentUserId) {
if (userId !== currentUserId) {
const isRoot = this.features.token.isRoot();
if (!isRoot) {
throw new OakUserInvisibleException();
}
}
}
this.setState({
currentUserId,
});
},
},
});

View File

@ -1,38 +0,0 @@
/** index.wxss **/
@import "../../../config/styles/mp/index.less";
@import "../../../config/styles/mp/mixins.less";
.page-body {
height: 100vh;
display: flex;
flex: 1;
flex-direction: column;
box-sizing: border-box;
align-items: stretch;
background-color: @oak-bg-color-page;
.safe-area-inset-bottom();
}
.container {
flex: 1;
display: flex;
flex-direction: column;
}
.container2 {
flex-direction: row;
align-items: center;
justify-content: center;
}
.card {
min-width: 480rpx;
text-align: center;
}
.list {
background-color: #fff;
margin-top: 20rpx;
padding: 0 20rpx;
}

View File

@ -1,7 +0,0 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../oak-app-domain';
export default function render(props: WebComponentProps<EntityDict, 'mobile', true, {
showBack: boolean;
userId: string;
currentUserId: string;
}, {}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,7 +0,0 @@
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import Style from './web.module.less';
import ChangePassword from '../../components/changePassword';
export default function render(props) {
const { showBack, userId, currentUserId } = props.data;
return ((userId || currentUserId) ? _jsx("div", { className: Style.container, children: _jsx(ChangePassword, { oakId: userId || currentUserId, oakPath: "$changePassword-component", oakAutoUnmount: true }) }) : _jsx(_Fragment, {}));
}

View File

@ -1,12 +0,0 @@
.container {
background: var(--oak-bg-color-container);
box-shadow: 0 2px 3px #0000001a;
border-radius: 3px;
padding: 30px 32px;
}
.list {
margin-top: 10px !important;
}

View File

@ -1,7 +0,0 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../oak-app-domain';
export default function render(props: WebComponentProps<EntityDict, 'mobile', true, {
showBack: boolean;
userId: string;
currentUserId: string;
}, {}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,8 +0,0 @@
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
import Style from './web.module.less';
import PageHeader from '../../components/common/pageHeader';
import ChangePassword from '../../components/changePassword';
export default function render(props) {
const { showBack, userId, currentUserId } = props.data;
return ((userId || currentUserId) ? _jsx(PageHeader, { showBack: showBack, title: "\u5BC6\u7801\u8BBE\u7F6E", children: _jsx("div", { className: Style.container, children: _jsx(ChangePassword, { oakId: userId || currentUserId, oakPath: "$changePassword-component", oakAutoUnmount: true }) }) }) : _jsx(_Fragment, {}));
}

View File

@ -1,4 +0,0 @@
/// <reference types="wechat-miniprogram" />
/// <reference types="react" />
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../oak-app-domain").EntityDict, keyof import("../../oak-app-domain").EntityDict, true, WechatMiniprogram.Component.DataOption>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -1,4 +0,0 @@
export default OakComponent({
isList: true,
methods: {},
});

View File

@ -1,4 +0,0 @@
{
"navigationBarTitleText": "OakIcon示例",
"usingComponents": {}
}

View File

@ -1,6 +0,0 @@
.page-body {
display: flex;
}

View File

@ -1,4 +0,0 @@
<!-- index.wxml -->
<view class="page-body">
未实现
</view>

View File

@ -1,3 +0,0 @@
import { EntityDict } from '../../oak-app-domain';
import { WebComponentProps } from 'oak-frontend-base';
export default function Render(props: WebComponentProps<EntityDict, 'token', true, {}, {}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,47 +0,0 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import JsonData from './iconfont.json';
import OakIcon from '../../components/icon';
import Style from './web.module.less';
/**
* 复制文本到剪切板中
*
* @export
* @param {*} value 需要复制的文本
* @param {*} cb 复制成功后的回调
*/
function copy(value, cb) {
// 动态创建 textarea 标签
const textarea = document.createElement('textarea');
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly';
textarea.style.position = 'absolute';
textarea.style.left = '-9999px';
// 将要 copy 的值赋给 textarea 标签的 value 属性
// 网上有些例子是赋值给innerText,这样也会赋值成功,但是识别不了\r\n的换行符赋值给value属性就可以
textarea.value = value;
// 将 textarea 插入到 body 中
document.body.appendChild(textarea);
// 选中值并复制
textarea.select();
textarea.setSelectionRange(0, textarea.value.length);
document.execCommand('Copy');
document.body.removeChild(textarea);
if (cb && Object.prototype.toString.call(cb) === '[object Function]') {
cb();
}
}
export default function Render(props) {
const { methods } = props;
const icons = JsonData.glyphs;
return (_jsx("div", { className: Style.container, children: _jsx("ul", { className: Style.dibBox, children: icons.map((ele) => {
return (_jsxs("li", { className: Style.dib, onClick: () => {
const content = `<OakIcon name='${ele.name}' />`;
copy(content, () => {
methods.setMessage({
type: 'success',
content,
});
});
}, children: [_jsx("div", { className: Style.iconBox, children: _jsx(OakIcon, { name: ele.name, size: 40 }) }), _jsx("div", { className: Style.name, children: ele.name })] }));
}) }) }));
}

View File

@ -1,8 +0,0 @@
/// <reference types="react" />
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
onlyCaptcha: boolean;
onlyPassword: boolean;
eventLoggedIn: string;
callback: (() => void) | undefined;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -1,119 +0,0 @@
import { LOCAL_STORAGE_KEYS } from '../../../config/constants';
const SEND_KEY = LOCAL_STORAGE_KEYS.captchaSendAt;
const SEND_CAPTCHA_LATENCY = process.env.NODE_ENV === 'development' ? 10 : 60;
export default OakComponent({
isList: false,
projection: {
id: 1,
mobile: 1,
userId: 1,
},
data: {
mobile: '',
captcha: '',
counter: 0,
refreshing: false,
password: '',
},
properties: {
onlyCaptcha: false,
onlyPassword: false,
eventLoggedIn: '',
callback: undefined,
},
formData({ features }) {
const lastSendAt = features.localStorage.load(SEND_KEY);
const now = Date.now();
let counter = 0;
if (typeof lastSendAt === 'number') {
counter = Math.max(SEND_CAPTCHA_LATENCY - Math.ceil((now - lastSendAt) / 1000), 0);
if (counter > 0) {
this.counterHandler = setTimeout(() => this.reRender(), 1000);
}
else if (this.counterHandler) {
clearTimeout(this.counterHandler);
this.counterHandler = undefined;
}
}
return {
counter,
};
},
methods: {
setMobile(value) {
this.setState({
mobile: value,
});
},
setCaptcha(value) {
this.setState({
captcha: value,
});
},
async sendCaptcha() {
const { mobile } = this.state;
try {
const result = await this.features.token.sendCaptcha(mobile, 'login');
// 显示返回消息
this.setMessage({
type: 'success',
content: result,
});
this.save(SEND_KEY, Date.now());
this.reRender();
}
catch (err) {
this.setMessage({
type: 'error',
content: err.message,
});
}
},
async loginByMobile() {
const { eventLoggedIn, callback } = this.props;
const { mobile, password, captcha } = this.state;
try {
await this.features.token.loginByMobile(mobile, password, captcha);
if (typeof callback === 'function') {
callback();
}
else if (eventLoggedIn) {
this.pubEvent(eventLoggedIn);
}
else {
this.navigateBack();
}
}
catch (err) {
this.setMessage({
type: 'error',
content: err.message,
});
}
},
async onRefreshMobile(e) {
this.setState({
refreshing: true,
});
try {
const { code, errMsg } = e.detail;
if (errMsg !== 'getPhoneNumber:ok') {
console.error(errMsg);
this.setMessage({
title: '获取手机号失败',
type: 'warning',
});
}
else {
await this.features.token.getWechatMpUserPhoneNumber(code);
}
}
catch (err) {
console.error(err);
}
this.setState({
refreshing: false,
});
},
},
});

View File

@ -1,10 +0,0 @@
{
"navigationBarTitleText": "绑定手机号",
"usingComponents": {
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-card": "@oak-frontend-base/miniprogram_npm/lin-ui/card/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",
"l-icon": "@oak-frontend-base/miniprogram_npm/lin-ui/icon/index",
"l-dialog": "@oak-frontend-base/miniprogram_npm/lin-ui/dialog/index"
}
}

View File

@ -1,40 +0,0 @@
/** index.wxss **/
@import "../../../config/styles/mp/index.less";
@import "../../../config/styles/mp/mixins.less";
.page-body {
height: 100vh;
display: flex;
flex: 1;
flex-direction: column;
justify-content: center;
align-items: center;
box-sizing: border-box;
background-color: @oak-bg-color-page;
.safe-area-inset-bottom();
}
.container {
flex: 1;
display: flex;
flex-direction: column;
}
.container2 {
flex-direction: row;
align-items: center;
justify-content: center;
}
.card {
min-width: 480rpx;
text-align: center;
}
.list {
background-color: #fff;
margin-top: 20rpx;
padding: 0 20rpx;
}

View File

@ -1,30 +0,0 @@
<!-- index.wxml -->
<view class="page-body">
<block wx:if="{{mobiles && mobiles.length > 0}}">
<view class="container">
<view class="list" wx:for="{{mobiles}}">
<l-list icon="mobile" title="{{item.mobile}}" is-link="{{false}}">
<view slot="right-section">
<view bind:tap="onRemoveModalOpen" data-id="{{item.id}}">
<l-icon name="delete" size="24" />
</view>
</view>
</l-list>
</view>
</view>
</block>
<block wx:else>
<view class="container container2">
<l-card type="primary" plaintext="{{true}}">
<view class="card">
您尚未授权手机号
</view>
</l-card>
</view>
</block>
<l-button type="default" block size="long" open-type="getPhoneNumber" bindgetphonenumber="onRefreshMobile">
授权手机号
</l-button>
</view>
<l-dialog show="{{confirmDeleteModalVisible}}" type="confirm" title="提示" content="确认删除吗?删除后无法用此号码登录" bind:linconfirm="onRemoveConfirm" bind:lincancel="onRemoveModalClose" />

View File

@ -1,8 +0,0 @@
{
"Login": "确定",
"Send": "发送验证码",
"placeholder": {
"Captcha": "输入4位短信验证码",
"Mobile": "请输入手机号"
}
}

View File

@ -1,35 +0,0 @@
.loginbox-main {
height: 100vh;
display: flex;
flex: 1;
align-items: center;
flex-direction: column;
background: var(--oak-bg-color-container);
padding-top: 20%;
}
.loginbox-wrap {
width: 90%;
display: block;
background: var(--oak-bg-color-container);
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;
font-size: 14px;
font-weight: 500;
}
.loginbox-bd {
height: 200px;
}
.loginbox-mobile {
position: relative;
padding: 0 32px;
}

View File

@ -1,20 +0,0 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function render(props: WebComponentProps<EntityDict, 'token', false, {
counter: number;
loginMode?: number;
loginAgreed?: boolean;
appId: string;
onlyCaptcha?: boolean;
onlyPassword?: boolean;
loading: boolean;
backUrl?: string;
mobile: string;
captcha: string;
password: string;
}, {
setCaptcha: (mobile: string) => void;
setMobile: (mobile: string) => void;
sendCaptcha: () => Promise<void>;
loginByMobile: () => Promise<void>;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,20 +0,0 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { isMobile, isCaptcha, } from 'oak-domain/lib/utils/validator';
import { MobileOutlined } from '@ant-design/icons';
import { Form, Input, Button } from 'antd';
import Style from './mobile.module.less';
export default function render(props) {
const { mobile, captcha, password, counter } = props.data;
const { t, setMobile, setCaptcha, sendCaptcha, loginByMobile } = props.methods;
const validMobile = isMobile(mobile);
const validCaptcha = isCaptcha(captcha);
const allowSubmit = validMobile && validCaptcha;
const LoginCaptcha = (_jsxs(Form, { colon: true, children: [_jsx(Form.Item, { name: "mobile", children: _jsx(Input, { allowClear: true, value: mobile, "data-attr": "mobile", type: "tel", maxLength: 11, prefix: _jsx(MobileOutlined, {}), placeholder: t('placeholder.Mobile'), size: "large", onChange: (e) => {
setMobile(e.target.value);
}, className: Style['loginbox-input'] }) }), _jsx(Form.Item, { name: "captcha", children: _jsx(Input, { allowClear: true, value: captcha, "data-attr": "captcha",
// type="number"
maxLength: 4, placeholder: t('placeholder.Captcha'), size: "large", onChange: (e) => {
setCaptcha(e.target.value);
}, className: Style['loginbox-input'], suffix: _jsx(Button, { type: "link", disabled: !validMobile || counter > 0, onClick: () => sendCaptcha(), children: counter > 0 ? `${counter}秒后可重发` : t('Send') }) }) }), _jsx(Form.Item, { children: _jsx(Button, { block: true, size: "large", type: "primary", htmlType: "submit", disabled: !allowSubmit, onClick: () => loginByMobile(), children: t('Login') }) })] }));
return (_jsx("div", { className: Style['loginbox-main'], children: _jsxs("div", { className: Style['loginbox-wrap'], children: [_jsx("div", { className: Style['loginbox-hd'], children: "\u4E3A\u4E86\u66F4\u597D\u7684\u4F53\u9A8C\uFF0C\u8BF7\u7ED1\u5B9A\u624B\u673A\u53F7" }), _jsx("div", { className: Style['loginbox-bd'], children: _jsx("div", { className: Style['loginbox-mobile'], children: LoginCaptcha }) })] }) }));
}

View File

@ -1,37 +0,0 @@
.loginbox-main {
display: flex;
flex: 1;
align-items: center;
flex-direction: column;
justify-content: center;
background: var(--oak-bg-color-container);
}
.loginbox-wrap {
width: 400px;
display: block;
background: var(--oak-bg-color-container);
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;
font-size: 14px;
font-weight: 500;
}
.loginbox-bd {
height: 200px;
}
.loginbox-mobile {
position: relative;
padding: 0 32px;
}

View File

@ -1,19 +0,0 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function render(props: WebComponentProps<EntityDict, 'token', false, {
counter: number;
loginMode?: number;
loginAgreed?: boolean;
appId: string;
onlyCaptcha?: boolean;
onlyPassword?: boolean;
loading: boolean;
backUrl?: string;
mobile: string;
captcha: string;
}, {
setCaptcha: (mobile: string) => void;
setMobile: (mobile: string) => void;
sendCaptcha: () => Promise<void>;
loginByMobile: () => Promise<void>;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,20 +0,0 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { isMobile, isCaptcha, } from 'oak-domain/lib/utils/validator';
import { MobileOutlined } from '@ant-design/icons';
import { Form, Input, Button } from 'antd';
import Style from './web.module.less';
export default function render(props) {
const { mobile, captcha, counter } = props.data;
const { t, setMobile, setCaptcha, sendCaptcha, loginByMobile } = props.methods;
const validMobile = isMobile(mobile);
const validCaptcha = isCaptcha(captcha);
const allowSubmit = validMobile && validCaptcha;
const LoginCaptcha = (_jsxs(Form, { colon: true, children: [_jsx(Form.Item, { name: "mobile", children: _jsx(Input, { allowClear: true, value: mobile, "data-attr": "mobile", type: "tel", maxLength: 11, prefix: _jsx(MobileOutlined, {}), placeholder: t('placeholder.Mobile'), size: "large", onChange: (e) => {
setMobile(e.target.value);
}, className: Style['loginbox-input'] }) }), _jsx(Form.Item, { name: "captcha", children: _jsx(Input, { allowClear: true, value: captcha, "data-attr": "captcha",
// type="number"
maxLength: 4, placeholder: t('placeholder.Captcha'), size: "large", onChange: (e) => {
setCaptcha(e.target.value);
}, className: Style['loginbox-input'], suffix: _jsx(Button, { type: "link", disabled: !validMobile || counter > 0, onClick: () => sendCaptcha(), children: counter > 0 ? `${counter}秒后可重发` : t('Send') }) }) }), _jsx(Form.Item, { children: _jsx(Button, { block: true, size: "large", type: "primary", htmlType: "submit", disabled: !allowSubmit, onClick: () => loginByMobile(), children: t('Login') }) })] }));
return (_jsx("div", { className: Style['loginbox-main'], children: _jsxs("div", { className: Style['loginbox-wrap'], children: [_jsx("div", { className: Style['loginbox-hd'], children: "\u4E3A\u4E86\u66F4\u597D\u7684\u4F53\u9A8C\uFF0C\u8BF7\u7ED1\u5B9A\u624B\u673A\u53F7" }), _jsx("div", { className: Style['loginbox-bd'], children: _jsx("div", { className: Style['loginbox-mobile'], children: LoginCaptcha }) })] }) }));
}

View File

@ -1,5 +0,0 @@
/// <reference types="react" />
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "mobile", true, {
showBack: boolean;
}>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -1,96 +0,0 @@
export default OakComponent({
entity: 'mobile',
isList: true,
projection: {
id: 1,
mobile: 1,
userId: 1,
ableState: 1,
},
filters: [
{
filter() {
// const token = this.features.token.getToken();
const userId = this.features.token.getUserId();
return {
userId,
};
},
},
],
formData: ({ data: mobiles, features }) => {
const token = features.token.getToken();
const tokenMobileId = token.entity === 'mobile' && token.entityId;
return {
tokenMobileId,
mobiles,
allowRemove: mobiles.length > 1,
};
},
data: {
confirmDeleteModalVisible: false,
refreshing: false,
deleteIdx: undefined,
},
properties: {
showBack: false,
},
methods: {
async onRefreshMobile(e) {
this.setState({
refreshing: true,
});
try {
const { code, errMsg } = e.detail;
if (errMsg !== 'getPhoneNumber:ok') {
console.error(errMsg);
this.setMessage({
title: '获取手机号失败',
type: 'warning',
});
}
else {
await this.features.token.getWechatMpUserPhoneNumber(code);
}
}
catch (err) {
console.error(err);
}
this.setState({
refreshing: false,
});
},
goAddMobile() {
const eventLoggedIn = `mobile:me:login:${Date.now()}`;
this.subEvent(eventLoggedIn, () => {
this.navigateBack();
});
this.navigateTo({
url: '/mobile/login',
eventLoggedIn,
});
},
async onRemoveConfirm() {
const { mobileId } = this.state;
this.removeItem(mobileId);
await this.execute();
this.setState({
confirmDeleteModalVisible: false,
mobileId: '',
});
},
onRemoveModalOpen(e) {
const mobileId = e.currentTarget.dataset.id;
this.setState({
confirmDeleteModalVisible: true,
mobileId,
});
},
onRemoveModalClose() {
this.setState({
confirmDeleteModalVisible: false,
mobileId: '',
});
},
},
});

View File

@ -1,10 +0,0 @@
{
"navigationBarTitleText": "绑定手机号",
"usingComponents": {
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-card": "@oak-frontend-base/miniprogram_npm/lin-ui/card/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",
"l-icon": "@oak-frontend-base/miniprogram_npm/lin-ui/icon/index",
"l-dialog": "@oak-frontend-base/miniprogram_npm/lin-ui/dialog/index"
}
}

View File

@ -1,38 +0,0 @@
/** index.wxss **/
@import "../../../config/styles/mp/index.less";
@import "../../../config/styles/mp/mixins.less";
.page-body {
height: 100vh;
display: flex;
flex: 1;
flex-direction: column;
box-sizing: border-box;
align-items: stretch;
background-color: @oak-bg-color-page;
.safe-area-inset-bottom();
}
.container {
flex: 1;
display: flex;
flex-direction: column;
}
.container2 {
flex-direction: row;
align-items: center;
justify-content: center;
}
.card {
min-width: 480rpx;
text-align: center;
}
.list {
background-color: #fff;
margin-top: 20rpx;
padding: 0 20rpx;
}

View File

@ -1,32 +0,0 @@
<!-- index.wxml -->
<view class="page-body">
<block wx:if="{{mobiles && mobiles.length > 0}}">
<view class="container">
<view class="list" wx:for="{{mobiles}}">
<l-list icon="mobile" title="{{item.mobile}}" is-link="{{false}}" >
<view slot="right-section">
<view wx:if="{{allowRemove}}" bind:tap="onRemoveModalOpen" data-id="{{item.id}}">
<l-icon name="delete" size="24" />
</view>
</view>
</l-list>
</view>
</view>
</block>
<block wx:else>
<view class="container container2">
<l-card type="primary" plaintext="{{true}}">
<view class="card">
您尚未授权手机号
</view>
</l-card>
</view>
</block>
<l-button type="default" block size="long" open-type="getPhoneNumber" bindgetphonenumber="onRefreshMobile">
授权手机号
</l-button>
</view>
<l-dialog show="{{confirmDeleteModalVisible}}" type="confirm" title="提示" content="确认删除吗?删除后无法用此号码登录" bind:linconfirm="onRemoveConfirm" bind:lincancel="onRemoveModalClose" />

View File

@ -1,33 +0,0 @@
.container {
height: 100vh;
display: flex;
flex-direction: column;
}
.list {
:global {
.t-list-item__meta {
&-avatar {
width: auto !important;
height: auto !important;
background: transparent;
border-radius: unset;
}
&-title {
margin: 0 !important;
}
}
}
}
.noData {
display: flex;
flex-direction: column;
flex: 1;
align-items: center;
justify-content: center;
}

View File

@ -1,9 +0,0 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function render(props: WebComponentProps<EntityDict, 'mobile', true, {
mobiles?: EntityDict['mobile']['OpSchema'][];
allowRemove: boolean;
tokenMobileId?: string;
}, {
goAddMobile: () => void;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,23 +0,0 @@
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { List, Button, Dialog } from 'antd-mobile';
import { MobileOutlined, DeleteOutlined } from '@ant-design/icons';
import Style from './mobile.module.less';
export default function render(props) {
const { mobiles, allowRemove, tokenMobileId } = props.data;
const { goAddMobile, removeItem, recoverItem, execute } = props.methods;
return (_jsxs("div", { className: Style.container, children: [mobiles && mobiles.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(List, { className: Style.list, children: mobiles?.map((ele, index) => (_jsx(List.Item, { prefix: _jsx(MobileOutlined, {}), extra: allowRemove && tokenMobileId !== ele.id && (_jsx("div", { onClick: async () => {
const result = await Dialog.confirm({
content: '确认删除吗?删除后无法用此号码登录',
});
if (result) {
removeItem(ele.id);
try {
await execute();
}
catch (err) {
recoverItem(ele.id);
throw err;
}
}
}, children: _jsx(DeleteOutlined, {}) })), children: ele.mobile }, index))) }), _jsx("div", { style: { flex: 1 } })] })) : (_jsx("div", { className: Style.noData, children: _jsx("span", { children: "\u5C1A\u672A\u7ED1\u5B9A\u624B\u673A\u53F7" }) })), _jsx(Button, { block: true, size: "large", color: "primary", onClick: () => goAddMobile(), children: "\u7ED1\u5B9A" })] }));
}

View File

@ -1,8 +0,0 @@
.container {
background: var(--oak-bg-color-container);
box-shadow: 0 2px 3px #0000001a;
border-radius: 3px;
padding: 30px 32px;
}

View File

@ -1,10 +0,0 @@
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
export default function render(props: WebComponentProps<EntityDict, 'mobile', true, {
mobiles?: EntityDict['mobile']['OpSchema'][];
allowRemove: boolean;
showBack: boolean;
tokenMobileId?: string;
}, {
goAddMobile: () => void;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,42 +0,0 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useState } from 'react';
import { List, Button, Modal, Row, Col } from 'antd';
import { MobileOutlined, DeleteOutlined } from '@ant-design/icons';
import Style from './web.module.less';
import PageHeader from '../../../components/common/pageHeader';
import MobileLogin from '../../../pages/mobile/login';
export default function render(props) {
const { mobiles, allowRemove, tokenMobileId, showBack = false } = props.data;
const { goAddMobile, removeItem, recoverItem, execute, subEvent } = props.methods;
const [open, setOpen] = useState(false);
const eventLoggedIn = `user:info:login:${Date.now()}`;
return (_jsxs(PageHeader, { showBack: showBack, title: "\u6211\u7684\u624B\u673A\u53F7", children: [_jsxs("div", { className: Style.container, children: [_jsx(Button, { type: "primary", onClick: () => {
setOpen(true);
}, style: { marginBottom: 16 }, children: "\u7ED1\u5B9A" }), _jsx(Row, { children: _jsx(Col, { xs: 24, sm: 12, children: _jsx(List, { bordered: true, children: mobiles?.map((ele, index) => (_jsx(List.Item, { extra: allowRemove &&
tokenMobileId !== ele.id && (_jsx("div", { onClick: () => {
const modal = Modal
.confirm({
title: `确认删除吗?删除后无法用此号码登录`,
okText: '确定',
cancelText: '取消',
onOk: async (e) => {
removeItem(ele.id);
try {
await execute();
}
catch (err) {
recoverItem(ele.id);
throw err;
}
modal.destroy();
},
onCancel: (e) => {
modal.destroy();
},
});
}, children: _jsx(DeleteOutlined, {}) })), children: _jsx(List.Item.Meta, { avatar: _jsx(MobileOutlined, {}), title: ele.mobile }) }, index))) }) }) })] }), _jsx(Modal, { title: "\u7ED1\u5B9A\u624B\u673A\u53F7", open: open, destroyOnClose: true, footer: null, onCancel: () => {
setOpen(false);
}, children: _jsx("div", { style: { padding: 16 }, children: _jsx(MobileLogin, { callback: () => {
setOpen(false);
}, oakPath: "$mobile/me-mobile/login", oakAutoUnmount: true }) }) })] }));
}

View File

@ -1,4 +0,0 @@
/// <reference types="wechat-miniprogram" />
/// <reference types="react" />
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "token", true, WechatMiniprogram.Component.DataOption>) => import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
export default _default;

View File

@ -1,154 +0,0 @@
export default OakComponent({
entity: 'token',
isList: true,
projection: {
id: 1,
userId: 1,
playerId: 1,
user: {
id: 1,
nickname: 1,
name: 1,
birth: 1,
gender: 1,
idState: 1,
userState: 1,
isRoot: 1,
extraFile$entity: {
$entity: 'extraFile',
data: {
id: 1,
tag1: 1,
origin: 1,
bucket: 1,
objectId: 1,
filename: 1,
extra1: 1,
type: 1,
entity: 1,
entityId: 1,
extension: 1,
},
filter: {
tag1: 'avatar',
},
indexFrom: 0,
count: 1,
},
mobile$user: {
$entity: 'mobile',
data: {
id: 1,
mobile: 1,
},
},
},
player: {
id: 1,
isRoot: 1,
},
},
filters: [
{
filter() {
const tokenId = this.features.token.getTokenValue();
if (tokenId) {
return {
id: tokenId,
};
}
return {
id: 'none',
};
},
},
],
formData: ({ data, features }) => {
const [token] = data || [];
const user = token?.user;
const player = token?.player;
const avatarFile = user?.extraFile$entity && user?.extraFile$entity[0];
const avatar = features.extraFile.getUrl(avatarFile);
const nickname = user && user.nickname;
const mobileData = user && user.mobile$user && user.mobile$user[0];
const { mobile } = mobileData || {};
const mobileCount = user?.mobile$user?.length || 0;
const isLoggedIn = !!token;
const isPlayingAnother = token && token.userId !== token.playerId;
const isRoot = !!player?.isRoot;
const mobileText = mobileCount && mobileCount > 1
? `${mobileCount}条手机号`
: mobile || '未绑定';
return {
tokenId: token?.id,
userId: user?.id,
avatar,
nickname,
mobile,
mobileCount,
mobileText,
isLoggedIn,
isPlayingAnother,
isRoot,
};
},
data: {
refreshing: false,
},
methods: {
async doLogin() {
this.setState({
refreshing: true,
});
try {
switch (process.env.OAK_PLATFORM) {
case 'wechatMp': {
await this.features.token.loginWechatMp();
this.setState({
refreshing: false,
});
break;
}
case 'web': {
const eventLoggedIn = `token:me:login:${Date.now()}`;
this.subEvent(eventLoggedIn, () => {
this.navigateBack();
});
this.navigateTo({
url: '/login',
eventLoggedIn,
}, undefined, true);
break;
}
}
}
catch (err) {
console.error(err);
}
},
goMyMobile() {
this.navigateTo({
url: '/mobile/me',
});
},
goUserManage() {
this.navigateTo({
url: '/user/manage',
});
},
goSetting() {
this.navigateTo({
url: '/setting',
});
},
goMyInfo() {
if (!this.state.isLoggedIn) {
return;
}
this.navigateTo({
url: '/user/info',
oakId: this.state.userId,
});
},
},
});

View File

@ -1,9 +0,0 @@
{
"navigationBarTitleText": "个人中心",
"usingComponents": {
"oak-icon": "../../../components/icon/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-avatar": "@oak-frontend-base/miniprogram_npm/lin-ui/avatar/index"
}
}

View File

@ -1,31 +0,0 @@
@import "../../../config/styles/mp/index.less";
@import "../../../config/styles/mp/mixins.less";
.page-body {
height: 100%;
display: flex;
flex: 1;
flex-direction: column;
background-color: @oak-bg-color-page;
// background-image: linear-gradient(to bottom, #ffffff, #f4f5f6);
}
.userInfo {
padding: 14rpx;
display: flex;
flex-direction: column;
align-items: center;
}
.nickname {
font-size: 30rpx;
color: @oak-text-color-secondary;
padding-top: 14rpx;
padding-bottom: 14rpx;
}
.list {
background-color: #ffffff;
padding: 0 10rpx;
}

View File

@ -1,23 +0,0 @@
<!-- index.wxml -->
<view class="page-body">
<view class="userInfo">
<block wx:if="{{avatar}}">
<l-avatar src="{{avatar}}" text="{{nickname || '未设置'}}" placement="bottom" bind:lintap="goMyInfo"/>
</block>
<block wx:else>
<l-avatar icon="user" size="140" icon-size="80" text="{{nickname || '未设置'}}" placement="bottom" bind:lintap="goMyInfo"/>
</block>
<block wx:if="{{!isLoggedIn}}">
<l-button shape="semicircle" type="default" size="mini" disabled="{{refreshing || oakLoading}}" bind:lintap="doLogin">{{t('login')}}</l-button>
</block>
</view>
<view class="list">
<l-list title="手机号" icon="phone" right-desc="{{mobileText}}" bind:lintap="goMyMobile" >
</l-list>
<block wx:if="{{isRoot}}">
<l-list title="用户管理" icon="user" hover bind:lintap="goUserManage" />
</block>
<l-list title="设置" icon="setting" bind:lintap="goSetting" >
</l-list>
</view>
</view>

View File

@ -1,4 +0,0 @@
{
"login": "登录",
"syncWeChat": "同步微信信息"
}

View File

@ -1,40 +0,0 @@
.container {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
background-color: var(--oak-bg-color-page);
}
.userInfo {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 10px 10px 10px;
margin-bottom: 10px;
background-color: var(--oak-bg-color-container);
.avatar {
width: 60px;
height: 60px;
margin-bottom: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.nickname {
margin-bottom: 10px;
font-size: 14px;
}
.userIcon {
color: #fff;
font-size: 24px;
}
}
.list {
background-color: #fff;
}

View File

@ -1,18 +0,0 @@
import { EntityDict } from '../../../oak-app-domain';
import { WebComponentProps } from 'oak-frontend-base';
export default function Render(props: WebComponentProps<EntityDict, 'token', true, {
avatar: string;
nickname?: string;
isLoggedIn?: boolean;
mobile?: string;
mobileCount?: number;
refreshing?: boolean;
isRoot: boolean;
tokenId?: string;
mobileText: string;
}, {
goMyInfo: () => Promise<void>;
doLogin: () => Promise<void>;
goMyMobile: () => Promise<void>;
goUserManage: () => Promise<void>;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,9 +0,0 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { List, Button, Avatar } from 'antd-mobile';
import { UserOutlined, MobileOutlined } from '@ant-design/icons';
import Style from './mobile.module.less';
export default function Render(props) {
const { avatar, isLoggedIn, refreshing, mobileText, isRoot, oakExecuting, tokenId, nickname, oakDirty, } = props.data;
const { doLogin, t, goMyMobile, goUserManage, goMyInfo } = props.methods;
return (_jsxs("div", { className: Style.container, children: [_jsxs("div", { className: Style.userInfo, children: [_jsx(Avatar, { className: Style.avatar, src: avatar }), _jsx("span", { className: Style.nickname, children: nickname || '未设置' }), isLoggedIn ? (_jsx(Button, { color: "primary", size: "small", disabled: refreshing, loading: refreshing, onClick: () => goMyInfo(), children: t('common::action.update') })) : (_jsx(Button, { size: "small", disabled: refreshing, loading: refreshing, onClick: () => doLogin(), children: t('login') }))] }), _jsxs(List, { className: Style.list, children: [_jsx(List.Item, { onClick: () => goMyMobile(), prefix: _jsx(MobileOutlined, {}), title: "\u624B\u673A\u53F7", extra: mobileText }), isRoot && (_jsx(List.Item, { onClick: () => goUserManage(), prefix: _jsx(UserOutlined, {}), title: "\u7528\u6237\u7BA1\u7406" }))] })] }));
}

View File

@ -1,61 +0,0 @@
.container {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
background-color: var(--oak-bg-color-page);
}
.userInfo {
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 10px 10px 10px;
margin-bottom: 10px;
background-color: var(--oak-bg-color-container);
.avatar {
width: 60px;
height: 60px;
margin-bottom: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.nickname {
margin-bottom: 10px;
font-size: 14px;
}
.userIcon {
color: #fff;
font-size: 24px;
}
}
.list {
background-color: #fff;
padding: 0 10px;
:global {
.t-list-item__meta {
&-avatar {
width: auto !important;
height: auto !important;
background: transparent;
border-radius: unset;
display: flex;
justify-content: center;
align-items: center;
}
&-title {
margin: 0 !important;
}
}
}
}

View File

@ -1,18 +0,0 @@
import { EntityDict } from '../../../oak-app-domain';
import { WebComponentProps } from 'oak-frontend-base';
export default function Render(props: WebComponentProps<EntityDict, 'token', true, {
avatar?: string;
nickname?: string;
isLoggedIn?: boolean;
mobile?: string;
mobileCount?: number;
refreshing?: boolean;
isRoot: boolean;
tokenId?: string;
mobileText: string;
}, {
goMyInfo: () => Promise<void>;
doLogin: () => Promise<void>;
goMyMobile: () => Promise<void>;
goUserManage: () => Promise<void>;
}>): import("react/jsx-runtime").JSX.Element;

View File

@ -1,9 +0,0 @@
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { List, Button, Avatar } from 'antd';
import { UserOutlined, MobileOutlined } from '@ant-design/icons';
import Style from './web.module.less';
export default function Render(props) {
const { avatar, isLoggedIn, refreshing, mobileText, isRoot, oakExecuting, tokenId, nickname, oakDirty, } = props.data;
const { doLogin, t, goMyMobile, goUserManage, goMyInfo } = props.methods;
return (_jsxs("div", { className: Style.container, children: [_jsxs("div", { className: Style.userInfo, children: [avatar ? (_jsx(Avatar, { className: Style.avatar, src: avatar })) : (_jsx(Avatar, { className: Style.avatar, icon: _jsx(UserOutlined, { className: Style.userIcon }) })), _jsx("span", { className: Style.nickname, children: nickname || '未设置' }), isLoggedIn ? (_jsx(Button, { type: "primary", size: "small", disabled: refreshing, loading: refreshing, onClick: () => goMyInfo(), children: t('common::action.update') })) : (_jsx(Button, { size: "small", disabled: refreshing, loading: refreshing, onClick: () => doLogin(), children: t('login') }))] }), _jsxs(List, { className: Style.list, split: true, children: [_jsx(List.Item, { onClick: () => goMyMobile(), children: _jsx(List.Item.Meta, { avatar: _jsx(MobileOutlined, {}), title: "\u624B\u673A\u53F7", description: mobileText }) }), isRoot && (_jsx(List.Item, { onClick: () => goUserManage(), children: _jsx(List.Item.Meta, { avatar: _jsx(UserOutlined, {}), title: "\u7528\u6237\u7BA1\u7406" }) }))] })] }));
}

View File

@ -2,7 +2,7 @@
"navigationBarTitleText": "用户详情",
"usingComponents": {
"actionPanel": "../../../../components/func/actionPanel/index",
"oak-icon": "../../../../components/icon/index",
"oak-icon": "@oak-frontend-base/components/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-avatar": "@oak-frontend-base/miniprogram_npm/lin-ui/avatar/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",

View File

@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"oak-icon": "../../icon/index",
"oak-icon": "@oak-frontend-base/icon/index",
"l-badge": "@oak-frontend-base/miniprogram_npm/lin-ui/badge/index"
}
}

View File

@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"oak-icon": "../../icon/index",
"oak-icon": "@oak-frontend-base/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-icon": "@oak-frontend-base/miniprogram_npm/lin-ui/icon/index",
"l-grid": "@oak-frontend-base/miniprogram_npm/lin-ui/grid/index",

View File

@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"oak-icon": "../../icon/index",
"oak-icon": "@oak-frontend-base/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-arc-popup": "@oak-frontend-base/miniprogram_npm/lin-ui/arc-popup/index",
"l-dialog": "@oak-frontend-base/miniprogram_npm/lin-ui/dialog/index",

View File

@ -3,7 +3,8 @@ import { Button, Space, Drawer, Modal, Tooltip } from 'antd';
import { WebComponentProps } from 'oak-frontend-base';
import { EntityDict } from '../../../oak-app-domain';
import Style from './web.module.less';
import OakIcon from '../../icon'
import OakIcon from 'oak-frontend-base/es/components/icon';
import IconDemo from '../../icon';
export default function render(props: WebComponentProps<EntityDict, 'address', true, {
placement: 'top' | 'bottom' | 'left' | 'right',
@ -19,6 +20,7 @@ export default function render(props: WebComponentProps<EntityDict, 'address', t
const { placement = 'bottom', style = {} } = props.data;
const { printCachedStore, printDebugStore, printRunningTree, resetInitialData, downloadEnv, resetEnv } = props.methods;
const [visible, setVisible] = useState(false);
const [iconOpen, setIconOpen] = useState(false);
return (
<React.Fragment>
<Button
@ -182,7 +184,7 @@ export default function render(props: WebComponentProps<EntityDict, 'address', t
type="primary"
shape="circle"
onClick={() => {
window.open('/icon')
setIconOpen(true);
}}
>
Icon
@ -190,6 +192,23 @@ export default function render(props: WebComponentProps<EntityDict, 'address', t
</Tooltip>
</Space>
</Drawer>
<Modal
width={960}
title="oak-icon"
footer={null}
open={iconOpen}
onCancel={() => {
setIconOpen(false);
}}
styles={{
body: {
height: window.innerHeight - 200,
overflowY: 'auto'
}
}}
>
<IconDemo />
</Modal>
</React.Fragment>
);
}

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,4 @@
{
"component": true
"navigationBarTitleText": "OakIcon示例",
"usingComponents": {}
}

View File

@ -1,22 +1,6 @@
@import './iconfont.less';
@import '../../config/styles/mp/index.less';
.oak-icon__primary {
color: @oak-color-primary;
.page-body {
display: flex;
}
.oak-icon__error {
color: @oak-color-error;
}
.oak-icon__warning {
color: @oak-color-warning;
}
.oak-icon__success {
color: @oak-color-success;
}
.oak-icon__info {
color: @oak-color-info;
}

View File

@ -1,11 +1,6 @@
export default OakComponent({
isList: false,
wechatMp: {
externalClasses: ['oak-class'],
isList: true,
methods: {
},
properties: {
name: '' as string,
size: 0 as number,
color: '' as string,
},
});
});

View File

@ -1 +1,4 @@
<view class="oak-icon {{ name === '' ? '' : 'oak-icon-' + name }} {{ color === '' || color === 'primary' || color === 'info' || color === 'error' || color === 'success' || color === 'warning' ? 'oak-icon__' + (color || 'primary') : ''}} oak-class" style="font-size: {{ size || 14 }}px; {{ color && color !== 'primary' && color !== 'info'&& color !== 'error'&& color !== 'success'&& color !== 'warning' ? 'color:' + color : '' }}"></view>
<!-- index.wxml -->
<view class="page-body">
未实现
</view>

View File

@ -1,21 +0,0 @@
@import './iconfont.less';
.oak-icon__primary {
color: var(--oak-color-primary);
}
.oak-icon__error {
color: var(--oak-color-error);
}
.oak-icon__warning {
color: var(--oak-color-warning);
}
.oak-icon__success {
color: var(--oak-color-success);
}
.oak-icon__info {
color: var(--oak-color-info);
}

View File

@ -1,7 +1,7 @@
.container {
display: flex;
padding: 30px 100px;
width: 960px;
width: 900px;
margin: 0 auto;
background-color: var(--oak-bg-color-page);
}

View File

@ -1,60 +1,70 @@
import { WebComponentProps } from 'oak-frontend-base';
import React from 'react';
import React, { useState } from 'react';
import { EntityDict } from '../../oak-app-domain';
import './web.less';
import { WebComponentProps } from 'oak-frontend-base';
import JsonData from './iconfont.json';
import OakIcon from 'oak-frontend-base/es/components/icon';
import Style from './web.module.less';
/**
*
*
* @export
* @param {*} value
* @param {*} cb
*/
function copy(value: string, cb?: () => void) {
// 动态创建 textarea 标签
const textarea = document.createElement('textarea') as any
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
// 将要 copy 的值赋给 textarea 标签的 value 属性
// 网上有些例子是赋值给innerText,这样也会赋值成功,但是识别不了\r\n的换行符赋值给value属性就可以
textarea.value = value
// 将 textarea 插入到 body 中
document.body.appendChild(textarea)
// 选中值并复制
textarea.select()
textarea.setSelectionRange(0, textarea.value.length)
document.execCommand('Copy')
document.body.removeChild(textarea)
if (cb && Object.prototype.toString.call(cb) === '[object Function]') {
cb()
}
}
export default function Render(
props: WebComponentProps<
EntityDict,
'user',
false,
{
name: string;
color?:
| 'primary'
| 'success'
| 'error'
| 'waring'
| 'info'
| string;
size?: string;
className?: string;
style?: React.CSSProperties;
},
{}
>
props: WebComponentProps<EntityDict, 'token', true, {}, {}>
) {
const { data } = props;
const {
name,
color = '',
size,
className,
style = {},
} = data;
const isColor = ['primary', 'info', 'success', 'error', 'warning'].includes(
color
const { methods } = props;
const icons = JsonData.glyphs;
return (
<div className={Style.container}>
<ul className={Style.dibBox}>
{icons.map((ele) => {
return (
<li className={Style.dib} onClick={() => {
const content = `<OakIcon name='${ele.name}' />`;
copy(content, () => {
methods.setMessage({
type: 'success',
content,
});
});
}}>
<div className={Style.iconBox}>
<OakIcon name={ele.name} size={40} />
</div>
<div className={Style.name}>{ele.name}</div>
</li>
);
})}
</ul>
</div>
);
let class_name = 'oak-icon ' + 'oak-icon-' + name;
if (isColor || color === '') {
class_name += ' ' + 'oak-icon__' + (color || 'primary');
}
if (className) {
class_name += ' ' + className;
}
return (
<span
className={class_name}
style={
Object.assign(
style,
size && { fontSize: size },
color && !isColor && { color }
) as React.CSSProperties
}
></span>
);
}
}

View File

@ -1,9 +1,9 @@
import React from 'react';
import { Dropdown, Button, Avatar } from 'antd';
import { Avatar } from 'antd';
import Styles from './web.module.less';
import { EntityDict } from '../../../oak-app-domain';
import OakIcon from '../../icon/index';
import OakIcon from 'oak-frontend-base/es/components/icon';
import { WebComponentProps } from 'oak-frontend-base';
import { AvatarSize } from 'antd/es/avatar/AvatarContext';

View File

@ -4,7 +4,7 @@ import { EntityDict } from '../../../oak-app-domain';
import Styles from './web.pc.module.less';
import { Button, List, Modal, Tag, Input, Radio } from 'antd';
import MyAvatar from '../avatar';
import OakIcon from '../../icon';
import OakIcon from 'oak-frontend-base/es/components/icon';
const PrimaryColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-primary');

View File

@ -5,7 +5,7 @@ import { EntityDict } from '../../../oak-app-domain';
import Styles from './web.pc.module.less';
import { Button, List, Popup, Tag, Input, Radio, Form, Space } from 'antd-mobile';
import MyAvatar from '../avatar';
import OakIcon from '../../icon';
import OakIcon from 'oak-frontend-base/es/components/icon';
const PrimaryColor = getComputedStyle(document.documentElement).getPropertyValue('--oak-color-primary');

View File

@ -1,7 +1,7 @@
{
"navigationBarTitleText": "个人中心",
"usingComponents": {
"oak-icon": "../../../components/icon/index",
"oak-icon": "@oak-frontend-base/components/icon/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-avatar": "@oak-frontend-base/miniprogram_npm/lin-ui/avatar/index"

View File

@ -2,7 +2,7 @@
"navigationBarTitleText": "用户详情",
"usingComponents": {
"actionPanel": "../../../../components/func/actionPanel/index",
"oak-icon": "../../../../components/icon/index",
"oak-icon": "@oak-frontend-base/components/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-avatar": "@oak-frontend-base/miniprogram_npm/lin-ui/avatar/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",

View File

@ -1,4 +0,0 @@
{
"navigationBarTitleText": "OakIcon示例",
"usingComponents": {}
}

View File

@ -1,6 +0,0 @@
.page-body {
display: flex;
}

View File

@ -1,6 +0,0 @@
export default OakComponent({
isList: true,
methods: {
},
});

View File

@ -1,4 +0,0 @@
<!-- index.wxml -->
<view class="page-body">
未实现
</view>

View File

@ -1,70 +0,0 @@
import React, { useState } from 'react';
import { EntityDict } from '../../oak-app-domain';
import { WebComponentProps } from 'oak-frontend-base';
import JsonData from './iconfont.json';
import OakIcon from '../../components/icon';
import Style from './web.module.less';
/**
*
*
* @export
* @param {*} value
* @param {*} cb
*/
function copy(value: string, cb?: () => void) {
// 动态创建 textarea 标签
const textarea = document.createElement('textarea') as any
// 将该 textarea 设为 readonly 防止 iOS 下自动唤起键盘,同时将 textarea 移出可视区域
textarea.readOnly = 'readonly'
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
// 将要 copy 的值赋给 textarea 标签的 value 属性
// 网上有些例子是赋值给innerText,这样也会赋值成功,但是识别不了\r\n的换行符赋值给value属性就可以
textarea.value = value
// 将 textarea 插入到 body 中
document.body.appendChild(textarea)
// 选中值并复制
textarea.select()
textarea.setSelectionRange(0, textarea.value.length)
document.execCommand('Copy')
document.body.removeChild(textarea)
if (cb && Object.prototype.toString.call(cb) === '[object Function]') {
cb()
}
}
export default function Render(
props: WebComponentProps<EntityDict, 'token', true, {}, {}>
) {
const { methods } = props;
const icons = JsonData.glyphs;
return (
<div className={Style.container}>
<ul className={Style.dibBox}>
{icons.map((ele) => {
return (
<li className={Style.dib} onClick={() => {
const content = `<OakIcon name='${ele.name}' />`;
copy(content, () => {
methods.setMessage({
type: 'success',
content,
});
});
}}>
<div className={Style.iconBox}>
<OakIcon name={ele.name} size={40} />
</div>
<div className={Style.name}>{ele.name}</div>
</li>
);
})}
</ul>
</div>
);
}

View File

@ -2,7 +2,7 @@
"navigationBarTitleText": "用户详情",
"usingComponents": {
"actionPanel": "../../../../components/func/actionPanel/index",
"oak-icon": "../../../../components/icon/index",
"oak-icon": "@oak-frontend-base/components/icon/index",
"l-button": "@oak-frontend-base/miniprogram_npm/lin-ui/button/index",
"l-avatar": "@oak-frontend-base/miniprogram_npm/lin-ui/avatar/index",
"l-list": "@oak-frontend-base/miniprogram_npm/lin-ui/list/index",