提交 b15834a6 作者: 郁骅焌

宏命令修改

上级 1dcd171e
# @umi-material/TestBlock
测试Block
测试
## Usage
```sh
umi block https://github.com/umijs/umi-blocks/tree/master/TestBlock
umi block https://github.com//tree/master/TestBlock
```
## LICENSE
......
{
"name": "@umi-block/TestBlock",
"version": "0.0.1",
"description": "测试Block",
"version": "1.0.0",
"description": "测试",
"main": "src/index.js",
"authors": {
"name": "heartrainy",
"email": ""
},
"repository": "umijs/umi-blocks/TestBlock",
"scripts": {
"dev": "umi dev"
},
......@@ -16,10 +15,11 @@
},
"devDependencies": {
"umi": "^2.0.0",
"umi-plugin-block-dev": "^2.0.0",
"umi-types": "^0.2.0"
},
},
"blockConfig": {
"specVersion": "0.1"
},
"license": "MIT"
}
import { parse } from 'url';
import moment from 'moment';
// mock tableListDataSource
let tableListDataSource: any[] = [];
for (let i = 0; i < 1; i += 1) {
tableListDataSource.push({
key: i,
column1: `column1_${i}`,
column2: Math.floor(Math.random() * 10) % 4,
column3: Math.floor(Math.random() * 1000),
column4: new Date(`2019-07-${Math.floor(i / 2) + 1}`).getTime(),
column5: Math.floor(Math.random() * 10) % 4,
href: 'https://ant.design',
avatar: [
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
][i % 2],
name: `TradeCode ${i}`,
title: `一个任务名称 ${i}`,
owner: '曲丽丽',
desc: '这是一段描述',
callNo: Math.floor(Math.random() * 1000),
status: Math.floor(Math.random() * 10) % 4,
updatedAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
createdAt: new Date(`2017-07-${Math.floor(i / 2) + 1}`),
progress: Math.ceil(Math.random() * 100),
});
}
function getRule(
req: { url: any },
res: {
json: (
arg0: {
list: any[];
pagination: { total: number; pageSize: number; current: number };
},
) => void;
},
u: any,
) {
let url = u;
if (!url || Object.prototype.toString.call(url) !== '[object String]') {
// eslint-disable-next-line prefer-destructuring
url = req.url;
}
const params = parse(url, true).query;
let dataSource = tableListDataSource;
if (params.sorter) {
const s = params.sorter.split('_');
dataSource = dataSource.sort((prev, next) => {
if (s[1] === 'descend') {
return next[s[0]] - prev[s[0]];
}
return prev[s[0]] - next[s[0]];
});
}
if (params.status) {
const status = params.status.split(',');
let filterDataSource: any[] = [];
status.forEach((s: string) => {
filterDataSource = filterDataSource.concat(
dataSource.filter(item => {
if (parseInt(`${item.status}`, 10) === parseInt(s.split('')[0], 10)) {
return true;
}
return false;
}),
);
});
dataSource = filterDataSource;
}
if (params.column1) {
dataSource = dataSource.filter(data => data.column1.indexOf(params.column1) > -1);
}
if (params.column2) {
dataSource = dataSource.filter(data => data.column2 == params.column2);
}
if (params.column3) {
dataSource = dataSource.filter(data => data.column3 == params.column3);
}
if (params.column4) {
dataSource = dataSource.filter(data => data.column4 <= moment(params.column4).valueOf());
}
if (params.column5) {
dataSource = dataSource.filter(data => data.column5 == params.column5);
}
let pageSize = 10;
if (params.pageSize) {
pageSize = parseInt(`${params.pageSize}`, 0);
}
const result = {
list: dataSource,
pagination: {
total: dataSource.length,
pageSize,
current: parseInt(`${params.currentPage}`, 10) || 1,
},
};
return res.json(result);
}
function postRule(
req: { url: any; body: any },
res: { json: (arg0: { list: any[]; pagination: { total: number } }) => void },
u: any,
b: { body: any },
) {
let url = u;
if (!url || Object.prototype.toString.call(url) !== '[object String]') {
// eslint-disable-next-line prefer-destructuring
url = req.url;
}
const body = (b && b.body) || req.body;
const { method, name, desc, key, column1, column2, column3, column4, column5 } = body;
switch (method) {
/* eslint no-case-declarations:0 */
case 'delete':
tableListDataSource = tableListDataSource.filter(item => key.indexOf(item.key) === -1);
break;
case 'post':
const i = Math.ceil(Math.random() * 10000);
tableListDataSource.unshift({
key: i,
column1: column1,
column2: column2,
column3: column3,
column4: column4,
column5: column5,
href: 'https://ant.design',
avatar: [
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
][i % 2],
name: `TradeCode ${i}`,
title: `一个任务名称 ${i}`,
owner: '曲丽丽',
desc,
callNo: Math.floor(Math.random() * 1000),
status: Math.floor(Math.random() * 10) % 2,
updatedAt: new Date(),
createdAt: new Date(),
progress: Math.ceil(Math.random() * 100),
});
break;
case 'update':
tableListDataSource = tableListDataSource.map(item => {
if (item.key === key) {
return { ...item, column1, column2, column3, column4, column5 };
}
return item;
});
break;
default:
break;
}
const result = {
list: tableListDataSource,
pagination: {
total: tableListDataSource.length,
},
};
return res.json(result);
}
export default {
'GET /api/rule': getRule,
'POST /api/rule': postRule,
};
import { Form, Input, Modal, Select, DatePicker } from 'antd';
import { FormComponentProps } from 'antd/es/form';
import React, { Component } from 'react';
const FormItem = Form.Item;
const { Option } = Select;
interface CreateFormProps extends FormComponentProps {
modalVisible: boolean;
handleAdd: (
fieldsValue: any,
) => void;
handleModalVisible: () => void;
}
const OptionStatus: any[] = [
{ value: 1, label: '状态1' },
{ value: 2, label: '状态2' },
{ value: 3, label: '状态3' },
{ value: 4, label: '状态4' },
]
class CreateForm extends Component<CreateFormProps> {
okHandle = () => {
const { form, handleAdd } = this.props;
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
handleAdd(fieldsValue);
});
};
render() {
const { modalVisible, form, handleModalVisible } = this.props;
return (
<Modal
destroyOnClose
title="新建"
visible={modalVisible}
onOk={this.okHandle}
onCancel={() => handleModalVisible()}
>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column1">
{form.getFieldDecorator('column1', {
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column2">
{form.getFieldDecorator('column2', {
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column3">
{form.getFieldDecorator('column3', {
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column4">
{form.getFieldDecorator('column4', {
rules: [{ required: true, message: '请选择时间!' }],
})(<DatePicker style={{ width: '100%' }} />)}
</FormItem>
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="Column5">
{form.getFieldDecorator('column5', {
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
</Modal>
);
}
};
export default Form.create<CreateFormProps>()(CreateForm);
@import '~antd/es/style/themes/default.less';
.standardTable {
:global {
.ant-table-pagination {
margin-top: 24px;
}
}
.tableAlert {
margin-bottom: 16px;
}
}
import { Table } from 'antd';
import { ColumnProps, TableRowSelection, TableProps } from 'antd/es/table';
import React, { Component } from 'react';
import { TableListItem } from '../../data.d';
import styles from './index.less';
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
export interface StandardTableProps<T> extends Omit<TableProps<T>, 'columns'> {
columns: StandardTableColumnProps[];
data: {
list: TableListItem[];
pagination: StandardTableProps<TableListItem>['pagination'];
};
selectedRows: TableListItem[];
onSelectRow: (rows: any) => void;
}
export interface StandardTableColumnProps extends ColumnProps<TableListItem> {
}
interface StandardTableState {
selectedRowKeys: string[];
}
class StandardTable extends Component<StandardTableProps<TableListItem>, StandardTableState> {
constructor(props: StandardTableProps<TableListItem>) {
super(props);
this.state = {
selectedRowKeys: [],
};
}
handleRowSelectChange: TableRowSelection<TableListItem>['onChange'] = (
selectedRowKeys,
selectedRows: TableListItem[],
) => {
const currySelectedRowKeys = selectedRowKeys as string[];
const { onSelectRow } = this.props;
if (onSelectRow) {
onSelectRow(selectedRows);
}
this.setState({ selectedRowKeys: currySelectedRowKeys });
};
handleTableChange: TableProps<TableListItem>['onChange'] = (
pagination,
filters,
sorter,
...rest
) => {
const { onChange } = this.props;
if (onChange) {
onChange(pagination, filters, sorter, ...rest);
}
};
cleanSelectedKeys = () => {
if (this.handleRowSelectChange) {
this.handleRowSelectChange([], []);
}
};
render() {
const { selectedRowKeys } = this.state;
const { data, rowKey, ...rest } = this.props;
const { list = [], pagination = false } = data || {};
const paginationProps = {
showSizeChanger: true,
showQuickJumper: true,
...pagination,
};
const rowSelection: TableRowSelection<TableListItem> = {
selectedRowKeys,
onChange: this.handleRowSelectChange
};
return (
<div className={styles.standardTable}>
<Table
rowKey={rowKey || 'key'}
rowSelection={rowSelection}
dataSource={list}
pagination={paginationProps}
onChange={this.handleTableChange}
{...rest}
/>
</div>
);
}
}
export default StandardTable;
import { DatePicker, Form, Input, Modal, Select } from 'antd';
import React, { Component } from 'react';
import moment from 'moment';
import { FormComponentProps } from 'antd/es/form';
import { TableListItem } from '../data.d';
export interface UpdateFormProps extends FormComponentProps {
handleUpdateModalVisible: (flag?: boolean, formVals?: Partial<TableListItem>) => void;
handleUpdate: (values: Partial<TableListItem>) => void;
updateModalVisible: boolean;
values: Partial<TableListItem>;
}
const FormItem = Form.Item;
const { Option } = Select;
const OptionStatus: any[] = [
{ value: 1, label: '状态1' },
{ value: 2, label: '状态2' },
{ value: 3, label: '状态3' },
{ value: 4, label: '状态4' },
]
class UpdateForm extends Component<UpdateFormProps> {
formLayout = {
labelCol: { span: 7 },
wrapperCol: { span: 13 },
};
okHandle = () => {
const { form, handleUpdate, values } = this.props;
console.log(values)
form.validateFields((err, fieldsValue) => {
if (err) return;
form.resetFields();
const updateValue = {
...values,
...fieldsValue
}
handleUpdate(updateValue);
});
};
render() {
const { updateModalVisible, handleUpdateModalVisible, form, values } = this.props;
return (
<Modal
width={640}
bodyStyle={{ padding: '32px 40px 48px' }}
destroyOnClose
title="编辑"
visible={updateModalVisible}
onOk={this.okHandle}
onCancel={() => handleUpdateModalVisible(false, values)}
>
<FormItem key="column1" {...this.formLayout} label="Column1">
{form.getFieldDecorator('column1', {
initialValue: values.column1,
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem key="column2" {...this.formLayout} label="Column2">
{form.getFieldDecorator('column2', {
initialValue: values.column2,
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
<FormItem key="column3" {...this.formLayout} label="Column3">
{form.getFieldDecorator('column3', {
initialValue: values.column3,
rules: [{ required: true, message: '请输入!' }],
})(<Input placeholder="请输入" />)}
</FormItem>
<FormItem key="column4" {...this.formLayout} label="Column4">
{form.getFieldDecorator('column4', {
initialValue: moment(values.column4),
rules: [{ required: true, message: '请选择时间!' }],
})(<DatePicker style={{ width: '100%' }} />)}
</FormItem>
<FormItem key="column5" {...this.formLayout} label="Column5">
{form.getFieldDecorator('column5', {
initialValue: values.column5,
rules: [{ required: true, message: '请输入!' }],
})(
<Select placeholder="请选择" style={{ width: '100%' }}>
{
OptionStatus.map(option => {
return <Option key={option.value} value={option.value}>{option.label}</Option>
})
}
</Select>
)}
</FormItem>
</Modal>
);
}
}
export default Form.create<UpdateFormProps>()(UpdateForm);
export interface TableListItem {
key: number;
column1?: string;
column2?: number;
column3?: number;
column4?: number;
column5?: number;
disabled?: boolean;
href: string;
avatar: string;
name: string;
title: string;
owner: string;
desc: string;
callNo: number;
status: number;
updatedAt: Date;
createdAt: Date;
progress: number;
}
export interface TableListPagination {
total: number;
pageSize: number;
current: number;
}
export interface TableListDate {
list: TableListItem[];
pagination: Partial<TableListPagination>;
}
export interface TableListParams {
sorter: string;
status: string;
name: string;
pageSize: number;
currentPage: number;
}
import { AnyAction, Reducer } from 'redux';
import { EffectsCommandMap } from 'dva';
import { addRule, queryRule, removeRule, updateRule } from './service';
import { TableListDate } from './data.d';
export interface StateType {
data: TableListDate;
}
export type Effect = (
action: AnyAction,
effects: EffectsCommandMap & { select: <T>(func: (state: StateType) => T) => T },
) => void;
export interface ModelType {
namespace: string;
state: StateType;
effects: {
fetch: Effect;
add: Effect;
remove: Effect;
update: Effect;
};
reducers: {
save: Reducer<StateType>;
};
}
const Model: ModelType = {
namespace: 'BLOCK_NAME_CAMEL_CASE',
state: {
data: {
list: [],
pagination: {},
},
},
effects: {
*fetch({ payload }, { call, put }) {
const response = yield call(queryRule, payload);
yield put({
type: 'save',
payload: response,
});
},
*add({ payload, callback }, { call, put }) {
const response = yield call(addRule, payload);
yield put({
type: 'save',
payload: response,
});
if (callback) callback();
},
*remove({ payload, callback }, { call, put }) {
const response = yield call(removeRule, payload);
yield put({
type: 'save',
payload: response,
});
if (callback) callback();
},
*update({ payload, callback }, { call, put }) {
const response = yield call(updateRule, payload);
yield put({
type: 'save',
payload: response,
});
if (callback) callback();
},
},
reducers: {
save(state, action) {
return {
...state,
data: action.payload,
};
},
},
};
export default Model;
import request from 'umi-request';
import { TableListParams } from './data.d';
export async function queryRule(params: TableListParams) {
return request('/api/rule', {
params,
});
}
export async function removeRule(params: TableListParams) {
return request('/api/rule', {
method: 'POST',
data: {
...params,
method: 'delete',
},
});
}
export async function addRule(params: TableListParams) {
return request('/api/rule', {
method: 'POST',
data: {
...params,
method: 'post',
},
});
}
export async function updateRule(params: TableListParams) {
return request('/api/rule', {
method: 'POST',
data: {
...params,
method: 'update',
},
});
}
@import '~antd/es/style/themes/default.less';
@import './utils/utils.less';
.tableList {
.tableListOperator {
margin-bottom: 16px;
button {
margin-right: 8px;
}
}
}
.tableListForm {
:global {
.ant-form-item {
display: flex;
margin-right: 0;
margin-bottom: 24px;
> .ant-form-item-label {
width: auto;
padding-right: 8px;
line-height: 32px;
}
.ant-form-item-control {
line-height: 32px;
}
}
.ant-form-item-control-wrapper {
flex: 1;
}
}
.submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
}
@media screen and (max-width: @screen-lg) {
.tableListForm :global(.ant-form-item) {
margin-right: 24px;
}
}
@media screen and (max-width: @screen-md) {
.tableListForm :global(.ant-form-item) {
margin-right: 8px;
}
}
.textOverflow() {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
word-break: break-all;
}
.textOverflowMulti(@line: 3, @bg: #fff) {
position: relative;
max-height: @line * 1.5em;
margin-right: -1em;
padding-right: 1em;
overflow: hidden;
line-height: 1.5em;
text-align: justify;
&::before {
position: absolute;
right: 14px;
bottom: 0;
padding: 0 1px;
background: @bg;
content: '...';
}
&::after {
position: absolute;
right: 14px;
width: 1em;
height: 1em;
margin-top: 0.2em;
background: white;
content: '';
}
}
// mixins for clearfix
// ------------------------
.clearfix() {
zoom: 1;
&::before,
&::after {
display: table;
content: ' ';
}
&::after {
clear: both;
height: 0;
font-size: 0;
visibility: hidden;
}
}
.normal {
background: #79F2AA;
}
import React from 'react';
import styles from './index.css';
const Block: React.FC = () => {
return (
<div className={styles.normal}>
<h1>I am a umi block!</h1>
</div>
);
}
export default Block;
{
"private": true,
"scripts": {
"dev": "cross-env PAGES_PATH='TestBlock/src' umi dev",
"dev": "cross-env PAGES_PATH='MySimpleTable/src' umi dev",
"format-imports": "import-sort --write '**/*.{js,jsx,ts,tsx}'",
"lint": "npm run lint:js && npm run lint:style",
"lint-staged": "lint-staged",
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论