文档:增加功能列表
后端 + 前端:完善展示分类功能
This commit is contained in:
parent
83a3689088
commit
dcc58fbba4
@ -27,6 +27,12 @@ class PicturesWall extends React.Component {
|
||||
],
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
if (this.props.urls) {
|
||||
this.setUrls(this.props.urls);
|
||||
}
|
||||
}
|
||||
|
||||
handleCancel = () => this.setState({ previewVisible: false })
|
||||
|
||||
handlePreview = (file) => {
|
||||
@ -137,6 +143,14 @@ class PicturesWall extends React.Component {
|
||||
return urls;
|
||||
};
|
||||
|
||||
getUrl = () => {
|
||||
let urls = this.getUrls();
|
||||
if (urls && urls.length > 0) {
|
||||
return urls[0];
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
setUrls = (urls) => {
|
||||
// let urls = this.props.urls;
|
||||
if (urls) {
|
||||
@ -188,7 +202,7 @@ class PicturesWall extends React.Component {
|
||||
|
||||
PicturesWall.propTypes = {
|
||||
maxLength: Number, // 最大照片墙图片数量
|
||||
// urls: String[], // 初始图片列表
|
||||
urls: Array, // 初始图片列表
|
||||
};
|
||||
|
||||
export default PicturesWall;
|
||||
|
@ -69,7 +69,6 @@ export default {
|
||||
});
|
||||
},
|
||||
* add({ payload }, { call, put }) {
|
||||
const { callback, body } = payload;
|
||||
// 显示加载中
|
||||
yield put({
|
||||
type: 'changeModalLoading',
|
||||
@ -77,6 +76,7 @@ export default {
|
||||
});
|
||||
|
||||
// 请求
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(addAdmin, body);
|
||||
// 响应
|
||||
if (response.code === 0) {
|
||||
|
@ -5,61 +5,129 @@ export default {
|
||||
namespace: 'productCategoryList',
|
||||
|
||||
state: {
|
||||
// 分页列表相关
|
||||
list: [],
|
||||
listLoading: false,
|
||||
|
||||
// 添加 or 修改表单相关
|
||||
modalVisible: false,
|
||||
modalType: undefined, // 'add' or 'update' 表单
|
||||
formVals: {}, // 当前表单值
|
||||
modalLoading: false,
|
||||
|
||||
},
|
||||
|
||||
effects: {
|
||||
*add({ payload }, { call, put }) {
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(productCategoryAdd, body);
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
},
|
||||
*update({ payload }, { call, put }) {
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(productCategoryUpdate, body);
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
},
|
||||
*updateStatus({ payload }, { call, put }) {
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(productCategoryUpdateStatus, body);
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
},
|
||||
*delete({ payload }, { call, put }) {
|
||||
const response = yield call(productCategoryDelete, payload);
|
||||
message.info('删除成功!');
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
},
|
||||
// 查询列表
|
||||
*tree({ payload }, { call, put }) {
|
||||
// 显示加载中
|
||||
yield put({
|
||||
type: 'changeListLoading',
|
||||
payload: true,
|
||||
});
|
||||
|
||||
// 请求
|
||||
const { queryParams } = payload;
|
||||
// 响应
|
||||
const response = yield call(productCategoryTree, queryParams);
|
||||
message.info('查询成功!');
|
||||
yield put({
|
||||
type: 'treeSuccess',
|
||||
payload: {
|
||||
list: response.data,
|
||||
},
|
||||
});
|
||||
|
||||
// 隐藏加载中
|
||||
yield put({
|
||||
type: 'changeListLoading',
|
||||
payload: false,
|
||||
});
|
||||
},
|
||||
*add({ payload }, { call, put }) {
|
||||
// 显示加载中
|
||||
yield put({
|
||||
type: 'changeModalLoading',
|
||||
payload: true,
|
||||
});
|
||||
|
||||
// 请求
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(productCategoryAdd, body);
|
||||
// 响应
|
||||
if (response.code === 0) {
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
// 刷新列表
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
}
|
||||
|
||||
// 隐藏加载中
|
||||
yield put({
|
||||
type: 'changeModalLoading',
|
||||
payload: false,
|
||||
});
|
||||
},
|
||||
*update({ payload }, { call, put }) {
|
||||
// 显示加载中
|
||||
yield put({
|
||||
type: 'changeModalLoading',
|
||||
payload: true,
|
||||
});
|
||||
|
||||
// 请求
|
||||
const { callback, body } = payload;
|
||||
const response = yield call(productCategoryUpdate, body);
|
||||
// 响应
|
||||
if (response.code === 0) {
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
// 刷新列表
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
}
|
||||
|
||||
// 隐藏加载中
|
||||
yield put({
|
||||
type: 'changeModalLoading',
|
||||
payload: false,
|
||||
});
|
||||
},
|
||||
*updateStatus({ payload }, { call, put }) {
|
||||
// 请求
|
||||
const { callback, body } = payload;
|
||||
// 响应
|
||||
const response = yield call(productCategoryUpdateStatus, body);
|
||||
if(response.code === 0) {
|
||||
message.info('更新状态成功!');
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
}
|
||||
},
|
||||
*delete({ payload }, { call, put }) {
|
||||
// 响应
|
||||
const response = yield call(productCategoryDelete, payload);
|
||||
if(response.code === 0) {
|
||||
message.info('删除成功!');
|
||||
if (callback) {
|
||||
callback(response);
|
||||
}
|
||||
yield put({
|
||||
type: 'tree',
|
||||
payload: {},
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@ -70,5 +138,25 @@ export default {
|
||||
...payload,
|
||||
};
|
||||
},
|
||||
// 修改加载中的状态
|
||||
changeModalLoading(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
modalLoading: payload,
|
||||
};
|
||||
},
|
||||
changeListLoading(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
listLoading: payload,
|
||||
};
|
||||
},
|
||||
// 设置所有属性
|
||||
setAll(state, { payload }) {
|
||||
return {
|
||||
...state,
|
||||
...payload,
|
||||
};
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -213,7 +213,7 @@ const AddOrUpdateForm = Form.create()(props => {
|
||||
// 清空表单
|
||||
form.resetFields();
|
||||
// 提示
|
||||
message.success('添加成功');
|
||||
message.success('新建成功');
|
||||
// 关闭弹窗
|
||||
handleModalVisible();
|
||||
},
|
||||
@ -232,7 +232,7 @@ const AddOrUpdateForm = Form.create()(props => {
|
||||
// 清空表单
|
||||
form.resetFields();
|
||||
// 提示
|
||||
message.success('更新成功');
|
||||
message.success('编辑成功');
|
||||
// 关闭弹窗
|
||||
handleModalVisible();
|
||||
},
|
||||
@ -242,7 +242,7 @@ const AddOrUpdateForm = Form.create()(props => {
|
||||
});
|
||||
};
|
||||
|
||||
const title = modalType === 'add' ? '新建管理员' : '更新管理员';
|
||||
const title = modalType === 'add' ? '新建员工' : '更新员工';
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
@ -389,11 +389,6 @@ const RoleAssignModal = Form.create()(props => {
|
||||
// 主界面
|
||||
@Form.create()
|
||||
class AdminList extends PureComponent {
|
||||
state = {
|
||||
// 分配角色弹窗
|
||||
modalRoleVisible: false,
|
||||
modalRoleRow: {},
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { dispatch } = this.props;
|
||||
@ -461,6 +456,7 @@ class AdminList extends PureComponent {
|
||||
dispatch,
|
||||
handleModalVisible: this.handleModalVisible, // Function
|
||||
};
|
||||
|
||||
// 分配角色 Modal 属性
|
||||
const roleAssignModal = {
|
||||
loading: roleAssignLoading,
|
||||
@ -485,7 +481,7 @@ class AdminList extends PureComponent {
|
||||
type="primary"
|
||||
onClick={() => this.handleModalVisible(true, 'add', {})}
|
||||
>
|
||||
新建管理员
|
||||
新建员工
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@ -500,4 +496,4 @@ class AdminList extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
export default AdminList;
|
||||
export default AdminList;
|
||||
|
@ -3,37 +3,208 @@
|
||||
import React, { PureComponent, Fragment } from 'react';
|
||||
import { connect } from 'dva';
|
||||
import moment from 'moment';
|
||||
import {Card, Form, Input, Select, Button, Modal, message, Table, Divider, InputNumber} from 'antd';
|
||||
import {Card, Form, Input, Select, Button, Modal, message, Table, Divider, InputNumber, TreeSelect, Spin} from 'antd';
|
||||
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||
|
||||
import styles from './ProductCategoryList.less';
|
||||
import PicturesWall from "../../components/Image/PicturesWall";
|
||||
|
||||
const FormItem = Form.Item;
|
||||
const { Option } = Select;
|
||||
const status = ['未知', '开启', '禁用'];
|
||||
|
||||
// 添加 form 表单
|
||||
const CreateForm = Form.create()(props => {
|
||||
const { modalVisible, form, handleAdd, handleModalVisible, modalType, initValues } = props;
|
||||
// 列表
|
||||
function List({ dataSource, loading, dispatch,
|
||||
handleModalVisible}) {
|
||||
|
||||
function handleStatus(record) {
|
||||
Modal.confirm({
|
||||
title: record.status === 1 ? '确认禁用?' : '确认开启?',
|
||||
content: `${record.name}`,
|
||||
onOk() {
|
||||
dispatch({
|
||||
type: 'productCategoryList/updateStatus',
|
||||
payload: {
|
||||
body: {
|
||||
id: record.id,
|
||||
status: record.status === 1 ? 2 : 1,
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
onCancel() {},
|
||||
});
|
||||
}
|
||||
|
||||
function handleDelete(record) {
|
||||
Modal.confirm({
|
||||
title: `确认删除?`,
|
||||
content: `${record.name}`,
|
||||
onOk() {
|
||||
dispatch({
|
||||
type: 'productCategoryList/delete',
|
||||
payload: {
|
||||
id: record.id,
|
||||
},
|
||||
});
|
||||
},
|
||||
onCancel() {},
|
||||
});
|
||||
}
|
||||
|
||||
const columns = [
|
||||
// {
|
||||
// title: 'id',
|
||||
// dataIndex: 'id',
|
||||
// render: text => <strong>{text}</strong>,
|
||||
// },
|
||||
{
|
||||
title: '分类名称',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '图片',
|
||||
dataIndex: 'picUrl',
|
||||
render(val) {
|
||||
return <img width={120} src={val} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '排序值',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
render(val) {
|
||||
return <span>{status[val]}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
render: (text, record) => {
|
||||
const statusText = record.status === 1 ? '禁用' : '开启';
|
||||
return (
|
||||
<Fragment>
|
||||
<a onClick={() => handleModalVisible(true, 'update', record)}>编辑</a>
|
||||
<Divider type="vertical"/>
|
||||
<a className={styles.tableDelete} onClick={() => handleStatus(record)}>
|
||||
{statusText}
|
||||
</a>
|
||||
|
||||
{
|
||||
record.status === 2 ? (
|
||||
<span>
|
||||
<Divider type="vertical"/>
|
||||
<a className={styles.tableDelete} onClick={() => handleDelete(record)}>
|
||||
删除
|
||||
</a>
|
||||
</span>
|
||||
) : ''
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Table
|
||||
defaultExpandAllRows={true}
|
||||
columns={columns}
|
||||
loading={loading}
|
||||
rowKey="id"
|
||||
dataSource={dataSource} />
|
||||
)
|
||||
}
|
||||
|
||||
// 新建 form 表单
|
||||
const AddOrUpdateForm = Form.create()(props => {
|
||||
const { dispatch, loading, modalVisible, form, handleModalVisible, modalType, categoryTree, formVals } = props;
|
||||
let picturesWall = null;
|
||||
|
||||
const okHandle = () => {
|
||||
form.validateFields((err, fieldsValue) => {
|
||||
form.validateFields((err, fields) => {
|
||||
if (err) return;
|
||||
form.resetFields();
|
||||
handleAdd({
|
||||
fields: fieldsValue,
|
||||
modalType,
|
||||
initValues,
|
||||
});
|
||||
if (modalType === 'add') {
|
||||
dispatch({
|
||||
type: 'productCategoryList/add',
|
||||
payload: {
|
||||
body: {
|
||||
...fields,
|
||||
picUrl: picturesWall ? picturesWall.getUrl() : undefined,
|
||||
},
|
||||
callback: () => {
|
||||
// 清空表单
|
||||
form.resetFields();
|
||||
// 提示
|
||||
message.success('新建成功');
|
||||
// 关闭弹窗
|
||||
handleModalVisible();
|
||||
},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'productCategoryList/update',
|
||||
payload: {
|
||||
body: {
|
||||
...formVals,
|
||||
...fields,
|
||||
picUrl: picturesWall ? picturesWall.getUrl() : undefined,
|
||||
},
|
||||
callback: () => {
|
||||
// 清空表单
|
||||
form.resetFields();
|
||||
// 提示
|
||||
message.success('编辑成功');
|
||||
// 关闭弹窗
|
||||
handleModalVisible();
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const selectStyle = {
|
||||
width: 200,
|
||||
};
|
||||
function onPidChange(value) {
|
||||
formVals.pid = parseInt(value);
|
||||
}
|
||||
|
||||
const title = modalType === 'add' ? '添加一个 Resource' : '更新一个 Resource';
|
||||
const okText = modalType === 'add' ? '添加' : '更新';
|
||||
// 处理分类筛选
|
||||
const buildSelectTree = (list) => {
|
||||
return list.map(item => {
|
||||
let children = [];
|
||||
// if (item.children) { // 暂时不允许添加二级分类。
|
||||
// children = buildSelectTree(item.children);
|
||||
// }
|
||||
return {
|
||||
title: item.name,
|
||||
value: item.id,
|
||||
key: item.id,
|
||||
children,
|
||||
};
|
||||
});
|
||||
};
|
||||
let categoryTreeSelect = buildSelectTree(categoryTree);
|
||||
categoryTreeSelect.unshift({
|
||||
title: '无父分类',
|
||||
value: 0,
|
||||
key: 0,
|
||||
children: [],
|
||||
});
|
||||
|
||||
const title = modalType === 'add' ? '新建分类' : '编辑分类';
|
||||
const okText = modalType === 'add' ? '新建' : '编辑';
|
||||
return (
|
||||
<Modal
|
||||
destroyOnClose
|
||||
@ -43,51 +214,61 @@ const CreateForm = Form.create()(props => {
|
||||
okText={okText}
|
||||
onCancel={() => handleModalVisible()}
|
||||
>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="分类名">
|
||||
{form.getFieldDecorator('name', {
|
||||
rules: [{ required: true, message: '请输入分类名!', min: 2 }],
|
||||
initialValue: initValues.name,
|
||||
})(<Input placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="分类图片">
|
||||
{form.getFieldDecorator('picUrl', {
|
||||
initialValue: initValues.handler,
|
||||
})(<Input placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="父分类编号">
|
||||
{form.getFieldDecorator('pid', {
|
||||
rules: [{ required: true, message: '请输入父分类编号!' }],
|
||||
initialValue: initValues.pid,
|
||||
})(<Input placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="排序值">
|
||||
{form.getFieldDecorator('sort', {
|
||||
rules: [{ required: true, message: '请输入排序值!' }],
|
||||
initialValue: initValues.sort,
|
||||
})(<InputNumber placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="描述">
|
||||
{form.getFieldDecorator('description', {
|
||||
rules: [{ required: true, message: '请输入描述!' }],
|
||||
initialValue: initValues.description,
|
||||
})(<Input.TextArea placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
<Spin spinning={loading}>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="分类名称">
|
||||
{form.getFieldDecorator('name', {
|
||||
rules: [{ required: true, message: '请输入分类名称!', min: 2 }],
|
||||
initialValue: formVals.name,
|
||||
})(<Input placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="父分类">
|
||||
{form.getFieldDecorator('pid', {
|
||||
rules: [{ required: true, message: '请选择父分类!' }],
|
||||
initialValue: formVals.pid,
|
||||
})(
|
||||
<TreeSelect
|
||||
showSearch
|
||||
style={{ width: 300 }}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
treeData={categoryTreeSelect}
|
||||
placeholder="选择父分类"
|
||||
onChange={onPidChange}
|
||||
/>
|
||||
)}
|
||||
</FormItem>
|
||||
{
|
||||
formVals.pid > 0 ? (
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="分类图片"
|
||||
extra="建议尺寸:480*480PX,大小不超过 2M" required={true}>
|
||||
<PicturesWall urls={formVals.picUrl ? [formVals.picUrl] : undefined} ref={(node) => picturesWall = node} maxLength={1} />
|
||||
</FormItem>
|
||||
) : ''
|
||||
}
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="排序值">
|
||||
{form.getFieldDecorator('sort', {
|
||||
rules: [{ required: true, message: '请输入排序值!' }],
|
||||
initialValue: formVals.sort,
|
||||
})(<InputNumber placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
<FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 15 }} label="描述">
|
||||
{form.getFieldDecorator('description', {
|
||||
rules: [{ required: true, message: '请输入描述!' }],
|
||||
initialValue: formVals.description,
|
||||
})(<Input.TextArea placeholder="请输入" />)}
|
||||
</FormItem>
|
||||
</Spin>
|
||||
</Modal>
|
||||
);
|
||||
});
|
||||
|
||||
@connect(({ productCategoryList, loading }) => ({
|
||||
productCategoryList,
|
||||
list: productCategoryList.list,
|
||||
loading: loading.models.productCategoryList,
|
||||
@connect(({ productCategoryList, }) => ({
|
||||
...productCategoryList,
|
||||
// list: productCategoryList.list,
|
||||
// loading: loading.models.productCategoryList,
|
||||
}))
|
||||
|
||||
@Form.create()
|
||||
class ProductCategoryList extends PureComponent {
|
||||
state = {
|
||||
modalVisible: false,
|
||||
modalType: 'add', //add update
|
||||
initValues: {},
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
const { dispatch } = this.props;
|
||||
@ -97,162 +278,41 @@ class ProductCategoryList extends PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
handleModalVisible = (flag, modalType, initValues) => {
|
||||
this.setState({
|
||||
modalVisible: !!flag,
|
||||
initValues: initValues || {},
|
||||
modalType: modalType || 'add',
|
||||
handleModalVisible = (modalVisible, modalType, record) => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: 'productCategoryList/setAll',
|
||||
payload: {
|
||||
modalVisible,
|
||||
modalType,
|
||||
formVals: record || {}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
handleAdd = ({ fields, modalType, initValues }) => {
|
||||
const { dispatch } = this.props;
|
||||
if (modalType === 'add') {
|
||||
dispatch({
|
||||
type: 'productCategoryList/add',
|
||||
payload: {
|
||||
body: {
|
||||
...fields,
|
||||
},
|
||||
callback: () => {
|
||||
message.success('添加成功');
|
||||
this.handleModalVisible();
|
||||
},
|
||||
},
|
||||
});
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'productCategoryList/update',
|
||||
payload: {
|
||||
body: {
|
||||
...initValues,
|
||||
...fields,
|
||||
},
|
||||
callback: () => {
|
||||
message.success('更新成功');
|
||||
this.handleModalVisible();
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
handleStatus(row) {
|
||||
const { dispatch, data } = this.props;
|
||||
|
||||
const title = row.status === 1 ? '确认禁用?' : '确认开启?';
|
||||
const updateStatus = row.status === 1 ? 2 : 1;
|
||||
|
||||
Modal.confirm({
|
||||
title: `${title}`,
|
||||
content: `${row.name}`,
|
||||
onOk() {
|
||||
dispatch({
|
||||
type: 'productCategoryList/updateStatus',
|
||||
payload: {
|
||||
body: {
|
||||
id: row.id,
|
||||
status: updateStatus,
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
onCancel() {},
|
||||
});
|
||||
}
|
||||
|
||||
handleDelete(row) {
|
||||
const { dispatch } = this.props;
|
||||
Modal.confirm({
|
||||
title: `确认删除?`,
|
||||
content: `${row.displayName}`,
|
||||
onOk() {
|
||||
dispatch({
|
||||
type: 'productCategoryList/delete',
|
||||
payload: {
|
||||
id: row.id,
|
||||
},
|
||||
});
|
||||
},
|
||||
onCancel() {},
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const { list } = this.props;
|
||||
const { modalVisible, modalType, initValues } = this.state;
|
||||
const parentMethods = {
|
||||
handleAdd: this.handleAdd,
|
||||
handleModalVisible: this.handleModalVisible,
|
||||
modalType,
|
||||
initValues,
|
||||
const { dispatch,
|
||||
list,listLoading,
|
||||
modalVisible, modalType, formVals, modalLoading,} = this.props;
|
||||
|
||||
// 列表属性
|
||||
const listProps = {
|
||||
dataSource: list,
|
||||
dispatch,
|
||||
loading: listLoading,
|
||||
handleModalVisible: this.handleModalVisible, // Function
|
||||
};
|
||||
const that = this;
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'id',
|
||||
dataIndex: 'id',
|
||||
render: text => <strong>{text}</strong>,
|
||||
},
|
||||
{
|
||||
title: '分类名',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '分类图片',
|
||||
dataIndex: 'picUrl',
|
||||
render(val) {
|
||||
return <img width={120} src={val} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '排序值',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
render(val) {
|
||||
return <span>{status[val]}</span>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
render: (text, record) => {
|
||||
const statusText = record.status === 1 ? '禁用' : '开启';
|
||||
return (
|
||||
<Fragment>
|
||||
<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>
|
||||
<Divider type="vertical"/>
|
||||
<a className={styles.tableDelete} onClick={() => this.handleStatus(record)}>
|
||||
{statusText}
|
||||
</a>
|
||||
|
||||
{
|
||||
record.status === 2 ? (
|
||||
<span>
|
||||
<Divider type="vertical"/>
|
||||
<a className={styles.tableDelete} onClick={() => this.handleDelete(record)}>
|
||||
删除
|
||||
</a>
|
||||
</span>
|
||||
) : ''
|
||||
}
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
},
|
||||
];
|
||||
// 添加 or 编辑表单属性
|
||||
const addOrUpdateFormProps = {
|
||||
modalVisible,
|
||||
modalType,
|
||||
formVals,
|
||||
dispatch,
|
||||
loading: modalLoading,
|
||||
categoryTree: list,
|
||||
handleModalVisible: this.handleModalVisible, // Function
|
||||
};
|
||||
|
||||
return (
|
||||
<PageHeaderWrapper>
|
||||
@ -264,13 +324,14 @@ class ProductCategoryList extends PureComponent {
|
||||
type="primary"
|
||||
onClick={() => this.handleModalVisible(true, 'add', {})}
|
||||
>
|
||||
新建商品分类
|
||||
新建分类
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Table defaultExpandAllRows={true} columns={columns} dataSource={list} rowKey="id" />
|
||||
<List {...listProps} />
|
||||
</Card>
|
||||
<CreateForm {...parentMethods} modalVisible={modalVisible} />
|
||||
|
||||
<AddOrUpdateForm {...addOrUpdateFormProps} />
|
||||
</PageHeaderWrapper>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,30 @@
|
||||
如下是 onemall 的功能列表。
|
||||
|
||||
* 当功能被完成时,会标记已完成。
|
||||
* 未完成的功能,欢迎一起来开发。
|
||||
|
||||
- [ ] 首页
|
||||
- 商品相关
|
||||
- [ ] 分类列表
|
||||
- [ ] 商品搜索
|
||||
- [ ] 商品列表(基于分类)
|
||||
- [ ] 商品列表(基于促销活动)
|
||||
- [ ] 商品详情
|
||||
- [ ] 商品收藏
|
||||
- 订单相关
|
||||
- [ ] 下单(直接购买)
|
||||
- [ ] 下单(购物车购买)
|
||||
- [ ] 下单(拼团)
|
||||
- [ ] 订单列表
|
||||
- [ ] 订单详情
|
||||
- [ ] 支付
|
||||
- [ ] 退款
|
||||
- [ ] 购物车
|
||||
- [ ] 收获地址
|
||||
- 营销相关
|
||||
- [ ] 优惠劵
|
||||
- [ ] 优惠码
|
||||
- 用户相关
|
||||
- [ ] 登陆
|
||||
- [ ] 注册
|
||||
- [ ] 个人信息
|
@ -1,5 +1,10 @@
|
||||
如下是 onemall 的功能列表。
|
||||
|
||||
* 当功能被完成时,会标记已完成。
|
||||
* 未完成的功能,欢迎一起来开发。
|
||||
|
||||
- [ ] 概述 TODO
|
||||
- [ ] 数据分析
|
||||
- [ ] 数据分析
|
||||
- [ ] TODO 未开始
|
||||
- [ ] 店铺资产
|
||||
- [ ] TODO 未开始
|
||||
@ -14,9 +19,9 @@
|
||||
- [ ] 订单评价
|
||||
- [ ] 会员管理
|
||||
- [ ] 会员资料
|
||||
- TODO 需要补充
|
||||
- TODO 需要补充
|
||||
- [ ] 营销管理
|
||||
- [ ] 广告管理
|
||||
- [ ] 广告管理
|
||||
- [ ] 优惠劵
|
||||
- [ ] 优惠码
|
||||
- [ ] 商品推荐
|
||||
@ -29,5 +34,5 @@
|
||||
- [ ] 权限管理
|
||||
- [ ] 短信管理
|
||||
- [ ] 短信模板
|
||||
- [ ] 发送日志
|
||||
- [ ] 操作日志
|
||||
- [ ] 发送日志
|
||||
- [ ] 操作日志
|
||||
|
@ -14,6 +14,7 @@ public enum ProductErrorCodeEnum {
|
||||
PRODUCT_CATEGORY_STATUS_EQUALS(1002001003, "商品分类已经是该状态"),
|
||||
PRODUCT_CATEGORY_DELETE_ONLY_DISABLE(1002001004, "只有关闭的商品分类才可以删除"),
|
||||
PRODUCT_CATEGORY_MUST_ENABLE(1002001005, "只有开启的商品分类,才可以使用"),
|
||||
PRODUCT_CATEGORY_PARENT_CAN_NOT_BE_LEVEL2(1002001005, "父分类必须是一级分类"),
|
||||
|
||||
// ========== PRODUCT SPU + SKU 模块 ==========
|
||||
PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE(1003002000, "一个 Sku 下,不能有重复的规格"),
|
||||
@ -46,4 +47,4 @@ public enum ProductErrorCodeEnum {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -47,11 +47,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
|
||||
@Override
|
||||
public CommonResult<ProductCategoryBO> addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO) {
|
||||
// 校验父分类是否存在
|
||||
if (!ProductCategoryConstants.PID_ROOT.equals(productCategoryAddDTO.getPid())
|
||||
&& productCategoryMapper.selectById(productCategoryAddDTO.getPid()) == null) {
|
||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 校验父分类
|
||||
validParent(productCategoryAddDTO.getPid());
|
||||
// 保存到数据库
|
||||
ProductCategoryDO productCategory = ProductCategoryConvert.INSTANCE.convert(productCategoryAddDTO)
|
||||
.setStatus(ProductCategoryConstants.STATUS_ENABLE);
|
||||
@ -65,10 +62,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
|
||||
@Override
|
||||
public CommonResult<Boolean> updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO) {
|
||||
// 校验分类是否存在
|
||||
if (productCategoryMapper.selectById(productCategoryUpdateDTO.getId()) == null) {
|
||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 校验父分类
|
||||
validParent(productCategoryUpdateDTO.getPid());
|
||||
// 校验不能设置自己为父分类
|
||||
if (productCategoryUpdateDTO.getId().equals(productCategoryUpdateDTO.getPid())) {
|
||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_SELF.getCode());
|
||||
@ -153,4 +148,18 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
||||
|| ProductCategoryConstants.STATUS_DISABLE.equals(status);
|
||||
}
|
||||
|
||||
private void validParent(Integer pid) {
|
||||
if (!ProductCategoryConstants.PID_ROOT.equals(pid)) {
|
||||
ProductCategoryDO parentCategory = productCategoryMapper.selectById(pid);
|
||||
// 校验父分类是否存在
|
||||
if (parentCategory == null) {
|
||||
throw ServiceExceptionUtil.exception(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_EXISTS.getCode());
|
||||
}
|
||||
// 父分类必须是一级分类
|
||||
if (!ProductCategoryConstants.PID_ROOT.equals(parentCategory.getPid())) {
|
||||
throw ServiceExceptionUtil.exception((ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_CAN_NOT_BE_LEVEL2.getCode()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user