From 23acc40d8d1d5c9a3cce615bb53f16b0d4683bea Mon Sep 17 00:00:00 2001
From: YunaiV <>
Date: Sun, 31 Mar 2019 00:12:15 +0800
Subject: [PATCH 1/5] =?UTF-8?q?=E5=89=8D=E7=AB=AF=EF=BC=9A=E7=AE=A1?=
=?UTF-8?q?=E7=90=86=E5=90=8E=E5=8F=B0=E5=A2=9E=E5=8A=A0=20Banner=20CRUD?=
=?UTF-8?q?=20=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
admin-web/config/proxy/proxy.dev.js | 8 +-
admin-web/config/router.config.js | 23 +
admin-web/mock/admin.js | 10 +-
admin-web/src/locales/zh-CN/menu.js | 2 +
admin-web/src/models/promotion/bannerList.js | 256 +++++++++++
.../src/pages/Product/ProductCategoryList.js | 1 -
admin-web/src/pages/Promotion/BannerList.js | 416 ++++++++++++++++++
admin-web/src/pages/Promotion/BannerList.less | 47 ++
admin-web/src/services/promotion.js | 34 ++
.../controller/admins/ResourceController.java | 8 +-
.../promotion/application/vo/BannerVO.java | 2 +-
.../mall/promotion/api/dto/BannerAddDTO.java | 4 +-
.../promotion/api/dto/BannerUpdateDTO.java | 5 +-
.../biz/service/BannerServiceImpl.java | 2 +-
.../main/resources/mapper/BannerMapper.xml | 6 +-
15 files changed, 806 insertions(+), 18 deletions(-)
create mode 100644 admin-web/src/models/promotion/bannerList.js
create mode 100644 admin-web/src/pages/Promotion/BannerList.js
create mode 100644 admin-web/src/pages/Promotion/BannerList.less
create mode 100644 admin-web/src/services/promotion.js
diff --git a/admin-web/config/proxy/proxy.dev.js b/admin-web/config/proxy/proxy.dev.js
index fd07c075a..0608bd7b3 100644
--- a/admin-web/config/proxy/proxy.dev.js
+++ b/admin-web/config/proxy/proxy.dev.js
@@ -2,7 +2,8 @@
export default {
'/admin-api/': {
- target: 'http://180.167.213.26:18083/',
+ // target: 'http://180.167.213.26:18083/',
+ target: 'http://127.0.0.1:18083/',
changeOrigin: true,
pathRewrite: {},
},
@@ -11,4 +12,9 @@ export default {
changeOrigin: true,
pathRewrite: {},
},
+ '/promotion-api/': {
+ target: 'http://127.0.0.1:18085/',
+ changeOrigin: true,
+ pathRewrite: {},
+ },
};
diff --git a/admin-web/config/router.config.js b/admin-web/config/router.config.js
index db32843b6..920467940 100644
--- a/admin-web/config/router.config.js
+++ b/admin-web/config/router.config.js
@@ -94,6 +94,29 @@ export default [
},
],
},
+ // promotion
+ {
+ path: '/promotion',
+ name: 'promotion',
+ icon: 'user',
+ routes: [
+ {
+ path: '/promotion/banner-list',
+ name: 'promotion-banner-list',
+ component: './Promotion/BannerList',
+ },
+ // {
+ // path: '/product/product-spu-add',
+ // name: 'product-spu-add',
+ // component: './Product/ProductSpuAddOrUpdate',
+ // },
+ // {
+ // path: '/product/product-category-list',
+ // name: 'product-category-list',
+ // component: './Product/ProductCategoryList',
+ // },
+ ],
+ },
{
path: '/dashboard',
name: 'dashboard',
diff --git a/admin-web/mock/admin.js b/admin-web/mock/admin.js
index be9c114b2..96a6da174 100644
--- a/admin-web/mock/admin.js
+++ b/admin-web/mock/admin.js
@@ -49,10 +49,10 @@ function getDictionaryTree(req, res) {
}
export default {
- 'GET /admin-api/admins/admin/menu_resource_tree': getAdminMenuAll,
- 'GET /admin-api/admins/admin/url_resource_list': getAdminUrls,
- 'GET /admin-api/admins/resource/tree': getResourceTree,
- 'GET /admin-api/admins/role/page': getQueryRole,
+ // 'GET /admin-api/admins/admin/menu_resource_tree': getAdminMenuAll,
+ // 'GET /admin-api/admins/admin/url_resource_list': getAdminUrls,
+ // 'GET /admin-api/admins/resource/tree': getResourceTree,
+ // 'GET /admin-api/admins/role/page': getQueryRole,
// 'GET /admin-api/admins/admin/page': getQueryRole,
- 'GET /admin-api/admins/data_dict/tree': getDictionaryTree,
+ // 'GET /admin-api/admins/data_dict/tree': getDictionaryTree,
};
diff --git a/admin-web/src/locales/zh-CN/menu.js b/admin-web/src/locales/zh-CN/menu.js
index 37dee7786..111932c6a 100644
--- a/admin-web/src/locales/zh-CN/menu.js
+++ b/admin-web/src/locales/zh-CN/menu.js
@@ -52,4 +52,6 @@ export default {
// 订单
'menu.order': '订单管理',
'menu.order.order-list': '订单管理',
+ // 营销相关
+ 'menu.promotion.promotion-banner-list': 'Banner 管理'
};
diff --git a/admin-web/src/models/promotion/bannerList.js b/admin-web/src/models/promotion/bannerList.js
new file mode 100644
index 000000000..ce4d46ada
--- /dev/null
+++ b/admin-web/src/models/promotion/bannerList.js
@@ -0,0 +1,256 @@
+import {message} from 'antd';
+import {buildTreeNode, findCheckedKeys} from '../../utils/tree.utils';
+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 = {
+ title: '',
+};
+
+export default {
+ namespace: 'bannerList',
+
+ state: {
+ // 分页列表相关
+ list: [],
+ listLoading: false,
+ pagination: PaginationHelper.defaultPaginationConfig,
+ searchParams: SEARCH_PARAMS_DEFAULT,
+
+ // 添加 or 修改表单相关
+ modalVisible: false,
+ modalType: undefined, // 'add' or 'update' 表单
+ formVals: {}, // 当前表单值
+ modalLoading: false,
+
+ // 分配角色表单相关
+ roleList: [],
+ roleModalVisible: false,
+ roleCheckedKeys: [], // 此处的 Key ,就是角色编号
+ roleAssignLoading: false,
+ },
+
+ effects: {
+ // 查询列表
+ * query({ payload }, { call, put }) {
+ // 显示加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: true,
+ });
+
+ // 请求
+ const response = yield call(queryBanner, payload);
+ // 响应
+ yield put({
+ type: 'setAll',
+ payload: {
+ list: response.data.list,
+ pagination: PaginationHelper.formatPagination(response.data, payload),
+ searchParams: {
+ title: payload.title || ''
+ }
+ },
+ });
+
+ // 隐藏加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: false,
+ });
+ },
+ * add({ payload }, { call, put }) {
+ const { callback, body } = payload;
+ // 显示加载中
+ yield put({
+ type: 'changeModalLoading',
+ payload: true,
+ });
+
+ // 请求
+ const response = yield call(addBanner, 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(updateBanner, 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(updateBannerStatus, payload);
+ // 响应
+ if (response.code === 0) {
+ message.info('更新状态成功!');
+ // 刷新列表
+ yield put({
+ type: 'query',
+ payload: {
+ ...PaginationHelper.defaultPayload
+ },
+ });
+ }
+ },
+
+ * delete({ payload }, { call, put }) {
+ // 请求
+ const response = yield call(deleteBanner, payload);
+ // 响应
+ if (response.code === 0) {
+ message.info('删除成功!');
+ // 刷新列表
+ yield put({
+ type: 'query',
+ payload: {
+ ...PaginationHelper.defaultPayload
+ },
+ });
+ }
+ },
+
+ * 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,
+ modalLoading: payload,
+ };
+ },
+ changeListLoading(state, { payload }) {
+ return {
+ ...state,
+ listLoading: payload,
+ };
+ },
+ // 设置所有属性
+ setAll(state, { payload }) {
+ return {
+ ...state,
+ ...payload,
+ };
+ }
+ },
+};
diff --git a/admin-web/src/pages/Product/ProductCategoryList.js b/admin-web/src/pages/Product/ProductCategoryList.js
index 2709c7dcf..b5738a29f 100644
--- a/admin-web/src/pages/Product/ProductCategoryList.js
+++ b/admin-web/src/pages/Product/ProductCategoryList.js
@@ -209,7 +209,6 @@ class ProductCategoryList extends PureComponent {
{
title: '排序值',
dataIndex: 'sort',
- render: sort => {sort},
},
{
title: '创建时间',
diff --git a/admin-web/src/pages/Promotion/BannerList.js b/admin-web/src/pages/Promotion/BannerList.js
new file mode 100644
index 000000000..3643eca25
--- /dev/null
+++ b/admin-web/src/pages/Promotion/BannerList.js
@@ -0,0 +1,416 @@
+/* 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 { TreeNode } = Tree;
+const status = ['未知', '正常', '禁用'];
+
+// 列表
+function List ({ dataSource, loading, pagination, searchParams, dispatch,
+ handleModalVisible}) {
+
+ function handleStatus(record) {
+ Modal.confirm({
+ title: record.status === 1 ? '确认禁用' : '取消禁用',
+ content: `${record.username}`,
+ onOk() {
+ dispatch({
+ type: 'bannerList/updateStatus',
+ payload: {
+ id: record.id,
+ status: record.status === 1 ? 2 : 1,
+ },
+ });
+ },
+ onCancel() {},
+ });
+ }
+
+ function handleDelete(record) {
+ Modal.confirm({
+ title: `确认删除?`,
+ content: `${record.title}`,
+ onOk() {
+ dispatch({
+ type: 'bannerList/delete',
+ payload: {
+ id: record.id,
+ },
+ });
+ },
+ onCancel() {},
+ });
+ }
+
+ const columns = [
+ {
+ title: '标题',
+ dataIndex: 'title'
+ },
+ {
+ title: '跳转链接',
+ dataIndex: 'url',
+ },
+ {
+ title: '图片',
+ dataIndex: 'picUrl',
+ render(val) {
+ return ;
+ },
+ },
+ {
+ 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: 'bannerList/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: 'bannerList/query',
+ payload: {
+ ...PaginationHelper.defaultPayload,
+ ...form.getFieldsValue()
+ }
+ })
+ }
+
+ // 提交搜索
+ function handleSubmit(e) {
+ // 阻止默认事件
+ e.preventDefault();
+ // 提交搜索
+ search();
+ }
+
+ // 重置搜索
+ function handleReset() {
+ // 重置表单
+ form.resetFields();
+ // 执行搜索
+ search();
+ }
+
+ return (
+
+ );
+});
+
+// 添加 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: 'bannerList/add',
+ payload: {
+ body: {
+ ...fields,
+ },
+ callback: () => {
+ // 清空表单
+ form.resetFields();
+ // 提示
+ message.success('添加成功');
+ // 关闭弹窗
+ handleModalVisible();
+ },
+ },
+ });
+ // 修改表单
+ } else {
+ dispatch({
+ type: 'bannerList/update',
+ payload: {
+ body: {
+ id: formVals.id,
+ ...fields,
+ },
+ callback: () => {
+ // 清空表单
+ form.resetFields();
+ // 提示
+ message.success('更新成功');
+ // 关闭弹窗
+ handleModalVisible();
+ },
+ },
+ });
+ }
+ });
+ };
+
+ const title = modalType === 'add' ? '新建 Banner' : '更新 Banner';
+ return (
+ handleModalVisible()}
+ >
+
+ {form.getFieldDecorator('title', {
+ rules: [{ required: true, message: '请输入标题!'},
+ {max: 32, min:2, message: '长度为 2-32 位'},
+ ],
+ initialValue: formVals.title,
+ })()}
+
+
+ {form.getFieldDecorator('url', {
+ rules: [{ required: true, message: '请输入跳转链接!'},
+ { type: 'url', message: '必须是 URL!'},
+ {max: 255, message: '最大长度为 255 位'},
+ ],
+ initialValue: formVals.picUrl,
+ })()}
+
+
+ {form.getFieldDecorator('picUrl', {
+ rules: [{ required: true, message: '请输入跳转链接!'},],
+ initialValue: formVals.picUrl,
+ })()}
+
+
+ {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(({ bannerList }) => ({
+ // list: bannerList.list,
+ // pagination: bannerList.pagination,
+ ...bannerList,
+}))
+
+// 主界面
+@Form.create()
+class BannerList extends PureComponent {
+
+ componentDidMount() {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'bannerList/query',
+ payload: {
+ ...PaginationHelper.defaultPayload
+ },
+ });
+ }
+
+ handleModalVisible = (modalVisible, modalType, record) => {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'bannerList/setAll',
+ payload: {
+ modalVisible,
+ modalType,
+ formVals: record || {}
+ },
+ });
+ };
+
+ 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;
+
+ // 列表属性
+ 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/BannerList.less b/admin-web/src/pages/Promotion/BannerList.less
new file mode 100644
index 000000000..7ad3dac3f
--- /dev/null
+++ b/admin-web/src/pages/Promotion/BannerList.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
new file mode 100644
index 000000000..40cdb6b0c
--- /dev/null
+++ b/admin-web/src/services/promotion.js
@@ -0,0 +1,34 @@
+import { stringify } from '@/utils/request.qs';
+import request from '@/utils/request';
+
+// banner
+
+export async function queryBanner(params) {
+ return request(`/promotion-api/admins/banner/page?${stringify(params)}`, {
+ method: 'GET',
+ });
+}
+
+export async function addBanner(params) {
+ return request(`/promotion-api/admins/banner/add?${stringify(params)}`, {
+ method: 'POST',
+ });
+}
+
+export async function updateBanner(params) {
+ return request(`/promotion-api/admins/banner/update?${stringify(params)}`, {
+ method: 'POST',
+ });
+}
+
+export async function updateBannerStatus(params) {
+ return request(`/promotion-api/admins/banner/update_status?${stringify(params)}`, {
+ method: 'POST',
+ });
+}
+
+export async function deleteBanner(params) {
+ return request(`/promotion-api/admins/banner/delete?${stringify(params)}`, {
+ method: 'POST',
+ });
+}
\ No newline at end of file
diff --git a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/ResourceController.java b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/ResourceController.java
index b3c359c7e..55faed61d 100644
--- a/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/ResourceController.java
+++ b/admin/admin-application/src/main/java/cn/iocoder/mall/admin/application/controller/admins/ResourceController.java
@@ -66,14 +66,14 @@ public class ResourceController {
@ApiImplicitParam(name = "sort", value = "排序", required = true, example = "1"),
@ApiImplicitParam(name = "displayName", value = "菜单展示名", required = true, example = "商品管理"),
@ApiImplicitParam(name = "pid", value = "父级资源编号", required = true, example = "1"),
- @ApiImplicitParam(name = "handler", value = "操作", required = true, example = "/order/list"),
+ @ApiImplicitParam(name = "handler", value = "操作", example = "/order/list"),
})
public CommonResult add(@RequestParam("name") String name,
@RequestParam("type") Integer type,
@RequestParam("sort") Integer sort,
@RequestParam("displayName") String displayName,
@RequestParam("pid") Integer pid,
- @RequestParam("handler") String handler) {
+ @RequestParam(value = "handler", required = false) String handler) {
ResourceAddDTO resourceAddDTO = new ResourceAddDTO().setName(name).setType(type).setSort(sort)
.setDisplayName(displayName).setPid(pid).setHandler(handler);
return ResourceConvert.INSTANCE.convert3(resourceService.addResource(AdminSecurityContextHolder.getContext().getAdminId(), resourceAddDTO));
@@ -87,14 +87,14 @@ public class ResourceController {
@ApiImplicitParam(name = "sort", value = "排序", required = true, example = "1"),
@ApiImplicitParam(name = "displayName", value = "菜单展示名", required = true, example = "商品管理"),
@ApiImplicitParam(name = "pid", value = "父级资源编号", required = true, example = "1"),
- @ApiImplicitParam(name = "handler", value = "操作", required = true, example = "/order/list"),
+ @ApiImplicitParam(name = "handler", value = "操作", example = "/order/list"),
})
public CommonResult update(@RequestParam("id") Integer id,
@RequestParam("name") String name,
@RequestParam("sort") Integer sort,
@RequestParam("displayName") String displayName,
@RequestParam("pid") Integer pid,
- @RequestParam("handler") String handler) {
+ @RequestParam(value = "handler", required = false) String handler) {
ResourceUpdateDTO resourceUpdateDTO = new ResourceUpdateDTO().setId(id).setName(name).setSort(sort).setDisplayName(displayName).setPid(pid).setHandler(handler);
return resourceService.updateResource(AdminSecurityContextHolder.getContext().getAdminId(), resourceUpdateDTO);
}
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/BannerVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/BannerVO.java
index 3a5c3f35a..e7e7c005f 100644
--- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/BannerVO.java
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/BannerVO.java
@@ -14,7 +14,7 @@ public class BannerVO {
private String title;
@ApiModelProperty(value = "跳转链接", required = true, example = "http://www.baidu.com")
private String url;
- @ApiModelProperty(value = "突脸链接", required = true, example = "http://www.iocoder.cn/01.jpg")
+ @ApiModelProperty(value = "图片链接", required = true, example = "http://www.iocoder.cn/01.jpg")
private String picUrl;
@ApiModelProperty(value = "排序", required = true, example = "10")
private Integer sort;
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerAddDTO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerAddDTO.java
index d368014e3..8581e834a 100644
--- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerAddDTO.java
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerAddDTO.java
@@ -12,13 +12,15 @@ import javax.validation.constraints.NotNull;
public class BannerAddDTO {
@NotEmpty(message = "标题不能为空")
- @Length(min = 6, max = 32, message = "标题长度为 6-32 位")
+ @Length(min = 2, max = 32, message = "标题长度为 2-32 位")
private String title;
@NotEmpty(message = "跳转链接不能为空")
@URL(message = "跳转链接格式不正确")
+ @Length(max = 255, message = "跳转链接最大长度为 255 位")
private String url;
@NotEmpty(message = "图片链接不能为空")
@URL(message = "图片链接格式不正确")
+ @Length(max = 255, message = "图片链接最大长度为 255 位")
private String picUrl;
@NotNull(message = "排序不能为空")
private Integer sort;
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerUpdateDTO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerUpdateDTO.java
index 9f7d222ba..a89a7728c 100644
--- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerUpdateDTO.java
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/BannerUpdateDTO.java
@@ -14,12 +14,15 @@ public class BannerUpdateDTO {
@NotNull(message = "编号不能为空")
private Integer id;
@NotEmpty(message = "标题不能为空")
- @Length(min = 6, max = 32, message = "标题长度为 6-32 位")
+ @Length(min = 2, max = 32, message = "标题长度为 2-32 位")
private String title;
@NotEmpty(message = "跳转链接不能为空")
@URL(message = "跳转链接格式不正确")
+ @Length(max = 255, message = "跳转链接最大长度为 255 位")
private String url;
+ @NotEmpty(message = "图片链接不能为空")
@URL(message = "图片链接格式不正确")
+ @Length(max = 255, message = "图片链接最大长度为 255 位")
private String picUrl;
@NotNull(message = "排序不能为空")
private Integer sort;
diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java
index 53c7933f7..89e7a488f 100644
--- a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java
+++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java
@@ -42,7 +42,7 @@ public class BannerServiceImpl implements BannerService {
@Override
public CommonResult addBanner(Integer adminId, BannerAddDTO bannerAddDTO) {
// 保存到数据库
- BannerDO banner = BannerConvert.INSTANCE.convert(bannerAddDTO);
+ BannerDO banner = BannerConvert.INSTANCE.convert(bannerAddDTO).setStatus(CommonStatusEnum.ENABLE.getValue());
banner.setDeleted(DeletedStatusEnum.DELETED_NO.getValue()).setCreateTime(new Date());
bannerMapper.insert(banner);
// 返回成功
diff --git a/promotion/promotion-service-impl/src/main/resources/mapper/BannerMapper.xml b/promotion/promotion-service-impl/src/main/resources/mapper/BannerMapper.xml
index 07adde196..0c8a1220e 100644
--- a/promotion/promotion-service-impl/src/main/resources/mapper/BannerMapper.xml
+++ b/promotion/promotion-service-impl/src/main/resources/mapper/BannerMapper.xml
@@ -76,7 +76,7 @@
url = #{url},
-
+
pic_url = #{picUrl} ,
@@ -85,8 +85,8 @@
status = #{status},
-
- VALUES = #{VALUES},
+
+ memo = #{memo},
deleted = #{deleted}
From 1fd9ab2a182bdee7009ce8a315a74b9ade6d0e17 Mon Sep 17 00:00:00 2001
From: YunaiV <>
Date: Sun, 31 Mar 2019 00:48:28 +0800
Subject: [PATCH 2/5] =?UTF-8?q?=E5=89=8D=E7=AB=AF=EF=BC=9AH5=20=E9=A6=96?=
=?UTF-8?q?=E9=A1=B5=E5=A2=9E=E5=8A=A0=20Banner=20=E5=88=97=E8=A1=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
mobile-web/src/api/promotion.js | 10 +++++
mobile-web/src/api/user.js | 9 -----
mobile-web/src/components/page/imageAd.vue | 2 +
mobile-web/src/page/page/page.vue | 17 ++++++++-
.../users/UsersProductCategoryController.java | 2 +-
.../admins/AdminsBannerController.java | 20 +++++-----
.../users/UsersProductCategoryController.java | 38 +++++++++++++++++++
.../application/convert/BannerConvert.java | 16 +++++---
.../AdminBannerPageVO.java} | 12 +++---
.../AdminsBannerVO.java} | 20 +++++-----
.../application/vo/users/UsersBannerVO.java | 32 ++++++++++++++++
.../mall/promotion/api/BannerService.java | 4 ++
.../mall/promotion/biz/dao/BannerMapper.java | 2 +
.../biz/service/BannerServiceImpl.java | 7 ++++
.../main/resources/mapper/BannerMapper.xml | 12 ++++++
15 files changed, 160 insertions(+), 43 deletions(-)
create mode 100644 mobile-web/src/api/promotion.js
create mode 100644 promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/users/UsersProductCategoryController.java
rename promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/{BannerPageVO.java => admins/AdminBannerPageVO.java} (61%)
rename promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/{BannerVO.java => admins/AdminsBannerVO.java} (79%)
create mode 100644 promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/users/UsersBannerVO.java
diff --git a/mobile-web/src/api/promotion.js b/mobile-web/src/api/promotion.js
new file mode 100644
index 000000000..9b1528117
--- /dev/null
+++ b/mobile-web/src/api/promotion.js
@@ -0,0 +1,10 @@
+import request from "../config/request";
+
+// Banner
+
+export function getBannerList() {
+ return request({
+ url: 'promotion-api/users/banner/list',
+ method: 'get',
+ });
+}
\ No newline at end of file
diff --git a/mobile-web/src/api/user.js b/mobile-web/src/api/user.js
index 9105a0567..366c25796 100644
--- a/mobile-web/src/api/user.js
+++ b/mobile-web/src/api/user.js
@@ -1,13 +1,5 @@
import request from "../config/request";
-
-export function GetUserIndex() {
- return request({
- url: '/User/GetUserIndex',
- method: 'get',
- })
-}
-
export function GetFavorite(data){
return request({
url: '/User/GetFavorite',
@@ -108,4 +100,3 @@ export function doPassportMobileSendRegisterCode(mobile) {
}
});
}
-
diff --git a/mobile-web/src/components/page/imageAd.vue b/mobile-web/src/components/page/imageAd.vue
index d031a1c1f..d655a1d5a 100644
--- a/mobile-web/src/components/page/imageAd.vue
+++ b/mobile-web/src/components/page/imageAd.vue
@@ -31,6 +31,8 @@
From 1f827e2d2c2912f331cc9a919bd88bf331f99d65 Mon Sep 17 00:00:00 2001
From: YunaiV <>
Date: Sun, 31 Mar 2019 10:25:39 +0800
Subject: [PATCH 4/5] =?UTF-8?q?=E5=89=8D=E7=AB=AF=EF=BC=9AH5=20=E9=A6=96?=
=?UTF-8?q?=E9=A1=B5=E5=A2=9E=E5=8A=A0=20Banner=20=E5=88=97=E8=A1=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
mobile-web/src/page/index.vue | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/mobile-web/src/page/index.vue b/mobile-web/src/page/index.vue
index 9ddc80cb6..61154a9bd 100644
--- a/mobile-web/src/page/index.vue
+++ b/mobile-web/src/page/index.vue
@@ -18,6 +18,4 @@ export default {
-
-
+
\ No newline at end of file
From b333340c202c090efdebed6e145949079353eb00 Mon Sep 17 00:00:00 2001
From: YunaiV <>
Date: Sun, 31 Mar 2019 13:14:43 +0800
Subject: [PATCH 5/5] =?UTF-8?q?=E5=90=8E=E7=AB=AF=EF=BC=9A=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0=E5=95=86=E5=93=81=E6=8E=A8=E8=8D=90=E5=A2=9E=E5=88=A0?=
=?UTF-8?q?=E6=94=B9=E6=9F=A5=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../admins/AdminsBannerController.java | 8 +-
.../AdminsProductRecommendController.java | 96 +++++++++++++
.../application/convert/BannerConvert.java | 4 +-
.../convert/ProductRecommendConvert.java | 29 ++++
...nerPageVO.java => AdminsBannerPageVO.java} | 6 +-
.../admins/AdminsProductRecommendPageVO.java | 34 +++++
.../vo/admins/AdminsProductRecommendVO.java | 88 ++++++++++++
.../api/ProductRecommendService.java | 26 ++++
.../promotion/api/bo/ProductRecommendBO.java | 106 ++++++++++++++
.../api/bo/ProductRecommendPageBO.java | 34 +++++
.../api/constant/ProductRecommendType.java | 43 ++++++
.../api/constant/PromotionErrorCodeEnum.java | 8 +-
.../api/dto/ProductRecommendAddDTO.java | 57 ++++++++
.../api/dto/ProductRecommendPageDTO.java | 44 ++++++
.../api/dto/ProductRecommendUpdateDTO.java | 68 +++++++++
.../biz/convert/ProductRecommendConvert.java | 30 ++++
.../biz/dao/ProductRecommendMapper.java | 30 ++++
.../biz/dataobject/ProductRecommendDO.java | 94 +++++++++++++
.../biz/service/BannerServiceImpl.java | 4 +
.../service/ProductRecommendServiceImpl.java | 133 ++++++++++++++++++
.../mapper/ProductRecommendMapper.xml | 125 ++++++++++++++++
21 files changed, 1057 insertions(+), 10 deletions(-)
create mode 100644 promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsProductRecommendController.java
create mode 100644 promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java
rename promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/{AdminBannerPageVO.java => AdminsBannerPageVO.java} (79%)
create mode 100644 promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendPageVO.java
create mode 100644 promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendVO.java
create mode 100644 promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/ProductRecommendService.java
create mode 100644 promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendBO.java
create mode 100644 promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendPageBO.java
create mode 100644 promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/ProductRecommendType.java
create mode 100644 promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendAddDTO.java
create mode 100644 promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendPageDTO.java
create mode 100644 promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendUpdateDTO.java
create mode 100644 promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/ProductRecommendConvert.java
create mode 100644 promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dao/ProductRecommendMapper.java
create mode 100644 promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/ProductRecommendDO.java
create mode 100644 promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/ProductRecommendServiceImpl.java
create mode 100644 promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsBannerController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsBannerController.java
index 0ab93a2db..b3d4b5f70 100644
--- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsBannerController.java
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsBannerController.java
@@ -8,7 +8,7 @@ import cn.iocoder.mall.promotion.api.dto.BannerAddDTO;
import cn.iocoder.mall.promotion.api.dto.BannerPageDTO;
import cn.iocoder.mall.promotion.api.dto.BannerUpdateDTO;
import cn.iocoder.mall.promotion.application.convert.BannerConvert;
-import cn.iocoder.mall.promotion.application.vo.admins.AdminBannerPageVO;
+import cn.iocoder.mall.promotion.application.vo.admins.AdminsBannerPageVO;
import cn.iocoder.mall.promotion.application.vo.admins.AdminsBannerVO;
import com.alibaba.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
@@ -32,9 +32,9 @@ public class AdminsBannerController {
@ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"),
@ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"),
})
- public CommonResult page(@RequestParam(value = "title", required = false) String title,
- @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo,
- @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
+ public CommonResult page(@RequestParam(value = "title", required = false) String title,
+ @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo,
+ @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
CommonResult result = bannerService.getBannerPage(new BannerPageDTO().setTitle(title).setPageNo(pageNo).setPageSize(pageSize));
return BannerConvert.INSTANCE.convert(result);
}
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsProductRecommendController.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsProductRecommendController.java
new file mode 100644
index 000000000..2f2d28021
--- /dev/null
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/controller/admins/AdminsProductRecommendController.java
@@ -0,0 +1,96 @@
+package cn.iocoder.mall.promotion.application.controller.admins;
+
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.admin.sdk.context.AdminSecurityContextHolder;
+import cn.iocoder.mall.promotion.api.ProductRecommendService;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendPageBO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendAddDTO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendPageDTO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendUpdateDTO;
+import cn.iocoder.mall.promotion.application.convert.ProductRecommendConvert;
+import cn.iocoder.mall.promotion.application.vo.admins.AdminsProductRecommendPageVO;
+import cn.iocoder.mall.promotion.application.vo.admins.AdminsProductRecommendVO;
+import com.alibaba.dubbo.config.annotation.Reference;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("admins/product_recommend")
+@Api("商品推荐模块")
+public class AdminsProductRecommendController {
+
+ @Reference(validation = "true")
+ private ProductRecommendService productRecommendService;
+
+ @GetMapping("/page")
+ @ApiOperation(value = "商品推荐分页")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "推荐类型", example = "1"),
+ @ApiImplicitParam(name = "pageNo", value = "页码,从 1 开始", example = "1"),
+ @ApiImplicitParam(name = "pageSize", value = "每页条数", required = true, example = "10"),
+ })
+ public CommonResult page(@RequestParam(value = "type", required = false) Integer type,
+ @RequestParam(value = "pageNo", defaultValue = "0") Integer pageNo,
+ @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
+ CommonResult result = productRecommendService.getProductRecommendPage(new ProductRecommendPageDTO().setType(type).setPageNo(pageNo).setPageSize(pageSize));
+ return ProductRecommendConvert.INSTANCE.convert(result);
+ }
+
+ @PostMapping("/add")
+ @ApiOperation(value = "创建商品推荐")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "type", value = "推荐类型", required = true, example = "1"),
+ @ApiImplicitParam(name = "productSpuId", value = "商品编号", required = true, example = "1"),
+ @ApiImplicitParam(name = "sort", value = "排序", required = true, example = "10"),
+ @ApiImplicitParam(name = "memo", value = "备注", example = "活动很牛逼"),
+ })
+ public CommonResult add(@RequestParam("type") Integer type,
+ @RequestParam("productSpuId") Integer productSpuId,
+ @RequestParam("sort") Integer sort,
+ @RequestParam(value = "memo", required = false) String memo) {
+ ProductRecommendAddDTO bannerAddDTO = new ProductRecommendAddDTO().setType(type).setProductSpuId(productSpuId)
+ .setSort(sort).setMemo(memo);
+ return ProductRecommendConvert.INSTANCE.convert2(productRecommendService.addProductRecommend(AdminSecurityContextHolder.getContext().getAdminId(), bannerAddDTO));
+ }
+
+ @PostMapping("/update")
+ @ApiOperation(value = "更新商品推荐")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "商品推荐编号", required = true, example = "1"),
+ @ApiImplicitParam(name = "type", value = "推荐类型", required = true, example = "1"),
+ @ApiImplicitParam(name = "productSpuId", value = "商品编号", required = true, example = "1"),
+ @ApiImplicitParam(name = "sort", value = "排序", required = true, example = "10"),
+ @ApiImplicitParam(name = "memo", value = "备注", example = "活动很牛逼"),
+ })
+ public CommonResult update(@RequestParam("id") Integer id,
+ @RequestParam("type") Integer type,
+ @RequestParam("productSpuId") Integer productSpuId,
+ @RequestParam("sort") Integer sort,
+ @RequestParam(value = "memo", required = false) String memo) {
+ ProductRecommendUpdateDTO bannerUpdateDTO = new ProductRecommendUpdateDTO().setId(id).setType(type).setProductSpuId(productSpuId)
+ .setSort(sort).setMemo(memo);
+ return productRecommendService.updateProductRecommend(AdminSecurityContextHolder.getContext().getAdminId(), bannerUpdateDTO);
+ }
+
+ @PostMapping("/update_status")
+ @ApiOperation(value = "更新商品推荐状态")
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "id", value = "商品推荐编号", required = true, example = "1"),
+ @ApiImplicitParam(name = "status", value = "状态。1 - 开启;2 - 禁用", required = true, example = "1"),
+ })
+ public CommonResult updateStatus(@RequestParam("id") Integer id,
+ @RequestParam("status") Integer status) {
+ return productRecommendService.updateProductRecommendStatus(AdminSecurityContextHolder.getContext().getAdminId(), id, status);
+ }
+
+ @PostMapping("/delete")
+ @ApiOperation(value = "删除商品推荐")
+ @ApiImplicitParam(name = "id", value = "商品推荐编号", required = true, example = "1")
+ public CommonResult delete(@RequestParam("id") Integer id) {
+ return productRecommendService.deleteProductRecommend(AdminSecurityContextHolder.getContext().getAdminId(), id);
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/BannerConvert.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/BannerConvert.java
index 7fbd35569..a7d5502fe 100644
--- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/BannerConvert.java
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/BannerConvert.java
@@ -3,7 +3,7 @@ package cn.iocoder.mall.promotion.application.convert;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.promotion.api.bo.BannerBO;
import cn.iocoder.mall.promotion.api.bo.BannerPageBO;
-import cn.iocoder.mall.promotion.application.vo.admins.AdminBannerPageVO;
+import cn.iocoder.mall.promotion.application.vo.admins.AdminsBannerPageVO;
import cn.iocoder.mall.promotion.application.vo.admins.AdminsBannerVO;
import cn.iocoder.mall.promotion.application.vo.users.UsersBannerVO;
import org.mapstruct.Mapper;
@@ -24,7 +24,7 @@ public interface BannerConvert {
CommonResult convert2(CommonResult result);
@Mappings({})
- CommonResult convert(CommonResult result);
+ CommonResult convert(CommonResult result);
@Mappings({})
List convertList(List banners);
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java
new file mode 100644
index 000000000..2c04fec01
--- /dev/null
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/convert/ProductRecommendConvert.java
@@ -0,0 +1,29 @@
+package cn.iocoder.mall.promotion.application.convert;
+
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendBO;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendPageBO;
+import cn.iocoder.mall.promotion.application.vo.admins.AdminsProductRecommendPageVO;
+import cn.iocoder.mall.promotion.application.vo.admins.AdminsProductRecommendVO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+@Mapper
+public interface ProductRecommendConvert {
+
+ ProductRecommendConvert INSTANCE = Mappers.getMapper(ProductRecommendConvert.class);
+
+ @Mappings({})
+ AdminsProductRecommendVO convert(ProductRecommendBO bannerBO);
+
+ @Mappings({})
+ CommonResult convert2(CommonResult result);
+
+ @Mappings({})
+ CommonResult convert(CommonResult result);
+
+// @Mappings({})
+// List convertList(List banners);
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminBannerPageVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsBannerPageVO.java
similarity index 79%
rename from promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminBannerPageVO.java
rename to promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsBannerPageVO.java
index f29f0f81d..7f5595e7f 100644
--- a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminBannerPageVO.java
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsBannerPageVO.java
@@ -6,7 +6,7 @@ import io.swagger.annotations.ApiModelProperty;
import java.util.List;
@ApiModel("Banner 分页 VO")
-public class AdminBannerPageVO {
+public class AdminsBannerPageVO {
@ApiModelProperty(value = "Banner 数组")
private List list;
@@ -17,7 +17,7 @@ public class AdminBannerPageVO {
return list;
}
- public AdminBannerPageVO setList(List list) {
+ public AdminsBannerPageVO setList(List list) {
this.list = list;
return this;
}
@@ -26,7 +26,7 @@ public class AdminBannerPageVO {
return total;
}
- public AdminBannerPageVO setTotal(Integer total) {
+ public AdminsBannerPageVO setTotal(Integer total) {
this.total = total;
return this;
}
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendPageVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendPageVO.java
new file mode 100644
index 000000000..e774b8429
--- /dev/null
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendPageVO.java
@@ -0,0 +1,34 @@
+package cn.iocoder.mall.promotion.application.vo.admins;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+@ApiModel("商品推荐分页 VO")
+public class AdminsProductRecommendPageVO {
+
+ @ApiModelProperty(value = "商品推荐数组")
+ private List list;
+ @ApiModelProperty(value = "商品推荐总数")
+ private Integer total;
+
+ public List getList() {
+ return list;
+ }
+
+ public AdminsProductRecommendPageVO setList(List list) {
+ this.list = list;
+ return this;
+ }
+
+ public Integer getTotal() {
+ return total;
+ }
+
+ public AdminsProductRecommendPageVO setTotal(Integer total) {
+ this.total = total;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendVO.java b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendVO.java
new file mode 100644
index 000000000..d95a6051a
--- /dev/null
+++ b/promotion/promotion-application/src/main/java/cn/iocoder/mall/promotion/application/vo/admins/AdminsProductRecommendVO.java
@@ -0,0 +1,88 @@
+package cn.iocoder.mall.promotion.application.vo.admins;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+@ApiModel("商品推荐 VO")
+public class AdminsProductRecommendVO {
+
+ @ApiModelProperty(value = "编号", required = true, example = "1")
+ private Integer id;
+ @ApiModelProperty(value = "推荐类型", required = true, example = "1")
+ private Integer type;
+ @ApiModelProperty(value = "商品编号", required = true, example = "1")
+ private Integer productSpuId;
+ @ApiModelProperty(value = "排序", required = true, example = "10")
+ private Integer sort;
+ @ApiModelProperty(value = "状态", required = true, example = "1")
+ private Integer status;
+ @ApiModelProperty(value = "备注", required = true, example = "这个活动很牛逼")
+ private String memo;
+ @ApiModelProperty(value = "创建时间", required = true, example = "时间戳格式")
+ private Date createTime;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public AdminsProductRecommendVO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+
+ public AdminsProductRecommendVO setType(Integer type) {
+ this.type = type;
+ return this;
+ }
+
+ public Integer getProductSpuId() {
+ return productSpuId;
+ }
+
+ public AdminsProductRecommendVO setProductSpuId(Integer productSpuId) {
+ this.productSpuId = productSpuId;
+ return this;
+ }
+
+ public Integer getSort() {
+ return sort;
+ }
+
+ public AdminsProductRecommendVO setSort(Integer sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public AdminsProductRecommendVO setStatus(Integer status) {
+ this.status = status;
+ return this;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public AdminsProductRecommendVO setMemo(String memo) {
+ this.memo = memo;
+ return this;
+ }
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public AdminsProductRecommendVO setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ return this;
+ }
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/ProductRecommendService.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/ProductRecommendService.java
new file mode 100644
index 000000000..9a87fbf10
--- /dev/null
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/ProductRecommendService.java
@@ -0,0 +1,26 @@
+package cn.iocoder.mall.promotion.api;
+
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendBO;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendPageBO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendAddDTO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendPageDTO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendUpdateDTO;
+
+import java.util.List;
+
+public interface ProductRecommendService {
+
+ CommonResult> getProductRecommendList(Integer type, Integer status);
+
+ CommonResult getProductRecommendPage(ProductRecommendPageDTO productRecommendPageDTO);
+
+ CommonResult addProductRecommend(Integer adminId, ProductRecommendAddDTO productRecommendAddDTO);
+
+ CommonResult updateProductRecommend(Integer adminId, ProductRecommendUpdateDTO productRecommendUpdateDTO);
+
+ CommonResult updateProductRecommendStatus(Integer adminId, Integer productRecommendId, Integer status);
+
+ CommonResult deleteProductRecommend(Integer adminId, Integer productRecommendId);
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendBO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendBO.java
new file mode 100644
index 000000000..6abc7c560
--- /dev/null
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendBO.java
@@ -0,0 +1,106 @@
+package cn.iocoder.mall.promotion.api.bo;
+
+import java.util.Date;
+
+/**
+ * 商品推荐 BO
+ */
+public class ProductRecommendBO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 类型
+ *
+ * {@link cn.iocoder.mall.promotion.api.constant.ProductRecommendType}
+ */
+ private Integer type;
+ /**
+ * 商品 Spu 编号
+ */
+ private Integer productSpuId;
+ /**
+ * 排序
+ */
+ private Integer sort;
+ /**
+ * 状态
+ *
+ * {@link cn.iocoder.common.framework.constant.CommonStatusEnum}
+ */
+ private Integer status;
+ /**
+ * 备注
+ */
+ private String memo;
+ /**
+ * 创建时间
+ */
+ private Date createTime;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public ProductRecommendBO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+
+ public ProductRecommendBO setType(Integer type) {
+ this.type = type;
+ return this;
+ }
+
+ public Integer getProductSpuId() {
+ return productSpuId;
+ }
+
+ public ProductRecommendBO setProductSpuId(Integer productSpuId) {
+ this.productSpuId = productSpuId;
+ return this;
+ }
+
+ public Integer getSort() {
+ return sort;
+ }
+
+ public ProductRecommendBO setSort(Integer sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public ProductRecommendBO setStatus(Integer status) {
+ this.status = status;
+ return this;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public ProductRecommendBO setMemo(String memo) {
+ this.memo = memo;
+ return this;
+ }
+
+ public Date getCreateTime() {
+ return createTime;
+ }
+
+ public ProductRecommendBO setCreateTime(Date createTime) {
+ this.createTime = createTime;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendPageBO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendPageBO.java
new file mode 100644
index 000000000..30d36c5dc
--- /dev/null
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/bo/ProductRecommendPageBO.java
@@ -0,0 +1,34 @@
+package cn.iocoder.mall.promotion.api.bo;
+
+import java.util.List;
+
+public class ProductRecommendPageBO {
+
+ /**
+ * ProductRecommend 数组
+ */
+ private List list;
+ /**
+ * 总量
+ */
+ private Integer total;
+
+ public List getList() {
+ return list;
+ }
+
+ public ProductRecommendPageBO setList(List list) {
+ this.list = list;
+ return this;
+ }
+
+ public Integer getTotal() {
+ return total;
+ }
+
+ public ProductRecommendPageBO setTotal(Integer total) {
+ this.total = total;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/ProductRecommendType.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/ProductRecommendType.java
new file mode 100644
index 000000000..302e69e31
--- /dev/null
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/ProductRecommendType.java
@@ -0,0 +1,43 @@
+package cn.iocoder.mall.promotion.api.constant;
+
+/**
+ * 商品推荐类型
+ */
+public enum ProductRecommendType {
+
+ HOT(1, "热卖推荐"),
+ NEW(2, "新品推荐"),
+
+ ;
+
+ /**
+ * 状态值
+ */
+ private final Integer value;
+ /**
+ * 状态名
+ */
+ private final String name;
+
+ ProductRecommendType(Integer value, String name) {
+ this.value = value;
+ this.name = name;
+ }
+
+ public Integer getValue() {
+ return value;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public static boolean isValid(Integer status) {
+ if (status == null) {
+ return false;
+ }
+ return HOT.value.equals(status)
+ || NEW.value.equals(status);
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java
index 9f98a271e..24d19f848 100644
--- a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/constant/PromotionErrorCodeEnum.java
@@ -8,10 +8,16 @@ package cn.iocoder.mall.promotion.api.constant;
public enum PromotionErrorCodeEnum {
// ========== Banner 模块 ==========
- BANNER_NOT_EXISTS(1002002000, "账号不存在"),
+ BANNER_NOT_EXISTS(1006000000, "账号不存在"),
+
+ // ========== PRODUCT RECOMMEND 模块 ==========
+ PRODUCT_RECOMMEND_NOT_EXISTS(1006001000, "商品推荐不存在"),
+ PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS(1006001001, "商品不存在"),
+ PRODUCT_RECOMMEND_EXISTS(1006001002, "该商品推荐已经存在"),
;
+
private final int code;
private final String message;
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendAddDTO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendAddDTO.java
new file mode 100644
index 000000000..af042b409
--- /dev/null
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendAddDTO.java
@@ -0,0 +1,57 @@
+package cn.iocoder.mall.promotion.api.dto;
+
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 商品推荐添加 DTO
+ */
+public class ProductRecommendAddDTO {
+
+ @NotNull(message = "推荐类型不能为空")
+ private Integer type;
+ @NotNull(message = "商品编号不能为空")
+ private Integer productSpuId;
+ @NotNull(message = "排序不能为空")
+ private Integer sort;
+ @Length(max = 255, message = "备注最大长度为 255 位")
+ private String memo;
+
+ public Integer getType() {
+ return type;
+ }
+
+ public ProductRecommendAddDTO setType(Integer type) {
+ this.type = type;
+ return this;
+ }
+
+ public Integer getProductSpuId() {
+ return productSpuId;
+ }
+
+ public ProductRecommendAddDTO setProductSpuId(Integer productSpuId) {
+ this.productSpuId = productSpuId;
+ return this;
+ }
+
+ public Integer getSort() {
+ return sort;
+ }
+
+ public ProductRecommendAddDTO setSort(Integer sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public ProductRecommendAddDTO setMemo(String memo) {
+ this.memo = memo;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendPageDTO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendPageDTO.java
new file mode 100644
index 000000000..21567327a
--- /dev/null
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendPageDTO.java
@@ -0,0 +1,44 @@
+package cn.iocoder.mall.promotion.api.dto;
+
+import javax.validation.constraints.NotNull;
+
+public class ProductRecommendPageDTO {
+
+ /**
+ * 推荐类型
+ */
+ private Integer type;
+
+ @NotNull(message = "页码不能为空")
+ private Integer pageNo;
+ @NotNull(message = "每页条数不能为空")
+ private Integer pageSize;
+
+ public Integer getPageNo() {
+ return pageNo;
+ }
+
+ public ProductRecommendPageDTO setPageNo(Integer pageNo) {
+ this.pageNo = pageNo;
+ return this;
+ }
+
+ public Integer getPageSize() {
+ return pageSize;
+ }
+
+ public ProductRecommendPageDTO setPageSize(Integer pageSize) {
+ this.pageSize = pageSize;
+ return this;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+
+ public ProductRecommendPageDTO setType(Integer type) {
+ this.type = type;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendUpdateDTO.java b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendUpdateDTO.java
new file mode 100644
index 000000000..779696686
--- /dev/null
+++ b/promotion/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/dto/ProductRecommendUpdateDTO.java
@@ -0,0 +1,68 @@
+package cn.iocoder.mall.promotion.api.dto;
+
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 商品推荐更新 DTO
+ */
+public class ProductRecommendUpdateDTO {
+
+ @NotNull(message = "编号不能为空")
+ private Integer id;
+ @NotNull(message = "类型不能为空")
+ private Integer type;
+ @NotNull(message = "商品编号不能为空")
+ private Integer productSpuId;
+ @NotNull(message = "排序不能为空")
+ private Integer sort;
+ @Length(max = 255, message = "备注最大长度为 255 位")
+ private String memo;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public ProductRecommendUpdateDTO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+
+ public ProductRecommendUpdateDTO setType(Integer type) {
+ this.type = type;
+ return this;
+ }
+
+ public Integer getProductSpuId() {
+ return productSpuId;
+ }
+
+ public ProductRecommendUpdateDTO setProductSpuId(Integer productSpuId) {
+ this.productSpuId = productSpuId;
+ return this;
+ }
+
+ public Integer getSort() {
+ return sort;
+ }
+
+ public ProductRecommendUpdateDTO setSort(Integer sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public ProductRecommendUpdateDTO setMemo(String memo) {
+ this.memo = memo;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/ProductRecommendConvert.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/ProductRecommendConvert.java
new file mode 100644
index 000000000..552e6246a
--- /dev/null
+++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/convert/ProductRecommendConvert.java
@@ -0,0 +1,30 @@
+package cn.iocoder.mall.promotion.biz.convert;
+
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendBO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendAddDTO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendUpdateDTO;
+import cn.iocoder.mall.promotion.biz.dataobject.ProductRecommendDO;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mappings;
+import org.mapstruct.factory.Mappers;
+
+import java.util.List;
+
+@Mapper
+public interface ProductRecommendConvert {
+
+ ProductRecommendConvert INSTANCE = Mappers.getMapper(ProductRecommendConvert.class);
+
+ @Mappings({})
+ ProductRecommendBO convertToBO(ProductRecommendDO banner);
+
+ @Mappings({})
+ List convertToBO(List bannerList);
+
+ @Mappings({})
+ ProductRecommendDO convert(ProductRecommendAddDTO bannerAddDTO);
+
+ @Mappings({})
+ ProductRecommendDO convert(ProductRecommendUpdateDTO bannerUpdateDTO);
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dao/ProductRecommendMapper.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dao/ProductRecommendMapper.java
new file mode 100644
index 000000000..f8a66228c
--- /dev/null
+++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dao/ProductRecommendMapper.java
@@ -0,0 +1,30 @@
+package cn.iocoder.mall.promotion.biz.dao;
+
+import cn.iocoder.mall.promotion.biz.dataobject.ProductRecommendDO;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface ProductRecommendMapper {
+
+ ProductRecommendDO selectById(@Param("id") Integer id);
+
+ ProductRecommendDO selectByProductSpuIdAndType(@Param("productSpuId") Integer productSpuId,
+ @Param("type") Integer type);
+
+ List selectListByTypeAndStatus(@Param("type") Integer type,
+ @Param("status") Integer status);
+
+ List selectPageByType(@Param("type") Integer type,
+ @Param("offset") Integer offset,
+ @Param("limit") Integer limit);
+
+ Integer selectCountByType(@Param("type") Integer type);
+
+ void insert(ProductRecommendDO bannerDO);
+
+ int update(ProductRecommendDO bannerDO);
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/ProductRecommendDO.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/ProductRecommendDO.java
new file mode 100644
index 000000000..4ae5f2a28
--- /dev/null
+++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/dataobject/ProductRecommendDO.java
@@ -0,0 +1,94 @@
+package cn.iocoder.mall.promotion.biz.dataobject;
+
+import cn.iocoder.common.framework.dataobject.DeletableDO;
+
+/**
+ * 商品推荐 DO
+ */
+public class ProductRecommendDO extends DeletableDO {
+
+ /**
+ * 编号
+ */
+ private Integer id;
+ /**
+ * 类型
+ *
+ * {@link cn.iocoder.mall.promotion.api.constant.ProductRecommendType}
+ */
+ private Integer type;
+ /**
+ * 商品 Spu 编号
+ */
+ private Integer productSpuId;
+ // TODO 芋艿,商品 spu 名
+ /**
+ * 排序
+ */
+ private Integer sort;
+ /**
+ * 状态
+ *
+ * {@link cn.iocoder.common.framework.constant.CommonStatusEnum}
+ */
+ private Integer status;
+ /**
+ * 备注
+ */
+ private String memo;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public ProductRecommendDO setId(Integer id) {
+ this.id = id;
+ return this;
+ }
+
+ public Integer getType() {
+ return type;
+ }
+
+ public ProductRecommendDO setType(Integer type) {
+ this.type = type;
+ return this;
+ }
+
+ public Integer getProductSpuId() {
+ return productSpuId;
+ }
+
+ public ProductRecommendDO setProductSpuId(Integer productSpuId) {
+ this.productSpuId = productSpuId;
+ return this;
+ }
+
+ public Integer getSort() {
+ return sort;
+ }
+
+ public ProductRecommendDO setSort(Integer sort) {
+ this.sort = sort;
+ return this;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public ProductRecommendDO setStatus(Integer status) {
+ this.status = status;
+ return this;
+ }
+
+ public String getMemo() {
+ return memo;
+ }
+
+ public ProductRecommendDO setMemo(String memo) {
+ this.memo = memo;
+ return this;
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java
index 6db630fc4..b408ba87c 100644
--- a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java
+++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/BannerServiceImpl.java
@@ -75,6 +75,10 @@ public class BannerServiceImpl implements BannerService {
if (!CommonStatusEnum.isValid(status)) {
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓
}
+ // 校验 Banner 存在
+ if (bannerMapper.selectById(bannerId) == null) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.BANNER_NOT_EXISTS.getCode());
+ }
// 更新到数据库
BannerDO updateBanner = new BannerDO().setId(bannerId).setStatus(status);
bannerMapper.update(updateBanner);
diff --git a/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/ProductRecommendServiceImpl.java b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/ProductRecommendServiceImpl.java
new file mode 100644
index 000000000..7fc773ba8
--- /dev/null
+++ b/promotion/promotion-service-impl/src/main/java/cn/iocoder/mall/promotion/biz/service/ProductRecommendServiceImpl.java
@@ -0,0 +1,133 @@
+package cn.iocoder.mall.promotion.biz.service;
+
+import cn.iocoder.common.framework.constant.CommonStatusEnum;
+import cn.iocoder.common.framework.constant.DeletedStatusEnum;
+import cn.iocoder.common.framework.constant.SysErrorCodeEnum;
+import cn.iocoder.common.framework.util.ServiceExceptionUtil;
+import cn.iocoder.common.framework.vo.CommonResult;
+import cn.iocoder.mall.product.api.ProductSpuService;
+import cn.iocoder.mall.promotion.api.ProductRecommendService;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendBO;
+import cn.iocoder.mall.promotion.api.bo.ProductRecommendPageBO;
+import cn.iocoder.mall.promotion.api.constant.PromotionErrorCodeEnum;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendAddDTO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendPageDTO;
+import cn.iocoder.mall.promotion.api.dto.ProductRecommendUpdateDTO;
+import cn.iocoder.mall.promotion.biz.convert.ProductRecommendConvert;
+import cn.iocoder.mall.promotion.biz.dao.ProductRecommendMapper;
+import cn.iocoder.mall.promotion.biz.dataobject.ProductRecommendDO;
+import com.alibaba.dubbo.config.annotation.Reference;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
+
+@Service // 实际上不用添加。添加的原因是,必须 Spring 报错提示
+@com.alibaba.dubbo.config.annotation.Service(validation = "true")
+public class ProductRecommendServiceImpl implements ProductRecommendService {
+
+ @Reference(validation = "true")
+ private ProductSpuService productSpuService;
+
+ @Autowired
+ private ProductRecommendMapper productRecommendMapper;
+
+ @Override
+ public CommonResult> getProductRecommendList(Integer type, Integer status) {
+ List productRecommends = productRecommendMapper.selectListByTypeAndStatus(type, status);
+ return CommonResult.success(ProductRecommendConvert.INSTANCE.convertToBO(productRecommends));
+ }
+
+ @Override
+ public CommonResult getProductRecommendPage(ProductRecommendPageDTO productRecommendPageDTO) {
+ ProductRecommendPageBO productRecommendPageBO = new ProductRecommendPageBO();
+ // 查询分页数据
+ int offset = (productRecommendPageDTO.getPageNo() - 1) * productRecommendPageDTO.getPageSize();
+ productRecommendPageBO.setList(ProductRecommendConvert.INSTANCE.convertToBO(productRecommendMapper.selectPageByType(productRecommendPageDTO.getType(),
+ offset, productRecommendPageDTO.getPageSize())));
+ // 查询分页总数
+ productRecommendPageBO.setTotal(productRecommendMapper.selectCountByType(productRecommendPageDTO.getType()));
+ return CommonResult.success(productRecommendPageBO);
+ }
+
+ @Override
+ public CommonResult addProductRecommend(Integer adminId, ProductRecommendAddDTO productRecommendAddDTO) {
+ // 校验参数
+ if (!CommonStatusEnum.isValid(productRecommendAddDTO.getType())) {
+ return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "推荐类型必须是新品(1)或热卖(2)"); // TODO 有点搓
+ }
+ // 校验商品不存在
+ if (productSpuService.getProductSpu(productRecommendAddDTO.getProductSpuId()) == null) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
+ }
+ // 校验商品是否已经推荐
+ if (productRecommendMapper.selectByProductSpuIdAndType(productRecommendAddDTO.getProductSpuId(), productRecommendAddDTO.getType()) != null) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_EXISTS.getCode());
+ }
+ // 保存到数据库
+ ProductRecommendDO productRecommend = ProductRecommendConvert.INSTANCE.convert(productRecommendAddDTO).setStatus(CommonStatusEnum.ENABLE.getValue());
+ productRecommend.setDeleted(DeletedStatusEnum.DELETED_NO.getValue()).setCreateTime(new Date());
+ productRecommendMapper.insert(productRecommend);
+ // 返回成功
+ return CommonResult.success(ProductRecommendConvert.INSTANCE.convertToBO(productRecommend));
+ }
+
+ @Override
+ public CommonResult updateProductRecommend(Integer adminId, ProductRecommendUpdateDTO productRecommendUpdateDTO) {
+ // 校验参数
+ if (!CommonStatusEnum.isValid(productRecommendUpdateDTO.getType())) {
+ return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "推荐类型必须是新品(1)或热卖(2)"); // TODO 有点搓
+ }
+ // 校验更新的商品推荐存在
+ if (productRecommendMapper.selectById(productRecommendUpdateDTO.getId()) == null) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
+ }
+ // 校验商品不存在
+ if (productSpuService.getProductSpu(productRecommendUpdateDTO.getProductSpuId()) == null) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
+ }
+ // 校验商品是否已经推荐
+ ProductRecommendDO existProductRecommend = productRecommendMapper.selectByProductSpuIdAndType(productRecommendUpdateDTO.getProductSpuId(), productRecommendUpdateDTO.getType());
+ if (existProductRecommend != null && !existProductRecommend.getId().equals(productRecommendUpdateDTO.getId())) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_EXISTS.getCode());
+ }
+ // 更新到数据库
+ ProductRecommendDO updateProductRecommend = ProductRecommendConvert.INSTANCE.convert(productRecommendUpdateDTO);
+ productRecommendMapper.update(updateProductRecommend);
+ // 返回成功
+ return CommonResult.success(true);
+ }
+
+ @Override
+ public CommonResult updateProductRecommendStatus(Integer adminId, Integer productRecommendId, Integer status) {
+ // 校验参数
+ if (!CommonStatusEnum.isValid(status)) {
+ return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "变更状态必须是开启(1)或关闭(2)"); // TODO 有点搓
+ }
+ // 校验更新的商品推荐存在
+ if (productRecommendMapper.selectById(productRecommendId) == null) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
+ }
+ // 更新到数据库
+ ProductRecommendDO updateProductRecommend = new ProductRecommendDO().setId(productRecommendId).setStatus(status);
+ productRecommendMapper.update(updateProductRecommend);
+ // 返回成功
+ return CommonResult.success(true);
+ }
+
+ @Override
+ public CommonResult deleteProductRecommend(Integer adminId, Integer productRecommendId) {
+ // 校验更新的商品推荐存在
+ if (productRecommendMapper.selectById(productRecommendId) == null) {
+ return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
+ }
+ // 更新到数据库
+ ProductRecommendDO updateProductRecommend = new ProductRecommendDO().setId(productRecommendId);
+ updateProductRecommend.setDeleted(DeletedStatusEnum.DELETED_YES.getValue());
+ productRecommendMapper.update(updateProductRecommend);
+ // 返回成功
+ return CommonResult.success(true);
+ }
+
+}
\ No newline at end of file
diff --git a/promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml b/promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml
new file mode 100644
index 000000000..939e6926d
--- /dev/null
+++ b/promotion/promotion-service-impl/src/main/resources/mapper/ProductRecommendMapper.xml
@@ -0,0 +1,125 @@
+
+
+
+
+
+ id, type, product_spu_id, sort,
+ status, memo, create_time
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ INSERT INTO product_recommend (
+ type, product_spu_id, sort, status, memo,
+ create_time, deleted
+ ) VALUES (
+ #{type}, #{productSpuId}, #{sort}, #{status}, #{memo},
+ #{createTime}, #{deleted}
+ )
+
+
+
+ UPDATE product_recommend
+
+
+ type = #{type},
+
+
+ product_spu_id = #{productSpuId},
+
+
+ sort = #{sort},
+
+
+ status = #{status},
+
+
+ memo = #{memo},
+
+
+ deleted = #{deleted}
+
+
+ WHERE id = #{id}
+
+
+
\ No newline at end of file