diff --git a/admin-web/config/proxy/proxy.dev.js b/admin-web/config/proxy/proxy.dev.js
index f8fc22be5..9f7a52d6f 100644
--- a/admin-web/config/proxy/proxy.dev.js
+++ b/admin-web/config/proxy/proxy.dev.js
@@ -25,4 +25,16 @@ export default {
changeOrigin: true,
pathRewrite: {},
},
+ '/user-api/': {
+ // target: 'http://180.167.213.26:18085/',
+ target: 'http://127.0.0.1:18082/',
+ changeOrigin: true,
+ pathRewrite: {},
+ },
+ '/pay-api/': {
+ // target: 'http://180.167.213.26:18085/',
+ target: 'http://127.0.0.1:18084/',
+ changeOrigin: true,
+ pathRewrite: {},
+ },
};
diff --git a/admin-web/config/proxy/proxy.prod.js b/admin-web/config/proxy/proxy.prod.js
index f8cef2eee..a8d5977a2 100644
--- a/admin-web/config/proxy/proxy.prod.js
+++ b/admin-web/config/proxy/proxy.prod.js
@@ -6,11 +6,21 @@ export default {
changeOrigin: true,
pathRewrite: {},
},
+ '/product-api/': {
+ target: 'http://api.shop.iocoder.cn:18099/product-api',
+ changeOrigin: true,
+ pathRewrite: {},
+ },
'/order-api/': {
target: 'http://api.shop.iocoder.cn:18099/order-api',
changeOrigin: true,
pathRewrite: {},
},
+ '/promotion-api/': {
+ target: 'http://api.shop.iocoder.cn:18099/promotion-api',
+ changeOrigin: true,
+ pathRewrite: {},
+ },
'/pay-api/': {
target: 'http://api.shop.iocoder.cn:18099/pay-api',
changeOrigin: true,
diff --git a/admin-web/config/router.config.js b/admin-web/config/router.config.js
index d8426e9e0..476db0680 100644
--- a/admin-web/config/router.config.js
+++ b/admin-web/config/router.config.js
@@ -58,6 +58,19 @@ export default [
},
],
},
+ // user
+ {
+ path: '/member', // TODO 芋艿,后面调整
+ name: 'user',
+ icon: 'user',
+ routes: [
+ {
+ path: '/member/user-list',
+ name: 'user-list',
+ component: './User/UserList',
+ },
+ ],
+ },
// order
{
path: 'order',
@@ -142,6 +155,24 @@ export default [
}
],
},
+ // pay
+ {
+ path: '/pay',
+ name: 'pay',
+ icon: 'user',
+ routes: [
+ {
+ path: '/pay/transaction-list',
+ name: 'pay-transaction-list',
+ component: './Pay/PayTransactionList',
+ },
+ {
+ path: '/pay/refund-list',
+ name: 'pay-refund-list',
+ component: './Pay/PayRefundList',
+ },
+ ],
+ },
{
path: '/dashboard',
name: 'dashboard',
diff --git a/admin-web/src/locales/zh-CN/menu.js b/admin-web/src/locales/zh-CN/menu.js
index 86202bdbd..849ae3b8c 100644
--- a/admin-web/src/locales/zh-CN/menu.js
+++ b/admin-web/src/locales/zh-CN/menu.js
@@ -60,4 +60,9 @@ export default {
'menu.promotion.coupon-card-template-list': '优惠劵管理',
'menu.promotion.time-limit-discount-list': '限时折扣',
'menu.promotion.full-privilege-list': '满减送',
+ // 会员相关
+ 'menu.user.user-list': '会员资料',
+ // 支付相关
+ 'menu.pay.pay-transaction-list': '支付单',
+ 'menu.pay.pay-refund-list': '退款单',
};
diff --git a/admin-web/src/models/pay/payRefundList.js b/admin-web/src/models/pay/payRefundList.js
new file mode 100644
index 000000000..067ff8ad4
--- /dev/null
+++ b/admin-web/src/models/pay/payRefundList.js
@@ -0,0 +1,97 @@
+import { message } from 'antd';
+import { productSpuPage, productSpuUpdateSort } from '../../services/product';
+import {routerRedux} from "dva/router";
+import PaginationHelper from '../../../helpers/PaginationHelper';
+import {getPromotionActivityPage} from "../../services/promotion";
+import {queryPayRefundPage, queryPayTransactionPage} from "../../services/pay";
+
+const SEARCH_PARAMS_DEFAULT = {
+ createBeginTime: undefined,
+ createEndTime: undefined,
+ finishBeginTime: undefined,
+ finishEndTime: undefined,
+ status: undefined,
+ payChannel: undefined,
+};
+
+export default {
+ namespace: 'payRefundList',
+
+ state: {
+ // 分页列表相关
+ list: [],
+ listLoading: false,
+ pagination: PaginationHelper.defaultPaginationConfig,
+ searchParams: SEARCH_PARAMS_DEFAULT,
+
+ // 添加 or 修改表单相关
+ },
+
+ effects: {
+ *page({ payload }, { call, put }) {
+ // const { queryParams } = payload;
+ // const response = yield call(productSpuPage, payload);
+ // message.info('查询成功!');
+ // yield put({
+ // type: 'treeSuccess',
+ // payload: {
+ // list: response.data,
+ // },
+ // });
+
+ // 显示加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: true,
+ });
+
+ // 请求
+ const response = yield call(queryPayRefundPage, payload);
+ // 响应
+ yield put({
+ type: 'setAll',
+ payload: {
+ list: response.data.list,
+ pagination: PaginationHelper.formatPagination(response.data, payload),
+ searchParams: {
+ createBeginTime: payload.createBeginTime,
+ createEndTime: payload.createEndTime,
+ finishBeginTime: payload.finishBeginTime,
+ finishEndTime: payload.finishEndTime,
+ status: payload.status,
+ payChannel: payload.payChannel,
+ }
+ },
+ });
+
+ // 隐藏加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: false,
+ });
+ },
+ },
+
+ reducers: {
+ treeSuccess(state, { payload }) {
+ return {
+ ...state,
+ ...payload,
+ };
+ },
+ // 修改加载中的状态
+ changeListLoading(state, { payload }) {
+ return {
+ ...state,
+ listLoading: payload,
+ };
+ },
+ // 设置所有属性
+ setAll(state, { payload }) {
+ return {
+ ...state,
+ ...payload,
+ };
+ }
+ },
+};
diff --git a/admin-web/src/models/pay/payTransactionList.js b/admin-web/src/models/pay/payTransactionList.js
new file mode 100644
index 000000000..0c0d2e5fc
--- /dev/null
+++ b/admin-web/src/models/pay/payTransactionList.js
@@ -0,0 +1,101 @@
+import { message } from 'antd';
+import { productSpuPage, productSpuUpdateSort } from '../../services/product';
+import {routerRedux} from "dva/router";
+import PaginationHelper from '../../../helpers/PaginationHelper';
+import {getPromotionActivityPage} from "../../services/promotion";
+import {queryPayTransactionPage} from "../../services/pay";
+
+const SEARCH_PARAMS_DEFAULT = {
+ createBeginTime: undefined,
+ createEndTime: undefined,
+ paymentBeginTime: undefined,
+ paymentEndTime: undefined,
+ status: undefined,
+ hasRefund: undefined,
+ payChannel: undefined,
+ orderSubject: '',
+};
+
+export default {
+ namespace: 'payTransactionList',
+
+ state: {
+ // 分页列表相关
+ list: [],
+ listLoading: false,
+ pagination: PaginationHelper.defaultPaginationConfig,
+ searchParams: SEARCH_PARAMS_DEFAULT,
+
+ // 添加 or 修改表单相关
+ },
+
+ effects: {
+ *page({ payload }, { call, put }) {
+ // const { queryParams } = payload;
+ // const response = yield call(productSpuPage, payload);
+ // message.info('查询成功!');
+ // yield put({
+ // type: 'treeSuccess',
+ // payload: {
+ // list: response.data,
+ // },
+ // });
+
+ // 显示加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: true,
+ });
+
+ // 请求
+ const response = yield call(queryPayTransactionPage, payload);
+ // 响应
+ yield put({
+ type: 'setAll',
+ payload: {
+ list: response.data.list,
+ pagination: PaginationHelper.formatPagination(response.data, payload),
+ searchParams: {
+ createBeginTime: payload.createBeginTime,
+ createEndTime: payload.createEndTime,
+ paymentBeginTime: payload.paymentBeginTime,
+ paymentEndTime: payload.paymentEndTime,
+ status: payload.status,
+ hasRefund: payload.hasRefund,
+ payChannel: payload.payChannel,
+ orderSubject: payload.orderSubject,
+ }
+ },
+ });
+
+ // 隐藏加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: false,
+ });
+ },
+ },
+
+ reducers: {
+ treeSuccess(state, { payload }) {
+ return {
+ ...state,
+ ...payload,
+ };
+ },
+ // 修改加载中的状态
+ changeListLoading(state, { payload }) {
+ return {
+ ...state,
+ listLoading: payload,
+ };
+ },
+ // 设置所有属性
+ setAll(state, { payload }) {
+ return {
+ ...state,
+ ...payload,
+ };
+ }
+ },
+};
diff --git a/admin-web/src/models/promotion/fullPrivilegeList.js b/admin-web/src/models/promotion/fullPrivilegeList.js
index a2cda79a7..4248c092b 100644
--- a/admin-web/src/models/promotion/fullPrivilegeList.js
+++ b/admin-web/src/models/promotion/fullPrivilegeList.js
@@ -5,9 +5,14 @@ import PaginationHelper from '../../../helpers/PaginationHelper';
import {getPromotionActivityPage} from "../../services/promotion";
const SEARCH_PARAMS_DEFAULT = {
- title: '',
- activityType: 2,
- status: 'ALL',
+ createBeginTime: undefined,
+ createEndTime: undefined,
+ paymentBeginTime: undefined,
+ paymentEndTime: undefined,
+ status: undefined,
+ hasRefund: undefined,
+ payChannel: undefined,
+ orderSubject: '',
};
export default {
@@ -63,36 +68,6 @@ export default {
payload: false,
});
},
- *updateSort({ payload }, { call, put }) {
- // 显示加载中
- yield put({
- type: 'changeSortModalLoading',
- payload: true,
- });
-
- // 请求
- const { callback, body } = payload;
- // 响应
- const response = yield call(productSpuUpdateSort, body);
- if(response.code === 0) {
- if (callback) {
- callback(response);
- }
- yield put({
- type: 'page',
- payload: {
- ...this.state.pagination,
- ...this.state.searchParams,
- },
- });
- }
-
- // 隐藏加载中
- yield put({
- type: 'changeSortModalLoading',
- payload: false,
- });
- },
},
reducers: {
@@ -103,12 +78,6 @@ export default {
};
},
// 修改加载中的状态
- changeSortModalLoading(state, { payload }) {
- return {
- ...state,
- sortModalLoading: payload,
- };
- },
changeListLoading(state, { payload }) {
return {
...state,
diff --git a/admin-web/src/models/promotion/timeLimitedDiscountList.js b/admin-web/src/models/promotion/timeLimitedDiscountList.js
index e69773cfb..d134733fe 100644
--- a/admin-web/src/models/promotion/timeLimitedDiscountList.js
+++ b/admin-web/src/models/promotion/timeLimitedDiscountList.js
@@ -63,36 +63,6 @@ export default {
payload: false,
});
},
- *updateSort({ payload }, { call, put }) {
- // 显示加载中
- yield put({
- type: 'changeSortModalLoading',
- payload: true,
- });
-
- // 请求
- const { callback, body } = payload;
- // 响应
- const response = yield call(productSpuUpdateSort, body);
- if(response.code === 0) {
- if (callback) {
- callback(response);
- }
- yield put({
- type: 'page',
- payload: {
- ...this.state.pagination,
- ...this.state.searchParams,
- },
- });
- }
-
- // 隐藏加载中
- yield put({
- type: 'changeSortModalLoading',
- payload: false,
- });
- },
},
reducers: {
@@ -103,12 +73,6 @@ export default {
};
},
// 修改加载中的状态
- changeSortModalLoading(state, { payload }) {
- return {
- ...state,
- sortModalLoading: payload,
- };
- },
changeListLoading(state, { payload }) {
return {
...state,
diff --git a/admin-web/src/models/user/userList.js b/admin-web/src/models/user/userList.js
new file mode 100644
index 000000000..26e312457
--- /dev/null
+++ b/admin-web/src/models/user/userList.js
@@ -0,0 +1,89 @@
+import { message } from 'antd';
+import { productSpuPage, productSpuUpdateSort } from '../../services/product';
+import {routerRedux} from "dva/router";
+import PaginationHelper from '../../../helpers/PaginationHelper';
+import {getPromotionActivityPage} from "../../services/promotion";
+import {queryUserPage} from "../../services/user";
+
+const SEARCH_PARAMS_DEFAULT = {
+ nickname: '',
+ status: 1,
+};
+
+export default {
+ namespace: 'userList',
+
+ state: {
+ // 分页列表相关
+ list: [],
+ listLoading: false,
+ pagination: PaginationHelper.defaultPaginationConfig,
+ searchParams: SEARCH_PARAMS_DEFAULT,
+
+ // 添加 or 修改表单相关
+ },
+
+ effects: {
+ *page({ payload }, { call, put }) {
+ // const { queryParams } = payload;
+ // const response = yield call(productSpuPage, payload);
+ // message.info('查询成功!');
+ // yield put({
+ // type: 'treeSuccess',
+ // payload: {
+ // list: response.data,
+ // },
+ // });
+
+ // 显示加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: true,
+ });
+
+ // 请求
+ const response = yield call(queryUserPage, payload);
+ // 响应
+ yield put({
+ type: 'setAll',
+ payload: {
+ list: response.data.list,
+ pagination: PaginationHelper.formatPagination(response.data, payload),
+ searchParams: {
+ nickname: payload.nickname,
+ status: payload.status,
+ }
+ },
+ });
+
+ // 隐藏加载中
+ yield put({
+ type: 'changeListLoading',
+ payload: false,
+ });
+ },
+ },
+
+ reducers: {
+ treeSuccess(state, { payload }) {
+ return {
+ ...state,
+ ...payload,
+ };
+ },
+ // 修改加载中的状态
+ changeListLoading(state, { payload }) {
+ return {
+ ...state,
+ listLoading: payload,
+ };
+ },
+ // 设置所有属性
+ setAll(state, { payload }) {
+ return {
+ ...state,
+ ...payload,
+ };
+ }
+ },
+};
diff --git a/admin-web/src/pages/Pay/PayRefundList.js b/admin-web/src/pages/Pay/PayRefundList.js
new file mode 100644
index 000000000..03bb590af
--- /dev/null
+++ b/admin-web/src/pages/Pay/PayRefundList.js
@@ -0,0 +1,319 @@
+/* eslint-disable */
+
+import React, { PureComponent, Fragment } from 'react';
+import { connect } from 'dva';
+import moment from 'moment';
+import {
+ Card,
+ Form,
+ Input,
+ Row,
+ Col,
+ Button,
+ Modal,
+ message,
+ Table,
+ Divider,
+ Tree,
+ Tabs,
+ TreeSelect,
+ Spin,
+ InputNumber, DatePicker, Select
+} from 'antd';
+const TabPane = Tabs.TabPane;
+import PageHeaderWrapper from '@/components/PageHeaderWrapper';
+const { RangePicker } = DatePicker;
+
+import styles from './PayRefundList.less';
+import PaginationHelper from "../../../helpers/PaginationHelper";
+
+const FormItem = Form.Item;
+
+const statuses = {
+ 1: '处理中',
+ 2: '成功',
+ 3: '失败',
+};
+
+const payChannels = {
+ 100: '微信 App 支付',
+ 101: '微信 JS API 支付',
+ 200: '支付宝 App 支付',
+ 9999: 'ping++',
+};
+
+// 列表
+function List({ dataSource, loading, pagination, searchParams, dispatch,}) {
+
+ function onPageChange(page) { // 翻页
+ dispatch({
+ type: 'payRefundList/page',
+ payload: {
+ pageNo: page.current,
+ pageSize: page.pageSize,
+ ...searchParams
+ }
+ })
+ }
+
+ const columns = [
+ // {
+ // title: 'id',
+ // dataIndex: 'id',
+ // render: text => {text},
+ // },
+ {
+ title: '创建时间',
+ dataIndex: 'createTime',
+ render: val => {moment(val).format('YYYY-MM-DD HH:mm:ss')},
+ width: 120,
+ },
+ {
+ title: '完成时间',
+ dataIndex: 'finishTime',
+ render: val => val ? {moment(val).format('YYYY-MM-DD HH:mm:ss')} : '',
+ width: 120,
+ },
+ {
+ title: '渠道流水号',
+ dataIndex: 'tradeNo',
+ },
+ {
+ title: '退款金额',
+ dataIndex: 'price',
+ render: val => val / 100.0,
+ },
+ {
+ title: '退款状态',
+ dataIndex: 'status',
+ render: val => statuses[val + ''],
+ },
+ {
+ title: '支付时间',
+ dataIndex: 'transaction.finishTime',
+ render: val => val ? {moment(val).format('YYYY-MM-DD HH:mm:ss')} : '',
+ width: 120,
+ },
+ {
+ title: '商户订单号',
+ dataIndex: 'orderId',
+ },
+ {
+ title: '商品名称',
+ dataIndex: 'transaction.orderSubject',
+ },
+ {
+ title: '支付金额',
+ dataIndex: 'transaction.price',
+ },
+ {
+ title: '支付渠道',
+ dataIndex: 'transaction.payChannel',
+ render: val => payChannels[val + ''],
+ },
+ {
+ title: '操作',
+ width: 120,
+ render: (text, record) => (
+
+ {/* this.handleModalVisible(true, 'update', record)}>更新*/}
+ alert('正在开发中')}>详情
+
+ ),
+ },
+ ];
+
+ // console.log(pagination);
+
+ return (
+
+ )
+}
+
+// 搜索表单
+const SearchForm = Form.create()(props => {
+ const {
+ form,
+ form: { getFieldDecorator },
+ dispatch,
+ searchParams,
+ } = props;
+
+ function search() {
+ const getBeginAndEndTime = (key, beginKey, endKey) => {
+ let val = form.getFieldsValue()[key];
+ if (val && val.length === 2) {
+ let res = {};
+ res[beginKey] = val[0].format('YYYY-MM-DD HH:mm:ss');
+ res[endKey] = val[1].format('YYYY-MM-DD HH:mm:ss');
+ return res;
+ }
+ return {};
+ };
+
+ dispatch({
+ type: 'payRefundList/page',
+ payload: {
+ ...PaginationHelper.defaultPayload,
+ ...searchParams,
+ ...form.getFieldsValue(),
+ createTime: undefined,
+ finishTime: undefined,
+ ...getBeginAndEndTime('createTime', 'createBeginTime', 'createEndTime'),
+ ...getBeginAndEndTime('finishTime', 'finishBeginTime', 'finishEndTime'),
+ }
+ })
+ }
+
+ // 提交搜索
+ function handleSubmit(e) {
+ // 阻止默认事件
+ e.preventDefault();
+ // 提交搜索
+ search();
+ }
+
+ // 重置搜索
+ function handleReset() {
+ // 重置表单
+ form.resetFields();
+ // 执行搜索
+ search();
+ }
+
+ return (
+
+ );
+});
+
+// payRefundList
+@connect(({ payRefundList }) => ({
+ ...payRefundList,
+ // list: payRefundList.list.spus,
+ // loading: loading.models.payRefundList,
+}))
+
+@Form.create()
+class PayTransactionList extends PureComponent {
+ state = {
+ modalVisible: false,
+ modalType: 'add', //add update
+ initValues: {},
+ };
+
+ componentDidMount() {
+ const { dispatch, searchParams } = this.props;
+ // 查询初始数据
+ dispatch({
+ type: 'payRefundList/page',
+ payload: {
+ ...searchParams,
+ ...PaginationHelper.defaultPayload,
+ },
+ });
+ }
+
+ handleSortModalVisible = (sortModalVisible, record) => {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'payRefundList/setAll',
+ payload: {
+ sortModalVisible,
+ formVals: record || {}
+ },
+ });
+ };
+
+ render() {
+ const { dispatch,
+ list, listLoading, searchParams, pagination,
+ categoryTree, formVals, } = this.props;
+
+ // 列表属性
+ const listProps = {
+ dataSource: list,
+ pagination,
+ searchParams,
+ dispatch,
+ categoryTree,
+ loading: listLoading,
+ handleSortModalVisible: this.handleSortModalVisible, // Func
+ };
+
+ // 搜索表单属性
+ const searchFormProps = {
+ dispatch,
+ categoryTree,
+ searchParams,
+ };
+
+ return (
+
+
+
+
+ {/**/}
+
+
+
+
+
+
+ );
+ }
+}
+
+export default PayTransactionList;
diff --git a/admin-web/src/pages/Pay/PayRefundList.less b/admin-web/src/pages/Pay/PayRefundList.less
new file mode 100644
index 000000000..ebb45c292
--- /dev/null
+++ b/admin-web/src/pages/Pay/PayRefundList.less
@@ -0,0 +1,15 @@
+@import '~antd/lib/style/themes/default.less';
+@import '~@/utils/utils.less';
+
+.tableList {
+ .tableListOperator {
+ margin-bottom: 16px;
+ button {
+ margin-right: 8px;
+ }
+ }
+}
+
+.tableDelete {
+ color: red;
+}
diff --git a/admin-web/src/pages/Pay/PayTransactionList.js b/admin-web/src/pages/Pay/PayTransactionList.js
new file mode 100644
index 000000000..1e2146521
--- /dev/null
+++ b/admin-web/src/pages/Pay/PayTransactionList.js
@@ -0,0 +1,328 @@
+/* eslint-disable */
+
+import React, { PureComponent, Fragment } from 'react';
+import { connect } from 'dva';
+import moment from 'moment';
+import {
+ Card,
+ Form,
+ Input,
+ Row,
+ Col,
+ Button,
+ Modal,
+ message,
+ Table,
+ Divider,
+ Tree,
+ Tabs,
+ TreeSelect,
+ Spin,
+ InputNumber, DatePicker, Select
+} from 'antd';
+const TabPane = Tabs.TabPane;
+import PageHeaderWrapper from '@/components/PageHeaderWrapper';
+const { RangePicker } = DatePicker;
+
+import styles from './PayTransactionList.less';
+import PaginationHelper from "../../../helpers/PaginationHelper";
+
+const FormItem = Form.Item;
+
+const statuses = {
+ 1: '等待支付',
+ 2: '支付成功',
+ 3: '取消支付',
+};
+
+const payChannels = {
+ 100: '微信 App 支付',
+ 101: '微信 JS API 支付',
+ 200: '支付宝 App 支付',
+ 9999: 'ping++',
+};
+
+// 列表
+function List({ dataSource, loading, pagination, searchParams, dispatch,}) {
+
+ function onPageChange(page) { // 翻页
+ dispatch({
+ type: 'payTransactionList/page',
+ payload: {
+ pageNo: page.current,
+ pageSize: page.pageSize,
+ ...searchParams
+ }
+ })
+ }
+
+ const columns = [
+ // {
+ // title: 'id',
+ // dataIndex: 'id',
+ // render: text => {text},
+ // },
+ {
+ title: '创建时间',
+ dataIndex: 'createTime',
+ render: val => {moment(val).format('YYYY-MM-DD HH:mm:ss')},
+ width: 120,
+ },
+ {
+ title: '支付时间',
+ dataIndex: 'paymentTime',
+ render: val => val ? {moment(val).format('YYYY-MM-DD HH:mm:ss')} : '',
+ width: 120,
+ },
+ {
+ title: '商户订单号',
+ dataIndex: 'orderId',
+ },
+ {
+ title: '商品名称',
+ dataIndex: 'orderSubject',
+ },
+ {
+ title: '支付金额',
+ dataIndex: 'price',
+ render: val => val / 100.0,
+ },
+ {
+ title: '支付状态',
+ dataIndex: 'status',
+ render: val => statuses[val + ''],
+ },
+ {
+ title: '支付渠道',
+ dataIndex: 'payChannel',
+ render: val => payChannels[val + ''],
+ },
+ {
+ title: '退款情况',
+ dataIndex: 'refundTotal',
+ render: val => val && val > 0 ? '有退款' : '无退款' ,
+ },
+ {
+ title: '退款金额',
+ dataIndex: 'refundTotal',
+ render: val => val && val > 0 ? val / 100.0 : undefined ,
+ },
+ {
+ title: '操作',
+ width: 120,
+ render: (text, record) => (
+
+ {/* this.handleModalVisible(true, 'update', record)}>更新*/}
+ alert('正在开发中')}>退款
+
+ ),
+ },
+ ];
+
+ // console.log(pagination);
+
+ return (
+
+ )
+}
+
+// 搜索表单
+const SearchForm = Form.create()(props => {
+ const {
+ form,
+ form: { getFieldDecorator },
+ dispatch,
+ searchParams,
+ } = props;
+
+ function search() {
+ const getBeginAndEndTime = (key, beginKey, endKey) => {
+ let val = form.getFieldsValue()[key];
+ if (val && val.length === 2) {
+ let res = {};
+ res[beginKey] = val[0].format('YYYY-MM-DD HH:mm:ss');
+ res[endKey] = val[1].format('YYYY-MM-DD HH:mm:ss');
+ return res;
+ }
+ return {};
+ };
+
+ dispatch({
+ type: 'payTransactionList/page',
+ payload: {
+ ...PaginationHelper.defaultPayload,
+ ...searchParams,
+ ...form.getFieldsValue(),
+ createTime: undefined,
+ paymentTime: undefined,
+ ...getBeginAndEndTime('createTime', 'createBeginTime', 'createEndTime'),
+ ...getBeginAndEndTime('paymentTime', 'paymentBeginTime', 'paymentEndTime'),
+ }
+ })
+ }
+
+ // 提交搜索
+ function handleSubmit(e) {
+ // 阻止默认事件
+ e.preventDefault();
+ // 提交搜索
+ search();
+ }
+
+ // 重置搜索
+ function handleReset() {
+ // 重置表单
+ form.resetFields();
+ // 执行搜索
+ search();
+ }
+
+ return (
+
+ );
+});
+
+// payTransactionList
+@connect(({ payTransactionList }) => ({
+ ...payTransactionList,
+ // list: payTransactionList.list.spus,
+ // loading: loading.models.payTransactionList,
+}))
+
+@Form.create()
+class PayTransactionList extends PureComponent {
+ state = {
+ modalVisible: false,
+ modalType: 'add', //add update
+ initValues: {},
+ };
+
+ componentDidMount() {
+ const { dispatch, searchParams } = this.props;
+ // 查询初始数据
+ dispatch({
+ type: 'payTransactionList/page',
+ payload: {
+ ...searchParams,
+ ...PaginationHelper.defaultPayload,
+ },
+ });
+ }
+
+ handleSortModalVisible = (sortModalVisible, record) => {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'payTransactionList/setAll',
+ payload: {
+ sortModalVisible,
+ formVals: record || {}
+ },
+ });
+ };
+
+ render() {
+ const { dispatch,
+ list, listLoading, searchParams, pagination,
+ categoryTree, formVals, } = this.props;
+
+ // 列表属性
+ const listProps = {
+ dataSource: list,
+ pagination,
+ searchParams,
+ dispatch,
+ categoryTree,
+ loading: listLoading,
+ handleSortModalVisible: this.handleSortModalVisible, // Func
+ };
+
+ // 搜索表单属性
+ const searchFormProps = {
+ dispatch,
+ categoryTree,
+ searchParams,
+ };
+
+ return (
+
+
+
+
+ {/**/}
+
+
+
+
+
+
+ );
+ }
+}
+
+export default PayTransactionList;
diff --git a/admin-web/src/pages/Pay/PayTransactionList.less b/admin-web/src/pages/Pay/PayTransactionList.less
new file mode 100644
index 000000000..ebb45c292
--- /dev/null
+++ b/admin-web/src/pages/Pay/PayTransactionList.less
@@ -0,0 +1,15 @@
+@import '~antd/lib/style/themes/default.less';
+@import '~@/utils/utils.less';
+
+.tableList {
+ .tableListOperator {
+ margin-bottom: 16px;
+ button {
+ margin-right: 8px;
+ }
+ }
+}
+
+.tableDelete {
+ color: red;
+}
diff --git a/admin-web/src/pages/User/UserList.js b/admin-web/src/pages/User/UserList.js
new file mode 100644
index 000000000..4330579e3
--- /dev/null
+++ b/admin-web/src/pages/User/UserList.js
@@ -0,0 +1,266 @@
+/* eslint-disable */
+
+import React, { PureComponent, Fragment } from 'react';
+import { connect } from 'dva';
+import moment from 'moment';
+import {
+ Card,
+ Form,
+ Input,
+ Row,
+ Col,
+ Button,
+ Modal,
+ message,
+ Table,
+ Divider,
+ Tree,
+ Tabs,
+ TreeSelect,
+ Spin,
+ InputNumber, Select
+} from 'antd';
+const TabPane = Tabs.TabPane;
+import PageHeaderWrapper from '@/components/PageHeaderWrapper';
+
+import styles from './UserList.less';
+import PaginationHelper from "../../../helpers/PaginationHelper";
+
+const FormItem = Form.Item;
+
+const statuses = {
+ 1: '开启',
+ 2: '关闭',
+};
+
+// 列表
+function List({ dataSource, loading, pagination, searchParams, dispatch,}) {
+
+ function onPageChange(page) { // 翻页
+ dispatch({
+ type: 'userList/page',
+ payload: {
+ pageNo: page.current,
+ pageSize: page.pageSize,
+ ...searchParams
+ }
+ })
+ }
+
+ const columns = [
+ // {
+ // title: 'id',
+ // dataIndex: 'id',
+ // render: text => {text},
+ // },
+ {
+ title: '昵称',
+ dataIndex: 'nickname',
+ },
+ {
+ title: '手机号码',
+ dataIndex: 'mobile',
+ },
+ {
+ title: '会员卡', // TODO 芋艿,未来增加
+ },
+ {
+ title: '累积交易次数', // TODO 芋艿,未来增加
+ },
+ {
+ title: '累计交易额', // TODO 芋艿,未来增加
+ },
+ {
+ title: '积分', // TODO 芋艿,未来增加
+ },
+ {
+ title: '会员标签', // TODO 芋艿,未来增加
+ },
+ {
+ title: '备注', // TODO 芋艿,未来增加
+ },
+ {
+ title: '状态',
+ dataIndex: 'status',
+ render: val => statuses[val + ''],
+ },
+ {
+ title: '操作',
+ width: 300,
+ render: (text, record) => (
+
+ {/* this.handleModalVisible(true, 'update', record)}>更新*/}
+ alert('正在开发中')}>编辑
+
+ ),
+ },
+ ];
+
+ // console.log(pagination);
+
+ return (
+
+ )
+}
+
+// 搜索表单
+const SearchForm = Form.create()(props => {
+ const {
+ form,
+ form: { getFieldDecorator },
+ dispatch,
+ searchParams,
+ } = props;
+
+ function search() {
+ dispatch({
+ type: 'userList/page',
+ payload: {
+ ...PaginationHelper.defaultPayload,
+ ...searchParams,
+ ...form.getFieldsValue(),
+ }
+ })
+ }
+
+ // 提交搜索
+ function handleSubmit(e) {
+ // 阻止默认事件
+ e.preventDefault();
+ // 提交搜索
+ search();
+ }
+
+ // 重置搜索
+ function handleReset() {
+ // 重置表单
+ form.resetFields();
+ // 执行搜索
+ search();
+ }
+
+ return (
+
+ );
+});
+
+// userList
+@connect(({ userList }) => ({
+ ...userList,
+ // list: userList.list.spus,
+ // loading: loading.models.userList,
+}))
+
+@Form.create()
+class UserList extends PureComponent {
+ state = {
+ modalVisible: false,
+ modalType: 'add', //add update
+ initValues: {},
+ };
+
+ componentDidMount() {
+ const { dispatch, searchParams } = this.props;
+ // 查询初始数据
+ dispatch({
+ type: 'userList/page',
+ payload: {
+ ...searchParams,
+ ...PaginationHelper.defaultPayload,
+ },
+ });
+ }
+
+ handleSortModalVisible = (sortModalVisible, record) => {
+ const { dispatch } = this.props;
+ dispatch({
+ type: 'userList/setAll',
+ payload: {
+ sortModalVisible,
+ formVals: record || {}
+ },
+ });
+ };
+
+ render() {
+ const { dispatch,
+ list, listLoading, searchParams, pagination,
+ categoryTree, formVals, } = this.props;
+
+ // 列表属性
+ const listProps = {
+ dataSource: list,
+ pagination,
+ searchParams,
+ dispatch,
+ categoryTree,
+ loading: listLoading,
+ handleSortModalVisible: this.handleSortModalVisible, // Func
+ };
+
+ // 搜索表单属性
+ const searchFormProps = {
+ dispatch,
+ categoryTree,
+ searchParams,
+ };
+
+ return (
+
+
+
+
+ {/**/}
+
+
+
+
+
+
+ );
+ }
+}
+
+export default UserList;
diff --git a/admin-web/src/pages/User/UserList.less b/admin-web/src/pages/User/UserList.less
new file mode 100644
index 000000000..ebb45c292
--- /dev/null
+++ b/admin-web/src/pages/User/UserList.less
@@ -0,0 +1,15 @@
+@import '~antd/lib/style/themes/default.less';
+@import '~@/utils/utils.less';
+
+.tableList {
+ .tableListOperator {
+ margin-bottom: 16px;
+ button {
+ margin-right: 8px;
+ }
+ }
+}
+
+.tableDelete {
+ color: red;
+}
diff --git a/admin-web/src/services/pay.js b/admin-web/src/services/pay.js
new file mode 100644
index 000000000..cb99c499c
--- /dev/null
+++ b/admin-web/src/services/pay.js
@@ -0,0 +1,18 @@
+import { stringify } from '@/utils/request.qs';
+import request from '@/utils/request';
+
+// Transaction
+
+export async function queryPayTransactionPage(params) {
+ return request(`/pay-api/admins/transaction/page?${stringify(params)}`, {
+ method: 'GET',
+ });
+}
+
+// Refund
+
+export async function queryPayRefundPage(params) {
+ return request(`/pay-api/admins/refund/page?${stringify(params)}`, {
+ method: 'GET',
+ });
+}
diff --git a/admin-web/src/services/user.js b/admin-web/src/services/user.js
index 89e03c6f6..2610164df 100644
--- a/admin-web/src/services/user.js
+++ b/admin-web/src/services/user.js
@@ -1,3 +1,4 @@
+import { stringify } from '@/utils/request.qs';
import request from '@/utils/request';
export async function query() {
@@ -7,3 +8,11 @@ export async function query() {
export async function queryCurrent() {
return request('/api/currentUser');
}
+
+// User
+
+export async function queryUserPage(params) {
+ return request(`/user-api/admins/user/page?${stringify(params)}`, {
+ method: 'GET',
+ });
+}
diff --git a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java
index d26800cf7..7a4e886f0 100644
--- a/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java
+++ b/common/common-framework/src/main/java/cn/iocoder/common/framework/util/ServiceExceptionUtil.java
@@ -71,6 +71,11 @@ public class ServiceExceptionUtil {
return new ServiceException(code, message);
}
+ public static ServiceException exception(Integer code, String messagePattern, Object... params) {
+ String message = doFormat(code, messagePattern, params);
+ return new ServiceException(code, message);
+ }
+
/**
* 将错误编号对应的消息使用 params 进行格式化。
*
@@ -107,4 +112,4 @@ public class ServiceExceptionUtil {
return sbuf.toString();
}
-}
\ No newline at end of file
+}
diff --git a/docs/guides/功能列表/功能列表-管理后台.md b/docs/guides/功能列表/功能列表-管理后台.md
index 8ba7696d3..59f2f6b65 100644
--- a/docs/guides/功能列表/功能列表-管理后台.md
+++ b/docs/guides/功能列表/功能列表-管理后台.md
@@ -7,26 +7,28 @@
- [ ] 数据分析【待认领】
- [ ] TODO 未开始
- [ ] 店铺资产【待认领】
- - [ ] TODO 未开始
+ - [ ] 支付单 20% 【待认领】
+ - [ ] 退款单 20% 【待认领】
+ - TODO 需要补充
- [ ] 商品管理
- [x] 发布商品
- [x] 商品列表
- [x] 展示类目
- [ ] 品牌管理【待认领】
- [ ] 订单管理
- - [ ] 销售单
- - [ ] 售后单
+ - [ ] 销售单 开发中
+ - [ ] 售后单 开发中
- [ ] 订单评价【待认领】
- [ ] 会员管理
- - [ ] 会员资料【待认领】
+ - [ ] 会员资料 20%【待认领】
- TODO 需要补充
- [ ] 营销管理
- [x] 首页广告
- [x] 商品推荐
- [x] 优惠劵
- [ ] 优惠码【待认领】
- - [ ] 满减送
- - [ ] 限制折扣
+ - [ ] 满减送 20% 【待认领】
+ - [ ] 限制折扣 20% 【待认领】
- [ ] 多人拼团【待认领】
- [ ] 系统管理
- [ ] 员工管理
diff --git a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/OrderController.java b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/OrderController.java
index 3b3bff303..08e83a2a2 100644
--- a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/OrderController.java
+++ b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/OrderController.java
@@ -13,17 +13,14 @@ import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
import cn.iocoder.mall.order.api.dto.OrderQueryDTO;
-import cn.iocoder.mall.order.api.dto.OrderReturnApplyDTO;
import cn.iocoder.mall.order.application.convert.CartConvert;
import cn.iocoder.mall.order.application.convert.OrderConvertAPP;
-import cn.iocoder.mall.order.application.convert.OrderReturnConvert;
import cn.iocoder.mall.order.application.po.user.OrderCreatePO;
-import cn.iocoder.mall.order.application.po.user.OrderReturnApplyPO;
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
-import org.apache.dubbo.config.annotation.Reference;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
+import org.apache.dubbo.config.annotation.Reference;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -76,7 +73,7 @@ public class OrderController {
HttpServletRequest request) {
Integer userId = UserSecurityContextHolder.getContext().getUserId();
// 获得购物车中选中的商品
- List cartItems = cartService.list(userId, true).getData();
+ List cartItems = cartService.list(userId, true);
if (cartItems.isEmpty()) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_CREATE_CART_IS_EMPTY.getCode());
}
@@ -105,12 +102,9 @@ public class OrderController {
.setUserId(UserSecurityContextHolder.getContext().getUserId())
.setItems(Collections.singletonList(new CalcOrderPriceDTO.Item(skuId, quantity, true)))
.setCouponCardId(couponCardId);
- CommonResult calcOrderPriceResult = cartService.calcOrderPrice(calcOrderPriceDTO);
- if (calcOrderPriceResult.isError()) {
- return CommonResult.error(calcOrderPriceResult);
- }
+ CalcOrderPriceBO calcOrderPrice = cartService.calcOrderPrice(calcOrderPriceDTO);
// 执行数据拼装
- return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPriceResult.getData()));
+ return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPrice));
}
@PostMapping("confirm_receiving")
diff --git a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java
index 46d3ca5c5..059923790 100644
--- a/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java
+++ b/order/order-application/src/main/java/cn/iocoder/mall/order/application/controller/users/UsersCartController.java
@@ -23,6 +23,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
+import static cn.iocoder.common.framework.vo.CommonResult.success;
+
@RestController
@RequestMapping("users/cart")
public class UsersCartController {
@@ -38,26 +40,17 @@ public class UsersCartController {
public CommonResult add(@RequestParam("skuId") Integer skuId,
@RequestParam("quantity") Integer quantity) {
// 添加到购物车
- CommonResult addResult = cartService.add(UserSecurityContextHolder.getContext().getUserId(),
- skuId, quantity);
- // 添加失败,则直接返回错误
- if (addResult.isError()) {
- return CommonResult.error(addResult);
- }
+ cartService.add(UserSecurityContextHolder.getContext().getUserId(), skuId, quantity);
// 获得目前购物车商品总数量
- return cartService.count(UserSecurityContextHolder.getContext().getUserId());
+ return success(cartService.count(UserSecurityContextHolder.getContext().getUserId()));
}
@PostMapping("update_quantity")
public CommonResult updateQuantity(@RequestParam("skuId") Integer skuId, // TODO 芋艿,先暂用这个 VO 。等促销活动出来后,做调整
@RequestParam("quantity") Integer quantity) {
// 添加到购物车
- CommonResult updateQuantityResult = cartService.updateQuantity(UserSecurityContextHolder.getContext().getUserId(),
+ cartService.updateQuantity(UserSecurityContextHolder.getContext().getUserId(),
skuId, quantity);
- // 添加失败,则直接返回错误
- if (updateQuantityResult.isError()) {
- return CommonResult.error(updateQuantityResult);
- }
// 获得目前购物车明细
return getCartDetail();
}
@@ -66,19 +59,14 @@ public class UsersCartController {
public CommonResult updateSelected(@RequestParam("skuIds") Set skuIds, // TODO 芋艿,先暂用这个 VO 。等促销活动出来后,做调整
@RequestParam("selected") Boolean selected) {
// 添加到购物车
- CommonResult updateSelectedResult = cartService.updateSelected(UserSecurityContextHolder.getContext().getUserId(),
- skuIds, selected);
- // 添加失败,则直接返回错误
- if (updateSelectedResult.isError()) {
- return CommonResult.error(updateSelectedResult);
- }
+ cartService.updateSelected(UserSecurityContextHolder.getContext().getUserId(), skuIds, selected);
// 获得目前购物车明细
return getCartDetail();
}
@GetMapping("count")
public CommonResult count() {
- return cartService.count(UserSecurityContextHolder.getContext().getUserId());
+ return success(cartService.count(UserSecurityContextHolder.getContext().getUserId()));
}
@GetMapping("/list")
@@ -88,50 +76,42 @@ public class UsersCartController {
private CommonResult getCartDetail() {
// 获得购物车中选中的
- List cartItems = cartService.list(UserSecurityContextHolder.getContext().getUserId(), null).getData();
+ List cartItems = cartService.list(UserSecurityContextHolder.getContext().getUserId(), null);
// 购物车为空时,构造空的 UsersOrderConfirmCreateVO 返回
if (cartItems.isEmpty()) {
UsersCartDetailVO result = new UsersCartDetailVO();
result.setItemGroups(Collections.emptyList());
result.setFee(new UsersCartDetailVO.Fee(0, 0, 0, 0));
- return CommonResult.success(result);
+ return success(result);
}
// 计算商品价格
- CommonResult calcOrderPriceResult = list0(cartItems, null);
- if (calcOrderPriceResult.isError()) {
- return CommonResult.error(calcOrderPriceResult);
- }
+ CalcOrderPriceBO calcOrder = list0(cartItems, null);
// 执行数据拼装
- return CommonResult.success(CartConvert.INSTANCE.convert2(calcOrderPriceResult.getData()));
+ return success(CartConvert.INSTANCE.convert2(calcOrder));
}
@GetMapping("/confirm_create_order")
public CommonResult getConfirmCreateOrder(@RequestParam(value = "couponCardId", required = false) Integer couponCardId) {
Integer userId = UserSecurityContextHolder.getContext().getUserId();
// 获得购物车中选中的
- List cartItems = cartService.list(userId, true).getData();
+ List cartItems = cartService.list(userId, true);
// 购物车为空时,构造空的 UsersOrderConfirmCreateVO 返回
if (cartItems.isEmpty()) {
UsersOrderConfirmCreateVO result = new UsersOrderConfirmCreateVO();
result.setItemGroups(Collections.emptyList());
result.setFee(new UsersOrderConfirmCreateVO.Fee(0, 0, 0, 0));
- return CommonResult.success(result);
+ return success(result);
}
// 计算商品价格
- CommonResult calcOrderPriceResult = list0(cartItems, couponCardId);
- if (calcOrderPriceResult.isError()) {
- return CommonResult.error(calcOrderPriceResult);
- }
+ CalcOrderPriceBO calcOrderPrice = list0(cartItems, couponCardId);
// 获得优惠劵
- CalcOrderPriceBO calcOrderPrice = calcOrderPriceResult.getData();
List couponCards = couponService.getCouponCardList(userId,
- CartConvert.INSTANCE.convertList(calcOrderPrice.getItemGroups())).getData();
+ CartConvert.INSTANCE.convertList(calcOrderPrice.getItemGroups()));
// 执行数据拼装
- return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPrice)
- .setCouponCards(couponCards));
+ return success(CartConvert.INSTANCE.convert(calcOrderPrice).setCouponCards(couponCards));
}
- private CommonResult list0(List cartItems, Integer couponCardId) {
+ private CalcOrderPriceBO list0(List cartItems, Integer couponCardId) {
// 创建计算的 DTO
CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO()
.setUserId(UserSecurityContextHolder.getContext().getUserId())
@@ -148,12 +128,8 @@ public class UsersCartController {
@PermitAll
public CommonResult calcSkuPrice(@RequestParam("skuId") Integer skuId) {
// 计算 sku 的价格
- CommonResult calcSkuPriceResult = cartService.calcSkuPrice(skuId);
- // 返回结果
- if (calcSkuPriceResult.isError()) {
- return CommonResult.error(calcSkuPriceResult);
- }
- return CommonResult.success(CartConvert.INSTANCE.convert2(calcSkuPriceResult.getData()));
+ CalcSkuPriceBO calcSkuPrice = cartService.calcSkuPrice(skuId);
+ return success(CartConvert.INSTANCE.convert2(calcSkuPrice));
}
public CommonResult