diff --git a/admin-web/config/router.config.js b/admin-web/config/router.config.js
index a058ce557..3bf367c03 100644
--- a/admin-web/config/router.config.js
+++ b/admin-web/config/router.config.js
@@ -125,6 +125,11 @@ export default [
name: 'product-brand-list',
component: './Product/ProductBrandList',
},
+ {
+ path: '/product/product-attr-list',
+ name: 'product-attr-list',
+ component: './Product/ProductAttrList',
+ },
],
},
// promotion
diff --git a/admin-web/src/locales/zh-CN/menu.js b/admin-web/src/locales/zh-CN/menu.js
index 2dcf49161..0e9ef9d14 100644
--- a/admin-web/src/locales/zh-CN/menu.js
+++ b/admin-web/src/locales/zh-CN/menu.js
@@ -52,6 +52,8 @@ export default {
'menu.product.product-spu-update': '商品编辑',
'menu.product.product-category-list': '商品分类',
'menu.product.product-brand-list': '商品品牌',
+ 'menu.product.product-attr-list': '规格管理',
+
// 订单
'menu.order': '订单管理',
'menu.order.order-list': '订单管理',
diff --git a/admin-web/src/models/admin/adminList.js b/admin-web/src/models/admin/adminList.js
index c9c433ec7..95025b69f 100644
--- a/admin-web/src/models/admin/adminList.js
+++ b/admin-web/src/models/admin/adminList.js
@@ -1,5 +1,5 @@
-import {message} from 'antd';
-import {buildTreeNode, findCheckedKeys} from '../../utils/tree.utils';
+import { message } from 'antd';
+import { buildTreeNode, findCheckedKeys } from '../../utils/tree.utils';
import {
addAdmin,
adminRoleAssign,
@@ -8,14 +8,30 @@ import {
queryAdminRoleList,
updateAdmin,
updateAdminStatus,
+ deptTreeAll,
} from '../../services/admin';
-import {arrayToStringParams} from '../../utils/request.qs';
+import { arrayToStringParams } from '../../utils/request.qs';
import PaginationHelper from '../../../helpers/PaginationHelper';
const SEARCH_PARAMS_DEFAULT = {
nickname: '',
};
+const buildSelectTree = list => {
+ return list.map(item => {
+ let children = [];
+ if (item.children) {
+ children = buildSelectTree(item.children);
+ }
+ return {
+ title: item.name,
+ value: `${item.name}-${item.id}`,
+ key: item.id,
+ children,
+ };
+ });
+};
+
export default {
namespace: 'adminList',
@@ -37,11 +53,22 @@ export default {
roleModalVisible: false,
roleCheckedKeys: [], // 此处的 Key ,就是角色编号
roleAssignLoading: false,
+
+ //部门相关
+ deptSelectTree: [],
},
effects: {
+ *getDeptmentTree({ payload }, { call, put }) {
+ const result = yield call(deptTreeAll, payload);
+ yield put({
+ type: 'treeSuccess',
+ payload: result.data,
+ });
+ },
+
// 查询列表
- * query({ payload }, { call, put }) {
+ *query({ payload }, { call, put }) {
// 显示加载中
yield put({
type: 'changeListLoading',
@@ -57,8 +84,8 @@ export default {
list: response.data.list,
pagination: PaginationHelper.formatPagination(response.data, payload),
searchParams: {
- nickname: payload.nickname || ''
- }
+ nickname: payload.nickname || '',
+ },
},
});
@@ -68,7 +95,7 @@ export default {
payload: false,
});
},
- * add({ payload }, { call, put }) {
+ *add({ payload }, { call, put }) {
// 显示加载中
yield put({
type: 'changeModalLoading',
@@ -87,7 +114,7 @@ export default {
yield put({
type: 'query',
payload: {
- ...PaginationHelper.defaultPayload
+ ...PaginationHelper.defaultPayload,
},
});
}
@@ -98,7 +125,7 @@ export default {
payload: false,
});
},
- * update({ payload }, { call, put }) {
+ *update({ payload }, { call, put }) {
const { callback, body } = payload;
// 显示加载中
yield put({
@@ -117,7 +144,7 @@ export default {
yield put({
type: 'query',
payload: {
- ...PaginationHelper.defaultPayload
+ ...PaginationHelper.defaultPayload,
},
});
}
@@ -129,7 +156,7 @@ export default {
});
},
- * updateStatus({ payload }, { call, put }) {
+ *updateStatus({ payload }, { call, put }) {
// 请求
const response = yield call(updateAdminStatus, payload);
// 响应
@@ -139,13 +166,13 @@ export default {
yield put({
type: 'query',
payload: {
- ...PaginationHelper.defaultPayload
+ ...PaginationHelper.defaultPayload,
},
});
}
},
- * delete({ payload }, { call, put }) {
+ *delete({ payload }, { call, put }) {
// 请求
const response = yield call(deleteAdmin, payload);
// 响应
@@ -155,13 +182,13 @@ export default {
yield put({
type: 'query',
payload: {
- ...PaginationHelper.defaultPayload
+ ...PaginationHelper.defaultPayload,
},
});
}
},
- * queryRoleList({ payload }, { call, put }) {
+ *queryRoleList({ payload }, { call, put }) {
// 显示加载中
yield put({
type: 'changeRoleAssignLoading',
@@ -191,7 +218,7 @@ export default {
});
},
- * roleAssign({ payload }, { call, put }) {
+ *roleAssign({ payload }, { call, put }) {
const { callback, body } = payload;
// 显示加载中
yield put({
@@ -220,6 +247,27 @@ export default {
},
reducers: {
+ treeSuccess(state, { payload }) {
+ const resultData = payload;
+ const treeData = buildSelectTree(resultData);
+
+ // // value 要保护 displayName 不然,搜索会失效
+ // const rootNode = [
+ // {
+ // title: '根节点',
+ // value: `根节点-0`,
+ // key: 0,
+ // children: [],
+ // },
+ // ];
+
+ // const deptSelectTree = rootNode.concat(treeData);
+ return {
+ ...state,
+ // list: resultData,
+ deptSelectTree: treeData,
+ };
+ },
changeRoleCheckedKeys(state, { payload }) {
return {
...state,
@@ -251,6 +299,6 @@ export default {
...state,
...payload,
};
- }
+ },
},
};
diff --git a/admin-web/src/models/admin/deptmentList.js b/admin-web/src/models/admin/deptmentList.js
index ab44614ea..b659beca0 100644
--- a/admin-web/src/models/admin/deptmentList.js
+++ b/admin-web/src/models/admin/deptmentList.js
@@ -1,5 +1,11 @@
import { message } from 'antd';
-import { deptTreePage, deptTreeAll, addDeptment, updateDeptment } from '../../services/admin';
+import {
+ deptTreePage,
+ deptTreeAll,
+ addDeptment,
+ updateDeptment,
+ deleteDeptment,
+} from '../../services/admin';
const buildSelectTree = list => {
return list.map(item => {
@@ -35,6 +41,13 @@ export default {
onSuccess && onSuccess();
}
},
+ *delete({ payload }, { call, put }) {
+ const { onSuccess, body } = payload;
+ const response = yield call(deleteDeptment, body);
+ if (response && response.code === 0) {
+ onSuccess && onSuccess();
+ }
+ },
*update({ payload }, { call, put }) {
const { onSuccess, body } = payload;
const response = yield call(updateDeptment, body);
diff --git a/admin-web/src/models/product/productAttrList.js b/admin-web/src/models/product/productAttrList.js
index 54ffaf64c..80405882d 100644
--- a/admin-web/src/models/product/productAttrList.js
+++ b/admin-web/src/models/product/productAttrList.js
@@ -1,36 +1,76 @@
import { message } from 'antd';
-import { productAttrTree, productAttrValueAdd } from '../../services/product';
+import {
+ productAttrTree,
+ productAttrValueAdd,
+ productAttrPage,
+ productAttrAdd,
+ productAttrUpdate,
+ productAttrUpdateStatus,
+ productAttrValueUpdate,
+ productAttrValueUpdateStatus,
+} from '../../services/product';
+import PaginationHelper from '../../../helpers/PaginationHelper';
export default {
namespace: 'productAttrList',
state: {
list: [],
+ // tree: [],
+ attrData: [],
+ pagination: PaginationHelper.defaultPaginationConfig,
},
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: {},
- // });
- // },
+ *add({ payload }, { call, put }) {
+ const { onSuccess, onFail, body } = payload;
+ const response = yield call(productAttrAdd, body);
+ if (response && response.code === 0) {
+ onSuccess && onSuccess();
+ } else {
+ onFail && onFail(response);
+ }
+ },
+
+ *update({ payload }, { call, put }) {
+ const { onSuccess, onFail, body } = payload;
+ const response = yield call(productAttrUpdate, body);
+ if (response && response.code === 0) {
+ onSuccess && onSuccess();
+ } else {
+ onFail && onFail(response);
+ }
+ },
+
+ *value_update({ payload }, { call, put }) {
+ const { onSuccess, onFail, body } = payload;
+ const response = yield call(productAttrValueUpdate, body);
+ if (response && response.code === 0) {
+ onSuccess && onSuccess();
+ } else {
+ onFail && onFail(response);
+ }
+ },
+
+ *update_status({ payload }, { call, put }) {
+ const { onSuccess, onFail, body } = payload;
+ const response = yield call(productAttrUpdateStatus, body);
+ if (response && response.code === 0) {
+ onSuccess && onSuccess();
+ } else {
+ onFail && onFail(response);
+ }
+ },
+
+ *value_update_status({ payload }, { call, put }) {
+ const { onSuccess, onFail, body } = payload;
+ const response = yield call(productAttrValueUpdateStatus, body);
+ if (response && response.code === 0) {
+ onSuccess && onSuccess();
+ } else {
+ onFail && onFail(response);
+ }
+ },
// *updateStatus({ payload }, { call, put }) {
// const { callback, body } = payload;
// const response = yield call(productCategoryUpdateStatus, body);
@@ -51,6 +91,21 @@ export default {
// });
// },
+ *page({ payload }, { call, put }) {
+ const result = yield call(productAttrPage, payload);
+ let attrData = {};
+ if (result.code === 0) {
+ attrData = result.data;
+ }
+ yield put({
+ type: 'save',
+ payload: {
+ attrData,
+ pagination: PaginationHelper.formatPagination(attrData, payload),
+ },
+ });
+ },
+
*tree({ payload }, { call, put }) {
const { queryParams } = payload;
const response = yield call(productAttrTree, queryParams);
@@ -62,6 +117,17 @@ export default {
},
});
},
+
+ *value_add({ payload }, { call, put }) {
+ const { onSuccess, onFail, body } = payload;
+ const response = yield call(productAttrValueAdd, body);
+ if (response && response.code === 0) {
+ onSuccess && onSuccess();
+ } else {
+ onFail && onFail(response);
+ }
+ },
+
*addValue({ payload, callback }, { call, put }) {
// debugger;
// const {queryParams} = payload;
@@ -84,10 +150,16 @@ export default {
callback(response.data);
}
}
- }
+ },
},
reducers: {
+ save(state, action) {
+ return {
+ ...state,
+ ...action.payload,
+ };
+ },
treeSuccess(state, { payload }) {
return {
...state,
diff --git a/admin-web/src/pages/Admin/AdminList.js b/admin-web/src/pages/Admin/AdminList.js
index 8e4e77ca5..1866cfad8 100644
--- a/admin-web/src/pages/Admin/AdminList.js
+++ b/admin-web/src/pages/Admin/AdminList.js
@@ -2,22 +2,44 @@
import React, { PureComponent, Fragment } from 'react';
import { connect } from 'dva';
-import {Card, Form, Input, Button, Modal, message, Table, Divider, Tree, Spin, Row, Col, Select, Icon} from 'antd';
-import { checkTypeWithEnglishAndNumbers } from '../../../helpers/validator'
+import {
+ Card,
+ Form,
+ Input,
+ Button,
+ Modal,
+ message,
+ Table,
+ Divider,
+ Tree,
+ Spin,
+ Row,
+ Col,
+ Select,
+ Icon,
+ TreeSelect,
+} from 'antd';
+import { checkTypeWithEnglishAndNumbers } from '../../../helpers/validator';
import PageHeaderWrapper from '@/components/PageHeaderWrapper';
import styles from './AdminList.less';
-import moment from "moment";
-import PaginationHelper from "../../../helpers/PaginationHelper";
+import moment from 'moment';
+import PaginationHelper from '../../../helpers/PaginationHelper';
const FormItem = Form.Item;
const { TreeNode } = Tree;
const status = ['未知', '正常', '禁用'];
// 列表
-function List ({ dataSource, loading, pagination, searchParams, dispatch,
- handleModalVisible, handleRoleAssignModalVisible}) {
-
+function List({
+ dataSource,
+ loading,
+ pagination,
+ searchParams,
+ dispatch,
+ handleModalVisible,
+ handleRoleAssignModalVisible,
+}) {
function handleRoleAssign(record) {
// 显示 Modal
handleRoleAssignModalVisible(true, record);
@@ -66,12 +88,16 @@ function List ({ dataSource, loading, pagination, searchParams, dispatch,
const columns = [
{
title: '账号',
- dataIndex: 'username'
+ dataIndex: 'username',
},
{
title: '员工姓名',
dataIndex: 'nickname',
},
+ {
+ title: '部门',
+ dataIndex: 'deptment.name',
+ },
{
title: '角色',
dataIndex: 'roles',
@@ -85,8 +111,8 @@ function List ({ dataSource, loading, pagination, searchParams, dispatch,
text += roles[i].name;
}
}
- return ({text});
- }
+ return {text};
+ },
},
{
title: '状态',
@@ -114,30 +140,30 @@ function List ({ dataSource, loading, pagination, searchParams, dispatch,
handleStatus(record)}>
{statusText}
- {
- record.status === 2 ?
-
-
- handleDelete(record)}>
- 删除
-
- : null
- }
+ {record.status === 2 ? (
+
+
+ handleDelete(record)}>
+ 删除
+
+
+ ) : null}
);
},
},
];
- function onPageChange(page) { // 翻页
+ function onPageChange(page) {
+ // 翻页
dispatch({
type: 'adminList/query',
payload: {
pageNo: page.current,
pageSize: page.pageSize,
- ...searchParams
- }
- })
+ ...searchParams,
+ },
+ });
}
return (
@@ -149,7 +175,7 @@ function List ({ dataSource, loading, pagination, searchParams, dispatch,
pagination={pagination}
onChange={onPageChange}
/>
- )
+ );
}
// 搜索表单
@@ -157,17 +183,23 @@ const SearchForm = Form.create()(props => {
const {
form,
form: { getFieldDecorator },
- dispatch
+ dispatch,
+ deptSelectTree,
} = props;
function search() {
+ const fields = form.getFieldsValue();
+ if (fields.deptmentId) {
+ const deptmentId = fields.deptmentId.split('-')[1];
+ fields.deptmentId = deptmentId;
+ }
dispatch({
type: 'adminList/query',
payload: {
...PaginationHelper.defaultPayload,
- ...form.getFieldsValue()
- }
- })
+ ...fields,
+ },
+ });
}
// 提交搜索
@@ -189,20 +221,36 @@ const SearchForm = Form.create()(props => {
return (
@@ -211,12 +259,24 @@ const SearchForm = Form.create()(props => {
// 添加 or 修改 Form 表单
const AddOrUpdateForm = Form.create()(props => {
- const { dispatch, modalVisible, form, handleModalVisible, modalType, formVals } = props;
+ const {
+ dispatch,
+ modalVisible,
+ form,
+ handleModalVisible,
+ modalType,
+ formVals,
+ deptSelectTree,
+ } = props;
const okHandle = () => {
form.validateFields((err, fields) => {
if (err) return;
// 添加表单
+ if (fields.deptmentId) {
+ const deptmentId = fields.deptmentId.split('-')[1];
+ fields.deptmentId = deptmentId;
+ }
if (modalType === 'add') {
dispatch({
type: 'adminList/add',
@@ -264,29 +324,52 @@ const AddOrUpdateForm = Form.create()(props => {
title={title}
visible={modalVisible}
onOk={okHandle}
- okText='保存'
+ okText="保存"
onCancel={() => handleModalVisible()}
>
{form.getFieldDecorator('username', {
- rules: [{ required: true, message: '请输入账号!'},
- {max: 16, min:6, message: '长度为 6-16 位'},
- { validator: (rule, value, callback) => checkTypeWithEnglishAndNumbers(rule, value, callback, '数字以及字母')}
+ rules: [
+ { required: true, message: '请输入账号!' },
+ { max: 16, min: 6, message: '长度为 6-16 位' },
+ {
+ validator: (rule, value, callback) =>
+ checkTypeWithEnglishAndNumbers(rule, value, callback, '数字以及字母'),
+ },
],
initialValue: formVals.username,
})()}
{form.getFieldDecorator('nickname', {
- rules: [{ required: true, message: '请输入员工姓名!'},
- {max: 10, message: '姓名最大长度为 10'}],
+ rules: [
+ { required: true, message: '请输入员工姓名!' },
+ { max: 10, message: '姓名最大长度为 10' },
+ ],
initialValue: formVals.nickname,
})()}
+
+ {form.getFieldDecorator('deptmentId', {
+ rules: [{ required: true, message: '请选择部门' }],
+ initialValue:
+ formVals.deptmentId && formVals.deptmentId !== 0 ? formVals.deptmentId : null,
+ })(
+
+ )}
+
{form.getFieldDecorator('password', {
- rules: [{ required: modalType === 'add', message: '请填写密码'}, // 添加时,必须输入密码
- {max: 16, min: 6, message: '长度为 6-18 位'}],
+ rules: [
+ { required: modalType === 'add', message: '请填写密码' }, // 添加时,必须输入密码
+ { max: 16, min: 6, message: '长度为 6-18 位' },
+ ],
initialValue: formVals.password,
})()}
@@ -321,7 +404,8 @@ const RoleAssignModal = Form.create()(props => {
const renderTreeNodes = data => {
return data.map(item => {
- if (item.children) { // 递归拼接节点
+ if (item.children) {
+ // 递归拼接节点
return (
{renderTreeNodes(item.children)}
@@ -387,32 +471,31 @@ const RoleAssignModal = Form.create()(props => {
onOk={okHandle}
onCancel={() => handleModalVisible()}
>
-
- {renderModalContent(treeData)}
-
+ {renderModalContent(treeData)}
);
});
-
@connect(({ adminList }) => ({
// list: adminList.list,
// pagination: adminList.pagination,
...adminList,
}))
-
// 主界面
@Form.create()
class AdminList extends PureComponent {
-
componentDidMount() {
const { dispatch } = this.props;
dispatch({
type: 'adminList/query',
payload: {
- ...PaginationHelper.defaultPayload
+ ...PaginationHelper.defaultPayload,
},
});
+ dispatch({
+ type: 'adminList/getDeptmentTree',
+ payload: {},
+ });
}
handleModalVisible = (modalVisible, modalType, record) => {
@@ -422,7 +505,7 @@ class AdminList extends PureComponent {
payload: {
modalVisible,
modalType,
- formVals: record || {}
+ formVals: record || {},
},
});
};
@@ -433,18 +516,29 @@ class AdminList extends PureComponent {
type: 'adminList/setAll',
payload: {
roleModalVisible: roleModalVisible,
- formVals: record || {}
+ formVals: record || {},
},
});
};
render() {
// let that = this;
- const { dispatch,
- list, listLoading, searchParams, pagination,
- modalVisible, modalType, formVals,
+ const {
+ dispatch,
+ list,
+ listLoading,
+ searchParams,
+ pagination,
+ modalVisible,
+ modalType,
+ formVals,
confirmLoading,
- roleList, roleModalVisible, roleAssignLoading, roleCheckedKeys } = this.props;
+ roleList,
+ roleModalVisible,
+ roleAssignLoading,
+ roleCheckedKeys,
+ deptSelectTree,
+ } = this.props;
// 列表属性
const listProps = {
@@ -461,6 +555,7 @@ class AdminList extends PureComponent {
// 搜索表单属性
const searchFormProps = {
dispatch,
+ deptSelectTree,
};
// 添加 or 更新表单属性
@@ -469,6 +564,7 @@ class AdminList extends PureComponent {
modalType,
formVals,
dispatch,
+ deptSelectTree,
handleModalVisible: this.handleModalVisible, // Function
};
diff --git a/admin-web/src/pages/Admin/DeptmentList.js b/admin-web/src/pages/Admin/DeptmentList.js
index a741a72c8..621d86539 100644
--- a/admin-web/src/pages/Admin/DeptmentList.js
+++ b/admin-web/src/pages/Admin/DeptmentList.js
@@ -107,13 +107,23 @@ export default class DepetmentList extends PureComponent {
componentDidMount() {
const { dispatch } = this.props;
dispatch({
- type: 'deptmentList/getDeptmentList',
+ type: 'deptmentList/getDeptmentAll',
payload: {
...PaginationHelper.defaultPayload,
},
});
}
+ initFetch = () => {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'deptmentList/getDeptmentAll',
+ payload: {
+ ...PaginationHelper.defaultPayload,
+ },
+ });
+ };
+
handleModalVisible = (flag, modalType, initValues) => {
this.setState({
modalVisible: !!flag,
@@ -130,6 +140,33 @@ export default class DepetmentList extends PureComponent {
}
};
+ handleDelete(row) {
+ const { dispatch } = this.props;
+ const _this = this;
+ Modal.confirm({
+ title: `确认删除?`,
+ content: `${row.name}`,
+ onOk() {
+ dispatch({
+ type: 'deptmentList/delete',
+ payload: {
+ body: {
+ id: row.id,
+ },
+ onSuccess: () => {
+ message.success('删除成功');
+ _this.initFetch();
+ },
+ onFail: response => {
+ message.warn('删除失败' + response.message);
+ },
+ },
+ });
+ },
+ onCancel() {},
+ });
+ }
+
handleAdd = ({ fields, modalType, initValues }) => {
const { dispatch } = this.props;
if (modalType === 'add') {
@@ -142,6 +179,7 @@ export default class DepetmentList extends PureComponent {
onSuccess: () => {
message.success('添加成功');
this.handleModalVisible();
+ this.initFetch();
},
onFail: response => {
message.warn('添加失败' + response.message);
@@ -159,6 +197,7 @@ export default class DepetmentList extends PureComponent {
onSuccess: () => {
message.success('更新成功成功');
this.handleModalVisible();
+ this.initFetch();
},
onFail: response => {
message.warn('更新失败' + response.message);
@@ -169,7 +208,7 @@ export default class DepetmentList extends PureComponent {
};
render() {
- const { deptmentData, deptmentList } = this.props;
+ const { deptmentData, deptmentList, loading } = this.props;
const { selectTree } = deptmentList;
const { modalVisible, modalType, initValues } = this.state;
const parentMethods = {
@@ -229,8 +268,9 @@ export default class DepetmentList extends PureComponent {
diff --git a/admin-web/src/pages/Product/ProductAttrList.js b/admin-web/src/pages/Product/ProductAttrList.js
new file mode 100644
index 000000000..fad82cb73
--- /dev/null
+++ b/admin-web/src/pages/Product/ProductAttrList.js
@@ -0,0 +1,550 @@
+import React, { PureComponent, Fragment, Component } from 'react';
+import {
+ Row,
+ Col,
+ Form,
+ Card,
+ Table,
+ Button,
+ Divider,
+ Modal,
+ Input,
+ message,
+ Switch,
+ Select,
+} from 'antd';
+import moment from 'moment';
+import { connect } from 'dva';
+import PageHeaderWrapper from '@/components/PageHeaderWrapper';
+import PaginationHelper from '../../../helpers/PaginationHelper';
+import styles from './ProductAttrList.less';
+
+const FormItem = Form.Item;
+const Option = Select.Option;
+
+const ValueCreateForm = Form.create()(props => {
+ const {
+ valueModalVisible,
+ form,
+ handleValueAdd,
+ handleValueModalVisible,
+ modalType,
+ initValues,
+ tree,
+ } = props;
+
+ const okHandle = () => {
+ form.validateFields((err, fieldsValue) => {
+ if (err) return;
+ let pid = fieldsValue.pid;
+ if (fieldsValue.pid) {
+ pid = pid.split('-')[1];
+ fieldsValue.pid = pid;
+ }
+ form.resetFields();
+ handleValueAdd({
+ fields: fieldsValue,
+ modalType,
+ initValues,
+ });
+ });
+ };
+
+ const selectStyle = {
+ width: 200,
+ };
+
+ function onTypeChange(event) {
+ initValues.type = parseInt(event.target.value);
+ }
+
+ const title = modalType === 'add' ? '添加规格值' : '编辑规格值';
+ const okText = modalType === 'add' ? '添加' : '编辑';
+ return (
+ handleValueModalVisible()}
+ >
+ {modalType === 'add' ? (
+
+ {form.getFieldDecorator('attrId', {
+ // initialValue: template.durationHour ? template.durationHour : '3',
+ rules: [
+ {
+ required: true,
+ message: '请选择规格',
+ },
+ ],
+ })(
+
+ )}
+
+ ) : null}
+
+ {form.getFieldDecorator('name', {
+ initialValue: initValues ? initValues.name : null,
+ rules: [{ required: true, message: '请输入规格值!', min: 2 }],
+ })()}
+
+
+ );
+});
+
+const CreateForm = Form.create()(props => {
+ const { modalVisible, form, handleAdd, handleModalVisible, modalType, initValues } = props;
+
+ const okHandle = () => {
+ form.validateFields((err, fieldsValue) => {
+ if (err) return;
+ let pid = fieldsValue.pid;
+ if (fieldsValue.pid) {
+ pid = pid.split('-')[1];
+ fieldsValue.pid = pid;
+ }
+ form.resetFields();
+ handleAdd({
+ fields: fieldsValue,
+ modalType,
+ initValues,
+ });
+ });
+ };
+
+ const selectStyle = {
+ width: 200,
+ };
+
+ function onTypeChange(event) {
+ initValues.type = parseInt(event.target.value);
+ }
+
+ const title = modalType === 'add' ? '添加规格' : '编辑规格';
+ const okText = modalType === 'add' ? '添加' : '编辑';
+ return (
+ handleModalVisible()}
+ >
+
+ {form.getFieldDecorator('name', {
+ initialValue: initValues ? initValues.name : null,
+ rules: [{ required: true, message: '请输入规格名称!', min: 2 }],
+ })()}
+
+
+ );
+});
+
+@connect(({ productAttrList, loading }) => ({
+ productAttrList,
+ attrData: productAttrList.attrData,
+ tree: productAttrList.tree,
+ loading: loading.models.productAttrList,
+}))
+@Form.create()
+export default class ProductAttrList extends PureComponent {
+ state = {
+ modalVisible: false,
+ valueModalVisible: false,
+ modalType: 'add', //add or update
+ initValues: {},
+ current: 1,
+ pageSize: 10,
+ name: null,
+ };
+
+ componentDidMount() {
+ this.initFetch();
+ }
+
+ initFetch = () => {
+ const { dispatch } = this.props;
+ const { current, pageSize, name } = this.state;
+ dispatch({
+ type: 'productAttrList/page',
+ payload: {
+ pageNo: current,
+ pageSize,
+ name,
+ },
+ });
+ // const { dispatch } = this.props;
+ dispatch({
+ type: 'productAttrList/tree',
+ payload: {
+ ...PaginationHelper.defaultPayload,
+ },
+ });
+ };
+
+ expandedRowRender = record => {
+ const columns = [
+ {
+ title: '规格值',
+ dataIndex: 'name',
+ },
+ {
+ title: '状态',
+ // dataIndex: 'status',
+ render: (text, record) => (
+ this.switchValueChange(checked, record)}
+ />
+ ),
+ },
+ {
+ title: '创建时间',
+ dataIndex: 'createTime',
+ sorter: true,
+ render: val => {moment(val).format('YYYY-MM-DD')},
+ },
+ {
+ title: '操作',
+ render: (text, record) => (
+
+ this.handleValueModalVisible(true, 'update', record)}>编辑
+
+ {/* this.handleDelete(record)}>
+ 删除
+ */}
+
+ ),
+ },
+ ];
+
+ return ;
+ };
+
+ handleAdd = ({ fields, modalType, initValues }) => {
+ const { dispatch } = this.props;
+ if (modalType === 'add') {
+ dispatch({
+ type: 'productAttrList/add',
+ payload: {
+ body: {
+ ...fields,
+ },
+ onSuccess: () => {
+ message.success('添加成功');
+ this.handleModalVisible();
+ this.initFetch();
+ },
+ onFail: response => {
+ message.warn('添加失败' + response.message);
+ },
+ },
+ });
+ } else {
+ dispatch({
+ type: 'productAttrList/update',
+ payload: {
+ body: {
+ ...initValues,
+ ...fields,
+ },
+ onSuccess: () => {
+ message.success('更新成功');
+ this.handleModalVisible();
+ this.initFetch();
+ },
+ onFail: response => {
+ message.warn('更新失败' + response.message);
+ },
+ },
+ });
+ }
+ };
+
+ handleValueAdd = ({ fields, modalType, initValues }) => {
+ const { dispatch } = this.props;
+ if (modalType === 'add') {
+ dispatch({
+ type: 'productAttrList/value_add',
+ payload: {
+ body: {
+ ...fields,
+ },
+ onSuccess: () => {
+ message.success('添加成功');
+ this.handleValueModalVisible();
+ this.initFetch();
+ },
+ onFail: response => {
+ message.warn('添加失败' + response.message);
+ },
+ },
+ });
+ } else {
+ dispatch({
+ type: 'productAttrList/value_update',
+ payload: {
+ body: {
+ ...initValues,
+ ...fields,
+ },
+ onSuccess: () => {
+ message.success('更新成功');
+ this.handleValueModalVisible();
+ this.initFetch();
+ },
+ onFail: response => {
+ message.warn('更新失败' + response.message);
+ },
+ },
+ });
+ }
+ };
+
+ handleModalVisible = (flag, modalType, initValues) => {
+ this.setState({
+ modalVisible: !!flag,
+ initValues: initValues || {},
+ modalType: modalType || 'add',
+ });
+ };
+
+ handleValueModalVisible = (flag, modalType, initValues) => {
+ this.setState({
+ valueModalVisible: !!flag,
+ initValues: initValues || {},
+ modalType: modalType || 'add',
+ });
+ };
+
+ handleTableChange = pagination => {
+ const { pageSize, current, index } = pagination;
+ this.setState(
+ {
+ current,
+ pageSize,
+ },
+ function() {
+ this.initFetch();
+ }
+ );
+ };
+
+ switchValueChange = (checked, record) => {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'productAttrList/value_update_status',
+ payload: {
+ body: {
+ id: record.id,
+ status: checked ? 1 : 2,
+ },
+ onSuccess: () => {
+ message.success('修改状态成功');
+ this.initFetch();
+ },
+ },
+ });
+ };
+
+ switchChange = (checked, record) => {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'productAttrList/update_status',
+ payload: {
+ body: {
+ id: record.id,
+ status: checked ? 1 : 2,
+ },
+ onSuccess: () => {
+ message.success('修改状态成功');
+ this.initFetch();
+ },
+ },
+ });
+ };
+
+ handleFormReset = () => {
+ const { form, dispatch } = this.props;
+ form.resetFields();
+ this.setState(
+ {
+ name: null,
+ },
+ function() {
+ this.initFetch();
+ }
+ );
+ };
+
+ handleCondition = e => {
+ e.preventDefault();
+
+ const { dispatch, form } = this.props;
+
+ form.validateFields((err, fieldsValue) => {
+ if (err) return;
+ const values = {
+ ...fieldsValue,
+ };
+
+ if (values.name) {
+ this.setState(
+ {
+ searched: true,
+ name: values.name,
+ },
+ function() {
+ this.initFetch();
+ }
+ );
+ } else {
+ this.initFetch();
+ }
+
+ // dispatch({
+ // type: 'fenfa/getCategoryList',
+ // payload: {
+ // key: values.name
+ // },
+ // });
+ });
+ };
+
+ renderSimpleForm() {
+ const { form } = this.props;
+ const { getFieldDecorator } = form;
+ return (
+
+ );
+ }
+
+ render() {
+ const { attrData, productAttrList, loading, tree } = this.props;
+ const columns = [
+ {
+ title: '规格名称',
+ dataIndex: 'name',
+ },
+ {
+ title: '状态',
+ // dataIndex: 'status',
+ render: (text, record) => (
+ this.switchChange(checked, record)}
+ />
+ ),
+ },
+ {
+ title: '创建时间',
+ dataIndex: 'createTime',
+ sorter: true,
+ render: val => {moment(val).format('YYYY-MM-DD')},
+ },
+ {
+ title: '操作',
+ render: (text, record) => (
+
+ this.handleModalVisible(true, 'update', record)}>编辑
+
+ this.handleValueModalVisible(true, 'add', {})}>新建规格值
+ {/* this.handleDelete(record)}>
+ 删除
+ */}
+
+ ),
+ },
+ ];
+
+ const { modalVisible, modalType, initValues, valueModalVisible } = this.state;
+
+ const parentMethods = {
+ handleAdd: this.handleAdd,
+ handleModalVisible: this.handleModalVisible,
+ modalType,
+ initValues,
+ };
+
+ const valueFormParentMethods = {
+ handleValueAdd: this.handleValueAdd,
+ handleValueModalVisible: this.handleValueModalVisible,
+ modalType,
+ initValues,
+ tree: tree,
+ };
+
+ const pagination = {
+ total: attrData.count,
+ index: this.state.current,
+ pageSize: this.state.pageSize,
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+ {this.renderSimpleForm()}
+
+
+
+
+ this.handleTableChange(pagination)}
+ />
+
+ {modalVisible ? : null}
+ {valueModalVisible ? (
+
+ ) : null}
+
+ );
+ }
+}
diff --git a/admin-web/src/pages/Product/ProductAttrList.less b/admin-web/src/pages/Product/ProductAttrList.less
new file mode 100644
index 000000000..22e257421
--- /dev/null
+++ b/admin-web/src/pages/Product/ProductAttrList.less
@@ -0,0 +1,11 @@
+@import '~antd/lib/style/themes/default.less';
+@import '~@/utils/utils.less';
+
+.tableList {
+ .tableListOperator {
+ margin-bottom: 16px;
+ button {
+ margin-right: 8px;
+ }
+ }
+}
diff --git a/admin-web/src/services/admin.js b/admin-web/src/services/admin.js
index d39953d0e..b3dca958e 100644
--- a/admin-web/src/services/admin.js
+++ b/admin-web/src/services/admin.js
@@ -74,6 +74,12 @@ export async function updateDeptment(params) {
});
}
+export async function deleteDeptment(params) {
+ return request(`/admin-api/admins/dept/delete?${stringify(params)}`, {
+ method: 'POST',
+ });
+}
+
export async function deptTreePage(params) {
return request(`/admin-api/admins/dept/tree/page?${stringify(params)}`, {
method: 'GET',
diff --git a/admin-web/src/services/product.js b/admin-web/src/services/product.js
index a8929dd4e..2236d74fc 100644
--- a/admin-web/src/services/product.js
+++ b/admin-web/src/services/product.js
@@ -4,23 +4,23 @@ import request from '@/utils/request';
// product category
export async function productCategoryTree(params) {
- return request(`/product-api/admins/category/tree?${stringify(params)}`, {
- method: 'GET',
- });
+ return request(`/product-api/admins/category/tree?${stringify(params)}`, {
+ method: 'GET',
+ });
}
export async function productCategoryAdd(params) {
- return request(`/product-api/admins/category/add?${stringify(params)}`, {
- method: 'POST',
- body: {},
- });
+ return request(`/product-api/admins/category/add?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
}
export async function productCategoryUpdate(params) {
- return request(`/product-api/admins/category/update?${stringify(params)}`, {
- method: 'POST',
- body: {},
- });
+ return request(`/product-api/admins/category/update?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
}
export async function productCategoryUpdateStatus(params) {
@@ -31,9 +31,9 @@ export async function productCategoryUpdateStatus(params) {
}
export async function productCategoryDelete(params) {
- return request(`/product-api/admins/category/delete?${stringify(params)}`, {
- method: 'POST',
- });
+ return request(`/product-api/admins/category/delete?${stringify(params)}`, {
+ method: 'POST',
+ });
}
// product spu + sku
@@ -85,12 +85,53 @@ export async function productSpuInfo(params) {
// product attr + attr value
+export async function productAttrPage(params) {
+ return request(`/product-api/admins/attr/page?${stringify(params)}`, {
+ method: 'GET',
+ });
+}
+
+export async function productAttrAdd(params) {
+ return request(`/product-api/admins/attr/add?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
+}
+
+export async function productAttrUpdate(params) {
+ return request(`/product-api/admins/attr/update?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
+}
+
+export async function productAttrUpdateStatus(params) {
+ return request(`/product-api/admins/attr/update_status?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
+}
+
export async function productAttrTree(params) {
return request(`/product-api/admins/attr/tree?${stringify(params)}`, {
method: 'GET',
});
}
+export async function productAttrValueUpdate(params) {
+ return request(`/product-api/admins/attr_value/update?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
+}
+
+export async function productAttrValueUpdateStatus(params) {
+ return request(`/product-api/admins/attr_value/update_status?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
+}
+
export async function productAttrValueAdd(params) {
return request(`/product-api/admins/attr_value/add?${stringify(params)}`, {
method: 'POST',
@@ -98,30 +139,30 @@ export async function productAttrValueAdd(params) {
});
}
- // product brand 2019-05-31
+// product brand 2019-05-31
export async function productBrandAdd(params) {
- return request(`/product-api/admins/brand/add?${stringify(params)}`, {
- method: 'POST',
- body: {},
- });
+ return request(`/product-api/admins/brand/add?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
}
export async function productBrandUpdate(params) {
- return request(`/product-api/admins/brand/update?${stringify(params)}`, {
- method: 'POST',
- body: {},
- });
+ return request(`/product-api/admins/brand/update?${stringify(params)}`, {
+ method: 'POST',
+ body: {},
+ });
}
export async function productBrandGet(params) {
return request(`/product-api/admins/brand/get?${stringify(params)}`, {
- method: 'GET'
+ method: 'GET',
});
}
export async function productBrandPage(params) {
return request(`/product-api/admins/brand/page?${stringify(params)}`, {
- method: 'GET'
+ method: 'GET',
});
}
diff --git a/docs/guides/功能列表/功能列表-管理后台.md b/docs/guides/功能列表/功能列表-管理后台.md
index 12477a334..9585d6e62 100644
--- a/docs/guides/功能列表/功能列表-管理后台.md
+++ b/docs/guides/功能列表/功能列表-管理后台.md
@@ -20,6 +20,7 @@
- [x] 展示类目
- [ ] 品牌管理【开发中 @黑子】
- [ ] 商品标签
+ - [ ] 商品规格页面【开发中 @Tprotect曦】
- [ ] 订单管理
- [x] 销售单
- [x] 售后单
@@ -49,7 +50,7 @@
- [x] 员工管理
- [x] 角色管理
- [x] 权限管理
- - [ ] 部门管理【开发中 @Tprotect曦】
+ - [x] 部门管理
- [x] 数据字典
- [x] 短信管理
- [X] 短信模板
diff --git a/docs/sql/mall_admin.sql b/docs/sql/mall_admin.sql
index abf6cf7ae..c9a8230fd 100644
--- a/docs/sql/mall_admin.sql
+++ b/docs/sql/mall_admin.sql
@@ -50,6 +50,7 @@ CREATE TABLE `admin` (
`nickname` varchar(10) NOT NULL COMMENT '昵称',
`password` varchar(32) NOT NULL COMMENT '密码\n *\n * TODO 芋艿 暂时最简单的 MD5',
`status` tinyint(11) NOT NULL COMMENT '账号状态',
+ `deptment_id` int(11) DEFAULT 0 NOT NULL COMMENT '部门id',
`create_time` datetime NOT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted` bit(1) DEFAULT NULL,
@@ -313,6 +314,8 @@ INSERT INTO `resource` VALUES (50, 2, 3, '删除字典', 19, '', NULL, 'system.d
INSERT INTO `resource` VALUES (51, 1, -1, '短信ss', 0, '', 'user', '', '2019-05-26 12:00:31', '2019-06-03 13:54:54', b'0');
INSERT INTO `resource` VALUES (52, 1, 1, '短信签名', 51, '/sms/sign-list', 'user', '', '2019-05-26 12:01:56', '2019-05-26 12:01:56', b'0');
INSERT INTO `resource` VALUES (53, 1, 2, '短信模板', 51, '/sms/template-list', 'user', '', '2019-05-26 12:02:19', '2019-05-26 12:02:18', b'0');
+INSERT INTO `resource` VALUES (54, 1, 3, '部门管理', 13, '/admin/dept-list', 'user', '', '2019-06-27 23:41:19', '2019-06-27 23:41:51', b'0');
+INSERT INTO `resource` VALUES (55, 1, 4, '规格管理', 20, '/product/product-attr-list', null, null, '2019-08-14 23:59:38', '2019-08-14 23:59:38', b'0');
COMMIT;
-- ----------------------------
diff --git a/docs/sql/mall_user.sql b/docs/sql/mall_user.sql
index 7500b7410..5be346735 100644
--- a/docs/sql/mall_user.sql
+++ b/docs/sql/mall_user.sql
@@ -139,6 +139,8 @@ CREATE TABLE `user_spu_collections` (
`spu_id` int(11) NOT NULL COMMENT '商品id',
`spu_name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '商品名字',
`spu_image` varchar(250) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '图片名字',
+ `sell_point` varchar(50) NOT NULL DEFAULT '' COMMENT '卖点',
+ `price` int(11) DEFAULT NULL COMMENT '价格',
`create_time` datetime(0) NOT NULL COMMENT '创建时间',
`update_time` datetime(0) NULL DEFAULT NULL COMMENT '更新时间',
`deleted` smallint(2) NOT NULL COMMENT '删除状态',
diff --git a/mobile-web/src/page/product/detail.vue b/mobile-web/src/page/product/detail.vue
index f2184ee14..1a50657b2 100644
--- a/mobile-web/src/page/product/detail.vue
+++ b/mobile-web/src/page/product/detail.vue
@@ -98,7 +98,7 @@
-
+
收藏
@@ -208,6 +208,7 @@
calSkuPriceResult: {
},
+ hasCollectionType:0
};
},
@@ -291,6 +292,20 @@
}
});
},
+ initHasUserSpuFavorite(spuId){
+ if (!checkLogin()) {
+ this.hasCollectionType = 0;
+ return;
+ }
+ //初始化验证商品收藏
+ hasUserSpuFavorite(spuId).then(data => {
+ let hasCollection = data;
+ // alert("是否收藏==" + hasCollection);
+ if (hasCollection) {
+ this.hasCollectionType = 1;
+ }
+ });
+ },
onClickCart() {
this.$router.push('/cart');
@@ -327,11 +342,14 @@
// alert("hasCollectionType==" + hasCollectionType);
collectionSpu(id,hasCollectionType).then(data =>{
let v = data;
- if (hasCollectionType == 1 && v){
- alert("商品已收藏");
- }else if (hasCollectionType == 2 && v){
- alert("商品已取消");
- }
+ this.hasCollectionType = hasCollectionType;
+ // if (hasCollectionType == 1 && v){
+ // // alert("商品已收藏");
+ // this.hasCollectionType = hasCollectionType;
+ // }else if (hasCollectionType == 2 && v){
+ // // alert("商品已取消");
+ // this.hasCollectionType = hasCollectionType;
+ // }
})
});
@@ -426,6 +444,7 @@
// 初始化 attrValueMap
this.attrValueMap.set(attr.attrValueId, attr.attrValueName);
}
+
}
// debugger;
this.vanSku = vanSku;
@@ -435,6 +454,9 @@
this.initialSku.quantity = 1;
// 执行 sku 价格计算
this.doCalcSkuPrice(this.initialSku.id);
+
+ this.initHasUserSpuFavorite(id);
+
});
// 获得购物车数量
if (checkLogin()) {
@@ -448,6 +470,9 @@
diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/message/ProductSpuCollectionMessage.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/message/ProductSpuCollectionMessage.java
index 685a2cc45..b957218e0 100644
--- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/message/ProductSpuCollectionMessage.java
+++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/message/ProductSpuCollectionMessage.java
@@ -37,6 +37,16 @@ public class ProductSpuCollectionMessage {
*/
private String spuImage;
+ /**
+ * 卖点
+ */
+ private String sellPoint;
+
+ /**
+ * 价格,单位:分
+ */
+ private Integer price;
+
/**
* 1 收藏 2 取消
*/
diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java
index a48375409..7ccdfb8ce 100644
--- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java
+++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductAttrServiceImpl.java
@@ -72,7 +72,7 @@ public class ProductAttrServiceImpl implements ProductAttrService {
public ProductAttrPageBO getProductAttrPage(ProductAttrPageDTO productAttrPageDTO) {
ProductAttrPageBO productAttrPageBO = new ProductAttrPageBO();
// 查询分页数据
- int offset = productAttrPageDTO.getPageNo() * productAttrPageDTO.getPageSize();
+ int offset = (productAttrPageDTO.getPageNo()-1) * productAttrPageDTO.getPageSize();
productAttrPageBO.setAttrs(ProductAttrConvert.INSTANCE.convert(productAttrMapper.selectListByNameLike(productAttrPageDTO.getName(),
offset, productAttrPageDTO.getPageSize())));
// 查询分页总数
diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuCollectionServiceImpl.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuCollectionServiceImpl.java
index dae127325..874cc4412 100644
--- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuCollectionServiceImpl.java
+++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/service/ProductSpuCollectionServiceImpl.java
@@ -6,11 +6,14 @@ import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
import cn.iocoder.mall.product.api.message.ProductSpuCollectionMessage;
import cn.iocoder.mall.product.dao.ProductSpuMapper;
import cn.iocoder.mall.product.dataobject.ProductSpuDO;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
+import java.util.List;
/**
* ProductSpuCollectionServiceImpl
@@ -47,9 +50,14 @@ public class ProductSpuCollectionServiceImpl implements ProductSpuCollectionServ
*/
private void sendProductSpuCollectionMessage(final ProductSpuDO productSpuDO, final Integer hasCollectionType,
final Integer userId) {
+ List result = Lists.newArrayList(Splitter.on(",").omitEmptyStrings().trimResults().split(productSpuDO.getPicUrls()));
ProductSpuCollectionMessage productSpuCollectionMessage = new ProductSpuCollectionMessage()
- .setSpuId(productSpuDO.getId()).setSpuName(productSpuDO.getName())
- .setSpuImage(productSpuDO.getPicUrls()).setHasCollectionType(hasCollectionType)
+ .setSpuId(productSpuDO.getId())
+ .setSpuName(productSpuDO.getName())
+ .setSpuImage(result.size() > 0 ? result.get(0) : "")
+ .setSellPoint(productSpuDO.getSellPoint())
+ .setPrice(productSpuDO.getPrice())
+ .setHasCollectionType(hasCollectionType)
.setUserId(userId);
rocketMQTemplate.convertAndSend(ProductSpuCollectionMessage.TOPIC, productSpuCollectionMessage);
}
diff --git a/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java b/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java
index 8b874d5ac..9a72166f7 100644
--- a/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java
+++ b/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/AdminController.java
@@ -5,8 +5,10 @@ import cn.iocoder.common.framework.util.CollectionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.admin.api.AdminService;
+import cn.iocoder.mall.admin.api.DeptmentService;
import cn.iocoder.mall.admin.api.ResourceService;
import cn.iocoder.mall.admin.api.RoleService;
+import cn.iocoder.mall.admin.api.bo.deptment.DeptmentBO;
import cn.iocoder.mall.admin.api.bo.resource.ResourceBO;
import cn.iocoder.mall.admin.api.bo.role.RoleBO;
import cn.iocoder.mall.admin.api.bo.admin.AdminBO;
@@ -23,6 +25,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.dubbo.config.annotation.Reference;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@@ -44,6 +47,9 @@ public class AdminController {
@Reference(validation = "true", version = "${dubbo.provider.RoleService.version}")
private RoleService roleService;
+ @Autowired
+ private DeptmentService deptmentService;
+
// =========== 当前管理员相关的资源 API ===========
// TODO 功能:当前管理员
@@ -85,7 +91,7 @@ public class AdminController {
}
// =========== 管理员管理 API ===========
-
+ //TODO 目前需要增加搜索所有子部门的用户
@GetMapping("/page")
@RequiresPermissions("system.admin.page")
@ApiOperation(value = "管理员分页")
@@ -97,7 +103,17 @@ public class AdminController {
// 查询角色数组
Map> roleMap = adminService.getAdminRolesMap(CollectionUtil.convertList(resultPage.getList(), AdminBO::getId));
resultPage.getList().forEach(admin -> admin.setRoles(AdminConvert.INSTANCE.convertAdminVORoleList(roleMap.get(admin.getId()))));
+
+ // 查询对应部门
+ List deptmentBOS = deptmentService.getAllDeptments();
+ Map deptNameMap = deptmentBOS.stream().collect(Collectors.toMap(d->d.getId(), d->d.getName()));
+ //管理员所在部门被删后,变成未分配状态
+ deptNameMap.put(0, "未分配");
+ resultPage.getList().forEach(admin->{
+ admin.setDeptment(new AdminVO.Deptment(admin.getDeptmentId(), deptNameMap.get(admin.getDeptmentId())));
+ });
}
+
return success(resultPage);
}
diff --git a/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/DeptmentController.java b/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/DeptmentController.java
index 132f520dc..1a74a8572 100644
--- a/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/DeptmentController.java
+++ b/system/system-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/DeptmentController.java
@@ -49,7 +49,7 @@ public class DeptmentController {
public CommonResult> treeAll(){
List list = deptmentService.getAllDeptments();
List voList = DeptmentConvert.INSTANCE.convert(list);
- Map nodeMap = calaNodeMap(voList);
+ Map nodeMap = calcNodeMap(voList);
// 获得到所有的根节点
List rootNodes = nodeMap.values().stream()
.filter(node -> node.getPid().equals(ResourceConstants.PID_ROOT))
@@ -64,7 +64,7 @@ public class DeptmentController {
PageResult voPageResult = DeptmentConvert.INSTANCE.convert(pageResult);
List list = deptmentService.getAllDeptments();
List voList = DeptmentConvert.INSTANCE.convert(list);
- Map nodeMap = calaNodeMap(voList);
+ Map nodeMap = calcNodeMap(voList);
voPageResult.getList().forEach(d->{
d.setChildren(nodeMap.get(d.getId()).getChildren());
});
@@ -97,7 +97,7 @@ public class DeptmentController {
));
}
- private Map calaNodeMap(List voList){
+ private Map calcNodeMap(List voList){
Map nodeMap = voList.stream().collect(Collectors.toMap(e->e.getId(), e->e));
nodeMap.values().stream()
diff --git a/system/system-application/src/main/java/cn/iocoder/mall/admin/application/vo/admin/AdminVO.java b/system/system-application/src/main/java/cn/iocoder/mall/admin/application/vo/admin/AdminVO.java
index 086e4266e..6847d1829 100644
--- a/system/system-application/src/main/java/cn/iocoder/mall/admin/application/vo/admin/AdminVO.java
+++ b/system/system-application/src/main/java/cn/iocoder/mall/admin/application/vo/admin/AdminVO.java
@@ -3,6 +3,7 @@ package cn.iocoder.mall.admin.application.vo.admin;
import cn.iocoder.mall.admin.api.bo.admin.AdminBO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -15,6 +16,8 @@ public class AdminVO extends AdminBO {
private List roles;
+ private Deptment deptment;
+
@ApiModel("管理员 VO - 角色")
@Data
@Accessors(chain = true)
@@ -28,4 +31,19 @@ public class AdminVO extends AdminBO {
}
+ @ApiModel("管理员 VO - 部门")
+ @Data
+ @Accessors(chain = true)
+ @AllArgsConstructor
+ public static class Deptment {
+
+ @ApiModelProperty(value = "部门编号", required = true, example = "1")
+ private Integer id;
+
+ @ApiModelProperty(value = "部门名称", required = true, example = "研发部")
+ private String name;
+
+
+ }
+
}
diff --git a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/admin/AdminBO.java b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/admin/AdminBO.java
index 88dbb3428..b348f2c3d 100644
--- a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/admin/AdminBO.java
+++ b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/bo/admin/AdminBO.java
@@ -28,4 +28,7 @@ public class AdminBO implements Serializable {
@ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
private Date createTime;
+ @ApiModelProperty(value = "部门ID", required = true, example = "1")
+ private Integer deptmentId;
+
}
diff --git a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminAddDTO.java b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminAddDTO.java
index 79ed25335..748b77399 100644
--- a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminAddDTO.java
+++ b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminAddDTO.java
@@ -7,6 +7,7 @@ import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.io.Serializable;
@@ -31,4 +32,8 @@ public class AdminAddDTO implements Serializable {
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
+ @ApiModelProperty(value = "部门ID", required = true, example = "1")
+ @NotNull(message = "部门不能为空")
+ private Integer deptmentId;
+
}
diff --git a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminPageDTO.java b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminPageDTO.java
index 26f508123..f1e8a1ee7 100644
--- a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminPageDTO.java
+++ b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminPageDTO.java
@@ -14,4 +14,8 @@ public class AdminPageDTO extends PageParam {
@ApiModelProperty(value = "昵称,模糊匹配", example = "小王")
private String nickname;
+
+ @ApiModelProperty(value = "所在部门ID")
+ private Integer deptmentId;
+
}
diff --git a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminUpdateDTO.java b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminUpdateDTO.java
index 5fac82467..c88c6e05b 100644
--- a/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminUpdateDTO.java
+++ b/system/system-service-api/src/main/java/cn/iocoder/mall/admin/api/dto/admin/AdminUpdateDTO.java
@@ -35,4 +35,8 @@ public class AdminUpdateDTO implements Serializable {
@Length(min = 4, max = 16, message = "密码长度为 4-16 位")
private String password;
+ @ApiModelProperty(value = "部门ID", required = true, example = "1")
+ @NotNull(message = "部门不能为空")
+ private Integer deptmentId;
+
}
diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminMapper.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminMapper.java
index 49e049537..a15c940cd 100644
--- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminMapper.java
+++ b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dao/AdminMapper.java
@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
+import org.omg.PortableInterceptor.INACTIVE;
import org.springframework.stereotype.Repository;
@Repository
@@ -19,7 +20,14 @@ public interface AdminMapper extends BaseMapper {
default IPage selectPage(AdminPageDTO adminPageDTO) {
return selectPage(new Page<>(adminPageDTO.getPageNo(), adminPageDTO.getPageSize()),
- new QueryWrapperX().likeIfPresent("nickname", adminPageDTO.getNickname()));
+ new QueryWrapperX().likeIfPresent("nickname", adminPageDTO.getNickname())
+ .eqIfPresent("deptment_id", adminPageDTO.getDeptmentId()));
+ }
+
+ default int updateDeptByDeptId(@Param("fromDeptId")Integer fromDeptId, @Param("toDeptId")Integer toDeptId){
+ QueryWrapper query = new QueryWrapper()
+ .eq("deptment_id", fromDeptId);
+ return update(new AdminDO().setDeptmentId(toDeptId), query);
}
}
diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminDO.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminDO.java
index 08b030628..88f7643d6 100644
--- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminDO.java
+++ b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/dataobject/AdminDO.java
@@ -36,6 +36,12 @@ public class AdminDO extends DeletableDO {
*/
private Integer status;
+ /**
+ * 管理员部门id
+ */
+ private Integer deptmentId;
+
+
// TODO 芋艿,最后登陆时间、最后登陆 IP
// TODO 芋艿,登陆日志
diff --git a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/DeptmentServiceImpl.java b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/DeptmentServiceImpl.java
index d7ec20235..2a02040cb 100644
--- a/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/DeptmentServiceImpl.java
+++ b/system/system-service-impl/src/main/java/cn/iocoder/mall/admin/service/DeptmentServiceImpl.java
@@ -11,6 +11,7 @@ import cn.iocoder.mall.admin.api.dto.depetment.DeptmentAddDTO;
import cn.iocoder.mall.admin.api.dto.depetment.DeptmentPageDTO;
import cn.iocoder.mall.admin.api.dto.depetment.DeptmentUpdateDTO;
import cn.iocoder.mall.admin.convert.DeptmentConvert;
+import cn.iocoder.mall.admin.dao.AdminMapper;
import cn.iocoder.mall.admin.dao.DeptmentMapper;
import cn.iocoder.mall.admin.dao.DeptmentRoleMapper;
import cn.iocoder.mall.admin.dataobject.DeptmentDO;
@@ -39,6 +40,9 @@ public class DeptmentServiceImpl implements DeptmentService {
@Autowired
private DeptmentRoleMapper deptmentRoleMapper;
+ @Autowired
+ private AdminMapper adminMapper;
+
@Override
public DeptmentBO addDeptment(Integer adminId, DeptmentAddDTO deptmentAddDTO) {
if (deptmentAddDTO.getPid() != 0 &&
@@ -69,6 +73,8 @@ public class DeptmentServiceImpl implements DeptmentService {
deptmentRoleMapper.deleteByDeptmentId(deptmentId);
+ //将改部门下所有员工的DeptmentID设置为0
+ adminMapper.updateDeptByDeptId(deptmentId, 0);
return true;
}
diff --git a/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/bo/UserProductSpuCollectionsBO.java b/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/bo/UserProductSpuCollectionsBO.java
index 694cd73a0..d427a7fc6 100644
--- a/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/bo/UserProductSpuCollectionsBO.java
+++ b/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/bo/UserProductSpuCollectionsBO.java
@@ -45,6 +45,16 @@ public class UserProductSpuCollectionsBO implements Serializable {
*/
private String spuImage;
+ /**
+ * 卖点
+ */
+ private String sellPoint;
+
+ /**
+ * 价格,单位:分
+ */
+ private Integer price;
+
/**
* 创建时间
*/
diff --git a/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/dto/UserProductSpuCollectionsAddDTO.java b/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/dto/UserProductSpuCollectionsAddDTO.java
index e949c3d1b..d2e86ae4f 100644
--- a/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/dto/UserProductSpuCollectionsAddDTO.java
+++ b/user/user-service-api/src/main/java/cn/iocoder/mall/user/api/dto/UserProductSpuCollectionsAddDTO.java
@@ -46,6 +46,16 @@ public class UserProductSpuCollectionsAddDTO implements Serializable {
*/
private String spuImage;
+ /**
+ * 卖点
+ */
+ private String sellPoint;
+
+ /**
+ * 价格,单位:分
+ */
+ private Integer price;
+
/**
* 创建时间
*/
diff --git a/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dataobject/UserProductSpuCollectionsDO.java b/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dataobject/UserProductSpuCollectionsDO.java
index bda45a973..9d532b9d5 100644
--- a/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dataobject/UserProductSpuCollectionsDO.java
+++ b/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/dataobject/UserProductSpuCollectionsDO.java
@@ -50,6 +50,16 @@ public class UserProductSpuCollectionsDO implements Serializable {
*/
private String spuImage;
+ /**
+ * 卖点
+ */
+ private String sellPoint;
+
+ /**
+ * 价格,单位:分
+ */
+ private Integer price;
+
/**
* 创建时间
*/
diff --git a/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/service/UserProductSpuCollectionsServiceImpl.java b/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/service/UserProductSpuCollectionsServiceImpl.java
index 2c4a6a20b..55e1858a6 100644
--- a/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/service/UserProductSpuCollectionsServiceImpl.java
+++ b/user/user-service-impl/src/main/java/cn/iocoder/mall/user/biz/service/UserProductSpuCollectionsServiceImpl.java
@@ -11,6 +11,8 @@ import cn.iocoder.mall.user.api.dto.UserProductSpuCollectionsUpdateDTO;
import cn.iocoder.mall.user.biz.convert.UserProductSpuCollectionsConvert;
import cn.iocoder.mall.user.biz.dao.UserProductSpuCollectionsMapper;
import cn.iocoder.mall.user.biz.dataobject.UserProductSpuCollectionsDO;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -33,6 +35,10 @@ public class UserProductSpuCollectionsServiceImpl implements UserProductSpuColle
@Autowired
private UserProductSpuCollectionsMapper userProductSpuCollectionsMapper;
+ // TODO 暂时先使用冗余字段,有需要在对接实时数据查询
+// @Reference(validation = "true", version = "${dubbo.consumer.PromotionActivityService.version}")
+// private ProductSpuService productSpuService;
+
@Override
public int addUserSkuCollections(UserProductSpuCollectionsAddDTO userProductSpuCollectionsAddDTO) {
@@ -72,6 +78,11 @@ public class UserProductSpuCollectionsServiceImpl implements UserProductSpuColle
return CommonResult.success(
new UserProductSpuCollectionsPageBO().setList(Collections.emptyList()).setTotal(totalCount));
}
+ for (UserProductSpuCollectionsDO userProductSpuCollectionsDO : list
+ ) {
+ List result = Lists.newArrayList(Splitter.on(",").omitEmptyStrings().trimResults().split(userProductSpuCollectionsDO.getSpuImage()));
+ userProductSpuCollectionsDO.setSpuImage(result.size() > 0 ? result.get(0) : "");
+ }
UserProductSpuCollectionsPageBO userProductSpuCollectionsPageBO = new UserProductSpuCollectionsPageBO();
userProductSpuCollectionsPageBO.setList(UserProductSpuCollectionsConvert.INSTANCE.convert(list));
diff --git a/user/user-service-impl/src/main/resources/mapper/UserProductSpuCollectionsMapper.xml b/user/user-service-impl/src/main/resources/mapper/UserProductSpuCollectionsMapper.xml
index d4d3b3daa..ec77f1fe0 100644
--- a/user/user-service-impl/src/main/resources/mapper/UserProductSpuCollectionsMapper.xml
+++ b/user/user-service-impl/src/main/resources/mapper/UserProductSpuCollectionsMapper.xml
@@ -4,7 +4,7 @@
id, user_id, nickname, spu_id, spu_name,
- spu_image, create_time, update_time,
+ spu_image,sell_point,price, create_time, update_time,
deleted