Commit e7087f45686f0e7306c6755ee48ac5738ebf60b1

Authored by boyang
1 parent 7d171173

feat: 开发用户列表积分显示与积分兑换

src/pages/Prepaid/components/PointsExchangeModal.tsx 0 → 100644
  1 +import { postIntegralExchangeIntegral } from '@/services/request';
  2 +import {
  3 + ModalForm,
  4 + ProFormInstance,
  5 + ProFormTextArea,
  6 +} from '@ant-design/pro-components';
  7 +import { Form, Input, message } from 'antd';
  8 +import React, { useRef } from 'react';
  9 +import '../index.less';
  10 +
  11 +interface PointsExchangeModalProps {
  12 + setVisible: (visible: boolean) => void;
  13 + userInfoObj: {
  14 + uid: string;
  15 + nickname?: string;
  16 + realName?: string;
  17 + [key: string]: any;
  18 + };
  19 + onClose: () => void;
  20 +}
  21 +
  22 +const PointsExchangeModal: React.FC<PointsExchangeModalProps> = ({
  23 + setVisible,
  24 + userInfoObj,
  25 + onClose,
  26 +}) => {
  27 + const [form] = Form.useForm<{ delta: string; remark: string }>();
  28 + const formRef = useRef<ProFormInstance>();
  29 + const uid = userInfoObj?.uid;
  30 + const userName = userInfoObj?.nickname || userInfoObj?.realName || '';
  31 +
  32 + return (
  33 + <div className="prepaid-index">
  34 + <ModalForm<{
  35 + delta: string;
  36 + remark: string;
  37 + }>
  38 + width={600}
  39 + open
  40 + title="积分兑换"
  41 + form={form}
  42 + formRef={formRef}
  43 + autoFocusFirstInput
  44 + submitter={{
  45 + searchConfig: {
  46 + submitText: '确认兑换',
  47 + resetText: '取消',
  48 + },
  49 + }}
  50 + modalProps={{
  51 + destroyOnClose: true,
  52 + onCancel: () => {
  53 + setVisible(false);
  54 + },
  55 + }}
  56 + onFinish={async (values) => {
  57 + try {
  58 + // 调用积分兑换API
  59 + await postIntegralExchangeIntegral({
  60 + data: {
  61 + id: Number(uid), // 使用用户的uid作为id参数
  62 + delta: values.delta, // 将delta设为负数
  63 + remark: values.remark, // 兑换说明
  64 + createByName: userName, // 使用昵称或真实姓名作为createByName
  65 + },
  66 + });
  67 +
  68 + message.success('积分兑换成功');
  69 + setVisible(false);
  70 + onClose();
  71 + return true;
  72 + } catch (error) {
  73 + console.error(error);
  74 + return false;
  75 + }
  76 + }}
  77 + onOpenChange={setVisible}
  78 + >
  79 + <Form.Item
  80 + label="兑换积分"
  81 + name="delta"
  82 + rules={[{ required: true, message: '请输入兑换积分' }]}
  83 + >
  84 + <Input style={{ height: '30px' }} placeholder="请输入兑换积分数量" />
  85 + </Form.Item>
  86 +
  87 + <Form.Item
  88 + label="兑换说明"
  89 + name="remark"
  90 + rules={[{ required: true, message: '请输入兑换说明' }]}
  91 + >
  92 + <ProFormTextArea
  93 + style={{ height: '100px' }}
  94 + placeholder="请输入兑换说明"
  95 + />
  96 + </Form.Item>
  97 + </ModalForm>
  98 + </div>
  99 + );
  100 +};
  101 +
  102 +export default PointsExchangeModal;
