Commit 6a8c3b0a authored by beisir's avatar beisir

feat: 修改规格

parent 0adbd8ef
...@@ -3,4 +3,3 @@ ...@@ -3,4 +3,3 @@
/config /config
.history .history
/src/utils/qiniu.min.js /src/utils/qiniu.min.js
/src/pages/GoodsManage-new
\ No newline at end of file
...@@ -156,6 +156,11 @@ export default { ...@@ -156,6 +156,11 @@ export default {
icon: 'smile', icon: 'smile',
component: './GoodsManage', component: './GoodsManage',
}, },
{
path: '/GoodsManage-new',
name: 'GoodsManageNew',
component: './GoodsManage-new',
},
{ {
component: './404', component: './404',
}, },
......
...@@ -15,7 +15,13 @@ export const toolBarList = () => [ ...@@ -15,7 +15,13 @@ export const toolBarList = () => [
</Button>, </Button>,
]; ];
export const Goodscolumns = ({ categoryData, supplyPrice, setSupplyPrice, supplyPriceRef }) => [ export const Goodscolumns = ({
categoryData,
supplyPrice,
setSupplyPrice,
supplyPriceRef,
onModifyForm,
}) => [
{ {
title: 'SKU编码', title: 'SKU编码',
dataIndex: 'skuId', dataIndex: 'skuId',
...@@ -134,9 +140,9 @@ export const Goodscolumns = ({ categoryData, supplyPrice, setSupplyPrice, supply ...@@ -134,9 +140,9 @@ export const Goodscolumns = ({ categoryData, supplyPrice, setSupplyPrice, supply
valueType: 'option', valueType: 'option',
fixed: 'right', fixed: 'right',
modalHide: true, modalHide: true,
render: () => ( render: (value, row) => (
<> <>
<Button key="update" type="link" onClick={() => {}}> <Button key="update" type="link" onClick={() => onModifyForm(row)}>
修改 修改
</Button> </Button>
<Button key="preview" type="link" onClick={() => {}}> <Button key="preview" type="link" onClick={() => {}}>
......
import React, { useState } from 'react';
import { Form, notification, Col, Input, Icon, Row, Button, Select } from 'antd';
import { filterSpecId } from './utils';
export const SelectSpecifications = ({ form, keys, formKey, labelName, specList, arrkey }) => {
const { getFieldValue, getFieldDecorator, setFieldsValue } = form;
const [countNumber, setCountNumber] = useState(0); // 添加计数器
getFieldDecorator(keys, { initialValue: [] });
const remove = k => {
const valueKey = getFieldValue(keys);
setFieldsValue({
[keys]: valueKey.filter(i => i !== k),
});
};
const add = () => {
const specValue = getFieldValue(formKey);
if (!specValue) {
notification.warning({ message: `请先选择${labelName}数据` });
return;
}
const valueKey = getFieldValue(keys);
const nextKeys = [...valueKey, countNumber];
setCountNumber(countNumber + 1);
setFieldsValue({
[keys]: nextKeys,
});
};
const formItemList = getFieldValue(keys);
const formItems = formItemList.map((k, index) => (
<Col style={{ marginRight: 20 }} key={k}>
<Form.Item style={{ width: 200 }} required={false} key={k}>
{getFieldDecorator(`${arrkey}[${k}]`, {
validateTrigger: ['onChange', 'onBlur'],
rules: [{ required: true, whitespace: true, message: 'Please input passenger' }],
})(<Input placeholder="passenger name" style={{ width: 150, marginRight: 8 }} />)}
<Icon className="dynamic-delete-button" type="minus-circle-o" onClick={() => remove(k)} />
</Form.Item>
</Col>
));
return (
<>
<Form.Item label={labelName}>
{getFieldDecorator(formKey)(
<Select allowClear showSearch onChange={(val, option) => {}} filterOption={filterSpecId}>
{specList.map(item => (
<Select.Option key={item.specId} value={item.specId}>
{item.specName}
</Select.Option>
))}
</Select>,
)}
</Form.Item>
<Row type="flex">
{formItems}
<Col>
<Button type="dashed" style={{ marginTop: 5 }} onClick={() => add()}>
<Icon type="plus" />
</Button>
</Col>
</Row>
</>
);
};
import React, { useEffect } from 'react';
import SuperSelect from 'antd-virtual-select';
import {
Form,
Modal,
Card,
Cascader,
Select,
Radio,
Popover,
Input,
Icon,
Button,
Row,
Col,
notification,
} from 'antd';
import { productTypeList } from '../staticdata';
import { useModalTitle, useSpecList, formItemLayout, filterSpecId } from './utils';
import { RadioComponent, CascaderComponent } from './libs';
import { productTypeRules, categoryIdRules, brandIdRules } from './rules';
import { SelectSpecifications } from './SelectSpecifications';
const { Option } = Select;
const filterOption = (input, op) => op.props.children.includes(input);
const OperationForm = props => {
const {
isEdit,
operationVisible,
setOperationVisible,
categoryData,
// virtualTreeData,
shopList,
barndList,
// virtualBarndList,
form,
} = props;
const {
getFieldDecorator,
setFieldsValue,
getFieldsValue,
validateFields,
resetFields,
getFieldValue,
} = form;
const [title] = useModalTitle(isEdit);
const [specList] = useSpecList();
useEffect(() => {
console.log(isEdit);
if (isEdit) {
setFieldsValue({
productType: 2,
});
} else {
setFieldsValue({
productType: 1,
});
}
}, [isEdit, operationVisible]);
const onSubmitGoodsForm = () => {
validateFields(async (errors, values) => {
if (!errors) {
const { first = [], firstKeys = [] } = values;
console.log(values);
console.log(firstKeys.map(key => first[key]));
}
});
};
const onCancelModalForm = () => {
setOperationVisible(false);
resetFields();
};
const { name } = getFieldsValue();
return (
<Modal
title={title}
width="1050px"
visible={operationVisible}
onCancel={onCancelModalForm}
onOk={() => onSubmitGoodsForm()}
>
<Form {...formItemLayout}>
<Card>
<Form.Item label="商品类型:">
{getFieldDecorator('productType', productTypeRules())(
RadioComponent({ productTypeList }),
)}
</Form.Item>
<Form.Item label="类目:">
{getFieldDecorator('categoryId', categoryIdRules())(
CascaderComponent({ categoryData }),
)}
</Form.Item>
<Form.Item label="商品品牌">
{getFieldDecorator('brandId', brandIdRules())(
<SuperSelect allowClear showSearch filterOption={filterOption}>
{barndList.map(item => (
<Option key={item.id} value={item.id}>
{item.name}
</Option>
))}
</SuperSelect>,
)}
</Form.Item>
<Form.Item label="商品名称">
<Popover content={name} trigger="hover">
{getFieldDecorator('name', {
rules: [{ required: true, message: '请输入商品名称' }],
})(<Input allowClear />)}
</Popover>
</Form.Item>
</Card>
<Card>
<SelectSpecifications
form={form}
keys="firstKeys"
arrkey="first"
formKey="firstSpecId"
labelName="一级规格"
specList={specList}
/>
<SelectSpecifications
form={form}
keys="secondKeys"
arrkey="tow"
formKey="secondSpecId"
labelName="二级规格"
specList={specList}
/>
</Card>
</Form>
</Modal>
);
};
export default Form.create()(OperationForm);
import React from 'react';
import { Radio, Cascader } from 'antd';
export const RadioComponent = ({ productTypeList }) => (
<Radio.Group>
{productTypeList.map(item => (
<Radio key={item.value} value={item.value} disabled={item.disabled}>
{item.label}
</Radio>
))}
</Radio.Group>
);
export const CascaderComponent = ({ categoryData }) => (
<Cascader
changeOnSelect
showSearch
fieldNames={{ label: 'name', value: 'id', children: 'children' }}
options={categoryData}
/>
);
export const productTypeRules = () => ({
rules: [{ required: true, message: '请选择商品类型' }],
});
export const categoryIdRules = () => ({
rules: [{ required: true, message: '请选择类目' }],
});
export const brandIdRules = () => ({
rules: [{ required: true, message: '请选择商品品牌' }],
});
import React, { useEffect, useState } from 'react';
import { getSpecList } from '../service';
export const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 2 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 22 },
},
};
export const useModalTitle = isEdit => {
const titleText = isEdit ? '修改商品' : '新增商品';
return [titleText];
};
export const useSpecList = () => {
const [specList, setSpecList] = useState([]);
useEffect(() => {
const featchData = async () => {
const { data = [] } = await getSpecList();
setSpecList(data);
};
featchData();
}, []);
return [specList];
};
export const filterSpecId = (input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
import React from 'react';
import SuperSelect from 'antd-virtual-select';
import { Form, Modal, Card, Cascader, Select, Radio } from 'antd';
import { productTypeList } from '../staticdata';
const { Option } = Select;
const filterOption = (input, op) => op.props.children.includes(input);
const OperationForm = props => {
const {
operationVisible,
setOperationVisible,
categoryData,
// virtualTreeData,
shopList,
barndList,
// virtualBarndList,
form,
} = props;
const { getFieldDecorator } = form;
return (
<Modal
width="1050px"
visible={operationVisible}
onCancel={() => {
setOperationVisible(false);
}}
>
<Form layout="inline">
<Card bordered={false}>
<Form.Item label="商品类型:">
{getFieldDecorator('productType', {
initialValue: 1,
rules: [{ required: true, message: '请选择商品类型' }],
})(
<Radio.Group>
{productTypeList.map(item => (
<Radio key={item.value} value={item.value} disabled={item.disabled}>
{item.label}
</Radio>
))}
</Radio.Group>,
)}
</Form.Item>
<Form.Item label="类目:">
{getFieldDecorator('categoryId', {
rules: [{ required: true, message: '请选择类目' }],
})(
<Cascader
style={{ width: 690 }}
changeOnSelect
showSearch
fieldNames={{ label: 'name', value: 'id', children: 'children' }}
options={categoryData}
/>,
)}
</Form.Item>
<Form.Item label="供货商">
{getFieldDecorator('supplierId', {
rules: [{ required: true, message: '请选择供货商' }],
})(
<Select allowClear showSearch style={{ width: 190 }} filterOption={filterOption}>
{shopList.map(item => (
<Option key={item.id} value={item.id}>
{item.name}
</Option>
))}
</Select>,
)}
</Form.Item>
<Form.Item label="商品品牌">
{getFieldDecorator('brandId', {
rules: [{ required: true, message: '请选择商品品牌' }],
})(
<SuperSelect allowClear showSearch style={{ width: 190 }} filterOption={filterOption}>
{barndList.map(item => (
<Option key={item.id} value={item.id}>
{item.name}
</Option>
))}
</SuperSelect>,
)}
</Form.Item>
</Card>
</Form>
</Modal>
);
};
export default Form.create()(OperationForm);
import { Card, Form, Pagination, Table, notification, Drawer, Spin } from 'antd';
import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { connect } from 'dva';
import { sortBy } from 'lodash';
import styles from './style.less';
import LocalStroage from '@/utils/localStorage';
import configApi from '../../../config/env.config';
import UpdatePrice from './UpdatePrice';
import UpdateStock from './UpdateStock';
import {
update,
spuDetail,
detail,
getSupplierList,
batchPushedOrOffline,
getImageInfo,
categoryList,
getVirtualCategory,
} from './service';
import LogModal from './LogModal';
import CreateModal from './createModal/normal';
// import CreateVirtualModal from './createModal/virtual';
import SupplyModal from './SupplyModal';
import ReasonModal from './reasonModal';
import ImgModal from './ImgModal';
import { column, JDSHOPID } from './staticdata';
import SearchForm from './SearchForm';
@connect(({ goodsManage }) => ({
goodsManage,
}))
class goodsManage extends Component {
state = {
pageNo: 1,
treeData: [],
virtualTreeData: [],
pageSize: 20,
priceInfo: {},
logVisible: false,
previewVisible: false,
supplyVisible: false,
createVisible: false, // 新增or编辑普通商品modal
// createVirtualVisible: false, // 新增or编辑虚拟普通商品modal
imgVisible: false,
offlineVisible: false,
selectedParams: {},
imgData: [],
detailData: [],
detailSpuId: '',
selectedRowKeys: [],
updatePriceVisible: false,
updateStockVisible: false,
initData: {},
// initVirtualData: {},
createloading: false,
type: 1,
};
loading = false;
currentSkuId = null;
supplierId = null;
shopList = [];
componentDidMount() {
this.props.goodsManage.tableData = {};
this.getShopList();
this.categoryList();
this.getVirtualCategory();
}
openOffline = (ids, type, productState) => {
const obj = { ids, type, productState };
this.setState({ selectedParams: obj });
this.setState({ offlineVisible: true });
};
showImg = async spuNo => {
this.setState({ imgVisible: true });
const [data] = await getImageInfo(spuNo);
this.setState({ imgData: data });
};
showSupply = async (id, type) => {
const [data] = await detail({ id });
this.setState({ supplyVisible: true, detailData: data, type });
};
handleSearch = page => {
this.loading = true;
const currentPage = this.state.pageNo;
this.setState(
{
pageNo: page || currentPage,
},
() => {
const { dispatch } = this.props;
const { pageSize, pageNo } = this.state;
dispatch({
type: 'goodsManage/getList',
payload: {
pageNo,
pageSize,
...this.searchForm.getFieldsValue(),
},
});
this.loading = false;
},
);
};
onPageChange = page => {
this.handleSearch(page);
};
onPageSizeChange = (current, size) => {
this.setState(
{
pageSize: size,
},
() => this.handleSearch(),
);
};
onSelectChange = selectedRowKeys => {
this.setState({ selectedRowKeys });
};
onReset = () => {
this.setState({
pageNo: 1,
pageSize: 20,
selectedRowKeys: [],
});
this.handleSearch();
};
onUpdateInfo = async ({ spuId, productType }) => {
this.setState({
createloading: true,
});
const { data } = await spuDetail({ id: spuId });
if (data) {
console.log(productType);
data.pageProductType = productType;
data.categoryId = data.thirdCategoryId;
data.firstSpecId = data.skuList[0].firstSpecId;
data.secondSpecId = data.skuList[0].secondSpecId;
data.firstSpecName = data.skuList[0].firstSpec;
data.secondSpecName = data.skuList[0].secondSpec;
data.firstSpecList = [];
data.secondSpecList = [];
data.colorKeys = [];
data.carouseList.forEach(i => {
if (i.specValue) {
data.colorKeys.push(i.specValue);
}
});
data.skuList.forEach(i => {
if (data.firstSpecList.indexOf(i.firstSpecValue) === -1) {
data.firstSpecList.push(`${i.firstSpecValue}`);
}
if (i.secondSpecValue && data.secondSpecList.indexOf(i.secondSpecValue) === -1) {
data.secondSpecList.push(i.secondSpecValue);
}
});
data.imageList = [];
data.carouseList.forEach(i => {
data.imageList[`${i.specValue}`] = i.skuSpecImageList || [];
});
data.editData = sortBy(data.skuList, item => item.firstSpecValue);
// const createVisible = data.type === 1;
// const createVirtualVisible = data.type !== 1;
// this.setState({
// initData: createVisible ? data : {},
// initVirtualData: createVirtualVisible ? data : {},
// createVisible,
// createVirtualVisible,
// createloading: false,
// });
// data.type = data.productType;
// data.productType = productType;
this.setState({
initData: data,
createVisible: true,
createloading: false,
});
}
};
onUpdate = async updateData => {
const [, error] = await update(updateData);
this.onLoad(error);
};
onLoad = error => {
if (!error) {
notification.success({ message: '操作成功' });
this.setState({
selectedRowKeys: [],
});
this.handleSearch();
}
};
viewLog = async skuId => {
this.currentSkuId = skuId;
this.setState({
logVisible: true,
});
};
updateStatus = async (ids, productState, offlineReason, fromDetail) => {
const [data] = await batchPushedOrOffline({
ids,
productState,
offlineReason,
});
if (data) {
this.handleSearch();
notification.success({
message: productState === 6 ? '上架成功' : '下架成功',
});
this.setState({ offlineVisible: false });
if (fromDetail) {
this.showDetail(this.state.detailSpuId);
}
}
};
audit = skuId => {
this.setState({
previewVisible: true,
src: `${configApi.prologueDomain}/goods/${skuId}?h=0&token=${LocalStroage.get(
'token',
)}&hideReport=1&time=${Date.now()}`,
});
};
offLine = (ids, productState) => {
const obj = { ids, productState };
this.setState({ offlineVisible: true, selectedParams: obj });
};
// 获取供应商列表
getShopList = async () => {
const { data } = await getSupplierList();
this.shopList = data || [];
};
filterShopList = (list = [], isEdit) =>
list.filter(item => isEdit || !JDSHOPID.includes(item.id));
openModal = (
{
skuId,
supplyPrice,
marketPrice,
salePrice,
marketableStock,
supplierId,
stock,
productStock,
},
isStock,
) => {
let visible = {};
if (isStock) {
visible = { updateStockVisible: true };
} else {
visible = { updatePriceVisible: true };
}
this.setState({
...visible,
priceInfo: {
id: skuId,
stock,
productStock,
marketableStock,
supplyPrice,
marketPrice,
salePrice,
supplierId,
},
});
};
cancel = query => {
this.setState({ updatePriceVisible: false, updateStockVisible: false });
if (query) {
this.handleSearch();
}
};
categoryList = async () => {
const { data: treeData } = await categoryList();
if (!treeData) return;
this.setState({ treeData });
};
getVirtualCategory = async () => {
const { virtualTreeData } = await getVirtualCategory();
if (!virtualTreeData) return;
this.setState({ virtualTreeData });
};
render() {
const {
goodsManage: { tableData = {} },
} = this.props;
const { pageNo, pageSize, selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
onChange: this.onSelectChange,
getCheckboxProps: record => ({
disabled: +record.state === 6, // Column configuration not to be checked
}),
};
return (
<PageHeaderWrapper>
<Spin spinning={this.state.createloading}>
<Card>
<SearchForm
handleSearch={this.handleSearch}
onReset={this.onReset}
onLoad={this.onLoad}
selectedRowKeys={this.state.selectedRowKeys}
onRef={ref => {
this.searchForm = ref;
}}
treeData={this.state.treeData}
shopList={this.shopList}
addSpu={() => this.setState({ createVisible: true, initData: {} })}
/>
</Card>
<Spin spinning={this.loading}>
<Table
dataSource={tableData?.records}
bordered
columns={column.call(this)}
rowKey={record => record.skuId}
pagination={false}
className={styles.tabletop}
rowSelection={rowSelection}
scroll={{ x: '100%', y: 500 }}
/>
</Spin>
<br />
{tableData && (
<Pagination
onChange={this.onPageChange}
total={tableData.total}
showTotal={total => `共${total}条`}
current={pageNo}
pageSize={pageSize}
showSizeChanger
onShowSizeChange={this.onPageSizeChange}
/>
)}
<LogModal
visible={this.state.logVisible}
id={this.currentSkuId}
onCancel={() => {
this.currentSkuId = null;
this.setState({ logVisible: false });
}}
/>
<Drawer
visible={this.state.previewVisible}
width="450"
onClose={() => {
this.setState({ previewVisible: false });
}}
title="商品预览"
>
<iframe
src={this.state.src}
frameBorder="0"
height="600"
width="375"
title="商品预览"
></iframe>
</Drawer>
<CreateModal
initData={this.state.initData}
visible={this.state.createVisible}
onCancel={() => {
this.setState({ createVisible: false, initData: {} });
}}
query={() => this.handleSearch()}
shopList={this.filterShopList(this.shopList, Object.keys(this.state.initData).length)}
treeData={this.state.treeData}
virtualTreeData={this.state.virtualTreeData}
></CreateModal>
{/* <CreateVirtualModal
initData={this.state.initVirtualData}
visible={this.state.createVirtualVisible}
onCancel={() => {
this.setState({ createVirtualVisible: false, initVirtualData: {} });
}}
query={() => this.handleSearch()}
shopList={this.shopList}
></CreateVirtualModal> */}
<SupplyModal
data={this.state.detailData}
visible={this.state.supplyVisible}
type={this.state.type}
onCancel={() => {
this.setState({ supplyVisible: false });
}}
></SupplyModal>
<ImgModal
data={this.state.imgData || []}
visible={this.state.imgVisible}
onCancel={() => {
this.setState({ imgVisible: false });
}}
></ImgModal>
<ReasonModal
visible={this.state.offlineVisible}
submit={reason => {
const { ids, productState } = this.state.selectedParams;
this.updateStatus(ids, productState, reason);
}}
onCancel={() => {
this.setState({ offlineVisible: false });
}}
></ReasonModal>
<UpdatePrice
visible={this.state.updatePriceVisible}
info={this.state.priceInfo}
onCancel={this.cancel}
/>
<UpdateStock
visible={this.state.updateStockVisible}
info={this.state.priceInfo}
onCancel={this.cancel}
/>
</Spin>
</PageHeaderWrapper>
);
}
}
export default Form.create()(goodsManage);
...@@ -5,7 +5,8 @@ import { Button } from 'antd'; ...@@ -5,7 +5,8 @@ import { Button } from 'antd';
import { categoryList, query, getVirtualCategory, getSupplierList, getBrandList } from './service'; import { categoryList, query, getVirtualCategory, getSupplierList, getBrandList } from './service';
import { Goodscolumns } from './Goodscolumns'; import { Goodscolumns } from './Goodscolumns';
import styled from './style.less'; import styled from './style.less';
import OperationModal from './components/operationModal'; // eslint-disable-next-line import/extensions
import OperationModal from './OperationModal/index.jsx';
export default () => { export default () => {
/** /**
...@@ -13,6 +14,7 @@ export default () => { ...@@ -13,6 +14,7 @@ export default () => {
* @type boolean * @type boolean
* @desc 整个页面的加载状态 * @desc 整个页面的加载状态
*/ */
const [isEdit, setIsEdit] = useState(false);
const [categoryData, setCategoryData] = useState([]); const [categoryData, setCategoryData] = useState([]);
const [operationVisible, setOperationVisible] = useState(false); const [operationVisible, setOperationVisible] = useState(false);
const actionRef = useRef(); const actionRef = useRef();
...@@ -39,8 +41,18 @@ export default () => { ...@@ -39,8 +41,18 @@ export default () => {
featchData(); featchData();
}, []); }, []);
const onAddGoodsForm = () => {
setIsEdit(false);
setOperationVisible(true);
};
const onModifyForm = () => {
// 修改form表单事件
setIsEdit(true);
setOperationVisible(true);
};
const toolBarList = [ const toolBarList = [
<Button key="getOffGoodsShelf" type="primary" onClick={() => setOperationVisible(true)}> <Button key="getOffGoodsShelf" type="primary" onClick={() => onAddGoodsForm()}>
新增商品 新增商品
</Button>, </Button>,
<Button key="putGoodsShelf">模版</Button>, <Button key="putGoodsShelf">模版</Button>,
...@@ -48,13 +60,19 @@ export default () => { ...@@ -48,13 +60,19 @@ export default () => {
批量修改库存 批量修改库存
</Button>, </Button>,
]; ];
console.log(operationVisible);
return ( return (
<PageHeaderWrapper> <PageHeaderWrapper>
<ProTable <ProTable
className={styled.protable} className={styled.protable}
actionRef={actionRef} actionRef={actionRef}
columns={Goodscolumns({ categoryData, supplyPrice, setSupplyPrice, supplyPriceRef })} columns={Goodscolumns({
categoryData,
supplyPrice,
setSupplyPrice,
supplyPriceRef,
onModifyForm,
})}
params={{ ...supplyPrice }} params={{ ...supplyPrice }}
request={params => { request={params => {
// 表单搜索项会从 params 传入,传递给后端接口。 // 表单搜索项会从 params 传入,传递给后端接口。
...@@ -86,6 +104,7 @@ export default () => { ...@@ -86,6 +104,7 @@ export default () => {
}} }}
/> />
<OperationModal <OperationModal
isEdit={isEdit}
operationVisible={operationVisible} operationVisible={operationVisible}
setOperationVisible={setOperationVisible} setOperationVisible={setOperationVisible}
categoryData={categoryData} // 实体商品类目 categoryData={categoryData} // 实体商品类目
......
import * as api from './service'; import * as api from './service';
const Model = { const Model = {
namespace: 'goodsManage', namespace: 'GoodsManage-new',
state: { state: {
tableData: {}, tableData: {},
shopList: [], shopList: [],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment