提交 9b913af9 authored 作者: YunaiV's avatar YunaiV

Merge remote-tracking branch 'origin/master'

......@@ -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
......
......@@ -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': '订单管理',
......
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,
};
}
},
},
};
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);
......
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,
......
......@@ -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 {
<Table
defaultExpandAllRows={true}
columns={columns}
dataSource={deptmentData.list ? deptmentData.list : []}
dataSource={deptmentList.list ? deptmentList.list : []}
rowKey="id"
loading={loading}
/>
</Card>
<CreateForm {...parentMethods} selectTree={selectTree} modalVisible={modalVisible} />
......
差异被折叠。
@import '~antd/lib/style/themes/default.less';
@import '~@/utils/utils.less';
.tableList {
.tableListOperator {
margin-bottom: 16px;
button {
margin-right: 8px;
}
}
}
......@@ -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',
......
......@@ -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',
});
}
......@@ -20,6 +20,7 @@
- [x] 展示类目
- [ ] 品牌管理【开发中 @黑子】
- [ ] 商品标签
- [ ] 商品规格页面【开发中 @Tprotect曦】
- [ ] 订单管理
- [x] 销售单
- [x] 售后单
......@@ -49,7 +50,7 @@
- [x] 员工管理
- [x] 角色管理 <!--【前端页面需要细化下】-->
- [x] 权限管理 <!--【前端页面需要细化下】-->
- [ ] 部门管理【开发中 @Tprotect曦】
- [x] 部门管理 <!--【员工页面部门搜索需要优化】-->
- [x] 数据字典
- [x] 短信管理
- [X] 短信模板
......
......@@ -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;
-- ----------------------------
......
......@@ -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 '删除状态',
......
......@@ -98,7 +98,7 @@
</div>
<van-goods-action>
<van-goods-action-mini-btn icon="like-o" @click="onFavoriteClicked">
<van-goods-action-mini-btn icon="like-o" :class="{active:hasCollectionType === 1 }" @click="onFavoriteClicked">
收藏
</van-goods-action-mini-btn>
<van-goods-action-mini-btn icon="cart" :info="cartCount > 0 ? cartCount : undefined" @click="onClickCart">
......@@ -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 @@
<style lang="less">
.goods {
.active {
color: #f44;
}
padding-bottom: 50px;
&-swipe {
......
<template>
<div>
<headerNav title="我的收藏"/>
<van-list
v-model="loading"
:finished="finished"
@load="onLoad"
<div>
<headerNav title="我的收藏"/>
<van-list
v-model="loading"
:finished="finished"
@load="onLoad"
>
<div v-for="(item,index) in list" :key="index">
<van-swipe-cell :right-width="65" :on-close="onClose(item)">
<product-card :product='item' />
<span>{{item.spuName}}</span>
<span slot="right" >删除</span>
<div v-for="(item,index) in list" :key="index">
<van-swipe-cell :right-width="65" :on-close="onClose(item)">
<van-card
:price="formatPrice(item.price)"
:desc="item.sellPoint"
:title="item.spuName"
:thumb="item.spuImage"
@click="skipProductSpuInfo(item.spuId)"
>
</van-card>
<template slot="right">
<van-button square type="danger" text="删除"/>
</template>
</van-swipe-cell>
</div>
</van-list>
</div>
</div>
</van-list>
</div>
</template>
<script>
import { GetFavoritePage ,DelFavorite} from "../../../api/user.js";
export default {
data(){
return{
loading:false,
finished:false,
list:[],
page:0,
pageSize:10
}
},
methods:{
onClose(item){
return function(clickPosition, instance) {
switch (clickPosition) {
case 'left':
case 'cell':
case 'outside':
instance.close();
break;
case 'right':
this.$dialog.confirm({
message: '确定删除吗?'
}).then(() => {
DelFavorite(item.spuId).then(response=>{
this.$toast('删除成功');
this.$router.go(0);
})
instance.close();
}).catch(() => {
// on cancel
});
break;
}
import {GetFavoritePage, DelFavorite} from "../../../api/user.js";
export default {
data() {
return {
loading: false,
finished: false,
list: [],
page: 0,
pageSize: 10
}
},
onLoad() {
let pageNo = this.page + 1;
GetFavoritePage(pageNo,this.pageSize).then(response=>{
this.page = pageNo;
this.list.push(...response.list);
// response.list.forEach(item => {
// this.list.push(item);
// });
this.loading = false;
if(this.list.length >= response.total){
this.finished = true;
methods: {
formatPrice(data) {
return (data / 100).toFixed(2);
},
skipProductSpuInfo(data) {
// return getProductSpuInfo(data);
this.$router.push('/product/'+data);
},
onClose(item) {
return function (clickPosition, instance) {
switch (clickPosition) {
case 'left':
case 'cell':
case 'outside':
instance.close();
break;
case 'right':
this.$dialog.confirm({
message: '确定删除吗?'
}).then(() => {
DelFavorite(item.spuId).then(response => {
this.$toast('删除成功');
this.$router.go(0);
})
instance.close();
}).catch(() => {
// on cancel
});
break;
}
}
},
onLoad() {
let pageNo = this.page + 1;
GetFavoritePage(pageNo, this.pageSize).then(response => {
this.page = pageNo;
this.list.push(...response.list);
// response.list.forEach(item => {
// this.list.push(item);
// });
this.loading = false;
if (this.list.length >= response.total) {
this.finished = true;
}
})
}
},
}
})
}
},
}
</script>
<style lang="less">
.van-swipe-cell{
&__left,
&__right {
color: #FFFFFF;
font-size: 15px;
width: 65px;
height: 100px;
display: inline-block;
text-align: center;
line-height: 100px;
background-color: #F44;
.van-swipe-cell {
&__left,
&__right {
color: #FFFFFF;
font-size: 15px;
width: 65px;
height: 100px;
display: inline-block;
text-align: center;
line-height: 100px;
background-color: #F44;
}
}
}
</style>
......@@ -37,6 +37,16 @@ public class ProductSpuCollectionMessage {
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 1 收藏 2 取消
*/
......
......@@ -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())));
// 查询分页总数
......
......@@ -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<String> 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);
}
......
......@@ -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<Integer, Collection<RoleBO>> roleMap = adminService.getAdminRolesMap(CollectionUtil.convertList(resultPage.getList(), AdminBO::getId));
resultPage.getList().forEach(admin -> admin.setRoles(AdminConvert.INSTANCE.convertAdminVORoleList(roleMap.get(admin.getId()))));
// 查询对应部门
List<DeptmentBO> deptmentBOS = deptmentService.getAllDeptments();
Map<Integer, String> 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);
}
......
......@@ -49,7 +49,7 @@ public class DeptmentController {
public CommonResult<List<DeptmentVO>> treeAll(){
List<DeptmentBO> list = deptmentService.getAllDeptments();
List<DeptmentVO> voList = DeptmentConvert.INSTANCE.convert(list);
Map<Integer, DeptmentVO> nodeMap = calaNodeMap(voList);
Map<Integer, DeptmentVO> nodeMap = calcNodeMap(voList);
// 获得到所有的根节点
List<DeptmentVO> rootNodes = nodeMap.values().stream()
.filter(node -> node.getPid().equals(ResourceConstants.PID_ROOT))
......@@ -64,7 +64,7 @@ public class DeptmentController {
PageResult<DeptmentVO> voPageResult = DeptmentConvert.INSTANCE.convert(pageResult);
List<DeptmentBO> list = deptmentService.getAllDeptments();
List<DeptmentVO> voList = DeptmentConvert.INSTANCE.convert(list);
Map<Integer, DeptmentVO> nodeMap = calaNodeMap(voList);
Map<Integer, DeptmentVO> nodeMap = calcNodeMap(voList);
voPageResult.getList().forEach(d->{
d.setChildren(nodeMap.get(d.getId()).getChildren());
});
......@@ -97,7 +97,7 @@ public class DeptmentController {
));
}
private Map<Integer, DeptmentVO> calaNodeMap(List<DeptmentVO> voList){
private Map<Integer, DeptmentVO> calcNodeMap(List<DeptmentVO> voList){
Map<Integer, DeptmentVO> nodeMap = voList.stream().collect(Collectors.toMap(e->e.getId(), e->e));
nodeMap.values().stream()
......
......@@ -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<Role> 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;
}
}
......@@ -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;
}
......@@ -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;
}
......@@ -14,4 +14,8 @@ public class AdminPageDTO extends PageParam {
@ApiModelProperty(value = "昵称,模糊匹配", example = "小王")
private String nickname;
@ApiModelProperty(value = "所在部门ID")
private Integer deptmentId;
}
......@@ -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;
}
......@@ -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<AdminDO> {
default IPage<AdminDO> selectPage(AdminPageDTO adminPageDTO) {
return selectPage(new Page<>(adminPageDTO.getPageNo(), adminPageDTO.getPageSize()),
new QueryWrapperX<AdminDO>().likeIfPresent("nickname", adminPageDTO.getNickname()));
new QueryWrapperX<AdminDO>().likeIfPresent("nickname", adminPageDTO.getNickname())
.eqIfPresent("deptment_id", adminPageDTO.getDeptmentId()));
}
default int updateDeptByDeptId(@Param("fromDeptId")Integer fromDeptId, @Param("toDeptId")Integer toDeptId){
QueryWrapper<AdminDO> query = new QueryWrapper<AdminDO>()
.eq("deptment_id", fromDeptId);
return update(new AdminDO().setDeptmentId(toDeptId), query);
}
}
......@@ -36,6 +36,12 @@ public class AdminDO extends DeletableDO {
*/
private Integer status;
/**
* 管理员部门id
*/
private Integer deptmentId;
// TODO 芋艿,最后登陆时间、最后登陆 IP
// TODO 芋艿,登陆日志
......
......@@ -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;
}
......
......@@ -45,6 +45,16 @@ public class UserProductSpuCollectionsBO implements Serializable {
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 创建时间
*/
......
......@@ -46,6 +46,16 @@ public class UserProductSpuCollectionsAddDTO implements Serializable {
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 创建时间
*/
......
......@@ -50,6 +50,16 @@ public class UserProductSpuCollectionsDO implements Serializable {
*/
private String spuImage;
/**
* 卖点
*/
private String sellPoint;
/**
* 价格,单位:分
*/
private Integer price;
/**
* 创建时间
*/
......
......@@ -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<String> 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));
......
......@@ -4,7 +4,7 @@
<sql id="FIELDS">
id, user_id, nickname, spu_id, spu_name,
spu_image, create_time, update_time,
spu_image,sell_point,price, create_time, update_time,
deleted
</sql>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论