文档:增加功能列表
后端 + 前端:完善展示分类功能
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 })
|
handleCancel = () => this.setState({ previewVisible: false })
|
||||||
|
|
||||||
handlePreview = (file) => {
|
handlePreview = (file) => {
|
||||||
@ -137,6 +143,14 @@ class PicturesWall extends React.Component {
|
|||||||
return urls;
|
return urls;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getUrl = () => {
|
||||||
|
let urls = this.getUrls();
|
||||||
|
if (urls && urls.length > 0) {
|
||||||
|
return urls[0];
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
setUrls = (urls) => {
|
setUrls = (urls) => {
|
||||||
// let urls = this.props.urls;
|
// let urls = this.props.urls;
|
||||||
if (urls) {
|
if (urls) {
|
||||||
@ -188,7 +202,7 @@ class PicturesWall extends React.Component {
|
|||||||
|
|
||||||
PicturesWall.propTypes = {
|
PicturesWall.propTypes = {
|
||||||
maxLength: Number, // 最大照片墙图片数量
|
maxLength: Number, // 最大照片墙图片数量
|
||||||
// urls: String[], // 初始图片列表
|
urls: Array, // 初始图片列表
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PicturesWall;
|
export default PicturesWall;
|
||||||
|
@ -69,7 +69,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
* add({ payload }, { call, put }) {
|
* add({ payload }, { call, put }) {
|
||||||
const { callback, body } = payload;
|
|
||||||
// 显示加载中
|
// 显示加载中
|
||||||
yield put({
|
yield put({
|
||||||
type: 'changeModalLoading',
|
type: 'changeModalLoading',
|
||||||
@ -77,6 +76,7 @@ export default {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 请求
|
// 请求
|
||||||
|
const { callback, body } = payload;
|
||||||
const response = yield call(addAdmin, body);
|
const response = yield call(addAdmin, body);
|
||||||
// 响应
|
// 响应
|
||||||
if (response.code === 0) {
|
if (response.code === 0) {
|
||||||
|
@ -5,61 +5,129 @@ export default {
|
|||||||
namespace: 'productCategoryList',
|
namespace: 'productCategoryList',
|
||||||
|
|
||||||
state: {
|
state: {
|
||||||
|
// 分页列表相关
|
||||||
list: [],
|
list: [],
|
||||||
|
listLoading: false,
|
||||||
|
|
||||||
|
// 添加 or 修改表单相关
|
||||||
|
modalVisible: false,
|
||||||
|
modalType: undefined, // 'add' or 'update' 表单
|
||||||
|
formVals: {}, // 当前表单值
|
||||||
|
modalLoading: false,
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
effects: {
|
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 }) {
|
*tree({ payload }, { call, put }) {
|
||||||
|
// 显示加载中
|
||||||
|
yield put({
|
||||||
|
type: 'changeListLoading',
|
||||||
|
payload: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 请求
|
||||||
const { queryParams } = payload;
|
const { queryParams } = payload;
|
||||||
|
// 响应
|
||||||
const response = yield call(productCategoryTree, queryParams);
|
const response = yield call(productCategoryTree, queryParams);
|
||||||
message.info('查询成功!');
|
|
||||||
yield put({
|
yield put({
|
||||||
type: 'treeSuccess',
|
type: 'treeSuccess',
|
||||||
payload: {
|
payload: {
|
||||||
list: response.data,
|
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,
|
...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();
|
form.resetFields();
|
||||||
// 提示
|
// 提示
|
||||||
message.success('添加成功');
|
message.success('新建成功');
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
handleModalVisible();
|
handleModalVisible();
|
||||||
},
|
},
|
||||||
@ -232,7 +232,7 @@ const AddOrUpdateForm = Form.create()(props => {
|
|||||||
// 清空表单
|
// 清空表单
|
||||||
form.resetFields();
|
form.resetFields();
|
||||||
// 提示
|
// 提示
|
||||||
message.success('更新成功');
|
message.success('编辑成功');
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
handleModalVisible();
|
handleModalVisible();
|
||||||
},
|
},
|
||||||
@ -242,7 +242,7 @@ const AddOrUpdateForm = Form.create()(props => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const title = modalType === 'add' ? '新建管理员' : '更新管理员';
|
const title = modalType === 'add' ? '新建员工' : '更新员工';
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
@ -389,11 +389,6 @@ const RoleAssignModal = Form.create()(props => {
|
|||||||
// 主界面
|
// 主界面
|
||||||
@Form.create()
|
@Form.create()
|
||||||
class AdminList extends PureComponent {
|
class AdminList extends PureComponent {
|
||||||
state = {
|
|
||||||
// 分配角色弹窗
|
|
||||||
modalRoleVisible: false,
|
|
||||||
modalRoleRow: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
@ -461,6 +456,7 @@ class AdminList extends PureComponent {
|
|||||||
dispatch,
|
dispatch,
|
||||||
handleModalVisible: this.handleModalVisible, // Function
|
handleModalVisible: this.handleModalVisible, // Function
|
||||||
};
|
};
|
||||||
|
|
||||||
// 分配角色 Modal 属性
|
// 分配角色 Modal 属性
|
||||||
const roleAssignModal = {
|
const roleAssignModal = {
|
||||||
loading: roleAssignLoading,
|
loading: roleAssignLoading,
|
||||||
@ -485,7 +481,7 @@ class AdminList extends PureComponent {
|
|||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => this.handleModalVisible(true, 'add', {})}
|
onClick={() => this.handleModalVisible(true, 'add', {})}
|
||||||
>
|
>
|
||||||
新建管理员
|
新建员工
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,156 +3,31 @@
|
|||||||
import React, { PureComponent, Fragment } from 'react';
|
import React, { PureComponent, Fragment } from 'react';
|
||||||
import { connect } from 'dva';
|
import { connect } from 'dva';
|
||||||
import moment from 'moment';
|
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 PageHeaderWrapper from '@/components/PageHeaderWrapper';
|
||||||
|
|
||||||
import styles from './ProductCategoryList.less';
|
import styles from './ProductCategoryList.less';
|
||||||
|
import PicturesWall from "../../components/Image/PicturesWall";
|
||||||
|
|
||||||
const FormItem = Form.Item;
|
const FormItem = Form.Item;
|
||||||
const { Option } = Select;
|
const { Option } = Select;
|
||||||
const status = ['未知', '开启', '禁用'];
|
const status = ['未知', '开启', '禁用'];
|
||||||
|
|
||||||
// 添加 form 表单
|
// 列表
|
||||||
const CreateForm = Form.create()(props => {
|
function List({ dataSource, loading, dispatch,
|
||||||
const { modalVisible, form, handleAdd, handleModalVisible, modalType, initValues } = props;
|
handleModalVisible}) {
|
||||||
|
|
||||||
const okHandle = () => {
|
|
||||||
form.validateFields((err, fieldsValue) => {
|
|
||||||
if (err) return;
|
|
||||||
form.resetFields();
|
|
||||||
handleAdd({
|
|
||||||
fields: fieldsValue,
|
|
||||||
modalType,
|
|
||||||
initValues,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const selectStyle = {
|
|
||||||
width: 200,
|
|
||||||
};
|
|
||||||
|
|
||||||
const title = modalType === 'add' ? '添加一个 Resource' : '更新一个 Resource';
|
|
||||||
const okText = modalType === 'add' ? '添加' : '更新';
|
|
||||||
return (
|
|
||||||
<Modal
|
|
||||||
destroyOnClose
|
|
||||||
title={title}
|
|
||||||
visible={modalVisible}
|
|
||||||
onOk={okHandle}
|
|
||||||
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>
|
|
||||||
</Modal>
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
@connect(({ productCategoryList, loading }) => ({
|
|
||||||
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;
|
|
||||||
dispatch({
|
|
||||||
type: 'productCategoryList/tree',
|
|
||||||
payload: {},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleModalVisible = (flag, modalType, initValues) => {
|
|
||||||
this.setState({
|
|
||||||
modalVisible: !!flag,
|
|
||||||
initValues: initValues || {},
|
|
||||||
modalType: modalType || 'add',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
function handleStatus(record) {
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: `${title}`,
|
title: record.status === 1 ? '确认禁用?' : '确认开启?',
|
||||||
content: `${row.name}`,
|
content: `${record.name}`,
|
||||||
onOk() {
|
onOk() {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'productCategoryList/updateStatus',
|
type: 'productCategoryList/updateStatus',
|
||||||
payload: {
|
payload: {
|
||||||
body: {
|
body: {
|
||||||
id: row.id,
|
id: record.id,
|
||||||
status: updateStatus,
|
status: record.status === 1 ? 2 : 1,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -161,16 +36,15 @@ class ProductCategoryList extends PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDelete(row) {
|
function handleDelete(record) {
|
||||||
const { dispatch } = this.props;
|
|
||||||
Modal.confirm({
|
Modal.confirm({
|
||||||
title: `确认删除?`,
|
title: `确认删除?`,
|
||||||
content: `${row.displayName}`,
|
content: `${record.name}`,
|
||||||
onOk() {
|
onOk() {
|
||||||
dispatch({
|
dispatch({
|
||||||
type: 'productCategoryList/delete',
|
type: 'productCategoryList/delete',
|
||||||
payload: {
|
payload: {
|
||||||
id: row.id,
|
id: record.id,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -178,29 +52,18 @@ class ProductCategoryList extends PureComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
|
||||||
const { list } = this.props;
|
|
||||||
const { modalVisible, modalType, initValues } = this.state;
|
|
||||||
const parentMethods = {
|
|
||||||
handleAdd: this.handleAdd,
|
|
||||||
handleModalVisible: this.handleModalVisible,
|
|
||||||
modalType,
|
|
||||||
initValues,
|
|
||||||
};
|
|
||||||
const that = this;
|
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
|
// {
|
||||||
|
// title: 'id',
|
||||||
|
// dataIndex: 'id',
|
||||||
|
// render: text => <strong>{text}</strong>,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: 'id',
|
title: '分类名称',
|
||||||
dataIndex: 'id',
|
|
||||||
render: text => <strong>{text}</strong>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '分类名',
|
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '分类图片',
|
title: '图片',
|
||||||
dataIndex: 'picUrl',
|
dataIndex: 'picUrl',
|
||||||
render(val) {
|
render(val) {
|
||||||
return <img width={120} src={val} />;
|
return <img width={120} src={val} />;
|
||||||
@ -210,11 +73,6 @@ class ProductCategoryList extends PureComponent {
|
|||||||
title: '排序值',
|
title: '排序值',
|
||||||
dataIndex: 'sort',
|
dataIndex: 'sort',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: '创建时间',
|
|
||||||
dataIndex: 'createTime',
|
|
||||||
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
@ -226,15 +84,20 @@ class ProductCategoryList extends PureComponent {
|
|||||||
title: '描述',
|
title: '描述',
|
||||||
dataIndex: 'description',
|
dataIndex: 'description',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '创建时间',
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
render: val => <span>{moment(val).format('YYYY-MM-DD')}</span>,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
render: (text, record) => {
|
render: (text, record) => {
|
||||||
const statusText = record.status === 1 ? '禁用' : '开启';
|
const statusText = record.status === 1 ? '禁用' : '开启';
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<a onClick={() => this.handleModalVisible(true, 'update', record)}>更新</a>
|
<a onClick={() => handleModalVisible(true, 'update', record)}>编辑</a>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<a className={styles.tableDelete} onClick={() => this.handleStatus(record)}>
|
<a className={styles.tableDelete} onClick={() => handleStatus(record)}>
|
||||||
{statusText}
|
{statusText}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
@ -242,7 +105,7 @@ class ProductCategoryList extends PureComponent {
|
|||||||
record.status === 2 ? (
|
record.status === 2 ? (
|
||||||
<span>
|
<span>
|
||||||
<Divider type="vertical"/>
|
<Divider type="vertical"/>
|
||||||
<a className={styles.tableDelete} onClick={() => this.handleDelete(record)}>
|
<a className={styles.tableDelete} onClick={() => handleDelete(record)}>
|
||||||
删除
|
删除
|
||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
@ -254,6 +117,203 @@ class ProductCategoryList extends PureComponent {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
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, fields) => {
|
||||||
|
if (err) return;
|
||||||
|
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();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
function onPidChange(value) {
|
||||||
|
formVals.pid = parseInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理分类筛选
|
||||||
|
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
|
||||||
|
title={title}
|
||||||
|
visible={modalVisible}
|
||||||
|
onOk={okHandle}
|
||||||
|
okText={okText}
|
||||||
|
onCancel={() => handleModalVisible()}
|
||||||
|
>
|
||||||
|
<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, }) => ({
|
||||||
|
...productCategoryList,
|
||||||
|
// list: productCategoryList.list,
|
||||||
|
// loading: loading.models.productCategoryList,
|
||||||
|
}))
|
||||||
|
|
||||||
|
@Form.create()
|
||||||
|
class ProductCategoryList extends PureComponent {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch({
|
||||||
|
type: 'productCategoryList/tree',
|
||||||
|
payload: {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleModalVisible = (modalVisible, modalType, record) => {
|
||||||
|
const { dispatch } = this.props;
|
||||||
|
dispatch({
|
||||||
|
type: 'productCategoryList/setAll',
|
||||||
|
payload: {
|
||||||
|
modalVisible,
|
||||||
|
modalType,
|
||||||
|
formVals: record || {}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { dispatch,
|
||||||
|
list,listLoading,
|
||||||
|
modalVisible, modalType, formVals, modalLoading,} = this.props;
|
||||||
|
|
||||||
|
// 列表属性
|
||||||
|
const listProps = {
|
||||||
|
dataSource: list,
|
||||||
|
dispatch,
|
||||||
|
loading: listLoading,
|
||||||
|
handleModalVisible: this.handleModalVisible, // Function
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加 or 编辑表单属性
|
||||||
|
const addOrUpdateFormProps = {
|
||||||
|
modalVisible,
|
||||||
|
modalType,
|
||||||
|
formVals,
|
||||||
|
dispatch,
|
||||||
|
loading: modalLoading,
|
||||||
|
categoryTree: list,
|
||||||
|
handleModalVisible: this.handleModalVisible, // Function
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageHeaderWrapper>
|
<PageHeaderWrapper>
|
||||||
<Card bordered={false}>
|
<Card bordered={false}>
|
||||||
@ -264,13 +324,14 @@ class ProductCategoryList extends PureComponent {
|
|||||||
type="primary"
|
type="primary"
|
||||||
onClick={() => this.handleModalVisible(true, 'add', {})}
|
onClick={() => this.handleModalVisible(true, 'add', {})}
|
||||||
>
|
>
|
||||||
新建商品分类
|
新建分类
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Table defaultExpandAllRows={true} columns={columns} dataSource={list} rowKey="id" />
|
<List {...listProps} />
|
||||||
</Card>
|
</Card>
|
||||||
<CreateForm {...parentMethods} modalVisible={modalVisible} />
|
|
||||||
|
<AddOrUpdateForm {...addOrUpdateFormProps} />
|
||||||
</PageHeaderWrapper>
|
</PageHeaderWrapper>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
如下是 onemall 的功能列表。
|
||||||
|
|
||||||
|
* 当功能被完成时,会标记已完成。
|
||||||
|
* 未完成的功能,欢迎一起来开发。
|
||||||
|
|
||||||
|
- [ ] 首页
|
||||||
|
- 商品相关
|
||||||
|
- [ ] 分类列表
|
||||||
|
- [ ] 商品搜索
|
||||||
|
- [ ] 商品列表(基于分类)
|
||||||
|
- [ ] 商品列表(基于促销活动)
|
||||||
|
- [ ] 商品详情
|
||||||
|
- [ ] 商品收藏
|
||||||
|
- 订单相关
|
||||||
|
- [ ] 下单(直接购买)
|
||||||
|
- [ ] 下单(购物车购买)
|
||||||
|
- [ ] 下单(拼团)
|
||||||
|
- [ ] 订单列表
|
||||||
|
- [ ] 订单详情
|
||||||
|
- [ ] 支付
|
||||||
|
- [ ] 退款
|
||||||
|
- [ ] 购物车
|
||||||
|
- [ ] 收获地址
|
||||||
|
- 营销相关
|
||||||
|
- [ ] 优惠劵
|
||||||
|
- [ ] 优惠码
|
||||||
|
- 用户相关
|
||||||
|
- [ ] 登陆
|
||||||
|
- [ ] 注册
|
||||||
|
- [ ] 个人信息
|
@ -1,3 +1,8 @@
|
|||||||
|
如下是 onemall 的功能列表。
|
||||||
|
|
||||||
|
* 当功能被完成时,会标记已完成。
|
||||||
|
* 未完成的功能,欢迎一起来开发。
|
||||||
|
|
||||||
- [ ] 概述 TODO
|
- [ ] 概述 TODO
|
||||||
- [ ] 数据分析
|
- [ ] 数据分析
|
||||||
- [ ] TODO 未开始
|
- [ ] TODO 未开始
|
||||||
|
@ -14,6 +14,7 @@ public enum ProductErrorCodeEnum {
|
|||||||
PRODUCT_CATEGORY_STATUS_EQUALS(1002001003, "商品分类已经是该状态"),
|
PRODUCT_CATEGORY_STATUS_EQUALS(1002001003, "商品分类已经是该状态"),
|
||||||
PRODUCT_CATEGORY_DELETE_ONLY_DISABLE(1002001004, "只有关闭的商品分类才可以删除"),
|
PRODUCT_CATEGORY_DELETE_ONLY_DISABLE(1002001004, "只有关闭的商品分类才可以删除"),
|
||||||
PRODUCT_CATEGORY_MUST_ENABLE(1002001005, "只有开启的商品分类,才可以使用"),
|
PRODUCT_CATEGORY_MUST_ENABLE(1002001005, "只有开启的商品分类,才可以使用"),
|
||||||
|
PRODUCT_CATEGORY_PARENT_CAN_NOT_BE_LEVEL2(1002001005, "父分类必须是一级分类"),
|
||||||
|
|
||||||
// ========== PRODUCT SPU + SKU 模块 ==========
|
// ========== PRODUCT SPU + SKU 模块 ==========
|
||||||
PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE(1003002000, "一个 Sku 下,不能有重复的规格"),
|
PRODUCT_SKU_ATTR_CANT_NOT_DUPLICATE(1003002000, "一个 Sku 下,不能有重复的规格"),
|
||||||
|
@ -47,11 +47,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductCategoryBO> addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO) {
|
public CommonResult<ProductCategoryBO> addProductCategory(Integer adminId, ProductCategoryAddDTO productCategoryAddDTO) {
|
||||||
// 校验父分类是否存在
|
// 校验父分类
|
||||||
if (!ProductCategoryConstants.PID_ROOT.equals(productCategoryAddDTO.getPid())
|
validParent(productCategoryAddDTO.getPid());
|
||||||
&& productCategoryMapper.selectById(productCategoryAddDTO.getPid()) == null) {
|
|
||||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_EXISTS.getCode());
|
|
||||||
}
|
|
||||||
// 保存到数据库
|
// 保存到数据库
|
||||||
ProductCategoryDO productCategory = ProductCategoryConvert.INSTANCE.convert(productCategoryAddDTO)
|
ProductCategoryDO productCategory = ProductCategoryConvert.INSTANCE.convert(productCategoryAddDTO)
|
||||||
.setStatus(ProductCategoryConstants.STATUS_ENABLE);
|
.setStatus(ProductCategoryConstants.STATUS_ENABLE);
|
||||||
@ -65,10 +62,8 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<Boolean> updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO) {
|
public CommonResult<Boolean> updateProductCategory(Integer adminId, ProductCategoryUpdateDTO productCategoryUpdateDTO) {
|
||||||
// 校验分类是否存在
|
// 校验父分类
|
||||||
if (productCategoryMapper.selectById(productCategoryUpdateDTO.getId()) == null) {
|
validParent(productCategoryUpdateDTO.getPid());
|
||||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_NOT_EXISTS.getCode());
|
|
||||||
}
|
|
||||||
// 校验不能设置自己为父分类
|
// 校验不能设置自己为父分类
|
||||||
if (productCategoryUpdateDTO.getId().equals(productCategoryUpdateDTO.getPid())) {
|
if (productCategoryUpdateDTO.getId().equals(productCategoryUpdateDTO.getPid())) {
|
||||||
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_SELF.getCode());
|
return ServiceExceptionUtil.error(ProductErrorCodeEnum.PRODUCT_CATEGORY_PARENT_NOT_SELF.getCode());
|
||||||
@ -153,4 +148,18 @@ public class ProductCategoryServiceImpl implements ProductCategoryService {
|
|||||||
|| ProductCategoryConstants.STATUS_DISABLE.equals(status);
|
|| 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