From a334e99b06df7f930080a2a37e866b90ba74bff8 Mon Sep 17 00:00:00 2001 From: YunaiV <> Date: Mon, 1 Apr 2019 18:33:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=EF=BC=9A=E5=95=86=E5=93=81?= =?UTF-8?q?=E6=8E=A8=E8=8D=90=E3=80=82=E5=BF=98=E8=AE=B0=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin-web/config/proxy/proxy.dev.js | 6 + admin-web/config/router.config.js | 10 +- admin-web/src/locales/zh-CN/menu.js | 3 +- admin-web/src/models/promotion/bannerList.js | 81 +--- .../models/promotion/productRecommendList.js | 178 ++++++++ admin-web/src/pages/Promotion/BannerList.js | 14 +- .../pages/Promotion/ProductRecommendList.js | 398 ++++++++++++++++++ .../pages/Promotion/ProductRecommendList.less | 47 +++ admin-web/src/services/promotion.js | 32 ++ mobile-web/src/api/promotion.js | 9 + mobile-web/src/config/env.js | 4 +- mobile-web/src/page/page/index.vue | 40 +- .../api/bo/ProductAttrAndValuePairBO.java | 4 +- .../mall/product/api/bo/ProductAttrBO.java | 3 +- .../product/api/bo/ProductAttrDetailBO.java | 3 +- .../product/api/bo/ProductAttrPageBO.java | 3 +- .../product/api/bo/ProductAttrSimpleBO.java | 3 +- .../product/api/bo/ProductAttrValueBO.java | 3 +- .../api/bo/ProductAttrValueDetailBO.java | 3 +- .../api/bo/ProductAttrValueSimpleBO.java | 4 +- .../product/api/bo/ProductCategoryBO.java | 3 +- .../mall/product/api/bo/ProductSkuBO.java | 4 +- .../product/api/bo/ProductSkuDetailBO.java | 3 +- .../mall/product/api/bo/ProductSpuBO.java | 3 +- .../product/api/bo/ProductSpuDetailBO.java | 3 +- .../mall/product/api/bo/ProductSpuPageBO.java | 3 +- .../mall/product/dao/ProductSpuMapper.java | 2 +- .../UsersProductRecommendController.java | 9 +- .../config/ServiceExceptionConfiguration.java | 4 +- .../mapper/ProductRecommendMapper.xml | 20 +- 30 files changed, 757 insertions(+), 145 deletions(-) create mode 100644 admin-web/src/models/promotion/productRecommendList.js create mode 100644 admin-web/src/pages/Promotion/ProductRecommendList.js create mode 100644 admin-web/src/pages/Promotion/ProductRecommendList.less diff --git a/admin-web/config/proxy/proxy.dev.js b/admin-web/config/proxy/proxy.dev.js index 0608bd7b3..a995408ba 100644 --- a/admin-web/config/proxy/proxy.dev.js +++ b/admin-web/config/proxy/proxy.dev.js @@ -7,6 +7,12 @@ export default { changeOrigin: true, pathRewrite: {}, }, + '/product-api/': { + // target: 'http://180.167.213.26:18083/', + target: 'http://127.0.0.1:18081/', + changeOrigin: true, + pathRewrite: {}, + }, '/order-api/': { target: 'http://127.0.0.1:18084/', changeOrigin: true, diff --git a/admin-web/config/router.config.js b/admin-web/config/router.config.js index 932f5bee0..caeb2563c 100644 --- a/admin-web/config/router.config.js +++ b/admin-web/config/router.config.js @@ -110,11 +110,11 @@ export default [ name: 'promotion-banner-list', component: './Promotion/BannerList', }, - // { - // path: '/product/product-spu-add', - // name: 'product-spu-add', - // component: './Product/ProductSpuAddOrUpdate', - // }, + { + path: '/promotion/product-recommend-list', + name: 'product-recommend-list', + component: './Promotion/ProductRecommendList', + }, // { // path: '/product/product-category-list', // name: 'product-category-list', diff --git a/admin-web/src/locales/zh-CN/menu.js b/admin-web/src/locales/zh-CN/menu.js index 9695fe996..ec963f8b7 100644 --- a/admin-web/src/locales/zh-CN/menu.js +++ b/admin-web/src/locales/zh-CN/menu.js @@ -55,4 +55,5 @@ export default { 'menu.order.order-refunds': '退货维权', // 营销相关 'menu.promotion.promotion-banner-list': 'Banner 管理', -}; + 'menu.promotion.product-recommend-list': '商品推荐', +}; \ No newline at end of file diff --git a/admin-web/src/models/promotion/bannerList.js b/admin-web/src/models/promotion/bannerList.js index ce4d46ada..4f139c05a 100644 --- a/admin-web/src/models/promotion/bannerList.js +++ b/admin-web/src/models/promotion/bannerList.js @@ -1,15 +1,10 @@ -import {message} from 'antd'; -import {buildTreeNode, findCheckedKeys} from '../../utils/tree.utils'; -import { +import {message} from 'antd';import { addBanner, - adminRoleAssign, deleteBanner, queryBanner, - queryBannerRoleList, updateBanner, updateBannerStatus, } from '../../services/promotion'; -import {arrayToStringParams} from '../../utils/request.qs'; import PaginationHelper from '../../../helpers/PaginationHelper'; const SEARCH_PARAMS_DEFAULT = { @@ -31,12 +26,6 @@ export default { modalType: undefined, // 'add' or 'update' 表单 formVals: {}, // 当前表单值 modalLoading: false, - - // 分配角色表单相关 - roleList: [], - roleModalVisible: false, - roleCheckedKeys: [], // 此处的 Key ,就是角色编号 - roleAssignLoading: false, }, effects: { @@ -161,78 +150,10 @@ export default { } }, - * queryRoleList({ payload }, { call, put }) { - // 显示加载中 - yield put({ - type: 'changeRoleAssignLoading', - payload: true, - }); - - // 请求 - const response = yield call(queryBannerRoleList, payload); - // 响应 - if (response.code === 0) { - const roleList = response.data; - const roleTreeData = buildTreeNode(roleList, 'name', 'id'); - const roleCheckedKeys = findCheckedKeys(roleList); - yield put({ - type: 'setAll', - payload: { - roleList: roleTreeData, - roleCheckedKeys, - }, - }); - } - - // 隐藏加载中 - yield put({ - type: 'changeRoleAssignLoading', - payload: false, - }); - }, - - * roleAssign({ payload }, { call, put }) { - const { callback, body } = payload; - // 显示加载中 - yield put({ - type: 'changeRoleAssignLoading', - payload: true, - }); - - // 请求 - const response = yield call(adminRoleAssign, { - id: body.id, - roleIds: arrayToStringParams(body.roleIds), - }); - // 响应 - if (response.code === 0) { - if (callback) { - callback(response); - } - } - - // 隐藏加载中 - yield put({ - type: 'changeRoleAssignLoading', - payload: false, - }); - }, }, reducers: { - changeRoleCheckedKeys(state, { payload }) { - return { - ...state, - roleCheckedKeys: payload, - }; - }, // 修改加载中的状态 - changeRoleAssignLoading(state, { payload }) { - return { - ...state, - roleAssignLoading: payload, - }; - }, changeModalLoading(state, { payload }) { return { ...state, diff --git a/admin-web/src/models/promotion/productRecommendList.js b/admin-web/src/models/promotion/productRecommendList.js new file mode 100644 index 000000000..d5011e05f --- /dev/null +++ b/admin-web/src/models/promotion/productRecommendList.js @@ -0,0 +1,178 @@ +import {message} from 'antd'; +import { + addProductRecommend, + deleteProductRecommend, + queryProductRecommend, + updateProductRecommend, + updateProductRecommendStatus, +} from '../../services/promotion'; +import PaginationHelper from '../../../helpers/PaginationHelper'; + +const SEARCH_PARAMS_DEFAULT = { + type: undefined, +}; + +export default { + namespace: 'productRecommendList', + + state: { + // 分页列表相关 + list: [], + listLoading: false, + pagination: PaginationHelper.defaultPaginationConfig, + searchParams: SEARCH_PARAMS_DEFAULT, + + // 添加 or 修改表单相关 + modalVisible: false, + modalType: undefined, // 'add' or 'update' 表单 + formVals: {}, // 当前表单值 + modalLoading: false, + }, + + effects: { + // 查询列表 + * query({ payload }, { call, put }) { + // 显示加载中 + yield put({ + type: 'changeListLoading', + payload: true, + }); + + // 请求 + const response = yield call(queryProductRecommend, payload); + // 响应 + yield put({ + type: 'setAll', + payload: { + list: response.data.list, + pagination: PaginationHelper.formatPagination(response.data, payload), + searchParams: { + type: payload.type + } + }, + }); + + // 隐藏加载中 + yield put({ + type: 'changeListLoading', + payload: false, + }); + }, + * add({ payload }, { call, put }) { + const { callback, body } = payload; + // 显示加载中 + yield put({ + type: 'changeModalLoading', + payload: true, + }); + + // 请求 + const response = yield call(addProductRecommend, body); + // 响应 + if (response.code === 0) { + if (callback) { + callback(response); + } + // 刷新列表 + yield put({ + type: 'query', + payload: { + ...PaginationHelper.defaultPayload + }, + }); + } + + // 隐藏加载中 + yield put({ + type: 'changeModalLoading', + payload: false, + }); + }, + * update({ payload }, { call, put }) { + const { callback, body } = payload; + // 显示加载中 + yield put({ + type: 'changeModalLoading', + payload: true, + }); + + // 请求 + const response = yield call(updateProductRecommend, body); + // 响应 + if (response.code === 0) { + if (callback) { + callback(response); + } + // 刷新列表 + yield put({ + type: 'query', + payload: { + ...PaginationHelper.defaultPayload + }, + }); + } + + // 隐藏加载中 + yield put({ + type: 'changeModalLoading', + payload: false, + }); + }, + + * updateStatus({ payload }, { call, put }) { + // 请求 + const response = yield call(updateProductRecommendStatus, payload); + // 响应 + if (response.code === 0) { + message.info('更新状态成功!'); + // 刷新列表 + yield put({ + type: 'query', + payload: { + ...PaginationHelper.defaultPayload + }, + }); + } + }, + + * delete({ payload }, { call, put }) { + // 请求 + const response = yield call(deleteProductRecommend, payload); + // 响应 + if (response.code === 0) { + message.info('删除成功!'); + // 刷新列表 + yield put({ + type: 'query', + payload: { + ...PaginationHelper.defaultPayload + }, + }); + } + }, + + }, + + reducers: { + // 修改加载中的状态 + changeModalLoading(state, { payload }) { + return { + ...state, + modalLoading: payload, + }; + }, + changeListLoading(state, { payload }) { + return { + ...state, + listLoading: payload, + }; + }, + // 设置所有属性 + setAll(state, { payload }) { + return { + ...state, + ...payload, + }; + } + }, +}; diff --git a/admin-web/src/pages/Promotion/BannerList.js b/admin-web/src/pages/Promotion/BannerList.js index 3643eca25..2ed408adb 100644 --- a/admin-web/src/pages/Promotion/BannerList.js +++ b/admin-web/src/pages/Promotion/BannerList.js @@ -342,24 +342,12 @@ class BannerList extends PureComponent { }); }; - handleRoleAssignModalVisible = (roleModalVisible, record) => { - const { dispatch } = this.props; - dispatch({ - type: 'bannerList/setAll', - payload: { - roleModalVisible: roleModalVisible, - formVals: record || {} - }, - }); - }; - render() { // let that = this; const { dispatch, list, listLoading, searchParams, pagination, modalVisible, modalType, formVals, - confirmLoading, - roleList, roleModalVisible, roleAssignLoading, roleCheckedKeys } = this.props; + confirmLoading,} = this.props; // 列表属性 const listProps = { diff --git a/admin-web/src/pages/Promotion/ProductRecommendList.js b/admin-web/src/pages/Promotion/ProductRecommendList.js new file mode 100644 index 000000000..4d8cf5857 --- /dev/null +++ b/admin-web/src/pages/Promotion/ProductRecommendList.js @@ -0,0 +1,398 @@ +/* eslint-disable */ + +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, + InputNumber +} from 'antd'; +import { checkTypeWithEnglishAndNumbers } from '../../../helpers/validator' +import PageHeaderWrapper from '@/components/PageHeaderWrapper'; + +import styles from './BannerList.less'; +import moment from "moment"; +import PaginationHelper from "../../../helpers/PaginationHelper"; + +const FormItem = Form.Item; +const SelectOption = Select.Option; +const { TreeNode } = Tree; +const status = ['未知', '正常', '禁用']; +const types = ['未知', '新品推荐', '热卖推荐']; + +// 列表 +function List ({ dataSource, loading, pagination, searchParams, dispatch, + handleModalVisible}) { + + function handleStatus(record) { + Modal.confirm({ + title: record.status === 1 ? '确认禁用' : '取消禁用', + content: `${record.productSpuId}`, + onOk() { + dispatch({ + type: 'productRecommendList/updateStatus', + payload: { + id: record.id, + status: record.status === 1 ? 2 : 1, + }, + }); + }, + onCancel() {}, + }); + } + + function handleDelete(record) { + Modal.confirm({ + title: `确认删除?`, + content: `${record.productSpuId}`, + onOk() { + dispatch({ + type: 'productRecommendList/delete', + payload: { + id: record.id, + }, + }); + }, + onCancel() {}, + }); + } + + const columns = [ + { + title: '推荐类型', + dataIndex: 'type', + render(val) { + return {types[val]}; // TODO 芋艿,此处要改 + }, + }, + { + title: '商品', + dataIndex: 'productSpuId', + }, + { + title: '排序值', + dataIndex: 'sort', + }, + { + title: '状态', + dataIndex: 'status', + render(val) { + return {status[val]}; // TODO 芋艿,此处要改 + }, + }, + { + title: '备注', + dataIndex: 'memo', + }, + { + title: '创建时间', + dataIndex: 'createTime', + render: val => {moment(val).format('YYYY-MM-DD HH:mm')}, + }, + { + title: '操作', + width: 360, + render: (text, record) => { + const statusText = record.status === 1 ? '禁用' : '开启'; // TODO 芋艿,此处要改 + return ( + + handleModalVisible(true, 'update', record)}>编辑 + + handleStatus(record)}> + {statusText} + + { + record.status === 2 ? + + + handleDelete(record)}> + 删除 + + : null + } + + ); + }, + }, + ]; + + function onPageChange(page) { // 翻页 + dispatch({ + type: 'productRecommendList/query', + payload: { + pageNo: page.current, + pageSize: page.pageSize, + ...searchParams + } + }) + } + + return ( + + ) +} + +// 搜索表单 +// TODO 芋艿,有没办法换成上面那种写法 +const SearchForm = Form.create()(props => { + const { + form, + form: { getFieldDecorator }, + dispatch + } = props; + + function search() { + dispatch({ + type: 'productRecommendList/query', + payload: { + ...PaginationHelper.defaultPayload, + ...form.getFieldsValue() + } + }) + } + + // 提交搜索 + function handleSubmit(e) { + // 阻止默认事件 + e.preventDefault(); + // 提交搜索 + search(); + } + + // 重置搜索 + function handleReset() { + // 重置表单 + form.resetFields(); + // 执行搜索 + search(); + } + + return ( + + + + + {getFieldDecorator('title')()} + + + + + + + + + + + ); +}); + +// 添加 or 修改 Form 表单 +const AddOrUpdateForm = Form.create()(props => { + const { dispatch, modalVisible, form, handleModalVisible, modalType, formVals } = props; + + const okHandle = () => { + form.validateFields((err, fields) => { + if (err) return; + // 添加表单 + if (modalType === 'add') { + dispatch({ + type: 'productRecommendList/add', + payload: { + body: { + ...fields, + }, + callback: () => { + // 清空表单 + form.resetFields(); + // 提示 + message.success('添加成功'); + // 关闭弹窗 + handleModalVisible(); + }, + }, + }); + // 修改表单 + } else { + dispatch({ + type: 'productRecommendList/update', + payload: { + body: { + id: formVals.id, + ...fields, + }, + callback: () => { + // 清空表单 + form.resetFields(); + // 提示 + message.success('更新成功'); + // 关闭弹窗 + handleModalVisible(); + }, + }, + }); + } + }); + }; + + const title = modalType === 'add' ? '新建 Banner' : '更新 Banner'; + return ( + handleModalVisible()} + > + + {form.getFieldDecorator('type', { + rules: [{ required: true, message: '请输入推荐类型!'}, + ], + initialValue: formVals.type, + })( + + )} + + + {form.getFieldDecorator('productSpuId', { + rules: [{ required: true, message: '请输入商品!'}, // TODO 芋艿,临时先输入商品编号,后面做成搜索。 + ], + initialValue: formVals.productSpuId, + })()} + + + {form.getFieldDecorator('sort', { + rules: [{ required: true, message: '请输入排序值!' }], + initialValue: formVals.sort, + })()} + + + {form.getFieldDecorator('memo', { + rules: [{ required: false, message: '请输入备注!' }, + {max: 255, message: '最大长度为 255 位'}, + ], + initialValue: formVals.memo, + })()} + + + ); +}); + +@connect(({ productRecommendList }) => ({ + // list: productRecommend.list, + // pagination: productRecommend.pagination, + ...productRecommendList, +})) + +// 主界面 +@Form.create() +class BannerList extends PureComponent { + + componentDidMount() { + const { dispatch } = this.props; + dispatch({ + type: 'productRecommendList/query', + payload: { + ...PaginationHelper.defaultPayload + }, + }); + } + + handleModalVisible = (modalVisible, modalType, record) => { + const { dispatch } = this.props; + dispatch({ + type: 'productRecommendList/setAll', + payload: { + modalVisible, + modalType, + formVals: record || {} + }, + }); + }; + + render() { + // let that = this; + const { dispatch, + list, listLoading, searchParams, pagination, + modalVisible, modalType, formVals, + confirmLoading, } = this.props; + + // 列表属性 + const listProps = { + dataSource: list, + pagination, + searchParams, + dispatch, + loading: listLoading, + confirmLoading, + handleModalVisible: this.handleModalVisible, // Function + }; + + // 搜索表单属性 + const searchFormProps = { + dispatch, + }; + + // 添加 or 更新表单属性 + const addOrUpdateFormProps = { + modalVisible, + modalType, + formVals, + dispatch, + handleModalVisible: this.handleModalVisible, // Function + }; + + return ( + + +
+
+ +
+
+ +
+
+ +
+ + + +
+ ); + } +} + +export default BannerList; \ No newline at end of file diff --git a/admin-web/src/pages/Promotion/ProductRecommendList.less b/admin-web/src/pages/Promotion/ProductRecommendList.less new file mode 100644 index 000000000..7ad3dac3f --- /dev/null +++ b/admin-web/src/pages/Promotion/ProductRecommendList.less @@ -0,0 +1,47 @@ +@import '~antd/lib/style/themes/default.less'; +@import '~@/utils/utils.less'; + +.tableList { + .tableListOperator { + margin-bottom: 16px; + button { + margin-right: 8px; + } + } +} + +.tableDelete { + color: red; +} + +.tableListForm { + :global { + .ant-form-item { + display: flex; + margin-right: 0; + margin-bottom: 24px; + > .ant-form-item-label { + width: auto; + padding-right: 8px; + line-height: 32px; + } + .ant-form-item-control { + line-height: 32px; + } + } + .ant-form-item-control-wrapper { + flex: 1; + } + } + .submitButtons { + display: block; + margin-bottom: 24px; + white-space: nowrap; + } +} + +@media screen and (max-width: @screen-lg) { + .tableListForm :global(.ant-form-item) { + margin-right: 24px; + } +} \ No newline at end of file diff --git a/admin-web/src/services/promotion.js b/admin-web/src/services/promotion.js index 40cdb6b0c..8269f341e 100644 --- a/admin-web/src/services/promotion.js +++ b/admin-web/src/services/promotion.js @@ -31,4 +31,36 @@ export async function deleteBanner(params) { return request(`/promotion-api/admins/banner/delete?${stringify(params)}`, { method: 'POST', }); +} + +// product recommend + +export async function queryProductRecommend(params) { + return request(`/promotion-api/admins/product_recommend/page?${stringify(params)}`, { + method: 'GET', + }); +} + +export async function addProductRecommend(params) { + return request(`/promotion-api/admins/product_recommend/add?${stringify(params)}`, { + method: 'POST', + }); +} + +export async function updateProductRecommend(params) { + return request(`/promotion-api/admins/product_recommend/update?${stringify(params)}`, { + method: 'POST', + }); +} + +export async function updateProductRecommendStatus(params) { + return request(`/promotion-api/admins/product_recommend/update_status?${stringify(params)}`, { + method: 'POST', + }); +} + +export async function deleteProductRecommend(params) { + return request(`/promotion-api/admins/product_recommend/delete?${stringify(params)}`, { + method: 'POST', + }); } \ No newline at end of file diff --git a/mobile-web/src/api/promotion.js b/mobile-web/src/api/promotion.js index 9b1528117..c44ea1106 100644 --- a/mobile-web/src/api/promotion.js +++ b/mobile-web/src/api/promotion.js @@ -7,4 +7,13 @@ export function getBannerList() { url: 'promotion-api/users/banner/list', method: 'get', }); +} + +// Product Recommend + +export function getProductRecommendList() { + return request({ + url: 'promotion-api/users/product_recommend/list', + method: 'get', + }); } \ No newline at end of file diff --git a/mobile-web/src/config/env.js b/mobile-web/src/config/env.js index cd3425bf5..aab5a5714 100644 --- a/mobile-web/src/config/env.js +++ b/mobile-web/src/config/env.js @@ -19,8 +19,8 @@ if (process.env.NODE_ENV == 'development') { // baseUrl = 'http://127.0.0.1'; // baseUrl = 'http://180.167.213.26:18099'; -// dataSources = 'remote'; -dataSources = 'local'; +dataSources = 'remote'; +// dataSources = 'local'; export { baseUrl, diff --git a/mobile-web/src/page/page/index.vue b/mobile-web/src/page/page/index.vue index 46d84d550..d50465234 100644 --- a/mobile-web/src/page/page/index.vue +++ b/mobile-web/src/page/page/index.vue @@ -13,14 +13,15 @@ -
- + +
+
-
- +
+
@@ -39,7 +40,7 @@ import imageAd from "../../components/page/imageAd.vue"; import imageText from "../../components/page/imageText.vue"; import product from "../../components/page/product.vue"; import { GetPage } from "../../api/page.js"; -import { getBannerList } from '../../api/promotion.js'; +import { getBannerList, getProductRecommendList } from '../../api/promotion.js'; export default { name:"page", @@ -60,6 +61,7 @@ export default { topheight:0, page:{}, banners: [], // Banner 列表 + productRecommends: [], // 推荐商品列表 } }, created:function(){ @@ -69,18 +71,30 @@ export default { }, mounted: function() { // 加载 Banner - let response = getBannerList(); - response.then(data => { - this.banners = data; - }); + { + let response = getBannerList(); + response.then(data => { + this.banners = data; + }); + } + // 加载 getProductRecommendList + { + let response = getProductRecommendList(); + response.then(data => { + this.productRecommends = data; + }); + } }, methods:{ - onBannerClick: function(event, index) { - debugger; - console.log(event); - }, + // onBannerClick: function(event, index) { + // debugger; + // console.log(event); + // }, settopheight:function(value){ this.topheight=value; + }, + showProduct(product){ + this.$router.push('/product/'+product.id); } } } diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrAndValuePairBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrAndValuePairBO.java index 527d3865f..dfea5d9f5 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrAndValuePairBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrAndValuePairBO.java @@ -1,9 +1,11 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; + /** * 商品规格明细 BO */ -public class ProductAttrAndValuePairBO { +public class ProductAttrAndValuePairBO implements Serializable { /** * 规格编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrBO.java index 1c1759624..2da299c38 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.Date; /** * 商品规格 VO */ -public class ProductAttrBO { +public class ProductAttrBO implements Serializable { /** * 规格编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrDetailBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrDetailBO.java index dcb6c78df..6a3c5edf3 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrDetailBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrDetailBO.java @@ -1,12 +1,13 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.Date; import java.util.List; /** * 商品规格明细 VO */ -public class ProductAttrDetailBO { +public class ProductAttrDetailBO implements Serializable { /** * 规格编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrPageBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrPageBO.java index 14923f57f..bf6176f5c 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrPageBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrPageBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.List; /** * 商品规格明细分页 BO */ -public class ProductAttrPageBO { +public class ProductAttrPageBO implements Serializable { /** * 规格数组 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrSimpleBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrSimpleBO.java index 1a0ecb399..9eda2af66 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrSimpleBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrSimpleBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.List; /** * 商品规格精简 VO */ -public class ProductAttrSimpleBO { +public class ProductAttrSimpleBO implements Serializable { /** * 规格编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueBO.java index 0cb4a77f0..3fe44272e 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.Date; /** * 商品规格值 VO */ -public class ProductAttrValueBO { +public class ProductAttrValueBO implements Serializable { /** * 规格值编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueDetailBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueDetailBO.java index 5e3954fed..c70690e99 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueDetailBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueDetailBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.Date; /** * 商品规格值 VO */ -public class ProductAttrValueDetailBO { +public class ProductAttrValueDetailBO implements Serializable { /** * 规格值编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueSimpleBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueSimpleBO.java index ea23bc301..7d1bb0ec9 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueSimpleBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductAttrValueSimpleBO.java @@ -1,9 +1,11 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; + /** * 商品规格值 VO */ -public class ProductAttrValueSimpleBO { +public class ProductAttrValueSimpleBO implements Serializable { /** * 规格值编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductCategoryBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductCategoryBO.java index ae56b4d2d..6450145cc 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductCategoryBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductCategoryBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.Date; /** * 商品分类 BO */ -public class ProductCategoryBO { +public class ProductCategoryBO implements Serializable { /** * 分类编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuBO.java index 7bc35b788..7ef2ea4ff 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuBO.java @@ -1,6 +1,8 @@ package cn.iocoder.mall.product.api.bo; -public class ProductSkuBO { +import java.io.Serializable; + +public class ProductSkuBO implements Serializable { private Integer id; diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuDetailBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuDetailBO.java index 6435cc69c..e6e9d5ab4 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuDetailBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSkuDetailBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.List; /** * 商品 Sku 明细 BO */ -public class ProductSkuDetailBO { +public class ProductSkuDetailBO implements Serializable { /** * sku 编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java index 711e7bfb1..c40702e1a 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuBO.java @@ -1,8 +1,9 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.List; -public class ProductSpuBO { +public class ProductSpuBO implements Serializable { /** * SPU 编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuDetailBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuDetailBO.java index 0b068aad3..2ad313429 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuDetailBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuDetailBO.java @@ -1,11 +1,12 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.List; /** * 商品 Spu 明细 BO(包括 Sku 明细) */ -public class ProductSpuDetailBO { +public class ProductSpuDetailBO implements Serializable { /** * SPU 编号 diff --git a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java index 89ca0756d..0d6093743 100644 --- a/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java +++ b/product/product-service-api/src/main/java/cn/iocoder/mall/product/api/bo/ProductSpuPageBO.java @@ -1,8 +1,9 @@ package cn.iocoder.mall.product.api.bo; +import java.io.Serializable; import java.util.List; -public class ProductSpuPageBO { +public class ProductSpuPageBO implements Serializable { /** * Spu 数组 diff --git a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java index 4428dd9ce..aab399241 100644 --- a/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java +++ b/product/product-service-impl/src/main/java/cn/iocoder/mall/product/dao/ProductSpuMapper.java @@ -12,7 +12,7 @@ public interface ProductSpuMapper { ProductSpuDO selectById(Integer id); - List selectByIds(Collection ids); + List selectByIds(@Param("ids") Collection ids); void insert(ProductSpuDO productSpuDO); diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java index 7e2dbd873..1b3c015e3 100644 --- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java +++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductRecommendController.java @@ -17,13 +17,14 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.Collection; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @RestController -@RequestMapping("users/banner") +@RequestMapping("users/product_recommend") @Api("商品推荐模块") public class UsersProductRecommendController { @@ -34,7 +35,7 @@ public class UsersProductRecommendController { @GetMapping("/list") @ApiOperation("获得所有 Banner 列表") - public CommonResult> list() { + public CommonResult>> list() { // 查询商品推荐列表 List productRecommends = productRecommendService.getProductRecommendList( null, CommonStatusEnum.ENABLE.getValue()).getData(); @@ -43,11 +44,11 @@ public class UsersProductRecommendController { productRecommends.stream().map(ProductRecommendBO::getProductSpuId).collect(Collectors.toSet())).getData(); Map spuMap = spus.stream().collect(Collectors.toMap(ProductSpuBO::getId, account -> account)); // 组合结果,返回 - Multimap result = new HashMultimap<>(); + Multimap result = HashMultimap.create(); productRecommends.sort(Comparator.comparing(ProductRecommendBO::getSort)); // 排序,按照 sort 升序 productRecommends.forEach(productRecommendBO -> result.put(productRecommendBO.getType(), ProductRecommendConvert.INSTANCE.convert(spuMap.get(productRecommendBO.getProductSpuId())))); // 将 ProductSpuBO 添加到 results 中 - return CommonResult.success(result); + return CommonResult.success(result.asMap()); } } \ No newline at end of file diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/config/ServiceExceptionConfiguration.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/config/ServiceExceptionConfiguration.java index 2931e04e5..632cb9cd2 100644 --- a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/config/ServiceExceptionConfiguration.java +++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/config/ServiceExceptionConfiguration.java @@ -1,7 +1,7 @@ package cn.iocoder.mall.promotion.biz.config; import cn.iocoder.common.framework.util.ServiceExceptionUtil; -import cn.iocoder.mall.user.service.api.constant.UserErrorCodeEnum; +import cn.iocoder.mall.promotion.api.constant.PromotionErrorCodeEnum; import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; @@ -18,7 +18,7 @@ public class ServiceExceptionConfiguration { // } catch (IOException e) { // throw new RuntimeException(e); // } - for (UserErrorCodeEnum item : UserErrorCodeEnum.values()) { + for (PromotionErrorCodeEnum item : PromotionErrorCodeEnum.values()) { ServiceExceptionUtil.put(item.getCode(), item.getMessage()); } } diff --git a/promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml b/promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml index 939e6926d..7632b2579 100644 --- a/promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml +++ b/promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml @@ -7,7 +7,7 @@ status, memo, create_time - + @@ -17,14 +17,14 @@ - + - SELECT FROM product_recommend @@ -32,7 +32,7 @@ AND deleted = 0 - SELECT FROM product_recommend @@ -41,13 +41,13 @@ product_spu_id = #{productSpuId} - type = #{type} + AND type = #{type} AND deleted = 0 - SELECT FROM product_recommend @@ -56,13 +56,13 @@ type = #{type} - status = #{status} + AND status = #{status} AND deleted = 0 - SELECT FROM product_recommend @@ -87,7 +87,7 @@ - + INSERT INTO product_recommend ( type, product_spu_id, sort, status, memo, create_time, deleted @@ -97,7 +97,7 @@ ) - + UPDATE product_recommend