... ...
src/pages/Prepaid/constant.tsx
... ... @@ -187,6 +187,27 @@ export const ACCOUNT_COLUMNS = [
187 187 hideInSearch: true,
188 188 },
189 189 {
  190 + title: '账户积分',
  191 + dataIndex: 'delta',
  192 + key: 'delta',
  193 + valueType: 'number',
  194 + hideInSearch: true,
  195 + },
  196 + {
  197 + title: '待领取积分',
  198 + dataIndex: 'pendingDelta',
  199 + key: 'pendingDelta',
  200 + valueType: 'number',
  201 + hideInSearch: true,
  202 + },
  203 + {
  204 + title: '已扣除积分',
  205 + dataIndex: 'deleteDelta',
  206 + key: 'deleteDelta',
  207 + valueType: 'number',
  208 + hideInSearch: true,
  209 + },
  210 + {
190 211 title: '账号',
191 212 dataIndex: 'account',
192 213 key: 'account',
... ...
src/pages/Prepaid/index.tsx
... ... @@ -16,6 +16,7 @@ import React, { useRef, useState } from &#39;react&#39;;
16 16 import CheckModal from '../Order/Order/components/CheckModal';
17 17 import { CHECK_TYPE } from '../Order/constant';
18 18 import BalanceChangeRecordsModal from './components/BalanceChangeRecordsModal';
  19 +import PointsExchangeModal from './components/PointsExchangeModal';
19 20 import RechargePrepaymentModal from './components/RechargePrepaymentModal';
20 21 import {
21 22 ACCOUNT_COLUMNS,
... ... @@ -23,18 +24,21 @@ import {
23 24 SALES_RECHARGE_PREPAYMENT_COLUMNS,
24 25 } from './constant';
25 26 import './index.less';
  27 +
26 28 const PrepaidPage = () => {
27 29 const prepaidActionRef = useRef<ActionType>();
28 30 const accountActionRef = useRef<ActionType>();
29 31 const [rechargePrepaymentModalVisible, setRechargePrepaymentModalVisible] =
30   - useState(false);
  32 + useState<boolean>(false);
31 33 const [currentOptPrepaymentObj, setCurrentOptPrepaymentObj] = useState(null);
32 34 const [currentOptUserObj, setCurrentOptUserObj] = useState(null);
33   - const [checkVisible, setCheckVisible] = useState(false);
  35 + const [checkVisible, setCheckVisible] = useState<boolean>(false);
34 36 const [
35 37 balanceChangeRecordsModalVisible,
36 38 setBalanceChangeRecordsModalVisible,
37   - ] = useState(false);
  39 + ] = useState<boolean>(false);
  40 + const [pointsExchangeModalVisible, setPointsExchangeModalVisible] =
  41 + useState<boolean>(false);
38 42  
39 43 const reloadPrepaidTable = () => {
40 44 prepaidActionRef.current?.reload();
... ... @@ -194,11 +198,24 @@ const PrepaidPage = () =&gt; {
194 198 valueType: 'option',
195 199 key: 'option',
196 200 fixed: 'right',
197   - width: 120,
  201 + width: 200,
198 202 render: (text, record) => {
199 203 let btns = [];
200 204 btns.push(
201 205 <Button
  206 + className="p-0 ml-2"
  207 + key="points"
  208 + type="link"
  209 + onClick={() => {
  210 + setCurrentOptUserObj(record);
  211 + setPointsExchangeModalVisible(true);
  212 + }}
  213 + >
  214 + 积分兑换
  215 + </Button>,
  216 + );
  217 + btns.push(
  218 + <Button
202 219 className="p-0"
203 220 key="view"
204 221 type="link"
... ... @@ -377,6 +394,19 @@ const PrepaidPage = () =&gt; {
377 394 }}
378 395 />
379 396 )}
  397 +
  398 + {pointsExchangeModalVisible && currentOptUserObj && (
  399 + <PointsExchangeModal
  400 + setVisible={(val: boolean) => {
  401 + setPointsExchangeModalVisible(val);
  402 + }}
  403 + userInfoObj={currentOptUserObj}
  404 + onClose={() => {
  405 + setPointsExchangeModalVisible(false);
  406 + reloadAccountTable();
  407 + }}
  408 + />
  409 + )}
380 410 </div>
381 411 );
382 412 };
... ...
src/services/definition.ts
... ... @@ -1521,30 +1521,12 @@ export interface Entry {
1521 1521 unEmpInsuranceC?: string;
1522 1522 }
1523 1523  
1524   -export interface File {
1525   - absolute?: boolean;
1526   - absoluteFile?: File;
1527   - absolutePath?: string;
1528   - canonicalFile?: File;
1529   - canonicalPath?: string;
1530   - directory?: boolean;
1531   - executable?: boolean;
1532   - file?: boolean;
1533   - /** @format int64 */
1534   - freeSpace?: number;
1535   - hidden?: boolean;
1536   - /** @format int64 */
1537   - lastModified?: number;
1538   - name?: string;
1539   - parent?: string;
1540   - parentFile?: File;
1541   - path?: string;
1542   - readable?: boolean;
1543   - /** @format int64 */
1544   - totalSpace?: number;
  1524 +export interface ExchangeIntegralDto {
  1525 + createByName?: string;
  1526 + delta?: number;
1545 1527 /** @format int64 */
1546   - usableSpace?: number;
1547   - writable?: boolean;
  1528 + id?: number;
  1529 + remark?: string;
1548 1530 }
1549 1531  
1550 1532 export interface FilePathDto {
... ... @@ -1687,6 +1669,11 @@ export interface InvoiceDto {
1687 1669 orderTypeText?: string;
1688 1670 /**
1689 1671 * @description
  1672 + * 买方税号
  1673 + */
  1674 + partyATaxid?: string;
  1675 + /**
  1676 + * @description
1690 1677 * 权限路径
1691 1678 */
1692 1679 path?: Array<string>;
... ... @@ -4102,7 +4089,7 @@ export interface ResetPwdVO {
4102 4089  
4103 4090 export interface Resource {
4104 4091 description?: string;
4105   - file?: File;
  4092 + file?: TsgFile;
4106 4093 filename?: string;
4107 4094 inputStream?: InputStream;
4108 4095 open?: boolean;
... ... @@ -4810,6 +4797,32 @@ export interface CompanyInfo {
4810 4797 taxIdIsNotNull?: boolean;
4811 4798 }
4812 4799  
  4800 +export interface TsgFile {
  4801 + absolute?: boolean;
  4802 + absoluteFile?: TsgFile;
  4803 + absolutePath?: string;
  4804 + canonicalFile?: TsgFile;
  4805 + canonicalPath?: string;
  4806 + directory?: boolean;
  4807 + executable?: boolean;
  4808 + file?: boolean;
  4809 + /** @format int64 */
  4810 + freeSpace?: number;
  4811 + hidden?: boolean;
  4812 + /** @format int64 */
  4813 + lastModified?: number;
  4814 + name?: string;
  4815 + parent?: string;
  4816 + parentFile?: TsgFile;
  4817 + path?: string;
  4818 + readable?: boolean;
  4819 + /** @format int64 */
  4820 + totalSpace?: number;
  4821 + /** @format int64 */
  4822 + usableSpace?: number;
  4823 + writable?: boolean;
  4824 +}
  4825 +
4813 4826 export interface InvoiceDetail {
4814 4827 createByName?: string;
4815 4828 /** @format date-time */
... ...
src/services/request.ts
... ... @@ -56,6 +56,7 @@ import type {
56 56 DistrictDo,
57 57 DistrictSearchDo,
58 58 Dto,
  59 + ExchangeIntegralDto,
59 60 FeedbackRegistrationDTO,
60 61 InventoryMaterialStockReq,
61 62 InvoiceBatchDownloadDto,
... ... @@ -71,7 +72,6 @@ import type {
71 72 MeasureUnitListRes,
72 73 MergeIntegralDto,
73 74 MessageQueryDTO,
74   - ModelAndView,
75 75 OrderAddVO,
76 76 OrderAuditLogQueryVO,
77 77 OrderBaseInfoQueryVO,
... ... @@ -3830,7 +3830,9 @@ export interface GetErrorResponse {
3830 3830 * @description
3831 3831 * OK
3832 3832 */
3833   - 200: ModelAndView;
  3833 + 200: {
  3834 + [propertyName: string]: any;
  3835 + };
3834 3836 /**
3835 3837 * @description
3836 3838 * Unauthorized
... ... @@ -3851,9 +3853,9 @@ export interface GetErrorResponse {
3851 3853 export type GetErrorResponseSuccess = GetErrorResponse[200];
3852 3854 /**
3853 3855 * @description
3854   - * errorHtml
  3856 + * error
3855 3857 * @tags basic-error-controller
3856   - * @produces text/html
  3858 + * @produces *
3857 3859 */
3858 3860 export const getError = /* #__PURE__ */ (() => {
3859 3861 const method = 'get';
... ... @@ -3877,7 +3879,9 @@ export interface PutErrorResponse {
3877 3879 * @description
3878 3880 * OK
3879 3881 */
3880   - 200: ModelAndView;
  3882 + 200: {
  3883 + [propertyName: string]: any;
  3884 + };
3881 3885 /**
3882 3886 * @description
3883 3887 * Created
... ... @@ -3903,9 +3907,9 @@ export interface PutErrorResponse {
3903 3907 export type PutErrorResponseSuccess = PutErrorResponse[200];
3904 3908 /**
3905 3909 * @description
3906   - * errorHtml
  3910 + * error
3907 3911 * @tags basic-error-controller
3908   - * @produces text/html
  3912 + * @produces *
3909 3913 * @consumes application/json
3910 3914 */
3911 3915 export const putError = /* #__PURE__ */ (() => {
... ... @@ -3930,7 +3934,9 @@ export interface PostErrorResponse {
3930 3934 * @description
3931 3935 * OK
3932 3936 */
3933   - 200: ModelAndView;
  3937 + 200: {
  3938 + [propertyName: string]: any;
  3939 + };
3934 3940 /**
3935 3941 * @description
3936 3942 * Created
... ... @@ -3956,9 +3962,9 @@ export interface PostErrorResponse {
3956 3962 export type PostErrorResponseSuccess = PostErrorResponse[200];
3957 3963 /**
3958 3964 * @description
3959   - * errorHtml
  3965 + * error
3960 3966 * @tags basic-error-controller
3961   - * @produces text/html
  3967 + * @produces *
3962 3968 * @consumes application/json
3963 3969 */
3964 3970 export const postError = /* #__PURE__ */ (() => {
... ... @@ -3983,7 +3989,9 @@ export interface DeleteErrorResponse {
3983 3989 * @description
3984 3990 * OK
3985 3991 */
3986   - 200: ModelAndView;
  3992 + 200: {
  3993 + [propertyName: string]: any;
  3994 + };
3987 3995 /**
3988 3996 * @description
3989 3997 * No Content
... ... @@ -4004,9 +4012,9 @@ export interface DeleteErrorResponse {
4004 4012 export type DeleteErrorResponseSuccess = DeleteErrorResponse[200];
4005 4013 /**
4006 4014 * @description
4007   - * errorHtml
  4015 + * error
4008 4016 * @tags basic-error-controller
4009   - * @produces text/html
  4017 + * @produces *
4010 4018 */
4011 4019 export const deleteError = /* #__PURE__ */ (() => {
4012 4020 const method = 'delete';
... ... @@ -4030,7 +4038,9 @@ export interface OptionsErrorResponse {
4030 4038 * @description
4031 4039 * OK
4032 4040 */
4033   - 200: ModelAndView;
  4041 + 200: {
  4042 + [propertyName: string]: any;
  4043 + };
4034 4044 /**
4035 4045 * @description
4036 4046 * No Content
... ... @@ -4051,9 +4061,9 @@ export interface OptionsErrorResponse {
4051 4061 export type OptionsErrorResponseSuccess = OptionsErrorResponse[200];
4052 4062 /**
4053 4063 * @description
4054   - * errorHtml
  4064 + * error
4055 4065 * @tags basic-error-controller
4056   - * @produces text/html
  4066 + * @produces *
4057 4067 * @consumes application/json
4058 4068 */
4059 4069 export const optionsError = /* #__PURE__ */ (() => {
... ... @@ -4078,7 +4088,9 @@ export interface HeadErrorResponse {
4078 4088 * @description
4079 4089 * OK
4080 4090 */
4081   - 200: ModelAndView;
  4091 + 200: {
  4092 + [propertyName: string]: any;
  4093 + };
4082 4094 /**
4083 4095 * @description
4084 4096 * No Content
... ... @@ -4099,9 +4111,9 @@ export interface HeadErrorResponse {
4099 4111 export type HeadErrorResponseSuccess = HeadErrorResponse[200];
4100 4112 /**
4101 4113 * @description
4102   - * errorHtml
  4114 + * error
4103 4115 * @tags basic-error-controller
4104   - * @produces text/html
  4116 + * @produces *
4105 4117 * @consumes application/json
4106 4118 */
4107 4119 export const headError = /* #__PURE__ */ (() => {
... ... @@ -4126,7 +4138,9 @@ export interface PatchErrorResponse {
4126 4138 * @description
4127 4139 * OK
4128 4140 */
4129   - 200: ModelAndView;
  4141 + 200: {
  4142 + [propertyName: string]: any;
  4143 + };
4130 4144 /**
4131 4145 * @description
4132 4146 * No Content
... ... @@ -4147,9 +4161,9 @@ export interface PatchErrorResponse {
4147 4161 export type PatchErrorResponseSuccess = PatchErrorResponse[200];
4148 4162 /**
4149 4163 * @description
4150   - * errorHtml
  4164 + * error
4151 4165 * @tags basic-error-controller
4152   - * @produces text/html
  4166 + * @produces *
4153 4167 * @consumes application/json
4154 4168 */
4155 4169 export const patchError = /* #__PURE__ */ (() => {
... ... @@ -4238,6 +4252,77 @@ export const postFileDirectDown = /* #__PURE__ */ (() =&gt; {
4238 4252 return request;
4239 4253 })();
4240 4254  
  4255 +/** @description request parameter type for postIntegralExchangeIntegral */
  4256 +export interface PostIntegralExchangeIntegralOption {
  4257 + /**
  4258 + * @description
  4259 + * dto
  4260 + */
  4261 + body: {
  4262 + /**
  4263 + @description
  4264 + dto */
  4265 + dto: ExchangeIntegralDto;
  4266 + };
  4267 +}
  4268 +
  4269 +/** @description response type for postIntegralExchangeIntegral */
  4270 +export interface PostIntegralExchangeIntegralResponse {
  4271 + /**
  4272 + * @description
  4273 + * OK
  4274 + */
  4275 + 200: ServerResult;
  4276 + /**
  4277 + * @description
  4278 + * Created
  4279 + */
  4280 + 201: any;
  4281 + /**
  4282 + * @description
  4283 + * Unauthorized
  4284 + */
  4285 + 401: any;
  4286 + /**
  4287 + * @description
  4288 + * Forbidden
  4289 + */
  4290 + 403: any;
  4291 + /**
  4292 + * @description
  4293 + * Not Found
  4294 + */
  4295 + 404: any;
  4296 +}
  4297 +
  4298 +export type PostIntegralExchangeIntegralResponseSuccess =
  4299 + PostIntegralExchangeIntegralResponse[200];
  4300 +/**
  4301 + * @description
  4302 + * 积分兑换
  4303 + * @tags 积分接口
  4304 + * @produces *
  4305 + * @consumes application/json
  4306 + */
  4307 +export const postIntegralExchangeIntegral = /* #__PURE__ */ (() => {
  4308 + const method = 'post';
  4309 + const url = '/integral/exchangeIntegral';
  4310 + function request(
  4311 + option: PostIntegralExchangeIntegralOption,
  4312 + ): Promise<PostIntegralExchangeIntegralResponseSuccess> {
  4313 + return requester(request.url, {
  4314 + method: request.method,
  4315 + ...option,
  4316 + }) as unknown as Promise<PostIntegralExchangeIntegralResponseSuccess>;
  4317 + }
  4318 +
  4319 + /** http method */
  4320 + request.method = method;
  4321 + /** request url */
  4322 + request.url = url;
  4323 + return request;
  4324 +})();
  4325 +
4241 4326 /** @description response type for postIntegralGetIntegralRecordTypes */
4242 4327 export interface PostIntegralGetIntegralRecordTypesResponse {
4243 4328 /**
... ... @@ -21212,6 +21297,77 @@ export const postServiceOrderExport = /* #__PURE__ */ (() =&gt; {
21212 21297 return request;
21213 21298 })();
21214 21299  
  21300 +/** @description request parameter type for postServiceOrderExportLockOrders */
  21301 +export interface PostServiceOrderExportLockOrdersOption {
  21302 + /**
  21303 + * @description
  21304 + * dto
  21305 + */
  21306 + body: {
  21307 + /**
  21308 + @description
  21309 + dto */
  21310 + dto: QueryWarningOrderStatistics;
  21311 + };
  21312 +}
  21313 +
  21314 +/** @description response type for postServiceOrderExportLockOrders */
  21315 +export interface PostServiceOrderExportLockOrdersResponse {
  21316 + /**
  21317 + * @description
  21318 + * OK
  21319 + */
  21320 + 200: any;
  21321 + /**
  21322 + * @description
  21323 + * Created
  21324 + */
  21325 + 201: any;
  21326 + /**
  21327 + * @description
  21328 + * Unauthorized
  21329 + */
  21330 + 401: any;
  21331 + /**
  21332 + * @description
  21333 + * Forbidden
  21334 + */
  21335 + 403: any;
  21336 + /**
  21337 + * @description
  21338 + * Not Found
  21339 + */
  21340 + 404: any;
  21341 +}
  21342 +
  21343 +export type PostServiceOrderExportLockOrdersResponseSuccess =
  21344 + PostServiceOrderExportLockOrdersResponse[200];
  21345 +/**
  21346 + * @description
  21347 + * exportLockOrders
  21348 + * @tags 内部订单
  21349 + * @produces *
  21350 + * @consumes application/json
  21351 + */
  21352 +export const postServiceOrderExportLockOrders = /* #__PURE__ */ (() => {
  21353 + const method = 'post';
  21354 + const url = '/service/order/exportLockOrders';
  21355 + function request(
  21356 + option: PostServiceOrderExportLockOrdersOption,
  21357 + ): Promise<PostServiceOrderExportLockOrdersResponseSuccess> {
  21358 + return requester(request.url, {
  21359 + method: request.method,
  21360 + ...option,
  21361 + }) as unknown as Promise<PostServiceOrderExportLockOrdersResponseSuccess>;
  21362 + }
  21363 +
  21364 + /** http method */
  21365 + request.method = method;
  21366 + /** request url */
  21367 + request.url = url;
  21368 + return request;
  21369 +})();
  21370 +
21215 21371 /** @description response type for postServiceOrderExportTemplate */
21216 21372 export interface PostServiceOrderExportTemplateResponse {
21217 21373 /**
... ...