-
This commit is contained in:
		| @ -1,27 +1,3 @@ | ||||
| <page-header-wrapper [title]="'提现记录'"> | ||||
| </page-header-wrapper> | ||||
|  | ||||
| <!-- <nz-card> | ||||
|     <nz-row [nzGutter]="16"> | ||||
|         <nz-col [nzXl]="6" [nzLg]="6" [nzSm]="12"> | ||||
|             <nz-statistic nzValue="100 笔" [nzTitle]="'待审核订单数'" [nzValueStyle]="{'font-size':'21px'}"> | ||||
|             </nz-statistic> | ||||
|         </nz-col> | ||||
|         <nz-col [nzXl]="6" [nzLg]="6" [nzSm]="12"> | ||||
|             <nz-statistic nzValue="80000.00 元" [nzTitle]="'待审核提现金额'" [nzValueStyle]="{'font-size':'21px'}"> | ||||
|             </nz-statistic> | ||||
|         </nz-col> | ||||
|         <nz-col [nzXl]="6" [nzLg]="6" [nzSm]="12"> | ||||
|             <nz-statistic nzValue="100 笔" [nzTitle]="'已提现订单数'" [nzValueStyle]="{'font-size':'21px'}"> | ||||
|             </nz-statistic> | ||||
|         </nz-col> | ||||
|         <nz-col [nzXl]="6" [nzLg]="6" [nzSm]="12"> | ||||
|             <nz-statistic nzValue="80000.00 元" [nzTitle]="'已提现金额'" [nzValueStyle]="{'font-size':'21px'}"> | ||||
|             </nz-statistic> | ||||
|         </nz-col> | ||||
|     </nz-row> | ||||
| </nz-card> --> | ||||
|  | ||||
| <nz-card class="search-box" nzBordered> | ||||
|   <div nz-row nzGutter="8"> | ||||
|     <div nz-col [nzXl]="_$expand ? 24 : 18" [nzLg]="24" [nzSm]="24" [nzXs]="24"> | ||||
| @ -56,17 +32,18 @@ | ||||
|     <div class="d-flex align-items-center "> | ||||
|       <div class="mr-md"> | ||||
|         已选择 | ||||
|                 <strong class="text-red">{{ selectedRows.length }}</strong> 条数据   累计提现 <strong | ||||
|                     class="text-red">{{ | ||||
|         <strong class="text-red">{{ selectedRows.length }}</strong> 条数据   累计提现 <strong class="text-red">{{ | ||||
|           totalCallNo }}</strong> | ||||
|                 <a *ngIf="totalCallNo > 0" (click)="st.clearCheck()" class="ml-lg">清空</a> | ||||
|         <!-- <a *ngIf="totalCallNo > 0" (click)="st.clearCheck()" class="ml-lg">清空</a> --> | ||||
|       </div> | ||||
|       <button nz-button (click)="this.auditAction(null)">审核</button> | ||||
|     </div> | ||||
|   </ng-template> | ||||
|  | ||||
|   <st #st [data]="service.$api_get_refund_page" [columns]="columns" [req]="{  process: beforeReq }" | ||||
|         [loading]="service.http.loading" [scroll]="{ x:'1200px' }" (change)="stChange($event)"> | ||||
|     [loading]="service.http.loading" [scroll]="{ x:'1200px' }" (change)="stChange($event)" | ||||
|     [res]="{ reName: { list: 'data.records', total: 'data.total' }, process: afterRes }" | ||||
|     [page]="{ show: true,  pageSizes:  [10, 20, 50, 100, 200, 500] }" [loading]="service.http.loading"> | ||||
|     <ng-template st-row="bankCardNumber" let-item let-index="index" let-column="column"> | ||||
|       {{ item.bankName }} <br> {{ item.bankCardNumber }} | ||||
|     </ng-template> | ||||
|  | ||||
| @ -1,9 +1,10 @@ | ||||
| import { Component, OnInit, ViewChild } from '@angular/core'; | ||||
| import { Router } from '@angular/router'; | ||||
| import { STComponent, STColumn, STChange, STRequestOptions } from '@delon/abc/st'; | ||||
| import { STComponent, STColumn, STChange, STRequestOptions, STData } from '@delon/abc/st'; | ||||
| import { SFComponent, SFSchema, SFDateWidgetSchema } from '@delon/form'; | ||||
| import { NzModalService } from 'ng-zorro-antd/modal'; | ||||
| import { FreightAccountService } from 'src/app/routes/financial-management/services/freight-account.service'; | ||||
| import Big from 'src/app/shared/utils/deal-precision'; | ||||
|  | ||||
|  | ||||
| @Component({ | ||||
| @ -12,12 +13,10 @@ import { FreightAccountService } from 'src/app/routes/financial-management/servi | ||||
|   styleUrls: ['../../../../commom/less/box.less', '../../../../commom/less/expend-but.less'] | ||||
| }) | ||||
| export class PartnerAccountManagementWithdrawalsRecordComponent implements OnInit { | ||||
|   @ViewChild('st', { static: true }) | ||||
|   st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) | ||||
|   sf!: SFComponent; | ||||
|   @ViewChild('auditModal', { static: false }) | ||||
|   auditModal!: any; | ||||
|   @ViewChild('st', { static: true }) st!: STComponent; | ||||
|   @ViewChild('sf', { static: false }) sf!: SFComponent; | ||||
|   @ViewChild('auditModal', { static: false }) auditModal!: any; | ||||
|   @ViewChild('viewReasonModal', { static: false }) viewReasonModal!: any; | ||||
|   columns: STColumn[] = this.initST(); | ||||
|   searchSchema: SFSchema = this.initSF(); | ||||
|  | ||||
| @ -52,11 +51,47 @@ export class PartnerAccountManagementWithdrawalsRecordComponent implements OnIni | ||||
|   }; | ||||
|  | ||||
|   stChange(e: STChange): void { | ||||
|     switch (e.type) { | ||||
|       case 'checkbox': | ||||
|         this.selectedRows = e.checkbox!; | ||||
|         this.totalCallNo = this.selectedRows.reduce((total, cv) => total + cv.amount, 0).toFixed(2); | ||||
|         break; | ||||
|     if (e.type === 'checkbox') { | ||||
|       const checkRows = (e.checkbox as STData[]) || []; | ||||
|       //判断当前页是否有选中的行 | ||||
|       if (checkRows.length === 0) { | ||||
|         // 当前页没有存在已勾选的行,移除之前所记录的当前页的行 | ||||
|         const stList = this.st.list; | ||||
|         stList.forEach(item => { | ||||
|           this.selectedRows = this.selectedRows.filter((e: any) => e.id !== item.id); | ||||
|         }) | ||||
|       } else { | ||||
|         //添加新增的行 | ||||
|         checkRows.forEach((item: any) => { | ||||
|           const newSelectedList = this.selectedRows.filter((r: any) => r.id === item.id); | ||||
|           if (newSelectedList.length === 0) { | ||||
|             this.selectedRows.push(item); | ||||
|  | ||||
|           } | ||||
|         }) | ||||
|         // 移除取消选中的行 | ||||
|         const stList = this.st.list; | ||||
|         stList.forEach(item => { | ||||
|           if (!item.checked) { | ||||
|             const index = this.selectedRows.findIndex(_item => item.id === _item.id); | ||||
|             if (index !== -1) this.selectedRows.splice(index, 1); | ||||
|           } | ||||
|         }) | ||||
|       } | ||||
|       let totalCallNo = 0; | ||||
|       this.selectedRows.forEach((item => { | ||||
|         totalCallNo = new Big(this.totalCallNo).plus(item?.amount).parse(); | ||||
|       })); | ||||
|       this.totalCallNo = totalCallNo; | ||||
|     } else if (e.type === 'loaded') { | ||||
|       // 页面加载时勾选 | ||||
|       (e?.loaded || []).forEach((r) => { | ||||
|         this.selectedRows.forEach((x) => { | ||||
|           if (x.id === r.id) { | ||||
|             r.checked = true; | ||||
|           } | ||||
|         }); | ||||
|       }); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @ -123,7 +158,7 @@ export class PartnerAccountManagementWithdrawalsRecordComponent implements OnIni | ||||
|   showReason(item: any) { | ||||
|     const modal = this.nzModalService.create({ | ||||
|       nzTitle: '查看原因', | ||||
|       nzContent: '运单数据异常,暂时无法开票,请联系客服400-xxxx-xxxx', | ||||
|       nzContent: item?.rejectionCause || item?.failCause, | ||||
|       nzFooter: [ | ||||
|         { | ||||
|           label: '关闭', | ||||
| @ -240,27 +275,27 @@ export class PartnerAccountManagementWithdrawalsRecordComponent implements OnIni | ||||
|  | ||||
|   private initST(): STColumn[] { | ||||
|     return [ | ||||
|       { title: '', index: 'key', type: 'checkbox' }, | ||||
|       { title: '提现时间', index: 'createTime', width: 180 }, | ||||
|       { title: '提现单号', index: 'refundApplyCode', width: 120 }, | ||||
|       { title: '网络货运人', index: 'ltdName', width: 140 }, | ||||
|       { title: '银行类型', index: 'bankTypeLabel', width: 100 }, | ||||
|       { title: '账户类型', index: 'bankTypeLabel', width: 100 }, | ||||
|       { title: '账户名称', index: 'bankAccountName', width: 140 }, | ||||
|       { title: '虚拟账户', index: 'virtualAccount', width: 100 }, | ||||
|       { title: '', index: 'key', type: 'checkbox', className: 'text-center' }, | ||||
|       { title: '提现时间', index: 'createTime', width: 180, className: 'text-center' }, | ||||
|       { title: '提现单号', index: 'refundApplyCode', width: 180, className: 'text-center' }, | ||||
|       { title: '网络货运人', index: 'ltdName', width: 220, className: 'text-center' }, | ||||
|       { title: '银行类型', index: 'bankTypeLabel', width: 100, className: 'text-center' }, | ||||
|       { title: '账户类型', index: 'bankTypeLabel', width: 100, className: 'text-center' }, | ||||
|       { title: '账户名称', index: 'bankAccountName', width: 220, className: 'text-center' }, | ||||
|       { title: '虚拟账户', index: 'virtualAccount', width: 180, className: 'text-center' }, | ||||
|       { | ||||
|         title: '提现金额', | ||||
|         index: 'amount', | ||||
|         width: 120, | ||||
|         width: 150, | ||||
|         type: 'widget', | ||||
|         className: 'text-right', | ||||
|         widget: { type: 'currency-chy', params: ({ record }) => ({ value: record.amount }) } | ||||
|       }, | ||||
|       { title: '提现银行账户', render: 'bankCardNumber', width: 180 }, | ||||
|       { title: '提现状态', index: 'refundStatusLabel', width: 100 }, | ||||
|       { title: '银行流水号', index: 'bankSerialNumber', width: 120 }, | ||||
|       { title: '核心交易流水', index: 'coreSerNo', width: 120 }, | ||||
|       { title: '失败原因', index: 'rejectionCause', width: 150, format: item => item.failCause || item.rejectionCause }, | ||||
|       { title: '提现银行账户', render: 'bankCardNumber', width: 200, className: 'text-center' }, | ||||
|       { title: '提现状态', index: 'refundStatusLabel', width: 100, className: 'text-center' }, | ||||
|       { title: '银行流水号', index: 'bankSerialNumber', width: 160, className: 'text-center' }, | ||||
|       { title: '核心交易流水', index: 'coreSerNo', width: 180, className: 'text-center' }, | ||||
|       { title: '失败原因', index: 'rejectionCause', width: 200, format: item => item.failCause, className: 'text-center' }, | ||||
|       { | ||||
|         title: '操作', | ||||
|         fixed: 'right', | ||||
| @ -278,6 +313,11 @@ export class PartnerAccountManagementWithdrawalsRecordComponent implements OnIni | ||||
|                 ltdId: item.ltdId | ||||
|               }) | ||||
|           }, | ||||
|           { | ||||
|             text: '查看原因', | ||||
|             iif: item => item.refundStatus === '4', | ||||
|             click: item => this.showReason(item) | ||||
|           }, | ||||
|           { | ||||
|             text: '审核', | ||||
|             iif: item => item.refundStatus === '1', | ||||
|  | ||||
							
								
								
									
										236
									
								
								src/app/shared/utils/deal-precision.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										236
									
								
								src/app/shared/utils/deal-precision.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,236 @@ | ||||
| /** | ||||
|  * 操作符类型运算符 | ||||
|  * +:加法运算 | ||||
|  * -:减法运算 | ||||
|  * *:乘法运算 | ||||
|  * /:除法运算 | ||||
|  */ | ||||
| type OperationType = '+' | '-' | '*' | '/'; | ||||
|  | ||||
| class Big { | ||||
|   /** | ||||
|    * Big值 | ||||
|    */ | ||||
|   private v: number; | ||||
|   /** | ||||
|    * 构造函数 | ||||
|    * @param v 初始值 | ||||
|    */ | ||||
|   constructor(v: number) { | ||||
|     this.v = v; | ||||
|   } | ||||
|   /** | ||||
|    * 转换整数,返回倍数及整数值,比如 | ||||
|    * 100  >>> { times: 1, num: 100 }   ===> 100 | ||||
|    * 3.14 >>> { times: 100, num: 3.14} ===> 314 | ||||
|    * @param n number | ||||
|    */ | ||||
|   private toInteger(n: number) { | ||||
|     const ret = { times: 1, num: 0 }; | ||||
|     if (Number.isInteger(n)) { | ||||
|       ret.num = n; | ||||
|       return ret; | ||||
|     } | ||||
|     ret.times = Math.pow(10, n.toString().split('.')[1].length); | ||||
|     ret.num = parseInt((n * ret.times + 0.5).toString(), 10); | ||||
|     return ret; | ||||
|   } | ||||
|   /** | ||||
|    * 执行运算 | ||||
|    * @param m 数值m | ||||
|    * @param n 数值n | ||||
|    * @param key 运算符 | ||||
|    */ | ||||
|   private operation(m: number = 0, n: number = 0, key: OperationType) { | ||||
|     const o1 = this.toInteger(m); | ||||
|     const o2 = this.toInteger(n); | ||||
|  | ||||
|     const n1 = o1.num; | ||||
|     const n2 = o2.num; | ||||
|  | ||||
|     const t1 = o1.times; | ||||
|     const t2 = o2.times; | ||||
|  | ||||
|     const max = Math.max(t1, t2); | ||||
|     let result = 0; | ||||
|     switch (key) { | ||||
|       case '+': | ||||
|         if (t1 === t2) { | ||||
|           // 两个小数位数相同 | ||||
|           result = n1 + n2; | ||||
|         } else if (t1 > t2) { | ||||
|           // o1 小数位 大于 o2 | ||||
|           result = n1 + n2 * (t1 / t2); | ||||
|         } else { | ||||
|           // o1 小数位 小于 o2 | ||||
|           result = n1 * (t2 / t1) + n2; | ||||
|         } | ||||
|         result /= max; | ||||
|         break; | ||||
|       case '-': | ||||
|         if (t1 === t2) { | ||||
|           result = n1 - n2; | ||||
|         } else if (t1 > t2) { | ||||
|           result = n1 - n2 * (t1 / t2); | ||||
|         } else { | ||||
|           result = n1 * (t2 / t1) - n2; | ||||
|         } | ||||
|         result /= max; | ||||
|         break; | ||||
|       case '*': | ||||
|         result = (n1 * n2) / (t1 * t2); | ||||
|         break; | ||||
|       case '/': | ||||
|         result = (n1 * t2) / (t1 * n2); | ||||
|         break; | ||||
|       default: | ||||
|         result = 0; | ||||
|     } | ||||
|     return new Big(result); | ||||
|   } | ||||
|   /** | ||||
|    * 数值化 | ||||
|    * @param n | ||||
|    */ | ||||
|   private numeric(n: number | Big) { | ||||
|     return n instanceof Big ? n.v : n; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 加法运算 | ||||
|    * @param n | ||||
|    */ | ||||
|   public plus(n: number | Big) { | ||||
|     return this.operation(this.v, this.numeric(n), '+'); | ||||
|   } | ||||
|   /** | ||||
|    * 减法运算 | ||||
|    * @param n | ||||
|    */ | ||||
|   public minus(n: number | Big) { | ||||
|     return this.operation(this.v, this.numeric(n), '-'); | ||||
|   } | ||||
|   /** | ||||
|    * 乘法运算 | ||||
|    * @param n | ||||
|    */ | ||||
|   public multipliedBy(n: number | Big) { | ||||
|     return this.operation(this.v, this.numeric(n), '*'); | ||||
|   } | ||||
|   /** | ||||
|    * 除法运算 | ||||
|    * @param n | ||||
|    */ | ||||
|   public dividedBy(n: number | Big) { | ||||
|     return this.operation(this.v, this.numeric(n), '/'); | ||||
|   } | ||||
|   /** | ||||
|    * 解析结果 | ||||
|    */ | ||||
|   public parse() { | ||||
|     return this.v; | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 小数点后固定指定位数,比如固定小数点后5位数字,则有 | ||||
|    * 30 ==> 30.00000 | ||||
|    * 3.14 ===> 3.14000 | ||||
|    * @param n | ||||
|    */ | ||||
|   public static digits(v: number | Big, len: number = 2) { | ||||
|     if (Number.isInteger(v)) { | ||||
|       return `${v}.${Array(len).fill(0).join('')}`; | ||||
|     } else { | ||||
|       const [prefix, suffix] = v.toString().split('.'); | ||||
|       const sLen = suffix.length; | ||||
|       if (sLen > len) { | ||||
|         return `${prefix}.${suffix.slice(0, len)}`; | ||||
|       } else if (sLen < len) { | ||||
|         return `${prefix}.${suffix}${Array(len - sLen) | ||||
|           .fill(0) | ||||
|           .join('')}`; | ||||
|       } else { | ||||
|         return `${prefix}.${suffix}`; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   public digits(len: number) { | ||||
|     return Big.digits(this.v, len); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 人民币格式处理 | ||||
|    * - 非数字:返回0 | ||||
|    * - 整数:直接返回 | ||||
|    * - 小数:保留小数点后两位,超出两位则截取 | ||||
|    * @param v | ||||
|    */ | ||||
|   public static rmb(v: string | number) { | ||||
|     if (isNaN(Number(v))) { | ||||
|       return '0'; | ||||
|     } else { | ||||
|       const foo = v.toString(); | ||||
|       if (/^[0-9]+$/.test(foo)) { | ||||
|         return foo; | ||||
|       } else { | ||||
|         const [prefix, suffix] = foo.split('.'); | ||||
|         const sLen = suffix.length; | ||||
|         if (sLen > 2) { | ||||
|           return `${prefix}.${suffix.slice(0, 2)}`; | ||||
|         } else if (sLen < 2) { | ||||
|           return `${foo}0`; | ||||
|         } else { | ||||
|           return foo; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   public rmb() { | ||||
|     return Big.rmb(this.v); | ||||
|   } | ||||
|   /** | ||||
|    * 切割数字 | ||||
|    * @param v | ||||
|    */ | ||||
|   public static split(v: string | number) { | ||||
|     if (isNaN(Number(v))) { | ||||
|       return []; | ||||
|     } else { | ||||
|       return v | ||||
|         .toString() | ||||
|         .split('.') | ||||
|         .map((item, i) => { | ||||
|           if (i === 1) { | ||||
|             return item && item.length < 2 ? `${item}0` : item; | ||||
|           } | ||||
|           return item; | ||||
|         }); | ||||
|     } | ||||
|   } | ||||
|   public split() { | ||||
|     return Big.split(this.v); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 省略 --> 如果超过1万,则返回万制,转换后小数点后保留两位 | ||||
|    * 比如:12345 返回 1.23万 | ||||
|    * @param v | ||||
|    */ | ||||
|   public static ellipsis(v: string | number) { | ||||
|     // 如果不是数值类型并且转换之后不为数字,则直接返回传入值 | ||||
|     if (isNaN(Number(v))) { | ||||
|       return v.toString(); | ||||
|     } | ||||
|     // 如果传入数值小于1万则没必要转换,直接返回 | ||||
|     if (+v < 10000) { | ||||
|       return v.toString(); | ||||
|     } | ||||
|     // 超过1万,处理之后再返回 | ||||
|     return Big.rmb(+v / 10000) + '万'; | ||||
|   } | ||||
|   public ellipsis(v: string | number) { | ||||
|     return Big.ellipsis(this.v); | ||||
|   } | ||||
| } | ||||
|  | ||||
| export default Big; | ||||
| @ -551,8 +551,7 @@ | ||||
|                 }, | ||||
|                 { | ||||
|                   "text": "提现记录", | ||||
|                   "link": "/partner/account-management/withdraw-record", | ||||
|                   "hide": true | ||||
|                   "link": "/partner/account-management/withdraw-record" | ||||
|                 }, | ||||
|                 { | ||||
|                   "text": "提现详情", | ||||
|  | ||||
		Reference in New Issue
	
	Block a user