Compare commits
78 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
04e4a3f407 | |
|
|
7400a45a4d | |
|
|
a0f1f2ad94 | |
|
|
c0a90482c0 | |
|
|
24b70acb75 | |
|
|
a5eab29e4a | |
|
|
61dd91dbc2 | |
|
|
1c96e5e8f7 | |
|
|
25b6f2d3f1 | |
|
|
6c511ac26c | |
|
|
2e2a78dcb7 | |
|
|
a4a5ef9bd0 | |
|
|
b6c9b5646a | |
|
|
f9882824f9 | |
|
|
af82979538 | |
|
|
eee7122e77 | |
|
|
6efb7c7893 | |
|
|
e20d7f8dda | |
|
|
148dd4f368 | |
|
|
817bbdf896 | |
|
|
9faf41d174 | |
|
|
ebe38dabf9 | |
|
|
40c62219fc | |
|
|
f48c063667 | |
|
|
6cb3dbf176 | |
|
|
2e23da7c66 | |
|
|
4cbd8a6f1c | |
|
|
9111ce544e | |
|
|
600210db9d | |
|
|
7988d0086e | |
|
|
ee67b98f2f | |
|
|
6e775b7db7 | |
|
|
6050d0b8ba | |
|
|
046a840914 | |
|
|
24ced13584 | |
|
|
c9503665a8 | |
|
|
a4f412d1c4 | |
|
|
fb0968d106 | |
|
|
355d700046 | |
|
|
bb1ba49186 | |
|
|
8dda8992f0 | |
|
|
7ed6de4832 | |
|
|
0b767f5bc3 | |
|
|
96af114bc2 | |
|
|
04fd2bb1c2 | |
|
|
975260e9c3 | |
|
|
6dfb18e03e | |
|
|
c2d9bbab0b | |
|
|
f7734f4560 | |
|
|
0cd74cd00b | |
|
|
bd65e46249 | |
|
|
95d3fd7a8f | |
|
|
b7b694434d | |
|
|
217cf81d88 | |
|
|
7a24c6451e | |
|
|
c44723198d | |
|
|
f538736894 | |
|
|
67cc36a050 | |
|
|
9ca73eaf70 | |
|
|
cae3570582 | |
|
|
3a9e9ba00b | |
|
|
76159154e0 | |
|
|
554c12ccb3 | |
|
|
189979a5b7 | |
|
|
887f6c9b4b | |
|
|
139546193b | |
|
|
e019d0a5b4 | |
|
|
28fada2229 | |
|
|
da06c75a92 | |
|
|
f802fa0f78 | |
|
|
69ad996ed9 | |
|
|
559034b85e | |
|
|
fef496cefe | |
|
|
bb6c8c539b | |
|
|
bde10e70ed | |
|
|
237f1e082e | |
|
|
8fa35952f9 | |
|
|
84619cc27f |
|
|
@ -53,3 +53,4 @@ unpackage/
|
|||
|
||||
# [package-lock.json。 已放开,请添加到假定未更改文件 ]
|
||||
# package-lock.json
|
||||
/.history/
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
# syntax = docker/dockerfile:experimental
|
||||
# 使用了 Docker 特性 Buildx 请开启相关特性
|
||||
|
||||
FROM node:16-alpine AS builder
|
||||
|
||||
ARG PLATFORM=$PLATFORM
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
COPY . /workspace
|
||||
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
|
||||
RUN apk update
|
||||
RUN apk add --no-cache --virtual .build-deps alpine-sdk python3
|
||||
|
||||
RUN npm config set registry https://registry.npmmirror.com
|
||||
|
||||
RUN cd /workspace/jeepay-ui-${PLATFORM} && npm install && npm run build
|
||||
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
ARG PLATFORM=$PLATFORM
|
||||
|
||||
ENV BACKEND_HOST $BACKEND_HOST
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
COPY --from=builder /workspace/jeepay-ui-${PLATFORM}/dist /workspace
|
||||
RUN chmod a+r /workspace
|
||||
|
||||
RUN rm -rf /etc/nginx/conf.d/default.conf
|
||||
|
||||
COPY --from=builder /workspace/default.conf.template /etc/nginx/templates/default.conf.template
|
||||
|
||||
# 编译命令
|
||||
# docker buildx build . --build-arg PLATFORM=cashier -t jeepay-payment:latest
|
||||
# docker buildx build . --build-arg PLATFORM=manager -t jeepay-manager:latest
|
||||
# docker buildx build . --build-arg PLATFORM=merchant -t jeepay-merchant:latest
|
||||
#
|
||||
# 如果你需要多平台镜像,你可以使用 --platform linux/amd64,linux/arm64
|
||||
# 比如 docker buildx build . --build-arg PLATFORM=cashier -t jeepay-ui-cashier:latest --platform linux/amd64,linux/arm64
|
||||
#
|
||||
# 启动命令
|
||||
# docker run -d -p 9226:80 -e BACKEND_HOST=172.20.0.9216 jeepay-ui-cashier:latest
|
||||
# docker run -d -p 9227:80 -e BACKEND_HOST=172.20.0.9217 jeepay-ui-manager:latest
|
||||
# docker run -d -p 9228:80 -e BACKEND_HOST=172.20.0.9218 jeepay-ui-merchant:latest
|
||||
156
README.md
156
README.md
|
|
@ -1,152 +1,42 @@
|
|||
<p align="center">
|
||||
<a href="https://www.jeepay.vip"><img src="https://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/jeepay_logo.svg"></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<strong>适合互联网企业使用的开源支付系统</strong>
|
||||
</p>
|
||||
<p align="center">
|
||||
👉 <a href="https://www.jeepay.vip">https://www.jeepay.vip</a> 👈
|
||||
</p>
|
||||
# Jeepay UI
|
||||
为Jeepay对应的前端项目,包括运营平台、商户系统、聚合码收银台。前端技术以vue为主,框架使用Ant Design Vue开发。
|
||||
|
||||
<p align="center">
|
||||
<a target="_blank" href="https://spring.io/projects/spring-boot">
|
||||
<img src="https://img.shields.io/badge/spring%20boot-2.4.5-yellowgreen" />
|
||||
</a>
|
||||
<a target="_blank" href="https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html">
|
||||
<img src="https://img.shields.io/badge/JDK-8+-green.svg" />
|
||||
</a>
|
||||
<a target="_blank" href="http://www.gnu.org/licenses/lgpl.html">
|
||||
<img src="https://img.shields.io/badge/license-LGPL--3.0-blue" />
|
||||
</a>
|
||||
<a href='https://gitee.com/jeequan/jeepay/stargazers' target="_blank">
|
||||
<img src='https://gitee.com/jeequan/jeepay/badge/star.svg?theme=gvp' alt='star'></img>
|
||||
</a>
|
||||
<a target="_blank" href='https://github.com/jeequan/jeepay'>
|
||||
<img src="https://img.shields.io/github/stars/jeequan/jeepay.svg?style=social" alt="github star"/>
|
||||
</a>
|
||||
</p>
|
||||
Java服务端项目:https://gitee.com/jeequan/jeepay
|
||||
|
||||
<br/>
|
||||
<p align="center">
|
||||
<a href="https://jq.qq.com/?_wv=1027&k=94WnXmdL">
|
||||
<img src="https://img.shields.io/badge/qq%E7%BE%A4%E2%91%A0-635647058-critical"/>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## 📚 项目介绍
|
||||
|
||||
Jeepay是一套适合互联网企业使用的开源支付系统,支持多渠道服务商和普通商户模式。已对接`微信支付`,`支付宝`,`云闪付`官方接口,支持聚合码支付。
|
||||
|
||||
Jeepay使用`Spring Boot`和`Ant Design Vue`开发,集成`Spring Security`实现权限管理功能,是一套非常实用的web开发框架。
|
||||
|
||||
### 🎁 名称的由来
|
||||
|
||||
Jeepay = Jee + pay,是由原XxPay支付系统作者带领团队开发,“Jee”是公司计全科技名称的表示,pay表示支付。中文名称为计全支付,释为:计出万全、支付安全,让支付更加方便安全。
|
||||
|
||||
|
||||
### 🍟 项目体验
|
||||
|
||||
- Jeepay支付流程体验:[https://www.jeequan.com/demo/jeepay_cashier.html](https://www.jeequan.com/demo/jeepay_cashier.html "Jeepay支付体验")
|
||||
- Jeepay运营平台和商户系统演体验:[https://www.jeequan.com/doc/detail_84.html](https://www.jeequan.com/doc/detail_84.html "Jeepay支付系统体验")
|
||||
- Jeepay项目文档:[https://www.jeepay.vip](https://www.jeepay.vip "Jeepay项目文档")
|
||||
|
||||
### 🍎 项目特点
|
||||
|
||||
* 支持多渠道对接,支付网关自动路由
|
||||
* 已对接`微信`服务商和普通商户接口,支持`V2`和`V3`接口
|
||||
* 已对接`支付宝`服务商和普通商户接口,支持RSA和RSA2签名
|
||||
* 已对接`云闪付`服务商接口,可选择多家支付机构
|
||||
* 提供http形式接口,提供各语言的`sdk`实现,方便对接
|
||||
* 接口请求和响应数据采用签名机制,保证交易安全可靠
|
||||
* 系统安全,支持`分布式`部署,`高并发`
|
||||
* 管理端包括`运营平台`和`商户系统`
|
||||
* 管理平台操作界面简洁、易用
|
||||
* 支付平台到商户系统的订单通知使用MQ实现,保证了高可用,消息可达
|
||||
* 支付渠道的接口参数配置界面自动化生成
|
||||
* 使用`spring security`实现权限管理
|
||||
* 前后端分离架构,方便二次开发
|
||||
* 由原`XxPay`团队开发,有着多年支付系统开发经验
|
||||
|
||||
## 🥞 系统架构
|
||||
|
||||
> Jeepay计全支付系统架构图
|
||||
|
||||

|
||||
|
||||
> 核心技术栈
|
||||
|
||||
| 软件名称 | 描述 | 版本
|
||||
|---|---|---
|
||||
|Jdk | Java环境 | 1.8
|
||||
|Spring Boot | 开发框架 | 2.4.5
|
||||
|Redis | 分布式缓存 | 3.2.8 或 高版本
|
||||
|MySQL | 数据库 | 5.7.X
|
||||
|ActiveMQ | 消息中间件 | 5.15.8 或 高版本
|
||||
|[Ant Design Vue](https://www.antdv.com/docs/vue/introduce-cn/) | Ant Design的Vue实现,前端开发使用 | 2.1.2
|
||||
|[MyBatis-Plus](https://mp.baomidou.com/) | MyBatis增强工具 | 3.4.2
|
||||
|[WxJava](https://gitee.com/binary/weixin-java-tools) | 微新开发Java SDK | 4.0.0
|
||||
|[Hutool](https://www.hutool.cn/) | Java工具类库 | 5.6.6
|
||||
|
||||
> 项目结构
|
||||
> 目录结构
|
||||
|
||||
```lua
|
||||
jeepay -- https://gitee.com/jeequan/jeepay
|
||||
|
||||
jeepay-ui
|
||||
├── jeepay-ui-manager -- 运营平台前端vue代码
|
||||
├── jeepay-ui-merchant -- 商户系统前端vue代码
|
||||
└── jeepay-ui-cashier -- 支付收银台vue代码
|
||||
├── jeepay-ui-cashier -- 聚合收银台项目
|
||||
├── jeepay-ui-manager -- 运营平台web管理端
|
||||
└── jeepay-ui-merchant -- 商户系统web管理端
|
||||
```
|
||||
> 参考命令
|
||||
|
||||
> 开发部署
|
||||
node版本要求:`<= 16 `
|
||||
|
||||
- 系统开发:[https://www.jeepay.vip/#/develop/dev_serv](https://www.jeepay.vip/#/develop/dev_serv)
|
||||
- 通道对接:[https://www.jeepay.vip/#/develop/dev_channel](https://www.jeepay.vip/#/develop/dev_channel)
|
||||
- 线上部署:[https://www.jeepay.vip/#/develop/deploy](https://www.jeepay.vip/#/develop/deploy)
|
||||
- 接口文档:[https://www.jeepay.vip/#/interface/payment_api](https://www.jeepay.vip/#/interface/payment_api)
|
||||
#### 参考命令
|
||||
|
||||
## 🍿 功能模块
|
||||
``` bash
|
||||
# 拉取源码完毕后请先安装依赖, 进入项目根目录命令行执行:
|
||||
|
||||
> Jeepay运营平台功能
|
||||
> npm install
|
||||
|
||||

|
||||
# 本地启动项目(开发环境):
|
||||
|
||||
> Jeepay商户系统功能
|
||||
1. 打开根目录下文件".env.development", 修改请求服务器地址"VUE_APP_API_BASE_URL";
|
||||
|
||||

|
||||
2. 在项目根目录命令行执行:
|
||||
|
||||
## 🍯 系统截图
|
||||
> npm run serve
|
||||
|
||||
`以下截图是从实际已完成功能界面截取,截图时间为:2021-05-29 02:05`
|
||||
# 打包(生产环境):
|
||||
|
||||

|
||||
1. 打开根目录下文件".env", 修改请求服务器地址"VUE_APP_API_BASE_URL";
|
||||
|
||||

|
||||
2. 在项目根目录命令行执行:
|
||||
|
||||

|
||||
> npm run build
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 🥪 关于我们
|
||||
***
|
||||
微信扫描下面二维码,关注官方公众号:计全科技,获取更多精彩内容。
|
||||
|
||||

|
||||
3. 文件将输出到 [/dist]目录, 拷贝到web服务器即可。
|
||||
```
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name localhost;
|
||||
root /workspace/;
|
||||
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
location /api/ {
|
||||
proxy_next_upstream http_502 http_504 error timeout invalid_header;
|
||||
|
||||
proxy_pass http://$BACKEND_HOST;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# favicon.ico
|
||||
location = /favicon.ico {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# robots.txt
|
||||
location = /robots.txt {
|
||||
log_not_found off;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# assets, media
|
||||
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
|
||||
expires 7d;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# svg, fonts
|
||||
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
expires 7d;
|
||||
access_log off;
|
||||
}
|
||||
|
||||
# gzip
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
|
||||
}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
NODE_ENV=production
|
||||
VUE_APP_BASE_URL=/
|
||||
VUE_APP_BASE_URL=
|
||||
VUE_APP_API_BASE_URL=
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jeepay-ui-cashier",
|
||||
"version": "0.1.0",
|
||||
"version": "1.10.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
@ -1949,6 +1949,44 @@
|
|||
"integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1618995547052&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.nlark.com/chalk/download/chalk-4.1.2.tgz?cache=0&sync_timestamp=1627646734234&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.2.tgz",
|
||||
"integrity": "sha1-qsTit3NKdAhnrrFr8CqtVWoeegE=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.nlark.com/color-convert/download/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.nlark.com/color-name/download/color-name-1.1.4.tgz",
|
||||
"integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npm.taobao.org/debug/download/debug-4.3.1.tgz?cache=0&sync_timestamp=1607566551397&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdebug%2Fdownload%2Fdebug-4.3.1.tgz",
|
||||
|
|
@ -1975,6 +2013,23 @@
|
|||
"integrity": "sha1-/wQLKwhTsjw9MQJ1I3BvGIXXa+4=",
|
||||
"dev": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.nlark.com/has-flag/download/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.nlark.com/json5/download/json5-2.2.0.tgz",
|
||||
"integrity": "sha1-Lf7+cgxrpSXZ69kJlQ8FFTFsiaM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/jsonfile/download/jsonfile-4.0.0.tgz?cache=0&sync_timestamp=1604161937969&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjsonfile%2Fdownload%2Fjsonfile-4.0.0.tgz",
|
||||
|
|
@ -1984,6 +2039,18 @@
|
|||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
|
||||
"integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npm.taobao.org/ms/download/ms-2.1.2.tgz?cache=0&sync_timestamp=1607433856030&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fms%2Fdownload%2Fms-2.1.2.tgz",
|
||||
|
|
@ -1998,6 +2065,28 @@
|
|||
"requires": {
|
||||
"minipass": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.nlark.com/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1626703414084&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
|
||||
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"vue-loader-v16": {
|
||||
"version": "npm:vue-loader@16.6.0",
|
||||
"resolved": "https://registry.nlark.com/vue-loader/download/vue-loader-16.6.0.tgz?cache=0&sync_timestamp=1632217703123&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue-loader%2Fdownload%2Fvue-loader-16.6.0.tgz",
|
||||
"integrity": "sha1-B03Rs97jCTfQpawi3GP+86nPoV8=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
"loader-utils": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -14254,97 +14343,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"vue-loader-v16": {
|
||||
"version": "npm:vue-loader@16.2.0",
|
||||
"resolved": "https://registry.nlark.com/vue-loader/download/vue-loader-16.2.0.tgz?cache=0&sync_timestamp=1620717743226&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fvue-loader%2Fdownload%2Fvue-loader-16.2.0.tgz",
|
||||
"integrity": "sha1-BGpTMI3Ufljv4g3ewe3sAnzjtG4=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chalk": "^4.1.0",
|
||||
"hash-sum": "^2.0.0",
|
||||
"loader-utils": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.nlark.com/ansi-styles/download/ansi-styles-4.3.0.tgz?cache=0&sync_timestamp=1618995547052&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fansi-styles%2Fdownload%2Fansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha1-7dgDYornHATIWuegkG7a00tkiTc=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-convert": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.nlark.com/chalk/download/chalk-4.1.1.tgz?cache=0&sync_timestamp=1618995354302&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fchalk%2Fdownload%2Fchalk-4.1.1.tgz",
|
||||
"integrity": "sha1-yAs/qyi/Y3HmhjMl7uZ+YYt35q0=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npm.taobao.org/color-convert/download/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha1-ctOmjVmMm9s68q0ehPIdiWq9TeM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"color-name": "~1.1.4"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npm.taobao.org/color-name/download/color-name-1.1.4.tgz",
|
||||
"integrity": "sha1-wqCah6y95pVD3m9j+jmVyCbFNqI=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1618559744568&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz",
|
||||
"integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"json5": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npm.taobao.org/json5/download/json5-2.2.0.tgz",
|
||||
"integrity": "sha1-Lf7+cgxrpSXZ69kJlQ8FFTFsiaM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/loader-utils/download/loader-utils-2.0.0.tgz",
|
||||
"integrity": "sha1-5MrOW4FtQloWa18JfhDNErNgZLA=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^2.1.2"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.nlark.com/supports-color/download/supports-color-7.2.0.tgz?cache=0&sync_timestamp=1622293630895&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fsupports-color%2Fdownload%2Fsupports-color-7.2.0.tgz",
|
||||
"integrity": "sha1-G33NyzK4E4gBs+R4umpRyqiWSNo=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"has-flag": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"vue-router": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.nlark.com/vue-router/download/vue-router-3.5.1.tgz",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jeepay-ui-cashier",
|
||||
"version": "1.1.1",
|
||||
"version": "1.10.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
|
|
|
|||
|
|
@ -35,15 +35,15 @@ router.beforeEach((to, from, next) => {
|
|||
}
|
||||
|
||||
if(!config.cacheToken) {
|
||||
next({ name: config.errorPageRouteName, params: { errInfo: "token参数有误!" } })
|
||||
next({ name: config.errorPageRouteName, params: { errInfo: "请通过二维码进入支付页面!" } })
|
||||
return false;
|
||||
}
|
||||
|
||||
//获取不到支付类型, 需要跳转到错误页面
|
||||
if( ! wayCode.getPayWay() ) {
|
||||
next({ name: config.errorPageRouteName, params: { errInfo: "不支持的支付方式!" } })
|
||||
return false;
|
||||
}
|
||||
//获取不到支付类型, 需要跳转到错误页面
|
||||
if( ! wayCode.getPayWay() ) {
|
||||
next({ name: config.errorPageRouteName, params: { errInfo: "不支持的支付方式! 请在微信/支付宝/银联应用内扫码进入!" } })
|
||||
return false;
|
||||
}
|
||||
|
||||
next()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="center">
|
||||
<img src="../assets/icon/error.svg" alt="">
|
||||
<p>支付失败,请重新扫码进入!</p>
|
||||
<!-- <p>支付失败,请重新扫码进入!</p>-->
|
||||
<p>错误: {{msg}}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -20,7 +20,7 @@ export default {
|
|||
|
||||
},
|
||||
mounted() {
|
||||
this.msg = this.$route.params.errInfo
|
||||
this.msg = this.$route.params.errInfo || '请重新扫码进入!'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jeepay-ui-manager",
|
||||
"version": "1.1.1",
|
||||
"version": "1.10.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ export const API_URL_ISV_PAYCONFIGS_LIST = '/api/isv/payConfigs'
|
|||
export const API_URL_MCH_PAYCONFIGS_LIST = '/api/mch/payConfigs'
|
||||
/** 商户支付通道配置 **/
|
||||
export const API_URL_MCH_PAYPASSAGE_LIST = '/api/mch/payPassages'
|
||||
/** 转账订单管理 **/
|
||||
export const API_URL_TRANSFER_ORDER_LIST = '/api/transferOrders'
|
||||
|
||||
/** 上传图片/文件地址 **/
|
||||
export const upload = {
|
||||
|
|
@ -291,3 +293,11 @@ export function mchNotifyResend (notifyId) {
|
|||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
||||
/** 查询支付宝授权地址URL **/
|
||||
export function queryAlipayIsvsubMchAuthUrl (mchAppId) {
|
||||
return request.request({
|
||||
url: '/api/mch/payConfigs/alipayIsvsubMchAuthUrls/' + mchAppId,
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<template v-slot:links>
|
||||
</template>
|
||||
<template v-slot:copyright>
|
||||
<a href="http://www.jeequan.com" target="_blank">@计全科技</a>
|
||||
Copyright © 2023 <a href="http://www.jeequan.com" target="_blank">jeequan.com</a>. All rights reserved.
|
||||
</template>
|
||||
</global-footer>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ export default {
|
|||
}
|
||||
.jeepay-card-add-text {
|
||||
padding-top: 5px;
|
||||
font-size: 16px;
|
||||
font-size: 13px;
|
||||
color: rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@
|
|||
:row-selection="rowSelection"
|
||||
:rowKey="rowKey"
|
||||
:scroll="{ x: scrollX }"
|
||||
:customRow="(record, index) => {
|
||||
if(!tableRowCrossColor){
|
||||
return {};
|
||||
}
|
||||
return { style: { 'background-color': index % 2 == 0 ? '#FCFCFC' : '#FFFFFF'} }
|
||||
}"
|
||||
>
|
||||
<!-- 自定义列插槽, 参考:https://github.com/feseed/admin-antd-vue/blob/master/src/components/ShTable.vue -->
|
||||
<!-- eslint-disable-next-line -->
|
||||
|
|
@ -41,7 +47,8 @@ export default {
|
|||
pageSize: { type: Number, default: 10 }, // 默认每页条数
|
||||
rowSelection: Object, // checkbox选择
|
||||
rowKey: { type: [String, Function] }, // 定义rowKey 如果不定义将会出现(树状结构出问题, checkbox不消失等)
|
||||
scrollX: { type: Number, default: 800 } // 表格显示滚动条的宽度
|
||||
scrollX: { type: Number, default: 500 }, // 表格显示滚动条的宽度
|
||||
tableRowCrossColor: { type: Boolean, default: false } // 是隔行换色
|
||||
},
|
||||
|
||||
data () {
|
||||
|
|
@ -117,3 +124,23 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
||||
// 调整antdv 的table默认padding高度
|
||||
.ant-table-fixed{
|
||||
tr{
|
||||
th{
|
||||
padding: 8px 8px !important;
|
||||
}
|
||||
th:first-child{ // 第一个表格 左填充16, 其他为8
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
td{
|
||||
padding: 8px 8px !important;
|
||||
}
|
||||
td:first-child{
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ export default {
|
|||
}
|
||||
return <div style="display:flex; justify-content: space-evenly;"> {firstEL}
|
||||
<a-dropdown>
|
||||
<a-button class="ant-dropdown-link" type="link" style="line-height:32px">更多<a-icon type="down" /></a-button>
|
||||
<a-button class="ant-dropdown-link" type="link" style="">更多<a-icon type="down" /></a-button>
|
||||
<a-menu slot="overlay">
|
||||
{menuEL}
|
||||
</a-menu>
|
||||
|
|
@ -41,3 +41,9 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
//当前页面的按钮, 减少padding
|
||||
button { padding: 8px !important;}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ export const asyncRouteDefine = {
|
|||
'MchAppPage': { defaultPath: '/apps', component: () => import ('@/views/mchApp/List') }, // 商户应用列表
|
||||
'PayOrderListPage': { defaultPath: '/payOrder', component: () => import('@/views/order/pay/PayOrderList') }, // 支付订单列表
|
||||
'RefundOrderListPage': { defaultPath: '/refundOrder', component: () => import('@/views/order/refund/RefundOrderList') }, // 退款订单列表
|
||||
'TransferOrderListPage': { defaultPath: '/transferOrder', component: () => import('@/views/order/transfer/TransferOrderList') }, // 转账订单
|
||||
'MchNotifyListPage': { defaultPath: '/notify', component: () => import('@/views/order/notify/MchNotifyList') }, // 商户通知列表
|
||||
'SysConfigPage': { defaultPath: '/config', component: () => import('@/views/sys/config/SysConfig') }, // 系统配置
|
||||
'SysLogPage': { defaultPath: '/log', component: () => import('@/views/sys/log/SysLog') } // 系统日志
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
:i18nRender="false"
|
||||
v-bind="settings"
|
||||
:breadcrumbRender="handleBreadcrumbRender"
|
||||
:siderWidth="210"
|
||||
>
|
||||
<!-- 1.0.0+ 版本 pro-layout 提供 API,
|
||||
我们推荐使用这种方式进行 LOGO 和 title 自定义
|
||||
|
|
@ -34,6 +35,8 @@
|
|||
|
||||
<template v-slot:rightContentRender>
|
||||
<right-content :top-menu="settings.layout === 'topmenu'" :is-mobile="isMobile" :theme="settings.theme" />
|
||||
<a style="color: red; float: right; padding-right: 10px;" href="https://www.jeequan.com/product/jeepay4plus.html" target="_blank">Plus商业版</a>
|
||||
<a style="color: red; float: right; padding-right: 10px;" href="https://www.jeequan.com/ifstore/list.html" target="_blank">接口市场</a>
|
||||
</template>
|
||||
<!-- custom footer / 自定义Footer -->
|
||||
<template v-slot:footerRender>
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import './utils/filter' // global filter
|
|||
import './global.less' // global style
|
||||
import 'ant-design-vue/dist/antd.less'
|
||||
import infoBox from '@/utils/infoBox'
|
||||
import VueClipboard from 'vue-clipboard2' // 复制插件
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
|
|
@ -23,6 +24,7 @@ Vue.config.productionTip = false
|
|||
Vue.component('pro-layout', ProLayout)
|
||||
Vue.component('page-container', PageHeaderWrapper)
|
||||
Vue.component('page-header-wrapper', PageHeaderWrapper)
|
||||
Vue.use(VueClipboard) // 复制插件
|
||||
|
||||
/**
|
||||
* @description 全局注册权限验证
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ export const printANSI = () => {
|
|||
/ /_/ // __/ __/ /_/ / /_/ / /_/ /
|
||||
\\____/ \\___/\\___/ .___/\\__,_/\\__, /
|
||||
/_/ /____/
|
||||
:: Jeepay :: (v1.0.0.RELEASE)
|
||||
适合互联网企业使用的开源支付系统 : https://www.jeepay.vip
|
||||
:: Jeepay :: (v2.2.2.RELEASE)
|
||||
让支付接入更简单 : https://www.jeequan.com
|
||||
`
|
||||
|
||||
console.log(`%c${text}`, 'color: #fc4d50')
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@
|
|||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
:scrollX="1100"
|
||||
rowKey="isvName"
|
||||
rowKey="isvNo"
|
||||
>
|
||||
<template slot="isvNameSlot" slot-scope="{record}"><b>{{ record.isvName }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@
|
|||
<a-row :gutter="16">
|
||||
<a-col v-for="(item, key) in isvParams" :key="key" :span="item.type === 'text' ? 12 : 24">
|
||||
<a-form-model-item :label="item.desc" :prop="item.name" v-if="item.type === 'text' || item.type === 'textarea'">
|
||||
<a-input v-model="ifParams[item.name]" placeholder="请输入" :type="item.type" />
|
||||
<a-input v-if="item.star === '1'" v-model="ifParams[item.name]" :placeholder="ifParams[item.name + '_ph']" :type="item.type" />
|
||||
<a-input v-else v-model="ifParams[item.name]" placeholder="请输入" :type="item.type" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item :label="item.desc" :prop="item.name" v-else-if="item.type === 'radio'">
|
||||
<a-radio-group v-model="ifParams[item.name]">
|
||||
|
|
@ -113,19 +114,26 @@
|
|||
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
<!-- 支付参数配置页面组件 -->
|
||||
<WxpayPayConfig ref="wxpayPayConfig" :callbackFunc="refCardList" />
|
||||
<!-- 支付参数配置页面组件 -->
|
||||
<AlipayPayConfig ref="alipayPayConfig" :callbackFunc="refCardList" />
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JeepayCard from '@/components/JeepayCard/JeepayCard'
|
||||
import JeepayUpload from '@/components/JeepayUpload/JeepayUpload'
|
||||
import WxpayPayConfig from './custom/WxpayPayConfig'
|
||||
import AlipayPayConfig from './custom/AlipayPayConfig'
|
||||
import { API_URL_ISV_PAYCONFIGS_LIST, getIsvPayConfigUnique, req, upload } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
JeepayCard,
|
||||
JeepayUpload
|
||||
JeepayUpload,
|
||||
WxpayPayConfig,
|
||||
AlipayPayConfig
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
|
@ -149,13 +157,18 @@ export default {
|
|||
ifParamsRules: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
ifParams: function (o, n) {
|
||||
this.$set(this.ifParams, 'appSecret', this.ifParams.appSecret) // 解决appSecret 双向绑定数据不显示的问题
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
generoterRules () {
|
||||
const rules = {}
|
||||
let newItems = []
|
||||
this.isvParams.forEach(item => {
|
||||
newItems = []
|
||||
if (item.verify === 'required') {
|
||||
if (item.verify === 'required' && item.star !== '1') {
|
||||
newItems.push({
|
||||
required: true,
|
||||
message: '请输入' + item.desc,
|
||||
|
|
@ -183,56 +196,75 @@ export default {
|
|||
},
|
||||
// 支付参数配置
|
||||
editPayIfConfigFunc (record) {
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.isvParamFormModel !== undefined) {
|
||||
this.$refs.isvParamFormModel.resetFields()
|
||||
}
|
||||
this.childrenVisible = true // 打开支付参数配置抽屉
|
||||
this.saveObject = {} // 要保存的对象
|
||||
this.ifParams = {} // 参数配置对象
|
||||
this.isvParams = {} // 支付接口定义描述
|
||||
this.saveObject.infoId = this.isvNo
|
||||
this.saveObject.ifCode = record.ifCode
|
||||
this.saveObject.state = record.ifConfigState === 0 ? 0 : 1
|
||||
if (record.configPageType === 1) { // JSON渲染页面
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.isvParamFormModel !== undefined) {
|
||||
this.$refs.isvParamFormModel.resetFields()
|
||||
}
|
||||
this.childrenVisible = true // 打开支付参数配置抽屉
|
||||
this.saveObject = {} // 要保存的对象
|
||||
this.ifParams = {} // 参数配置对象
|
||||
this.isvParams = {} // 支付接口定义描述
|
||||
this.saveObject.infoId = this.isvNo
|
||||
this.saveObject.ifCode = record.ifCode
|
||||
this.saveObject.state = record.ifConfigState === 0 ? 0 : 1
|
||||
|
||||
if (!record) {
|
||||
return
|
||||
}
|
||||
// 获取支付参数
|
||||
getIsvPayConfigUnique(this.saveObject.infoId, this.saveObject.ifCode).then(res => {
|
||||
if (!res || !res.ifParams) {
|
||||
if (!record) {
|
||||
return
|
||||
}
|
||||
this.saveObject = res
|
||||
this.ifParams = JSON.parse(res.ifParams)
|
||||
})
|
||||
|
||||
const newItems = [] // 重新加载支付接口配置定义描述json
|
||||
JSON.parse(record.isvParams).forEach(item => {
|
||||
const radioItems = [] // 存放单选框value title
|
||||
if (item.type === 'radio') {
|
||||
const valueItems = item.values.split(',')
|
||||
const titleItems = item.titles.split(',')
|
||||
for (const i in valueItems) {
|
||||
radioItems.push({
|
||||
value: valueItems[i],
|
||||
title: titleItems[i]
|
||||
})
|
||||
const that = this
|
||||
// 获取支付参数
|
||||
getIsvPayConfigUnique(this.saveObject.infoId, this.saveObject.ifCode).then(res => {
|
||||
if (res && res.ifParams) {
|
||||
this.saveObject = res
|
||||
this.ifParams = JSON.parse(res.ifParams)
|
||||
}
|
||||
}
|
||||
newItems.push({
|
||||
name: item.name,
|
||||
desc: item.desc,
|
||||
type: item.type,
|
||||
verify: item.verify,
|
||||
values: radioItems
|
||||
})
|
||||
})
|
||||
|
||||
this.isvParams = newItems // 重新赋值接口定义描述
|
||||
this.generoterRules()
|
||||
const newItems = [] // 重新加载支付接口配置定义描述json
|
||||
JSON.parse(record.isvParams).forEach(item => {
|
||||
const radioItems = [] // 存放单选框value title
|
||||
if (item.type === 'radio') {
|
||||
const valueItems = item.values.split(',')
|
||||
const titleItems = item.titles.split(',')
|
||||
|
||||
for (const i in valueItems) {
|
||||
// 检查参数是否为数字类型 然后赋值给radio值
|
||||
let radioVal = valueItems[i]
|
||||
if (!isNaN((radioVal))) { radioVal = Number(radioVal) }
|
||||
|
||||
radioItems.push({
|
||||
value: radioVal,
|
||||
title: titleItems[i]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (item.star === '1') {
|
||||
that.ifParams[item.name + '_ph'] = that.ifParams[item.name] ? that.ifParams[item.name] : '请输入'
|
||||
if (that.ifParams[item.name]) {
|
||||
that.ifParams[item.name] = ''
|
||||
}
|
||||
}
|
||||
|
||||
newItems.push({
|
||||
name: item.name,
|
||||
desc: item.desc,
|
||||
type: item.type,
|
||||
verify: item.verify,
|
||||
values: radioItems,
|
||||
star: item.star // 脱敏标识 1-是
|
||||
})
|
||||
})
|
||||
that.isvParams = newItems // 重新赋值接口定义描述
|
||||
that.generoterRules()
|
||||
that.$forceUpdate()
|
||||
})
|
||||
} else if (record.configPageType === 2) { // 自定义配置页面,页面放在custom目录下,配置模块命名规则:if_code + PayConfig
|
||||
this.$refs[record.ifCode + 'PayConfig'].show(this.isvNo, record)
|
||||
}
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
|
|
@ -252,6 +284,13 @@ export default {
|
|||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
this.isvParams.forEach(item => {
|
||||
if (item.star === '1' && that.ifParams[item.name] === '') {
|
||||
that.ifParams[item.name] = undefined
|
||||
}
|
||||
that.ifParams[item.name + '_ph'] = undefined
|
||||
})
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
req.add(API_URL_ISV_PAYCONFIGS_LIST, reqParams).then(res => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,312 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
title="填写参数"
|
||||
width="40%"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:visible="visible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="支付接口费率" prop="ifRate">
|
||||
<a-input v-model="saveObject.ifRate" placeholder="请输入" suffix="%" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
<a-radio :value="1">
|
||||
启用
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
停用
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="备注" prop="remark">
|
||||
<a-input v-model="saveObject.remark" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
{{ saveObject.ifCode }} 服务商参数配置
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
<a-form-model ref="isvParamFormModel" :model="ifParams" layout="vertical" :rules="ifParamsRules">
|
||||
<a-row :gutter="16">
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="环境配置" prop="sandbox">
|
||||
<a-radio-group v-model="ifParams.sandbox">
|
||||
<a-radio :value="1">沙箱环境</a-radio>
|
||||
<a-radio :value="0">生产环境</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="合作伙伴身份(PID)" prop="pid">
|
||||
<a-input v-model="ifParams.pid" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppID" prop="appId">
|
||||
<a-input v-model="ifParams.appId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="应用私钥" prop="privateKey">
|
||||
<a-input v-model="ifParams.privateKey" :placeholder="ifParams.privateKey_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝公钥" prop="alipayPublicKey">
|
||||
<a-input v-model="ifParams.alipayPublicKey" :placeholder="ifParams.alipayPublicKey_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="接口签名方式(推荐使用RSA2)" prop="signType">
|
||||
<a-radio-group v-model="ifParams.signType" defaultValue="RSA">
|
||||
<a-radio value="RSA">RSA</a-radio>
|
||||
<a-radio value="RSA2">RSA2</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="公钥证书" prop="useCert">
|
||||
<a-radio-group v-model="ifParams.useCert" defaultValue="1">
|
||||
<a-radio :value="1">使用证书(请使用RSA2私钥)</a-radio>
|
||||
<a-radio :value="0">不使用证书</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="应用公钥证书(.crt格式)" prop="appPublicCert">
|
||||
<a-input v-model="ifParams.appPublicCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.appPublicCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'appPublicCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝公钥证书(.crt格式)" prop="alipayPublicCert">
|
||||
<a-input v-model="ifParams.alipayPublicCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.alipayPublicCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'alipayPublicCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝根证书(.crt格式)" prop="alipayRootCert">
|
||||
<a-input v-model="ifParams.alipayRootCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.alipayRootCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'alipayRootCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<div class="drawer-btn-center" v-if="$access('ENT_MCH_PAY_CONFIG_ADD')">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose" icon="close">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit" icon="check" :loading="btnLoading">保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JeepayCard from '@/components/JeepayCard/JeepayCard'
|
||||
import JeepayUpload from '@/components/JeepayUpload/JeepayUpload'
|
||||
import { API_URL_ISV_PAYCONFIGS_LIST, req, getIsvPayConfigUnique, upload } from '@/api/manage'
|
||||
export default {
|
||||
components: {
|
||||
JeepayCard,
|
||||
JeepayUpload
|
||||
},
|
||||
props: {
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
visible: false, // 抽屉开关
|
||||
isAdd: true,
|
||||
action: upload.cert, // 上传文件地址
|
||||
saveObject: {}, // 保存的对象
|
||||
ifParams: {}, // 参数配置对象
|
||||
rules: {
|
||||
ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {
|
||||
pid: [{ required: true, message: '请输入合作伙伴身份(PID)', trigger: 'blur' }],
|
||||
appId: [{ required: true, message: '请输入应用AppID', trigger: 'blur' }],
|
||||
privateKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.isAdd && !value) {
|
||||
callback(new Error('请输入应用私钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayPublicKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.useCert === 0 && this.isAdd && !value) {
|
||||
callback(new Error('请输入支付宝公钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appPublicCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.useCert === 1 && !this.ifParams.appPublicCert) {
|
||||
callback(new Error('请上传应用公钥证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayPublicCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.useCert === 1 && !this.ifParams.alipayPublicCert) {
|
||||
callback(new Error('请上传支付宝公钥证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayRootCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.useCert === 1 && !this.ifParams.alipayRootCert) {
|
||||
callback(new Error('请上传支付宝根证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (isvNo, record) {
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.isvParamFormModel !== undefined) {
|
||||
this.$refs.isvParamFormModel.resetFields()
|
||||
}
|
||||
|
||||
// 数据初始化
|
||||
this.saveObject = {
|
||||
infoId: isvNo,
|
||||
ifCode: record.ifCode,
|
||||
state: record.ifConfigState === 0 ? 0 : 1
|
||||
}
|
||||
|
||||
// 参数配置对象,数据初始化
|
||||
this.ifParams = {
|
||||
sandbox: 0,
|
||||
signType: 'RSA2',
|
||||
useCert: 0,
|
||||
privateKey: '',
|
||||
privateKey_ph: '请输入',
|
||||
alipayPublicKey: '',
|
||||
alipayPublicKey_ph: '请输入'
|
||||
}
|
||||
this.visible = true
|
||||
this.getIsvPayConfig()
|
||||
},
|
||||
// 支付参数配置
|
||||
getIsvPayConfig () {
|
||||
const that = this
|
||||
// 获取支付参数
|
||||
getIsvPayConfigUnique(that.saveObject.infoId, that.saveObject.ifCode).then(res => {
|
||||
if (res && res.ifParams) {
|
||||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
|
||||
that.ifParams.privateKey_ph = that.ifParams.privateKey
|
||||
that.ifParams.privateKey = ''
|
||||
|
||||
that.ifParams.alipayPublicKey_ph = that.ifParams.alipayPublicKey
|
||||
that.ifParams.alipayPublicKey = ''
|
||||
|
||||
that.isAdd = false
|
||||
} else if (res === undefined) {
|
||||
that.isAdd = true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
this.$refs.isvParamFormModel.validate(valid2 => {
|
||||
if (valid && valid2) { // 验证通过
|
||||
that.btnLoading = true
|
||||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
if (Object.keys(that.ifParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.clearEmptyKey('privateKey')
|
||||
that.clearEmptyKey('alipayPublicKey')
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
req.add(API_URL_ISV_PAYCONFIGS_LIST, reqParams).then(res => {
|
||||
that.$message.success('保存成功')
|
||||
that.visible = false
|
||||
that.btnLoading = false
|
||||
that.callbackFunc()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 脱敏数据为空时,删除对应key
|
||||
clearEmptyKey (key) {
|
||||
if (!this.ifParams[key]) {
|
||||
this.ifParams[key] = undefined
|
||||
}
|
||||
this.ifParams[key + '_ph'] = undefined
|
||||
},
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
uploadSuccess (value, name) {
|
||||
this.ifParams[name] = value
|
||||
this.$forceUpdate()
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,335 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
title="填写参数"
|
||||
width="40%"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:visible="visible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="支付接口费率" prop="ifRate">
|
||||
<a-input v-model="saveObject.ifRate" placeholder="请输入" suffix="%" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
<a-radio :value="1">
|
||||
启用
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
停用
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="备注" prop="remark">
|
||||
<a-input v-model="saveObject.remark" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
{{ saveObject.ifCode }} 服务商参数配置
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
<a-form-model ref="isvParamFormModel" :model="ifParams" layout="vertical" :rules="ifParamsRules">
|
||||
<a-row :gutter="16">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="微信支付商户号" prop="mchId">
|
||||
<a-input v-model="ifParams.mchId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppID" prop="appId">
|
||||
<a-input v-model="ifParams.appId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppSecret" prop="appSecret">
|
||||
<a-input v-model="ifParams.appSecret" :placeholder="ifParams.appSecret_ph" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="oauth2地址(置空将使用官方)" prop="oauth2Url">
|
||||
<a-input v-model="ifParams.oauth2Url" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="微信支付API版本" prop="apiVersion">
|
||||
<a-radio-group v-model="ifParams.apiVersion" defaultValue="V2">
|
||||
<a-radio value="V2">V2</a-radio>
|
||||
<a-radio value="V3">V3</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="APIv2密钥" prop="key">
|
||||
<a-input v-model="ifParams.key" :placeholder="ifParams.key_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="APIv3密钥" prop="apiV3Key">
|
||||
<a-input v-model="ifParams.apiV3Key" :placeholder="ifParams.apiV3Key_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="序列号" prop="serialNo">
|
||||
<a-input v-model="ifParams.serialNo" :placeholder="ifParams.serialNo_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="API证书(apiclient_cert.p12)" prop="cert">
|
||||
<a-input v-model="ifParams.cert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.cert"
|
||||
@uploadSuccess="uploadSuccess($event, 'cert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="证书文件(apiclient_cert.pem)" prop="apiClientCert">
|
||||
<a-input v-model="ifParams.apiClientCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.apiClientCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'apiClientCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="私钥文件(apiclient_key.pem)" prop="apiClientKey">
|
||||
<a-input v-model="ifParams.apiClientKey" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.apiClientKey"
|
||||
@uploadSuccess="uploadSuccess($event, 'apiClientKey')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<div class="drawer-btn-center" v-if="$access('ENT_MCH_PAY_CONFIG_ADD')">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose" icon="close">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit" icon="check" :loading="btnLoading">保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JeepayCard from '@/components/JeepayCard/JeepayCard'
|
||||
import JeepayUpload from '@/components/JeepayUpload/JeepayUpload'
|
||||
import { API_URL_ISV_PAYCONFIGS_LIST, req, getIsvPayConfigUnique, upload } from '@/api/manage'
|
||||
export default {
|
||||
components: {
|
||||
JeepayCard,
|
||||
JeepayUpload
|
||||
},
|
||||
props: {
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
visible: false, // 抽屉开关
|
||||
isAdd: true,
|
||||
action: upload.cert, // 上传文件地址
|
||||
saveObject: {}, // 保存的对象
|
||||
ifParams: { apiVersion: 'V2' }, // 参数配置对象
|
||||
rules: {
|
||||
ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {
|
||||
mchId: [{ required: true, message: '请输入微信支付商户号', trigger: 'blur' }],
|
||||
appId: [{ required: true, message: '请输入应用AppID', trigger: 'blur' }],
|
||||
appSecret: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.isAdd && !value) {
|
||||
callback(new Error('请输入应用AppSecret'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
key: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V2' && this.isAdd && !value) {
|
||||
callback(new Error('请输入API密钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiV3Key: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请输入API V3秘钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
serialNo: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请输入序列号'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
cert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请上传API证书(apiclient_cert.p12)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiClientCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请上传证书文件(apiclient_cert.pem)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiClientKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && !value) {
|
||||
callback(new Error('请上传私钥文件(apiclient_key.pem)'))
|
||||
}
|
||||
callback()
|
||||
} }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (isvNo, record) {
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.isvParamFormModel !== undefined) {
|
||||
this.$refs.isvParamFormModel.resetFields()
|
||||
}
|
||||
|
||||
// 数据初始化
|
||||
this.saveObject = {
|
||||
infoId: isvNo,
|
||||
ifCode: record.ifCode,
|
||||
state: record.ifConfigState === 0 ? 0 : 1
|
||||
}
|
||||
|
||||
// 参数配置对象,数据初始化
|
||||
this.ifParams = {
|
||||
apiVersion: 'V2',
|
||||
appSecret: '',
|
||||
appSecret_ph: '请输入',
|
||||
key: '',
|
||||
key_ph: '请输入',
|
||||
apiV3Key: '',
|
||||
apiV3Key_ph: '请输入',
|
||||
serialNo: '',
|
||||
serialNo_ph: '请输入'
|
||||
}
|
||||
this.visible = true
|
||||
this.getIsvPayConfig()
|
||||
},
|
||||
// 支付参数配置
|
||||
getIsvPayConfig () {
|
||||
const that = this
|
||||
// 获取支付参数
|
||||
getIsvPayConfigUnique(that.saveObject.infoId, that.saveObject.ifCode).then(res => {
|
||||
if (res && res.ifParams) {
|
||||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
|
||||
that.ifParams.appSecret_ph = that.ifParams.appSecret
|
||||
that.ifParams.appSecret = ''
|
||||
|
||||
that.ifParams.key_ph = that.ifParams.key
|
||||
that.ifParams.key = ''
|
||||
|
||||
that.ifParams.apiV3Key_ph = that.ifParams.apiV3Key
|
||||
that.ifParams.apiV3Key = ''
|
||||
|
||||
that.ifParams.serialNo_ph = that.ifParams.serialNo
|
||||
that.ifParams.serialNo = ''
|
||||
|
||||
that.isAdd = false
|
||||
} else if (res === undefined) {
|
||||
that.isAdd = true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
this.$refs.isvParamFormModel.validate(valid2 => {
|
||||
if (valid && valid2) { // 验证通过
|
||||
that.btnLoading = true
|
||||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
if (Object.keys(that.ifParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.clearEmptyKey('appSecret')
|
||||
that.clearEmptyKey('key')
|
||||
that.clearEmptyKey('apiV3Key')
|
||||
that.clearEmptyKey('serialNo')
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
req.add(API_URL_ISV_PAYCONFIGS_LIST, reqParams).then(res => {
|
||||
that.$message.success('保存成功')
|
||||
that.visible = false
|
||||
that.btnLoading = false
|
||||
that.callbackFunc()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 脱敏数据为空时,删除对应key
|
||||
clearEmptyKey (key) {
|
||||
if (!this.ifParams[key]) {
|
||||
this.ifParams[key] = undefined
|
||||
}
|
||||
this.ifParams[key + '_ph'] = undefined
|
||||
},
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
uploadSuccess (value, name) {
|
||||
this.ifParams[name] = value
|
||||
this.$forceUpdate()
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
|
|
@ -40,8 +40,7 @@
|
|||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
:scrollX="1200"
|
||||
rowKey="mchName"
|
||||
rowKey="mchNo"
|
||||
>
|
||||
<template slot="mchNameSlot" slot-scope="{record}">
|
||||
<b v-if="!$access('ENT_MCH_INFO_VIEW')">{{ record.mchName }}</b>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="私钥 AppSecret" prop="appSecret" >
|
||||
<a-input v-model="saveObject.appSecret" placeholder="请输入" type="textarea" />
|
||||
<a-input v-model="saveObject.appSecret" :placeholder="saveObject.appSecret_ph" type="textarea" />
|
||||
<a-button type="primary" ghost @click="randomKey(false, 128, 0)"><a-icon type="file-sync" />随机生成私钥</a-button>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
|
|
@ -74,8 +74,7 @@ export default {
|
|||
saveObject: {}, // 数据对象
|
||||
rules: {
|
||||
mchNo: [{ required: true, message: '请输入商户号', trigger: 'blur' }],
|
||||
appName: [{ required: true, message: '请输入应用名称', trigger: 'blur' }],
|
||||
appSecret: [{ required: true, message: '请输入私钥或点击随机生成私钥' }]
|
||||
appName: [{ required: true, message: '请输入应用名称', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -87,7 +86,8 @@ export default {
|
|||
this.saveObject = {
|
||||
'state': 1,
|
||||
'appSecret': '',
|
||||
'mchNo': mchNo
|
||||
'mchNo': mchNo,
|
||||
'appSecret_ph': '请输入'
|
||||
}
|
||||
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
|
|
@ -95,17 +95,25 @@ export default {
|
|||
}
|
||||
|
||||
const that = this
|
||||
that.rules.appSecret = []
|
||||
if (!this.isAdd) { // 修改信息 延迟展示弹层
|
||||
that.appId = appId
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MCH_APP, appId).then(res => {
|
||||
that.saveObject = res
|
||||
if (!that.saveObject.appSecret) { // 解决商户私钥为空无法写入的问题
|
||||
that.saveObject.appSecret = ''
|
||||
}
|
||||
that.saveObject.appSecret_ph = res.appSecret
|
||||
that.saveObject.appSecret = ''
|
||||
})
|
||||
|
||||
this.visible = true
|
||||
} else {
|
||||
// 新增时,appSecret必填
|
||||
that.rules.appSecret.push({
|
||||
required: true,
|
||||
message: '请输入私钥或点击随机生成私钥',
|
||||
trigger: 'blur'
|
||||
})
|
||||
|
||||
that.visible = true // 展示弹层信息
|
||||
}
|
||||
},
|
||||
|
|
@ -114,6 +122,7 @@ export default {
|
|||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
if (valid) { // 验证通过
|
||||
delete that.saveObject.appSecret_ph
|
||||
// 请求接口
|
||||
if (that.isAdd) {
|
||||
req.add(API_URL_MCH_APP, that.saveObject).then(res => {
|
||||
|
|
@ -122,6 +131,9 @@ export default {
|
|||
that.callbackFunc() // 刷新列表
|
||||
})
|
||||
} else {
|
||||
if (that.saveObject.appSecret === '') {
|
||||
delete that.saveObject.appSecret
|
||||
}
|
||||
req.updateById(API_URL_MCH_APP, that.appId, that.saveObject).then(res => {
|
||||
that.$message.success('修改成功')
|
||||
that.visible = false
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<a-modal v-model="isShow" title="支付宝子商户扫码授权" @ok="handleOkFunc" @cancel="handleOkFunc">
|
||||
|
||||
<div style="text-align: center">
|
||||
<p>方式1: <br/> 请商家登录【支付宝】APP, 扫描如下二维码, 按提示授权: </p>
|
||||
<img style="margin-bottom: 10px" :src="apiResData.authQrImgUrl">
|
||||
<hr/>
|
||||
|
||||
<p style="margin-top: 10px">
|
||||
方式2: <br/> <a-button size="small" class="copy-btn" v-clipboard:copy="apiResData.authUrl" v-clipboard:success="onCopySuccess" >点击复制</a-button>
|
||||
链接并发送给商户,商户进入链接,按照页面提示自主授权:
|
||||
</p>
|
||||
<a target="_blank" :href="apiResData.authUrl">{{ apiResData.authUrl }}</a>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { queryAlipayIsvsubMchAuthUrl } from '@/api/manage'
|
||||
export default {
|
||||
|
||||
props: {
|
||||
callbackFunc: { type: Function }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
appId: '',
|
||||
apiResData: {}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
show: function (appId) { // 弹层打开事件
|
||||
this.apiResData = {}
|
||||
this.appId = appId
|
||||
const that = this
|
||||
queryAlipayIsvsubMchAuthUrl(appId).then(res => {
|
||||
that.apiResData = res
|
||||
this.isShow = true
|
||||
})
|
||||
},
|
||||
|
||||
handleOkFunc: function () { // 点击【确认】按钮事件
|
||||
this.isShow = false
|
||||
if (this.callbackFunc) {
|
||||
this.callbackFunc()
|
||||
}
|
||||
},
|
||||
|
||||
onCopySuccess () {
|
||||
this.$message.success('复制成功')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -34,8 +34,7 @@
|
|||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
:scrollX="1200"
|
||||
rowKey="mchName"
|
||||
rowKey="appId"
|
||||
>
|
||||
<template slot="appIdSlot" slot-scope="{record}">
|
||||
<b>{{ record.appId }}</b>
|
||||
|
|
|
|||
|
|
@ -10,11 +10,6 @@
|
|||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="支付接口费率" prop="ifRate">
|
||||
<a-input v-model="saveObject.ifRate" placeholder="请输入" suffix="%" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
|
|
@ -43,7 +38,7 @@
|
|||
<a-row :gutter="16">
|
||||
<a-col v-for="(item, key) in mchParams" :key="key" :span="item.type === 'text' ? 12 : 24">
|
||||
<a-form-model-item :label="item.desc" :prop="item.name" v-if="item.type === 'text' || item.type === 'textarea'">
|
||||
<a-input v-model="ifParams[item.name]" placeholder="请输入" :type="item.type" />
|
||||
<a-input v-model="ifParams[item.name]" :placeholder="item.star === '1' ? ifParams[item.name + '_ph'] : '请输入'" :type="item.type" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item :label="item.desc" :prop="item.name" v-else-if="item.type === 'radio'">
|
||||
<a-radio-group v-model="ifParams[item.name]">
|
||||
|
|
@ -101,12 +96,17 @@ export default {
|
|||
ifParams: {}, // 参数配置对象
|
||||
rules: {
|
||||
infoId: [{ required: true, trigger: 'blur' }],
|
||||
ifCode: [{ required: true, trigger: 'blur' }],
|
||||
ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
ifCode: [{ required: true, trigger: 'blur' }]
|
||||
// ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
ifParams: function (o, n) {
|
||||
this.$set(this.ifParams, 'appSecret', this.ifParams.appSecret) // 解决appSecret 双向绑定数据不显示的问题
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (appId, record) {
|
||||
|
|
@ -133,35 +133,47 @@ export default {
|
|||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
}
|
||||
})
|
||||
|
||||
const newItems = [] // 重新加载支付接口配置定义描述json
|
||||
let radioItems = [] // 存放单选框value title
|
||||
const mchParams = this.mchType === 1 ? record.normalMchParams : record.isvsubMchParams // 根据商户类型获取接口定义描述
|
||||
JSON.parse(mchParams).forEach(item => {
|
||||
radioItems = []
|
||||
if (item.type === 'radio') {
|
||||
const valueItems = item.values.split(',')
|
||||
const titleItems = item.titles.split(',')
|
||||
for (const i in valueItems) {
|
||||
radioItems.push({
|
||||
value: valueItems[i],
|
||||
title: titleItems[i]
|
||||
})
|
||||
const newItems = [] // 重新加载支付接口配置定义描述json
|
||||
let radioItems = [] // 存放单选框value title
|
||||
const mchParams = this.mchType === 1 ? record.normalMchParams : record.isvsubMchParams // 根据商户类型获取接口定义描述
|
||||
JSON.parse(mchParams).forEach(item => {
|
||||
radioItems = []
|
||||
if (item.type === 'radio') {
|
||||
const valueItems = item.values.split(',')
|
||||
const titleItems = item.titles.split(',')
|
||||
for (const i in valueItems) {
|
||||
// 检查参数是否为数字类型 然后赋值给radio值
|
||||
let radioVal = valueItems[i]
|
||||
if (!isNaN((radioVal))) { radioVal = Number(radioVal) }
|
||||
radioItems.push({
|
||||
value: radioVal,
|
||||
title: titleItems[i]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
newItems.push({
|
||||
name: item.name,
|
||||
desc: item.desc,
|
||||
type: item.type,
|
||||
verify: item.verify,
|
||||
values: radioItems
|
||||
})
|
||||
})
|
||||
|
||||
that.mchParams = newItems // 重新赋值接口定义描述
|
||||
that.visible = true // 打开支付参数配置抽屉
|
||||
that.generoterRules()
|
||||
if (item.star === '1') {
|
||||
that.ifParams[item.name + '_ph'] = that.ifParams[item.name] ? that.ifParams[item.name] : '请输入'
|
||||
if (that.ifParams[item.name]) {
|
||||
that.ifParams[item.name] = ''
|
||||
}
|
||||
}
|
||||
|
||||
newItems.push({
|
||||
name: item.name,
|
||||
desc: item.desc,
|
||||
type: item.type,
|
||||
verify: item.verify,
|
||||
values: radioItems,
|
||||
star: item.star // 脱敏标识 1-是
|
||||
})
|
||||
})
|
||||
|
||||
that.mchParams = newItems // 重新赋值接口定义描述
|
||||
that.visible = true // 打开支付参数配置抽屉
|
||||
that.generoterRules()
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
|
|
@ -173,7 +185,7 @@ export default {
|
|||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
reqParams.ifRate = that.saveObject.ifRate
|
||||
// reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
|
|
@ -181,6 +193,13 @@ export default {
|
|||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.mchParams.forEach(item => {
|
||||
if (item.star === '1' && that.ifParams[item.name] === '') {
|
||||
that.ifParams[item.name] = undefined
|
||||
}
|
||||
that.ifParams[item.name + '_ph'] = undefined
|
||||
})
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
|
|
@ -208,7 +227,7 @@ export default {
|
|||
let newItems = []
|
||||
this.mchParams.forEach(item => {
|
||||
newItems = []
|
||||
if (item.verify === 'required') {
|
||||
if (item.verify === 'required' && item.star !== '1') {
|
||||
newItems.push({
|
||||
required: true,
|
||||
message: '请输入' + item.desc,
|
||||
|
|
|
|||
|
|
@ -34,8 +34,11 @@
|
|||
</div>
|
||||
<!-- 卡片底部操作栏 -->
|
||||
<div class="jeepay-card-ops">
|
||||
<a v-if="record.mchType == 2 && record.ifCode == 'alipay' && $access('ENT_MCH_PAY_CONFIG_ADD')" @click="toAlipayAuthPageFunc(record)">扫码授权 <a-icon key="right" type="right" style="fontSize: 13px"></a-icon></a>
|
||||
|
||||
<a v-if="$access('ENT_MCH_PAY_CONFIG_ADD')" @click="editPayIfConfigFunc(record)">填写参数 <a-icon key="right" type="right" style="fontSize: 13px"></a-icon></a>
|
||||
<a v-else>暂无操作</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -73,6 +76,7 @@
|
|||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData2"
|
||||
rowKey="wayCode"
|
||||
>
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<a-badge :status="record.passageState === 0?'error':'processing'" :text="record.passageState === 0?'禁用':'启用'" />
|
||||
|
|
@ -91,10 +95,17 @@
|
|||
<a-button type="primary" icon="arrow-right" v-if="$access('ENT_MCH_PAY_PASSAGE_LIST') && currentStep ===0" @click="stepChange(1)">下一步</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 支付参数配置页面组件 -->
|
||||
<!-- 支付参数配置JSON渲染页面组件 -->
|
||||
<MchPayConfigAddOrEdit ref="mchPayConfigAddOrEdit" :callbackFunc="refCardList" />
|
||||
<!-- 支付参数配置自定义页面组件 wxpay -->
|
||||
<WxpayPayConfig ref="wxpayPayConfig" :callbackFunc="refCardList" />
|
||||
<!-- 支付参数配置自定义页面组件 alipay -->
|
||||
<AlipayPayConfig ref="alipayPayConfig" :callbackFunc="refCardList" />
|
||||
<!-- 支付通道配置页面组件 -->
|
||||
<MchPayPassageAddOrEdit ref="mchPayPassageAddOrEdit" :callbackFunc="searchFunc"/>
|
||||
<!-- 支付宝授权弹层 -->
|
||||
<AlipayAuth ref="alipayAuthPage" :callbackFunc="refCardList"/>
|
||||
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
|
|
@ -105,6 +116,9 @@ import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
|||
import { API_URL_MCH_PAYCONFIGS_LIST, API_URL_MCH_PAYPASSAGE_LIST, req, getAvailablePayInterfaceList } from '@/api/manage'
|
||||
import MchPayConfigAddOrEdit from './MchPayConfigAddOrEdit'
|
||||
import MchPayPassageAddOrEdit from './MchPayPassageAddOrEdit'
|
||||
import WxpayPayConfig from './custom/WxpayPayConfig'
|
||||
import AlipayPayConfig from './custom/AlipayPayConfig'
|
||||
import AlipayAuth from './AlipayAuth'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
|
|
@ -120,7 +134,10 @@ export default {
|
|||
JeepayTable,
|
||||
JeepayTableColumns,
|
||||
MchPayConfigAddOrEdit,
|
||||
MchPayPassageAddOrEdit
|
||||
MchPayPassageAddOrEdit,
|
||||
WxpayPayConfig,
|
||||
AlipayPayConfig,
|
||||
AlipayAuth
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
|
@ -155,7 +172,9 @@ export default {
|
|||
},
|
||||
// 刷新支付接口card列表
|
||||
refCardList () {
|
||||
this.$refs.infoCard.refCardList()
|
||||
if (this.$refs.infoCard) {
|
||||
this.$refs.infoCard.refCardList()
|
||||
}
|
||||
},
|
||||
// 请求支付通道数据
|
||||
reqTableDataFunc (params) {
|
||||
|
|
@ -175,9 +194,11 @@ export default {
|
|||
title: '提示',
|
||||
content: '当前应用所属商户为特约商户,请先配置服务商支付参数!'
|
||||
})
|
||||
return
|
||||
} else if (record.configPageType === 1) {
|
||||
this.$refs.mchPayConfigAddOrEdit.show(this.appId, record)
|
||||
} else if (record.configPageType === 2) {
|
||||
this.$refs[record.ifCode + 'PayConfig'].show(this.appId, record)
|
||||
}
|
||||
this.$refs.mchPayConfigAddOrEdit.show(this.appId, record)
|
||||
},
|
||||
// 支付通道配置
|
||||
editPayPassageFunc (record) {
|
||||
|
|
@ -196,6 +217,21 @@ export default {
|
|||
// 抽屉关闭
|
||||
onClose () {
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
// 支付宝子商户 扫码授权
|
||||
toAlipayAuthPageFunc (record) {
|
||||
if (!record) {
|
||||
return
|
||||
}
|
||||
if (record.subMchIsvConfig === 0) {
|
||||
this.$error({
|
||||
title: '提示',
|
||||
content: '当前应用所属商户为特约商户,请先配置服务商支付参数!'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$refs.alipayAuthPage.show(this.appId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,328 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
title="填写参数"
|
||||
width="40%"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:visible="visible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
<a-radio :value="1">
|
||||
启用
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
停用
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="备注" prop="remark">
|
||||
<a-input v-model="saveObject.remark" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
{{ saveObject.ifCode }} 商户参数配置
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
<a-form-model ref="mchParamFormModel" :model="ifParams" layout="vertical" :rules="ifParamsRules">
|
||||
<a-row :gutter="16" v-if="mchType === 1">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="环境配置" prop="sandbox">
|
||||
<a-radio-group v-model="ifParams.sandbox">
|
||||
<a-radio :value="1">沙箱环境</a-radio>
|
||||
<a-radio :value="0">生产环境</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppID" prop="appId">
|
||||
<a-input v-model="ifParams.appId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="应用私钥" prop="privateKey">
|
||||
<a-input v-model="ifParams.privateKey" :placeholder="ifParams.privateKey_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝公钥" prop="alipayPublicKey">
|
||||
<a-input v-model="ifParams.alipayPublicKey" :placeholder="ifParams.alipayPublicKey_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="接口签名方式(推荐使用RSA2)" prop="signType">
|
||||
<a-radio-group v-model="ifParams.signType" defaultValue="RSA">
|
||||
<a-radio value="RSA">RSA</a-radio>
|
||||
<a-radio value="RSA2">RSA2</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="公钥证书" prop="useCert">
|
||||
<a-radio-group v-model="ifParams.useCert" defaultValue="1">
|
||||
<a-radio :value="1">使用证书(请使用RSA2私钥)</a-radio>
|
||||
<a-radio :value="0">不使用证书</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="应用公钥证书(.crt格式)" prop="appPublicCert">
|
||||
<a-input v-model="ifParams.appPublicCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.appPublicCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'appPublicCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝公钥证书(.crt格式)" prop="alipayPublicCert">
|
||||
<a-input v-model="ifParams.alipayPublicCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.alipayPublicCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'alipayPublicCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝根证书(.crt格式)" prop="alipayRootCert">
|
||||
<a-input v-model="ifParams.alipayRootCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.alipayRootCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'alipayRootCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" v-else-if="mchType === 2">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="子商户app_auth_token" prop="appAuthToken">
|
||||
<a-input v-model="ifParams.appAuthToken" placeholder="请输入子商户app_auth_token" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<div class="drawer-btn-center" v-if="$access('ENT_MCH_PAY_CONFIG_ADD')">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose" icon="close">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit" icon="check" :loading="btnLoading">保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JeepayCard from '@/components/JeepayCard/JeepayCard'
|
||||
import JeepayUpload from '@/components/JeepayUpload/JeepayUpload'
|
||||
import { API_URL_MCH_PAYCONFIGS_LIST, req, getMchPayConfigUnique, upload } from '@/api/manage'
|
||||
export default {
|
||||
components: {
|
||||
JeepayCard,
|
||||
JeepayUpload
|
||||
},
|
||||
props: {
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
visible: false, // 抽屉开关
|
||||
isAdd: true,
|
||||
mchType: 1,
|
||||
action: upload.cert, // 上传文件地址
|
||||
saveObject: {}, // 保存的对象
|
||||
ifParams: {}, // 参数配置对象
|
||||
rules: {
|
||||
// ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {
|
||||
appId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入应用AppID'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
privateKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.isAdd && !value) {
|
||||
callback(new Error('请输入应用私钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayPublicKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.isAdd && this.ifParams.useCert === 0 && !value) {
|
||||
callback(new Error('请输入支付宝公钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appPublicCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.ifParams.useCert === 1 && !this.ifParams.appPublicCert) {
|
||||
callback(new Error('请上传应用公钥证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayPublicCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.ifParams.useCert === 1 && !this.ifParams.alipayPublicCert) {
|
||||
callback(new Error('请上传支付宝公钥证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayRootCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.ifParams.useCert === 1 && !this.ifParams.alipayRootCert) {
|
||||
callback(new Error('请上传支付宝根证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appAuthToken: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 2 && !value) {
|
||||
callback(new Error('请输入子商户app_auth_token'))
|
||||
}
|
||||
callback()
|
||||
} }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (appId, record) {
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.mchParamFormModel !== undefined) {
|
||||
this.$refs.mchParamFormModel.resetFields()
|
||||
}
|
||||
|
||||
this.mchType = record.mchType
|
||||
|
||||
// 数据初始化
|
||||
this.saveObject = {
|
||||
infoId: appId,
|
||||
ifCode: record.ifCode,
|
||||
state: record.ifConfigState === 0 ? 0 : 1
|
||||
}
|
||||
|
||||
// 参数配置对象,数据初始化
|
||||
this.ifParams = {
|
||||
sandbox: 0,
|
||||
signType: 'RSA2',
|
||||
useCert: 0,
|
||||
privateKey: '',
|
||||
privateKey_ph: '请输入',
|
||||
alipayPublicKey: '',
|
||||
alipayPublicKey_ph: '请输入',
|
||||
appPublicCert: '',
|
||||
alipayPublicCert: '',
|
||||
alipayRootCert: ''
|
||||
}
|
||||
this.visible = true
|
||||
this.getMchPayConfig()
|
||||
},
|
||||
// 支付参数配置
|
||||
getMchPayConfig () {
|
||||
const that = this
|
||||
// 获取支付参数
|
||||
getMchPayConfigUnique(that.saveObject.infoId, that.saveObject.ifCode).then(res => {
|
||||
if (res && res.ifParams) {
|
||||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
|
||||
that.ifParams.privateKey_ph = that.ifParams.privateKey
|
||||
that.ifParams.privateKey = ''
|
||||
|
||||
that.ifParams.alipayPublicKey_ph = that.ifParams.alipayPublicKey
|
||||
that.ifParams.alipayPublicKey = ''
|
||||
|
||||
that.isAdd = false
|
||||
} else if (res === undefined) {
|
||||
that.isAdd = true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
const that = this
|
||||
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
this.$refs.mchParamFormModel.validate(valid2 => {
|
||||
if (valid && valid2) { // 验证通过
|
||||
that.btnLoading = true
|
||||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
// reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
if (Object.keys(that.ifParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.clearEmptyKey('privateKey')
|
||||
that.clearEmptyKey('alipayPublicKey')
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
req.add(API_URL_MCH_PAYCONFIGS_LIST, reqParams).then(res => {
|
||||
that.$message.success('保存成功')
|
||||
that.visible = false
|
||||
that.btnLoading = false
|
||||
that.callbackFunc()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 脱敏数据为空时,删除对应key
|
||||
clearEmptyKey (key) {
|
||||
if (!this.ifParams[key]) {
|
||||
this.ifParams[key] = undefined
|
||||
}
|
||||
this.ifParams[key + '_ph'] = undefined
|
||||
},
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
uploadSuccess (value, name) {
|
||||
this.ifParams[name] = value
|
||||
this.$forceUpdate()
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
title="填写参数"
|
||||
width="40%"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:visible="visible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
<a-radio :value="1">
|
||||
启用
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
停用
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="备注" prop="remark">
|
||||
<a-input v-model="saveObject.remark" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
{{ saveObject.ifCode }} 商户参数配置
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
<a-form-model ref="mchParamFormModel" :model="ifParams" layout="vertical" :rules="ifParamsRules">
|
||||
<a-row :gutter="16" v-if="mchType === 1">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="微信支付商户号" prop="mchId">
|
||||
<a-input v-model="ifParams.mchId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppID" prop="appId">
|
||||
<a-input v-model="ifParams.appId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppSecret" prop="appSecret">
|
||||
<a-input v-model="ifParams.appSecret" :placeholder="ifParams.appSecret_ph" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="oauth2地址(置空将使用官方)" prop="oauth2Url">
|
||||
<a-input v-model="ifParams.oauth2Url" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="微信支付API版本" prop="apiVersion">
|
||||
<a-radio-group v-model="ifParams.apiVersion" defaultValue="V2">
|
||||
<a-radio value="V2">V2</a-radio>
|
||||
<a-radio value="V3">V3</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="APIv2密钥" prop="key">
|
||||
<a-input v-model="ifParams.key" :placeholder="ifParams.key_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="APIv3秘钥" prop="apiV3Key">
|
||||
<a-input v-model="ifParams.apiV3Key" :placeholder="ifParams.apiV3Key_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="序列号" prop="serialNo">
|
||||
<a-input v-model="ifParams.serialNo" :placeholder="ifParams.serialNo_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="API证书(apiclient_cert.p12)" prop="cert">
|
||||
<a-input v-model="ifParams.cert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.cert"
|
||||
@uploadSuccess="uploadSuccess($event, 'cert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="证书文件(apiclient_cert.pem)" prop="apiClientCert">
|
||||
<a-input v-model="ifParams.apiClientCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.apiClientCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'apiClientCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="私钥文件(apiclient_key.pem)" prop="apiClientKey">
|
||||
<a-input v-model="ifParams.apiClientKey" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.apiClientKey"
|
||||
@uploadSuccess="uploadSuccess($event, 'apiClientKey')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" v-else-if="mchType === 2">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="子商户ID" prop="subMchId">
|
||||
<a-input v-model="ifParams.subMchId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="子账户appID(线上支付必填)" prop="subMchAppId">
|
||||
<a-input v-model="ifParams.subMchAppId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<div class="drawer-btn-center" v-if="$access('ENT_MCH_PAY_CONFIG_ADD')">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose" icon="close">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit" icon="check" :loading="btnLoading">保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JeepayCard from '@/components/JeepayCard/JeepayCard'
|
||||
import JeepayUpload from '@/components/JeepayUpload/JeepayUpload'
|
||||
import { API_URL_MCH_PAYCONFIGS_LIST, req, getMchPayConfigUnique, upload } from '@/api/manage'
|
||||
export default {
|
||||
components: {
|
||||
JeepayCard,
|
||||
JeepayUpload
|
||||
},
|
||||
props: {
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
visible: false, // 抽屉开关
|
||||
isAdd: true,
|
||||
mchType: 1,
|
||||
action: upload.cert, // 上传文件地址
|
||||
saveObject: {}, // 保存的对象
|
||||
ifParams: { apiVersion: 'V2' }, // 参数配置对象
|
||||
rules: {
|
||||
// ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {
|
||||
mchId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入微信支付商户号'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入应用AppID'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appSecret: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入应用AppSecret'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
key: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V2' && this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入API密钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiV3Key: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入API V3秘钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
serialNo: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入序列号'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
cert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请上传API证书(apiclient_cert.p12)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiClientCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请上传证书文件(apiclient_cert.pem)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiClientKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.mchType === 1 && !this.ifParams.apiClientKey) {
|
||||
callback(new Error('请上传私钥文件(apiclient_key.pem)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
subMchId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 2 && !value) {
|
||||
callback(new Error('请输入子商户ID'))
|
||||
}
|
||||
callback()
|
||||
} }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (appId, record) {
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.mchParamFormModel !== undefined) {
|
||||
this.$refs.mchParamFormModel.resetFields()
|
||||
}
|
||||
|
||||
this.mchType = record.mchType
|
||||
|
||||
// 数据初始化
|
||||
this.saveObject = {
|
||||
infoId: appId,
|
||||
ifCode: record.ifCode,
|
||||
state: record.ifConfigState === 0 ? 0 : 1
|
||||
}
|
||||
|
||||
// 参数配置对象,数据初始化
|
||||
this.ifParams = {
|
||||
apiVersion: 'V2',
|
||||
appSecret: '',
|
||||
appSecret_ph: '请输入',
|
||||
key: '',
|
||||
key_ph: '请输入',
|
||||
apiV3Key: '',
|
||||
apiV3Key_ph: '请输入',
|
||||
serialNo: '',
|
||||
serialNo_ph: '请输入'
|
||||
}
|
||||
this.visible = true
|
||||
this.getMchPayConfig()
|
||||
},
|
||||
// 支付参数配置
|
||||
getMchPayConfig () {
|
||||
const that = this
|
||||
// 获取支付参数
|
||||
getMchPayConfigUnique(that.saveObject.infoId, that.saveObject.ifCode).then(res => {
|
||||
if (res && res.ifParams) {
|
||||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
|
||||
that.ifParams.appSecret_ph = that.ifParams.appSecret
|
||||
that.ifParams.appSecret = ''
|
||||
|
||||
that.ifParams.key_ph = that.ifParams.key
|
||||
that.ifParams.key = ''
|
||||
|
||||
that.ifParams.apiV3Key_ph = that.ifParams.apiV3Key
|
||||
that.ifParams.apiV3Key = ''
|
||||
|
||||
that.ifParams.serialNo_ph = that.ifParams.serialNo
|
||||
that.ifParams.serialNo = ''
|
||||
|
||||
that.isAdd = false
|
||||
} else if (res === undefined) {
|
||||
that.isAdd = true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
this.$refs.mchParamFormModel.validate(valid2 => {
|
||||
if (valid && valid2) { // 验证通过
|
||||
that.btnLoading = true
|
||||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
// reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
if (Object.keys(that.ifParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.clearEmptyKey('appSecret')
|
||||
that.clearEmptyKey('key')
|
||||
that.clearEmptyKey('apiV3Key')
|
||||
that.clearEmptyKey('serialNo')
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
req.add(API_URL_MCH_PAYCONFIGS_LIST, reqParams).then(res => {
|
||||
that.$message.success('保存成功')
|
||||
that.visible = false
|
||||
that.btnLoading = false
|
||||
that.callbackFunc()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 脱敏数据为空时,删除对应key
|
||||
clearEmptyKey (key) {
|
||||
if (!this.ifParams[key]) {
|
||||
this.ifParams[key] = undefined
|
||||
}
|
||||
this.ifParams[key + '_ph'] = undefined
|
||||
},
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
uploadSuccess (value, name) {
|
||||
this.ifParams[name] = value
|
||||
this.$forceUpdate()
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">支付</a-select-option>
|
||||
<a-select-option value="2">退款</a-select-option>
|
||||
<a-select-option value="3">转账</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
|
|
@ -54,7 +55,6 @@
|
|||
:searchData="searchData"
|
||||
:rowSelection="rowSelection"
|
||||
rowKey="orderId"
|
||||
:scrollX="1050"
|
||||
>
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<a-tag
|
||||
|
|
@ -67,9 +67,9 @@
|
|||
<template slot="orderTypeSlot" slot-scope="{record}">
|
||||
<a-tag
|
||||
:key="record.orderType"
|
||||
:color="record.orderType === 1?'green':record.orderType === 2?'volcano':'orange'"
|
||||
:color="record.orderType === 1?'green':record.orderType === 2?'volcano': record.orderType === 3? 'blue': 'orange'"
|
||||
>
|
||||
{{ record.orderType === 1?'支付':record.orderType === 2?'退款':'未知' }}
|
||||
{{ record.orderType === 1?'支付':record.orderType === 2?'退款':record.orderType === 3? '转账':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
|
|
@ -124,8 +124,8 @@
|
|||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单类型">
|
||||
<a-tag :color="detailData.orderType === 1?'green':detailData.orderType === 2?'volcano':'orange'">
|
||||
{{ detailData.orderType === 1?'支付':detailData.orderType === 2?'退款':'未知' }}
|
||||
<a-tag :color="detailData.orderType === 1?'green':detailData.orderType === 2?'volcano': detailData.orderType === 3? 'blue' : 'orange'">
|
||||
{{ detailData.orderType === 1?'支付':detailData.orderType === 2?'退款':detailData.orderType === 3 ? '转账': '未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
|
|
|||
|
|
@ -14,11 +14,20 @@
|
|||
<a-icon slot="suffixIcon" type="sync" />
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
<jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />
|
||||
<jeepay-text-up :placeholder="'商户订单号'" :msg="searchData.mchOrderNo" v-model="searchData.mchOrderNo" />
|
||||
<jeepay-text-up :placeholder="'支付/商户/渠道订单号'" :msg="searchData.unionOrderId" v-model="searchData.unionOrderId" />
|
||||
<!-- <jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'商户订单号'" :msg="searchData.mchOrderNo" v-model="searchData.mchOrderNo" />-->
|
||||
<jeepay-text-up :placeholder="'商户号'" :msg="searchData.mchNo" v-model="searchData.mchNo" />
|
||||
<jeepay-text-up :placeholder="'服务商号'" :msg="searchData.isvNo" v-model="searchData.isvNo" />
|
||||
<jeepay-text-up :placeholder="'应用AppId'" :msg="searchData.appId" v-model="searchData.appId"/>
|
||||
<a-form-item v-if="$access('ENT_PAY_ORDER_SEARCH_PAY_WAY')" label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.wayCode" placeholder="支付方式" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option :key="item.wayCode" v-for="item in payWayList" :value="item.wayCode">
|
||||
{{ item.wayName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.state" placeholder="支付状态" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
|
|
@ -39,11 +48,12 @@
|
|||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.wayCode" placeholder="支付方式" default-value="">
|
||||
<a-select v-model="searchData.divisionState" placeholder="分账状态" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option :key="item.wayCode" v-for="item in payWayList" :value="item.wayCode">
|
||||
{{ item.wayName }}
|
||||
</a-select-option>
|
||||
<a-select-option value="0">未发生分账</a-select-option>
|
||||
<a-select-option value="1">等待分账任务处理</a-select-option>
|
||||
<a-select-option value="2">分账处理中</a-select-option>
|
||||
<a-select-option value="3">分账任务已结束(状态请看分账记录)</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<span class="table-page-search-submitButtons">
|
||||
|
|
@ -63,32 +73,57 @@
|
|||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="payOrderId"
|
||||
:scrollX="1350"
|
||||
:tableRowCrossColor="true"
|
||||
>
|
||||
<template slot="amountSlot" slot-scope="{record}"><b>¥{{ record.amount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="refundAmountSlot" slot-scope="{record}">¥{{ record.refundAmount/100 }}</template> <!-- 自定义插槽 -->
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':record.state === 6?'':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'支付中':record.state === 2?'支付成功':record.state === 3?'支付失败':record.state === 4?'已撤销':record.state === 5?'已退款':record.state === 6?'订单关闭':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template slot="refundStateSlot" slot-scope="{record}">
|
||||
<a-tag
|
||||
:key="record.refundState"
|
||||
:color="record.refundState === 0?'blue':record.refundState === 1?'orange':record.refundState === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.refundState === 0?'未发起':record.refundState === 1?'部分退款':record.refundState === 2?'全额退款':'未知' }}
|
||||
</a-tag>
|
||||
<template slot="divisionStateSlot" slot-scope="{record}">
|
||||
<span v-if="record.divisionState == 0"> - </span>
|
||||
<a-tag color="orange" v-else-if="record.divisionState == 1">待分账</a-tag>
|
||||
<a-tag color="red" v-else-if="record.divisionState == 2">分账处理中</a-tag>
|
||||
<a-tag color="green" v-else-if="record.divisionState == 3">任务已结束</a-tag>
|
||||
<span v-else>未知</span>
|
||||
</template>
|
||||
<template slot="notifySlot" slot-scope="{record}">
|
||||
<a-badge :status="record.notifyState === 1?'processing':'error'" :text="record.notifyState === 1?'已发送':'未发送'" />
|
||||
</template>
|
||||
<template slot="orderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">支付</span>{{ record.payOrderId }}</p>
|
||||
<p style="margin-bottom: 0">
|
||||
<span style="color:#56cf56;background:#d8eadf">商户</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.mchOrderNo.length > record.payOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.mchOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.mchOrderNo, record.payOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.mchOrderNo }}</span>
|
||||
</p>
|
||||
<p v-if="record.channelOrderNo" style="margin-bottom: 0;margin-top: 10px">
|
||||
<span style="color:#fff;background:#E09C4D;">渠道</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.channelOrderNo.length > record.payOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.channelOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.channelOrderNo, record.payOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.channelOrderNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" v-if="$access('ENT_PAY_ORDER_VIEW')" @click="detailFunc(record.payOrderId)">详情</a-button>
|
||||
<a-button type="link" v-if="$access('ENT_PAY_ORDER_REFUND')" style="color: red" v-show="(record.state === 2)" @click="openFunc(record, record.payOrderId)">退款</a-button>
|
||||
<a-button type="link" v-if="$access('ENT_PAY_ORDER_REFUND')" style="color: red" v-show="(record.state === 2 && record.refundState !== 2)" @click="openFunc(record, record.payOrderId)">退款</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
|
|
@ -159,10 +194,16 @@
|
|||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="手续费"><a-tag color="pink">{{ detailData.mchFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="商家费率">{{ (detailData.mchFeeRate*100).toFixed(2) }}%</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':'volcano'">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':detailData.state === 6?'':'volcano'">
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'支付中':detailData.state === 2?'支付成功':detailData.state === 3?'支付失败':detailData.state === 4?'已撤销':detailData.state === 5?'已退款':detailData.state === 6?'订单关闭':'未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
|
|
@ -322,6 +363,27 @@
|
|||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="订单分账模式">
|
||||
<span v-if="detailData.divisionMode == 0">该笔订单不允许分账</span>
|
||||
<span v-else-if="detailData.divisionMode == 1">支付成功按配置自动完成分账</span>
|
||||
<span v-else-if="detailData.divisionMode == 2">商户手动分账(解冻商户金额)</span>
|
||||
<span v-else>未知</span>
|
||||
</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="分账状态">
|
||||
<a-tag color="blue" v-if="detailData.divisionState == 0">未发生分账</a-tag>
|
||||
<a-tag color="orange" v-else-if="detailData.divisionState == 1">待分账</a-tag>
|
||||
<a-tag color="red" v-else-if="detailData.divisionState == 2">分账处理中</a-tag>
|
||||
<a-tag color="green" v-else-if="detailData.divisionState == 3">任务已结束</a-tag>
|
||||
<a-tag color="#f50" v-else>未知</a-tag>
|
||||
</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="最新分账发起时间">{{ detailData.divisionLastTime }}</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-row justify="start" type="flex">
|
||||
|
|
@ -350,16 +412,19 @@ import moment from 'moment'
|
|||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ key: 'amount', title: '支付金额', ellipsis: true, width: '130px', fixed: 'left', scopedSlots: { customRender: 'amountSlot' } },
|
||||
{ key: 'mchName', title: '商户名称', dataIndex: 'mchName', ellipsis: true, width: '100px' },
|
||||
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
{ key: 'mchOrderNo', title: '商户订单号', dataIndex: 'mchOrderNo' },
|
||||
{ key: 'wayName', title: '支付方式', dataIndex: 'wayName', width: 150 },
|
||||
{ key: 'amount', title: '支付金额', ellipsis: true, width: 108, fixed: 'left', scopedSlots: { customRender: 'amountSlot' } },
|
||||
{ key: 'refundAmount', title: '退款金额', width: 108, scopedSlots: { customRender: 'refundAmountSlot' } },
|
||||
{ key: 'mchFeeAmount', dataIndex: 'mchFeeAmount', title: '手续费', customRender: (text) => '¥' + (text / 100).toFixed(2), width: 100 },
|
||||
{ key: 'mchName', title: '商户名称', dataIndex: 'mchName', ellipsis: true, width: 100 },
|
||||
{ key: 'orderNo', title: '订单号', scopedSlots: { customRender: 'orderSlot' }, width: 210 },
|
||||
// { key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
// { key: 'mchOrderNo', title: '商户订单号', dataIndex: 'mchOrderNo' },
|
||||
{ key: 'wayName', title: '支付方式', dataIndex: 'wayName', width: 120 },
|
||||
{ key: 'state', title: '支付状态', scopedSlots: { customRender: 'stateSlot' }, width: 100 },
|
||||
{ key: 'refundState', title: '退款状态', scopedSlots: { customRender: 'refundStateSlot' }, width: 100 },
|
||||
{ key: 'notifyState', title: '回调状态', scopedSlots: { customRender: 'notifySlot' }, width: 100 },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', width: 180 },
|
||||
{ key: 'op', title: '操作', width: '160px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
{ key: 'divisionState', title: '分账状态', scopedSlots: { customRender: 'divisionStateSlot' }, width: 100 },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', width: 120 },
|
||||
{ key: 'op', title: '操作', width: 120, fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
|
|
@ -380,7 +445,9 @@ export default {
|
|||
computed: {
|
||||
},
|
||||
mounted () {
|
||||
this.initPayWay()
|
||||
if (this.$access('ENT_PAY_ORDER_SEARCH_PAY_WAY')) {
|
||||
this.initPayWay()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
queryFunc () {
|
||||
|
|
@ -392,7 +459,7 @@ export default {
|
|||
return req.list(API_URL_PAY_ORDER_LIST, params)
|
||||
},
|
||||
searchFunc: function () { // 点击【查询】按钮点击事件
|
||||
this.$refs.infoTable.refTable(true)
|
||||
this.$refs.infoTable.refTable(false)
|
||||
},
|
||||
|
||||
// 打开退款弹出框
|
||||
|
|
@ -425,7 +492,33 @@ export default {
|
|||
req.list(API_URL_PAYWAYS_LIST, { 'pageSize': -1 }).then(res => { // 支付方式下拉列表
|
||||
that.payWayList = res.records
|
||||
})
|
||||
},
|
||||
changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = parseInt(baseLength / 2)
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -14,9 +14,10 @@
|
|||
<a-icon slot="suffixIcon" type="sync" />
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
<jeepay-text-up :placeholder="'退款订单号'" :msg="searchData.refundOrderId" v-model="searchData.refundOrderId" />
|
||||
<jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />
|
||||
<jeepay-text-up :placeholder="'渠道支付订单号'" :msg="searchData.channelPayOrderNo" v-model="searchData.channelPayOrderNo" />
|
||||
<jeepay-text-up :placeholder="'支付/退款列订单号'" :msg="searchData.unionOrderId" v-model="searchData.unionOrderId" />
|
||||
<!-- <jeepay-text-up :placeholder="'退款订单号'" :msg="searchData.refundOrderId" v-model="searchData.refundOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'渠道支付订单号'" :msg="searchData.channelPayOrderNo" v-model="searchData.channelPayOrderNo" />-->
|
||||
<jeepay-text-up :placeholder="'商户号'" :msg="searchData.mchNo" v-model="searchData.mchNo" />
|
||||
<jeepay-text-up :placeholder="'服务商号'" :msg="searchData.isvNo" v-model="searchData.isvNo" />
|
||||
<jeepay-text-up :placeholder="'应用AppId'" :msg="searchData.appId" v-model="searchData.appId"/>
|
||||
|
|
@ -53,9 +54,8 @@
|
|||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
:rowSelection="rowSelection"
|
||||
rowKey="refundOrderId"
|
||||
:scrollX="1350"
|
||||
:tableRowCrossColor="true"
|
||||
>
|
||||
<template slot="payAmountSlot" slot-scope="{record}"><b>¥{{ record.payAmount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="refundAmountSlot" slot-scope="{record}"><b>¥{{ record.refundAmount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
|
|
@ -64,9 +64,41 @@
|
|||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'退款中':record.state === 2?'退款成功':record.state === 3?'退款失败':'未知' }}
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'退款中':record.state === 2?'退款成功':record.state === 3?'退款失败':record.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template slot="payOrderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">支付</span>{{ record.payOrderId }}</p>
|
||||
<p v-if="record.channelPayOrderNo" style="margin-bottom: 0;">
|
||||
<span style="color:#fff;background:#E09C4D">渠道</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.channelPayOrderNo.length > record.payOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.channelPayOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.channelPayOrderNo, record.payOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.channelPayOrderNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template slot="refundOrderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">退款</span>{{ record.refundOrderId }}</p>
|
||||
<p style="margin-bottom: 0;">
|
||||
<span style="color:#56cf56;background:#d8eadf">商户</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.mchRefundNo.length > record.payOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.mchRefundNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.mchRefundNo, record.refundOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.mchRefundNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" v-if="$access('ENT_REFUND_ORDER_VIEW')" @click="detailFunc(record.refundOrderId)">详情</a-button>
|
||||
|
|
@ -165,7 +197,7 @@
|
|||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':'volcano'">
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'退款中':detailData.state === 2?'退款成功':detailData.state === 3?'退款失败':'未知' }}
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'退款中':detailData.state === 2?'退款成功':detailData.state === 3?'退款失败':detailData.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
|
@ -294,14 +326,15 @@
|
|||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ key: 'payAmount', title: '支付金额', fixed: 'left', scopedSlots: { customRender: 'payAmountSlot' } },
|
||||
{ key: 'refundAmount', title: '退款金额', scopedSlots: { customRender: 'refundAmountSlot' } },
|
||||
{ key: 'refundOrderId', title: '退款订单号', dataIndex: 'refundOrderId' },
|
||||
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
{ key: 'mchRefundNo', title: '商户退款单号', dataIndex: 'mchRefundNo' },
|
||||
{ key: 'payAmount', title: '支付金额', ellipsis: true, fixed: 'left', scopedSlots: { customRender: 'payAmountSlot' }, width: 100 },
|
||||
{ key: 'refundAmount', title: '退款金额', ellipsis: true, scopedSlots: { customRender: 'refundAmountSlot' }, width: 100 },
|
||||
{ key: 'pay', title: '退款订单号', scopedSlots: { customRender: 'refundOrderSlot' }, width: 220 },
|
||||
{ key: 'refund', title: '支付订单号', scopedSlots: { customRender: 'payOrderSlot' }, width: 220 },
|
||||
// { key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
// { key: 'mchRefundNo', title: '商户退款单号', dataIndex: 'mchRefundNo' },
|
||||
{ key: 'state', title: '状态', scopedSlots: { customRender: 'stateSlot' }, width: 100 },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期', width: 120 },
|
||||
{ key: 'op', title: '操作', width: 100, fixed: 'right', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
|
|
@ -320,17 +353,6 @@
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
rowSelection () {
|
||||
const that = this
|
||||
return {
|
||||
onChange: (selectedRowKeys, selectedRows) => {
|
||||
that.selectedIds = [] // 清空选中数组
|
||||
selectedRows.forEach(function (data) { // 赋值选中参数
|
||||
that.selectedIds.push(data.payOrderId)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
|
|
@ -363,7 +385,33 @@
|
|||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
},
|
||||
changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = parseInt(baseLength / 2)
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,194 @@
|
|||
<!-- 订单详情抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
width="50%"
|
||||
placement="right"
|
||||
:closable="true"
|
||||
:visible="isShow"
|
||||
title="转账订单详情"
|
||||
@close="isShow = false"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户类型">
|
||||
{{ detailData.mchType === 1?'普通商户':detailData.mchType === 2?'特约商户':'未知' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户号">{{ detailData.mchNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户名称">{{ detailData.mchName }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用APPID">{{ detailData.appId }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="服务商号">{{ detailData.isvNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账订单号">
|
||||
<a-tag color="purple">{{ detailData.transferId }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户转账单号">{{ detailData.mchOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">{{ detailData.channelOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="金额">
|
||||
<a-tag color="green">{{ detailData.amount/100 }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="货币代码">{{ detailData.currency }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款账号">
|
||||
<a-tag color="green">{{ detailData.accountNo }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款人姓名">{{ detailData.accountName }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账备注">{{ detailData.transferDesc }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':'volcano'">
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'转账中':detailData.state === 2?'转账成功':detailData.state === 3?'转账失败':detailData.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账成功时间">{{ detailData.successTime }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="创建时间">{{ detailData.createdAt }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="更新时间">{{ detailData.updatedAt }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="接口代码">{{ detailData.ifCode }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="入账类型">{{ detailData.entryType }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="客户端IP">{{ detailData.clientIp }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="异步通知地址">{{ detailData.notifyUrl }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">{{ detailData.channelOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道错误码">{{ detailData.errCode }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道错误描述">{{ detailData.errMsg }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-form-model-item label="渠道额外参数">
|
||||
<a-input
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black"
|
||||
v-model="detailData.channelExtra"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
<a-col :sm="24">
|
||||
<a-form-model-item label="扩展参数">
|
||||
<a-input
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black"
|
||||
v-model="detailData.extParam"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script>
|
||||
import { API_URL_TRANSFER_ORDER_LIST, req } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
detailData: {},
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
recordId: null // 更新对象ID
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show: function (recordId) {
|
||||
const that = this
|
||||
req.getById(API_URL_TRANSFER_ORDER_LIST, recordId).then(res => {
|
||||
that.detailData = res
|
||||
})
|
||||
this.isShow = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<div class="table-page-search-wrapper">
|
||||
<a-form layout="inline" class="table-head-ground">
|
||||
<div class="table-layer">
|
||||
<a-form-item label="" class="table-head-layout" style="max-width:350px;min-width:300px">
|
||||
<a-range-picker
|
||||
@change="onChange"
|
||||
:show-time="{ format: 'HH:mm:ss' }"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
:disabled-date="disabledDate"
|
||||
>
|
||||
<a-icon slot="suffixIcon" type="sync" />
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
<jeepay-text-up :placeholder="'转账/商户/渠道订单号'" :msg="searchData.unionOrderId" v-model="searchData.unionOrderId" />
|
||||
<!-- <jeepay-text-up :placeholder="'转账订单号'" :msg="searchData.transferId" v-model="searchData.transferId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'商户订单号'" :msg="searchData.mchOrderNo" v-model="searchData.mchOrderNo" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'渠道支付订单号'" :msg="searchData.channelOrderNo" v-model="searchData.channelOrderNo" />-->
|
||||
<jeepay-text-up :placeholder="'商户号'" :msg="searchData.mchNo" v-model="searchData.mchNo" />
|
||||
<jeepay-text-up :placeholder="'应用AppId'" :msg="searchData.appId" v-model="searchData.appId"/>
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.state" placeholder="转账状态" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">订单生成</a-select-option>
|
||||
<a-select-option value="1">转账中</a-select-option>
|
||||
<a-select-option value="2">转账成功</a-select-option>
|
||||
<a-select-option value="3">转账失败</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<span class="table-page-search-submitButtons">
|
||||
<a-button type="primary" icon="search" @click="queryFunc" :loading="btnLoading">搜索</a-button>
|
||||
<a-button style="margin-left: 8px" icon="reload" @click="() => this.searchData = {}">重置</a-button>
|
||||
</span>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
@btnLoadClose="btnLoading=false"
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="transferId"
|
||||
:tableRowCrossColor="true"
|
||||
>
|
||||
<template slot="transferAmountSlot" slot-scope="{record}"><b>¥{{ record.amount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'转账中':record.state === 2?'转账成功':record.state === 3?'转账失败':record.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template slot="orderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">转账</span>{{ record.transferId }}</p>
|
||||
<p style="margin-bottom: 0;">
|
||||
<span style="color:#56cf56;background:#d8eadf">商户</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.mchOrderNo.length > record.transferId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.mchOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.mchOrderNo, record.transferId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.mchOrderNo }}</span>
|
||||
</p>
|
||||
<p v-if="record.channelOrderNo" style="margin-bottom: 0;margin-top: 10px">
|
||||
<span style="color:#fff;background:#E09C4D">渠道</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.channelOrderNo.length > record.transferId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.channelOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.channelOrderNo, record.transferId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.channelOrderNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" v-if="$access('ENT_TRANSFER_ORDER_VIEW')" @click="detailFunc(record.transferId)">详情</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 订单详情 页面组件 -->
|
||||
<TransferOrderDetail ref="transferOrderDetail" />
|
||||
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script>
|
||||
import JeepayTable from '@/components/JeepayTable/JeepayTable'
|
||||
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' // 文字上移组件
|
||||
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
||||
import TransferOrderDetail from './TransferOrderDetail'
|
||||
import { API_URL_TRANSFER_ORDER_LIST, req } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ title: '转账金额', scopedSlots: { customRender: 'transferAmountSlot' }, width: 108 },
|
||||
{ title: '商户名称', dataIndex: 'mchName' },
|
||||
{ key: 'orderNo', title: '订单号', scopedSlots: { customRender: 'orderSlot' }, width: 260 },
|
||||
// { title: '渠道订单号', dataIndex: 'channelOrderNo' },
|
||||
{ title: '收款账号', dataIndex: 'accountNo', width: 200 },
|
||||
{ title: '收款人姓名', dataIndex: 'accountName' },
|
||||
{ title: '转账备注', dataIndex: 'transferDesc' },
|
||||
{ title: '状态', scopedSlots: { customRender: 'stateSlot' }, width: 100 },
|
||||
{ title: '创建日期', dataIndex: 'createdAt' },
|
||||
{ title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'IsvListPage',
|
||||
components: { JeepayTable, JeepayTableColumns, JeepayTextUp, TransferOrderDetail },
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {},
|
||||
createdStart: '', // 选择开始时间
|
||||
createdEnd: '' // 选择结束时间
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
queryFunc () {
|
||||
this.btnLoading = true
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
// 请求table接口数据
|
||||
reqTableDataFunc: (params) => {
|
||||
return req.list(API_URL_TRANSFER_ORDER_LIST, params)
|
||||
},
|
||||
searchFunc: function () { // 点击【查询】按钮点击事件
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
detailFunc: function (recordId) {
|
||||
this.$refs.transferOrderDetail.show(recordId)
|
||||
},
|
||||
moment,
|
||||
onChange (date, dateString) {
|
||||
this.searchData.createdStart = dateString[0] // 开始时间
|
||||
this.searchData.createdEnd = dateString[1] // 结束时间
|
||||
},
|
||||
disabledDate (current) { // 今日之后日期不可选
|
||||
return current && current > moment().endOf('day')
|
||||
},
|
||||
changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = parseInt(baseLength / 2)
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -43,17 +43,29 @@
|
|||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24" v-if="saveObject.isIsvMode == 1">
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="支付参数配置页面类型" prop="configPageType">
|
||||
<a-radio-group v-model="saveObject.configPageType">
|
||||
<a-radio :value="1">
|
||||
根据接口配置定义描述渲染页面
|
||||
</a-radio>
|
||||
<a-radio :value="2">
|
||||
自定义页面
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24" v-if="saveObject.isIsvMode == 1 && this.saveObject.configPageType === 1">
|
||||
<a-form-model-item label="服务商接口配置定义描述" prop="isvParams">
|
||||
<a-input v-model="saveObject.isvParams" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24" v-if="saveObject.isIsvMode == 1">
|
||||
<a-col :span="24" v-if="saveObject.isIsvMode == 1 && this.saveObject.configPageType === 1">
|
||||
<a-form-model-item label="特约商户接口配置定义描述" prop="isvsubMchParams">
|
||||
<a-input v-model="saveObject.isvsubMchParams" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24" v-if="saveObject.isMchMode == 1">
|
||||
<a-col :span="24" v-if="saveObject.isMchMode == 1 && this.saveObject.configPageType === 1">
|
||||
<a-form-model-item label="普通商户接口配置定义描述" prop="normalMchParams">
|
||||
<a-input v-model="saveObject.normalMchParams" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
|
|
@ -124,19 +136,19 @@ export default {
|
|||
|
||||
data () {
|
||||
const validateNormalMchParams = (rule, value, callback) => { // 普通商户接口配置定义描述 验证器
|
||||
if (this.saveObject.isMchMode === 1 && !value) {
|
||||
if (this.saveObject.isMchMode === 1 && this.saveObject.configPageType === 1 && !value) {
|
||||
callback(new Error('请输入普通商户接口配置定义描述'))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
const validateIsvParams = (rule, value, callback) => { // 服务商接口配置定义描述 验证器
|
||||
if (this.saveObject.isIsvMode === 1 && !value) {
|
||||
if (this.saveObject.isIsvMode === 1 && this.saveObject.configPageType === 1 && !value) {
|
||||
callback(new Error('请输入服务商接口配置定义描述'))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
const validateIsvsubMchParams = (rule, value, callback) => { // 特约商户接口配置定义描述 验证器
|
||||
if (this.saveObject.isIsvMode === 1 && !value) {
|
||||
if (this.saveObject.isIsvMode === 1 && this.saveObject.configPageType === 1 && !value) {
|
||||
callback(new Error('请输入特约商户接口配置定义描述'))
|
||||
}
|
||||
callback()
|
||||
|
|
@ -176,7 +188,8 @@ export default {
|
|||
this.saveObject = {
|
||||
'isMchMode': 1,
|
||||
'isIsvMode': 1,
|
||||
'state': 1
|
||||
'state': 1,
|
||||
'configPageType': 1
|
||||
}
|
||||
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,17 @@
|
|||
<template>
|
||||
<page-header-wrapper>
|
||||
<template>
|
||||
<a-card style="width: calc(100% - 24px);margin-bottom: 20px;">
|
||||
<a-alert message="" type="info">
|
||||
<template #description>
|
||||
<p style="display: flex; justify-content: space-between; margin: 0 0 4px;">
|
||||
计全科技已开放支付接口购买渠道,官方团队开发、源码提供、下载后直接使用。<a href="https://docs.jeequan.com/docs/jeepay/jeepay-1ejdnsuhveb16" target="_blank">接口下载、安装说明。</a>
|
||||
<a href="https://www.jeequan.com/ifstore/list.html" target="_blank">前往接口市场 ></a>
|
||||
</p>
|
||||
</template>
|
||||
</a-alert>
|
||||
</a-card>
|
||||
</template>
|
||||
<JeepayCard
|
||||
ref="infoCard"
|
||||
:reqCardListFunc="reqCardListFunc"
|
||||
|
|
@ -53,8 +65,8 @@ export default {
|
|||
return {
|
||||
jeepayCard: {
|
||||
name: '支付接口',
|
||||
height: 300,
|
||||
span: { xxl: 6, xl: 4, lg: 4, md: 3, sm: 2, xs: 1 },
|
||||
height: 200,
|
||||
span: { xxl: 8, xl: 4, lg: 4, md: 3, sm: 2, xs: 1 },
|
||||
addAuthority: this.$access('ENT_PC_IF_DEFINE_ADD')
|
||||
}
|
||||
}
|
||||
|
|
@ -118,7 +130,7 @@ export default {
|
|||
align-items: center;
|
||||
}
|
||||
.title {
|
||||
font-size: 16px;
|
||||
font-size: 13px;
|
||||
font-family: PingFang SC, PingFang SC-Bold;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@
|
|||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="wayCode"
|
||||
:scrollX="500"
|
||||
>
|
||||
<template slot="wayCodeSlot" slot-scope="{record}"><b>{{ record.wayCode }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
:scrollX="500"
|
||||
rowKey="roleName"
|
||||
>
|
||||
<template slot="roleIdSlot" slot-scope="{record}"><b>{{ record.roleId }}</b></template> <!-- 自定义插槽 -->
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
:searchData="searchData"
|
||||
:rowSelection="rowSelection"
|
||||
rowKey="sysLogId"
|
||||
:scrollX="1200"
|
||||
>
|
||||
<template slot="userNameSlot" slot-scope="{record}"><b>{{ record.userName }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="sysTypeSlot" slot-scope="{record}">
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="sysUserId"
|
||||
:scrollX="1350"
|
||||
>
|
||||
|
||||
<template slot="avatarSlot" slot-scope="{record}">
|
||||
|
|
|
|||
|
|
@ -53,7 +53,10 @@
|
|||
<img :src="vercodeIcon" slot="prefix" class="user" alt="user" />
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<div class="code-img"><img v-show="vercodeImgSrc" :src="vercodeImgSrc" @click="refVercode()"/></div>
|
||||
<div class="code-img" style="position: relative;background:#ddd">
|
||||
<img v-show="vercodeImgSrc" :src="vercodeImgSrc" @click="refVercode()"/>
|
||||
<div class="vercode-mask" v-show="isOverdue" @click="refVercode()">已过期 请刷新</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a-form-item>
|
||||
|
|
@ -89,6 +92,7 @@ export default {
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
isOverdue: false, // 设置过期样式
|
||||
isAutoLogin: true, // 是否是自动登录
|
||||
loginBtnLoadingFlag: false, // 登录按钮是否显示 加载状态
|
||||
showLoginErrorInfo: '', // 是否显示登录错误面板信息
|
||||
|
|
@ -145,6 +149,17 @@ export default {
|
|||
vercode().then(res => {
|
||||
that.vercodeImgSrc = res.imageBase64Data
|
||||
that.vercodeToken = res.vercodeToken
|
||||
|
||||
this.isOverdue = false
|
||||
if (this.timer) clearInterval(this.timer) // 如果多次点击则清除已有的定时器
|
||||
// 超过60秒提示过期刷新
|
||||
this.timer = setInterval(() => {
|
||||
res.expireTime--
|
||||
if (res.expireTime <= 0) {
|
||||
that.isOverdue = true
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -211,5 +226,19 @@ export default {
|
|||
margin-top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.vercode-mask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000;
|
||||
opacity: 0.8;
|
||||
text-align:center;
|
||||
line-height: 40px;
|
||||
color:#fff;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -16,25 +16,7 @@ function getGitHash () {
|
|||
return 'unknown'
|
||||
}
|
||||
|
||||
const isProd = process.env.NODE_ENV === 'production'
|
||||
|
||||
const assetsCDN = {
|
||||
// webpack build externals
|
||||
externals: {
|
||||
vue: 'Vue',
|
||||
'vue-router': 'VueRouter',
|
||||
vuex: 'Vuex',
|
||||
axios: 'axios'
|
||||
},
|
||||
css: [],
|
||||
// https://unpkg.com/browse/vue@2.6.10/
|
||||
js: [
|
||||
'//cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js',
|
||||
'//cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js',
|
||||
'//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js',
|
||||
'//cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js'
|
||||
]
|
||||
}
|
||||
// const isProd = process.env.NODE_ENV === 'production'
|
||||
|
||||
// vue.config.js
|
||||
const vueConfig = {
|
||||
|
|
@ -51,7 +33,7 @@ const vueConfig = {
|
|||
})
|
||||
],
|
||||
// if prod, add externals
|
||||
externals: isProd ? assetsCDN.externals : {}
|
||||
externals: {}
|
||||
},
|
||||
|
||||
chainWebpack: (config) => {
|
||||
|
|
@ -71,17 +53,9 @@ const vueConfig = {
|
|||
.use('file-loader')
|
||||
.loader('file-loader')
|
||||
.options({
|
||||
limit: 100000,
|
||||
name: 'assets/[name].[hash:8].[ext]'
|
||||
})
|
||||
|
||||
// if prod is on
|
||||
// assets require on cdn
|
||||
if (isProd) {
|
||||
config.plugin('html').tap(args => {
|
||||
args[0].cdn = assetsCDN
|
||||
return args
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
css: {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "jeepay-ui-merchant",
|
||||
"version": "1.1.1",
|
||||
"version": "1.10.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
|
|
@ -34,6 +34,7 @@
|
|||
"vue-clipboard2": "^0.2.1",
|
||||
"vue-cropper": "0.4.9",
|
||||
"vue-i18n": "^8.17.4",
|
||||
"vue-qr": "^2.5.0",
|
||||
"vue-quill-editor": "^3.0.6",
|
||||
"vue-router": "^3.1.2",
|
||||
"vue-svg-component-runtime": "^1.0.1",
|
||||
|
|
|
|||
|
|
@ -86,6 +86,17 @@ export const API_URL_PAYWAYS_LIST = '/api/payWays'
|
|||
export const API_URL_MCH_PAYCONFIGS_LIST = '/api/mch/payConfigs'
|
||||
/** 商户支付通道配置 **/
|
||||
export const API_URL_MCH_PAYPASSAGE_LIST = '/api/mch/payPassages'
|
||||
/** 转账订单管理 **/
|
||||
export const API_URL_TRANSFER_ORDER_LIST = '/api/transferOrders'
|
||||
|
||||
/** 分账组管理 **/
|
||||
export const API_URL_DIVISION_RECEIVER_GROUP = '/api/divisionReceiverGroups'
|
||||
|
||||
/** 分账账号管理 **/
|
||||
export const API_URL_DIVISION_RECEIVER = '/api/divisionReceivers'
|
||||
|
||||
/** 分账记录管理 **/
|
||||
export const API_URL_PAY_ORDER_DIVISION_RECORD_LIST = '/api/division/records'
|
||||
|
||||
/** 上传图片/文件地址 **/
|
||||
export const upload = {
|
||||
|
|
@ -235,3 +246,62 @@ export function getWebSocketPrefix () {
|
|||
return 'ws://' + domain.replace('http://', '')
|
||||
}
|
||||
}
|
||||
|
||||
/** 查询支付宝授权地址URL **/
|
||||
export function queryAlipayIsvsubMchAuthUrl (mchAppId) {
|
||||
return request.request({
|
||||
url: '/api/mch/payConfigs/alipayIsvsubMchAuthUrls/' + mchAppId,
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/** 查询商户转账支出的接口 **/
|
||||
export function queryMchTransferIfCode (appId) {
|
||||
return request.request({
|
||||
url: 'api/mchTransfers/ifCodes/' + appId,
|
||||
method: 'GET'
|
||||
})
|
||||
}
|
||||
|
||||
/** 获取渠道用户ID二维码地址 **/
|
||||
export function getChannelUserQrImgUrl (ifCode, appId, extParam) {
|
||||
return request.request({
|
||||
url: '/api/mchTransfers/channelUserId',
|
||||
method: 'GET',
|
||||
params: { ifCode, appId, extParam }
|
||||
})
|
||||
}
|
||||
|
||||
/** 转账 **/
|
||||
export function doTransfer (parameter) {
|
||||
return request.request({
|
||||
url: '/api/mchTransfers/doTransfer',
|
||||
method: 'POST',
|
||||
data: parameter
|
||||
}, true, true, true)
|
||||
}
|
||||
|
||||
/** 查询当前应用支持的支付接口 **/
|
||||
export function getIfCodeByAppId (appId) {
|
||||
return request.request({
|
||||
url: '/api/mch/payConfigs/ifCodes/' + appId,
|
||||
method: 'GET'
|
||||
}, true, true, true)
|
||||
}
|
||||
|
||||
/** 退款接口 */
|
||||
export function payOrderRefund (payOrderId, refundAmount, refundReason) {
|
||||
return request.request({
|
||||
url: '/api/payOrder/refunds/' + payOrderId,
|
||||
method: 'POST',
|
||||
data: { refundAmount, refundReason }
|
||||
})
|
||||
}
|
||||
|
||||
/** 分账重试 */
|
||||
export function resendDivision (recordId) {
|
||||
return request.request({
|
||||
url: '/api/division/records/resend/' + recordId,
|
||||
method: 'POST'
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="40" height="40" viewBox="0 0 40 40">
|
||||
<defs>
|
||||
<clipPath id="clip-path">
|
||||
<rect id="矩形_3796" data-name="矩形 3796" width="17" height="20" transform="translate(7694 5293)" fill="#fff" stroke="#707070" stroke-width="1"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<g id="PayPal" transform="translate(-7454 -5095)">
|
||||
<path id="路径_4159" data-name="路径 4159" d="M190.218,137.3l-.02-.02-.02-.02c-1.442-1.442-3.6-2.176-6.511-2.561a91.682,91.682,0,0,0-10.426-.453,91.64,91.64,0,0,0-10.426.453c-2.929.387-5.089,1.126-6.531,2.582s-2.2,3.6-2.581,6.531a91.665,91.665,0,0,0-.453,10.426,91.651,91.651,0,0,0,.453,10.426c.385,2.916,1.12,5.069,2.562,6.511l.02.02.02.02c1.442,1.442,3.6,2.176,6.511,2.561a91.679,91.679,0,0,0,10.426.453,91.64,91.64,0,0,0,10.426-.453c2.929-.387,5.089-1.126,6.531-2.582s2.2-3.6,2.581-6.531a91.69,91.69,0,0,0,.453-10.426,91.64,91.64,0,0,0-.453-10.426c-.385-2.916-1.12-5.069-2.562-6.511Z" transform="translate(7300.76 4960.764)" fill="#c3cbe6"/>
|
||||
<path id="矩形_2559" data-name="矩形 2559" d="M1,0H11a1,1,0,0,1,1,1V4H0V1A1,1,0,0,1,1,0Z" transform="translate(7468.001 5109.007)" fill="#e60012"/>
|
||||
<g id="蒙版组_330" data-name="蒙版组 330" transform="translate(-228.5 -188)" clip-path="url(#clip-path)">
|
||||
<g id="组_1372" data-name="组 1372" transform="translate(7694 5293)">
|
||||
<path id="路径_11885" data-name="路径 11885" d="M302.719,129.325l.345-2.136H298.75l2.416-15.7c0-.058,0-.058.057-.173a.252.252,0,0,1,.173-.058h5.983c2.013,0,3.337.462,4.084,1.27a4.157,4.157,0,0,1,.69,1.212,8.721,8.721,0,0,1,0,1.732v.519l.345.173a3.1,3.1,0,0,1,.69.519,2.356,2.356,0,0,1,.575,1.27,6.219,6.219,0,0,1-.058,1.789,6.092,6.092,0,0,1-.748,2.02,3.2,3.2,0,0,1-1.208,1.27,7.716,7.716,0,0,1-1.553.75,7.418,7.418,0,0,1-1.9.231h-.69a1.419,1.419,0,0,0-1.381,1.212v.231l-.575,3.694v.173a.056.056,0,0,1-.057.058h-.058a22.977,22.977,0,0,0-2.819-.058Z" transform="translate(-298.051 -110.452)" fill="#253b80"/>
|
||||
<path id="路径_11886" data-name="路径 11886" d="M420.32,248.293c0,.173-.058.231-.058.4-.863,4.329-3.624,5.714-7.191,5.714H411.23a.865.865,0,0,0-.863.75l-.92,6-.23,1.732c-.058.231.173.462.4.519h3.337a.752.752,0,0,0,.748-.693v-.173l.633-3.925.058-.231a.8.8,0,0,1,.748-.693h.46c3.164,0,5.523-1.328,6.328-5.021.288-1.558.173-2.886-.633-3.752a5.7,5.7,0,0,0-.978-.635Z" transform="translate(-405.066 -243.214)" fill="#179bd7"/>
|
||||
<path id="路径_11887" data-name="路径 11887" d="M459.074,228.212c-.173,0-.23-.058-.4-.058s-.288-.058-.4-.058a15.249,15.249,0,0,0-1.611-.173h-4.832a.752.752,0,0,0-.748.693l-.978,6.637v.173a.865.865,0,0,1,.863-.75H452.8c3.567,0,6.386-1.443,7.191-5.714,0-.173.057-.231.057-.4-.23-.058-.46-.231-.69-.289l-.288-.058Z" transform="translate(-444.684 -223.479)" fill="#222d65"/>
|
||||
<path id="路径_11888" data-name="路径 11888" d="M282.712,90.528a.8.8,0,0,1,.748-.693h4.832a5.112,5.112,0,0,1,1.611.173c.173,0,.288.058.4.058.173,0,.23.058.4.058l.173.058a3.516,3.516,0,0,1,.69.289,3.938,3.938,0,0,0-.863-3.578c-.92-1.1-2.646-1.558-4.775-1.558h-6.213a.866.866,0,0,0-.863.75l-2.531,16.507c-.057.289.173.52.46.635H280.7l.978-6.118c.058,0,1.035-6.58,1.035-6.58Z" transform="translate(-276.318 -85.333)" fill="#253b80"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.2 KiB |
|
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-modal v-model="visible" title="自动获取渠道用户ID" @ok="handleClose" :footer="null" :width="300">
|
||||
<div style="width:100%;margin-bottom:20px;text-align:center">
|
||||
<div style="width: 300px" class="qrcode" id="qrCodeUrl"></div>
|
||||
<vueQr :text="qrImgUrl"/>
|
||||
<hr/>
|
||||
<span>{{ payText }}</span>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ReconnectingWebSocket from 'reconnectingwebsocket'
|
||||
import vueQr from 'vue-qr'
|
||||
import { getWebSocketPrefix, getChannelUserQrImgUrl } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
components: { vueQr },
|
||||
data () {
|
||||
return {
|
||||
visible: false,
|
||||
qrImgUrl: '',
|
||||
payText: '', // 二维码底部描述文字
|
||||
transferOrderWebSocket: null, // 支付订单webSocket对象
|
||||
extObject: null // 扩展对象, 将原样返回。
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
// show
|
||||
showModal (appId, ifCode, extObject) {
|
||||
const that = this
|
||||
that.extObject = extObject
|
||||
// 关闭上一个webSocket监听
|
||||
if (this.transferOrderWebSocket) {
|
||||
this.transferOrderWebSocket.close()
|
||||
}
|
||||
|
||||
// 根据不同的支付方式,展示不同的信息
|
||||
this.payText = ''
|
||||
if (ifCode === 'wxpay') {
|
||||
this.payText = '请使用微信客户端"扫一扫"'
|
||||
} else if (ifCode === 'alipay') {
|
||||
this.payText = '请使用支付宝客户端"扫一扫"'
|
||||
}
|
||||
|
||||
// 当前客户端CID
|
||||
const cid = appId + new Date().getTime()
|
||||
// 获取二维码地址
|
||||
getChannelUserQrImgUrl(ifCode, appId, cid).then(res => {
|
||||
that.qrImgUrl = res
|
||||
|
||||
that.visible = true // 打开弹窗
|
||||
|
||||
// 监听响应结果
|
||||
that.transferOrderWebSocket = new ReconnectingWebSocket(getWebSocketPrefix() + '/api/anon/ws/channelUserId/' + appId + '/' + cid)
|
||||
that.transferOrderWebSocket.onopen = () => {}
|
||||
that.transferOrderWebSocket.onmessage = (msgObject) => {
|
||||
that.$emit('changeChannelUserId', { channelUserId: msgObject.data, extObject: that.extObject }) // 上层赋值
|
||||
that.handleClose()
|
||||
}
|
||||
})
|
||||
},
|
||||
handleClose (e) {
|
||||
if (this.transferOrderWebSocket) {
|
||||
this.transferOrderWebSocket.close()
|
||||
}
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.describe {
|
||||
img {
|
||||
width: 30px;
|
||||
height: 25px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<template v-slot:links>
|
||||
</template>
|
||||
<template v-slot:copyright>
|
||||
<a href="http://www.jeequan.com" target="_blank">@计全科技</a>
|
||||
Copyright © 2023 <a href="http://www.jeequan.com" target="_blank">jeequan.com</a>. All rights reserved.
|
||||
</template>
|
||||
</global-footer>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@
|
|||
:row-selection="rowSelection"
|
||||
:rowKey="rowKey"
|
||||
:scroll="{ x: scrollX }"
|
||||
:customRow="(record, index) => {
|
||||
if(!tableRowCrossColor){
|
||||
return {};
|
||||
}
|
||||
return { style: { 'background-color': index % 2 == 0 ? '#FCFCFC' : '#FFFFFF'} }
|
||||
}"
|
||||
>
|
||||
<!-- 自定义列插槽, 参考:https://github.com/feseed/admin-antd-vue/blob/master/src/components/ShTable.vue -->
|
||||
<!-- eslint-disable-next-line -->
|
||||
|
|
@ -41,7 +47,8 @@ export default {
|
|||
pageSize: { type: Number, default: 10 }, // 默认每页条数
|
||||
rowSelection: Object, // checkbox选择
|
||||
rowKey: { type: [String, Function] }, // 定义rowKey 如果不定义将会出现(树状结构出问题, checkbox不消失等)
|
||||
scrollX: { type: Number, default: 980 } // 定义表格的最小宽度,在小就会出现横向的滚动条
|
||||
scrollX: { type: Number, default: 800 }, // 定义表格的最小宽度,在小就会出现横向的滚动条
|
||||
tableRowCrossColor: { type: Boolean, default: false } // 是隔行换色
|
||||
},
|
||||
|
||||
data () {
|
||||
|
|
@ -117,3 +124,24 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
|
||||
// 调整antdv 的table默认padding高度
|
||||
.ant-table-fixed{
|
||||
tr{
|
||||
th{
|
||||
padding: 8px 8px !important;
|
||||
}
|
||||
th:first-child{ // 第一个表格 左填充16, 其他为8
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
td{
|
||||
padding: 8px 8px !important;
|
||||
}
|
||||
td:first-child{
|
||||
padding-left: 16px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ export default {
|
|||
}
|
||||
return <div style="display:flex; justify-content: space-evenly;"> {firstEL}
|
||||
<a-dropdown>
|
||||
<a-button style="line-height:32px" type="link" class="ant-dropdown-link">更多<a-icon type="down" /></a-button>
|
||||
<a-button style="" type="link" class="ant-dropdown-link">更多<a-icon type="down" /></a-button>
|
||||
<a-menu slot="overlay">
|
||||
{menuEL}
|
||||
</a-menu>
|
||||
|
|
@ -40,3 +40,9 @@ export default {
|
|||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
//当前页面的按钮, 减少padding
|
||||
button { padding: 8px !important;}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,14 @@ export const asyncRouteDefine = {
|
|||
|
||||
'MchAppPage': { defaultPath: '/apps', component: () => import ('@/views/mchApp/List') }, // 商户应用列表
|
||||
'PayTestPage': { defaultPath: '/paytest', component: () => import ('@/views/payTest/PayTest') }, // 支付测试
|
||||
'MchTransferPage': { defaultPath: '/doTransfer', component: () => import ('@/views/transfer/MchTransferPage') }, // 转账
|
||||
|
||||
'PayOrderListPage': { defaultPath: '/payOrder', component: () => import('@/views/order/pay/PayOrderList') }, // 支付订单列表
|
||||
'RefundOrderListPage': { defaultPath: '/refundOrder', component: () => import('@/views/order/refund/RefundOrderList') } // 退款订单列表
|
||||
'RefundOrderListPage': { defaultPath: '/refundOrder', component: () => import('@/views/order/refund/RefundOrderList') }, // 退款订单列表
|
||||
'TransferOrderListPage': { defaultPath: '/transferOrder', component: () => import('@/views/order/transfer/TransferOrderList') }, // 转账订单
|
||||
|
||||
'DivisionReceiverGroupPage': { defaultPath: '/divisionReceiverGroup', component: () => import('@/views/division/group/DivisionReceiverGroupPage') }, // 分账账号组管理
|
||||
'DivisionReceiverPage': { defaultPath: '/divisionReceiver', component: () => import('@/views/division/receiver/DivisionReceiverPage') }, // 分账账号管理
|
||||
'DivisionRecordPage': { defaultPath: '/divisionRecord', component: () => import('@/views/division/record/DivisionRecordPage') } // 分账记录
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
:i18nRender="false"
|
||||
v-bind="settings"
|
||||
:breadcrumbRender="handleBreadcrumbRender"
|
||||
:siderWidth="210"
|
||||
>
|
||||
<!-- 1.0.0+ 版本 pro-layout 提供 API,
|
||||
我们推荐使用这种方式进行 LOGO 和 title 自定义
|
||||
|
|
@ -34,6 +35,8 @@
|
|||
|
||||
<template v-slot:rightContentRender>
|
||||
<right-content :top-menu="settings.layout === 'topmenu'" :is-mobile="isMobile" :theme="settings.theme" />
|
||||
<a style="color: red; float: right; padding-right: 10px;" href="https://www.jeequan.com/product/jeepay4plus.html" target="_blank">Plus商业版</a>
|
||||
<a style="color: red; float: right; padding-right: 10px;" href="https://www.jeequan.com/ifstore/list.html" target="_blank">接口市场</a>
|
||||
</template>
|
||||
<!-- custom footer / 自定义Footer -->
|
||||
<template v-slot:footerRender>
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ export const printANSI = () => {
|
|||
/ /_/ // __/ __/ /_/ / /_/ / /_/ /
|
||||
\\____/ \\___/\\___/ .___/\\__,_/\\__, /
|
||||
/_/ /____/
|
||||
:: Jeepay :: (v1.0.0.RELEASE)
|
||||
适合互联网企业使用的开源支付系统 : https://www.jeepay.vip
|
||||
:: Jeepay :: (v2.2.2.RELEASE)
|
||||
让支付接入更简单 : https://www.jeequan.com
|
||||
`
|
||||
|
||||
console.log(`%c${text}`, 'color: #fc4d50')
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
|
||||
// 定义全局自增ID
|
||||
var atomicLong = 1
|
||||
|
||||
export function timeFix () {
|
||||
const time = new Date()
|
||||
const hour = time.getHours()
|
||||
|
|
@ -10,3 +14,8 @@ export function isIE () {
|
|||
const ie11 = (() => 'ActiveXObject' in window)()
|
||||
return compare('MSIE') || ie11
|
||||
}
|
||||
|
||||
/** 生成自增序列号(不重复) **/
|
||||
export function genRowKey () {
|
||||
return new Date().getTime() + '_' + (atomicLong++)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,96 @@
|
|||
<template>
|
||||
<a-modal v-model="isShow" :title=" isAdd ? '新增菜单' : '修改菜单' " @ok="handleOkFunc" :confirmLoading="confirmLoading">
|
||||
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="rules">
|
||||
|
||||
<a-form-model-item label="组名称:" prop="receiverGroupName">
|
||||
<a-input v-model="saveObject.receiverGroupName" />
|
||||
</a-form-model-item>
|
||||
|
||||
<a-form-model-item label="自动分账组" prop="autoDivisionFlag">
|
||||
<a-radio-group v-model="saveObject.autoDivisionFlag">
|
||||
<a-radio :value="1">是</a-radio> <a-radio :value="0">否</a-radio>
|
||||
</a-radio-group>
|
||||
<hr/>
|
||||
<p style="color: indianred">1. 自动分账组: 当订单分账模式为自动分账,该组下的所有正常分账状态的账号将作为订单分账对象</p>
|
||||
<p style="color: indianred">2. 每个商户仅有一个默认分账组, 当该组更新为自动分账时,其他组将改为否</p>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
|
||||
</a-modal>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { API_URL_DIVISION_RECEIVER_GROUP, req } from '@/api/manage'
|
||||
export default {
|
||||
|
||||
props: {
|
||||
callbackFunc: { type: Function }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isAdd: true, // 新增 or 修改页面标识
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: { autoDivisionFlag: 0 }, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
rules: {
|
||||
receiverGroupName: [
|
||||
{ required: true, message: '请输入组名称', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
show: function (recordId) { // 弹层打开事件
|
||||
this.isAdd = !recordId
|
||||
this.saveObject = { autoDivisionFlag: 0 } // 数据清空
|
||||
this.confirmLoading = false // 关闭loading
|
||||
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
|
||||
const that = this
|
||||
if (!this.isAdd) { // 修改信息 延迟展示弹层
|
||||
that.recordId = recordId
|
||||
req.getById(API_URL_DIVISION_RECEIVER_GROUP, recordId).then(res => {
|
||||
that.saveObject = res
|
||||
that.isShow = true
|
||||
})
|
||||
} else {
|
||||
that.isShow = true // 立马展示弹层信息
|
||||
}
|
||||
},
|
||||
|
||||
handleOkFunc: function () { // 点击【确认】按钮事件
|
||||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
if (valid) { // 验证通过
|
||||
// 请求接口
|
||||
|
||||
that.confirmLoading = true // 显示loading
|
||||
|
||||
if (that.isAdd) {
|
||||
req.add(API_URL_DIVISION_RECEIVER_GROUP, that.saveObject).then(res => {
|
||||
that.$message.success('添加成功')
|
||||
that.isShow = false
|
||||
that.callbackFunc() // 刷新列表
|
||||
}).catch(res => { that.confirmLoading = false })
|
||||
} else {
|
||||
req.updateById(API_URL_DIVISION_RECEIVER_GROUP, that.recordId, that.saveObject).then(res => {
|
||||
that.$message.success('修改成功')
|
||||
that.isShow = false
|
||||
that.callbackFunc() // 刷新列表
|
||||
}).catch(res => { that.confirmLoading = false })
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<div v-if="$access('ENT_DIVISION_RECEIVER_GROUP_LIST')" class="table-page-search-wrapper">
|
||||
<a-form layout="inline" class="table-head-ground">
|
||||
<div
|
||||
class="table-layer"
|
||||
>
|
||||
<jeepay-text-up :placeholder="'组ID'" :msg="searchData.receiverGroupId" v-model="searchData.receiverGroupId" />
|
||||
<jeepay-text-up :placeholder="'组名称'" :msg="searchData.receiverGroupName" v-model="searchData.receiverGroupName" />
|
||||
<span class="table-page-search-submitButtons">
|
||||
<a-button type="primary" @click="searchFunc" icon="search" :loading="btnLoading">查询</a-button>
|
||||
<a-button style="margin-left: 8px;" @click="() => this.searchData = {}" icon="reload">重置</a-button>
|
||||
</span>
|
||||
</div>
|
||||
</a-form>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_DIVISION_RECEIVER_GROUP_ADD')" type="primary" icon="plus" @click="addFunc" class="mg-b-30">新建</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
rowKey="receiverGroupId"
|
||||
>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a v-if="$access('ENT_DIVISION_RECEIVER_GROUP_EDIT')" @click="editFunc(record.receiverGroupId)">修改</a>
|
||||
<a style="color: red" v-if="$access('ENT_DIVISION_RECEIVER_GROUP_DELETE')" @click="delFunc(record.receiverGroupId)">删除</a>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增 / 修改 页面组件 -->
|
||||
<InfoAddOrEdit ref="infoAddOrEdit" :callbackFunc="searchFunc" />
|
||||
|
||||
</page-header-wrapper>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import JeepayTable from '@/components/JeepayTable/JeepayTable'
|
||||
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
||||
import { API_URL_DIVISION_RECEIVER_GROUP, req } from '@/api/manage'
|
||||
import InfoAddOrEdit from './AddOrEdit'
|
||||
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' // 文字上移组件
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ key: 'receiverGroupId', dataIndex: 'receiverGroupId', title: '组ID' },
|
||||
{ key: 'receiverGroupName', dataIndex: 'receiverGroupName', title: '组名称' },
|
||||
{ key: 'autoDivisionFlag', dataIndex: 'autoDivisionFlag', title: '自动分账组', customRender: (text, record, index) => text === 1 ? '是' : '否' },
|
||||
{ key: 'createdBy', dataIndex: 'createdBy', title: '创建人' },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建时间' },
|
||||
{ key: 'op', title: '操作', width: '200px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'RolePage',
|
||||
components: { JeepayTable, JeepayTableColumns, InfoAddOrEdit, JeepayTextUp },
|
||||
data () {
|
||||
return {
|
||||
tableColumns: tableColumns,
|
||||
searchData: {},
|
||||
btnLoading: false
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 请求table接口数据
|
||||
reqTableDataFunc: (params) => {
|
||||
return req.list(API_URL_DIVISION_RECEIVER_GROUP, params)
|
||||
},
|
||||
|
||||
searchFunc: function () { // 点击【查询】按钮点击事件
|
||||
this.btnLoading = true // 打开查询按钮上的loading
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
|
||||
addFunc: function () { // 业务通用【新增】 函数
|
||||
this.$refs.infoAddOrEdit.show()
|
||||
},
|
||||
|
||||
editFunc: function (recordId) { // 业务通用【修改】 函数
|
||||
this.$refs.infoAddOrEdit.show(recordId)
|
||||
},
|
||||
|
||||
delFunc: function (recordId) { // 业务通用【删除】 函数
|
||||
const that = this
|
||||
this.$infoBox.confirmDanger('确认删除?', '', () => {
|
||||
// 需要【按钮】loading 请返回 promise对象, 不需要请直接返回null
|
||||
return req.delById(API_URL_DIVISION_RECEIVER_GROUP, recordId).then(res => {
|
||||
that.$message.success('删除成功!')
|
||||
that.$refs.infoTable.refTable(false)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<div v-if="$access('ENT_DIVISION_RECEIVER_LIST')" class="table-page-search-wrapper">
|
||||
|
||||
<a-form layout="inline" class="table-head-ground">
|
||||
|
||||
<div class="table-layer">
|
||||
|
||||
<a-form-item label="" class="table-head-layout" :wrapper-col="{span: 16}">
|
||||
<a-select v-model="searchData.appId" placeholder="选择应用">
|
||||
<a-select-option key="" >全部应用</a-select-option>
|
||||
<a-select-option v-for="(item) in mchAppList" :key="item.appId" >{{ item.appName }} [{{ item.appId }}]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<jeepay-text-up placeholder="分账接收者ID[精准]" :msg="searchData.receiverId" v-model="searchData.receiverId" />
|
||||
<jeepay-text-up placeholder="接收者账号别名[模糊]" :msg="searchData.receiverAlias" v-model="searchData.receiverAlias" />
|
||||
<jeepay-text-up placeholder="组ID[精准]" :msg="searchData.receiverGroupId" v-model="searchData.receiverGroupId" />
|
||||
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.state" placeholder="账号状态(本系统)" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">正常分账</a-select-option>
|
||||
<a-select-option value="0">暂停分账</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<span class="table-page-search-submitButtons">
|
||||
<a-button type="primary" @click="searchFunc" icon="search" :loading="btnLoading">查询</a-button>
|
||||
<a-button style="margin-left: 8px;" @click="() => this.searchData = {}" icon="reload">重置</a-button>
|
||||
</span>
|
||||
</div>
|
||||
</a-form>
|
||||
<div>
|
||||
<a-button v-if="$access('ENT_DIVISION_RECEIVER_ADD')" type="danger" icon="plus" @click="addFunc" class="mg-b-30">新建</a-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
ref="infoTable"
|
||||
:initData="false"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
rowKey="receiverId"
|
||||
>
|
||||
|
||||
<!-- 渠道类型 -->
|
||||
<template slot="ifCodeSlot" slot-scope="{record}">
|
||||
<template v-if="record.ifCode === 'wxpay'" ><span style="color: green"><a-icon type="wechat" /> 微信</span></template>
|
||||
<template v-else-if="record.ifCode == 'alipay'" ><span style="color: dodgerblue"><a-icon type="alipay-circle" /> 支付宝</span></template>
|
||||
<template v-else >{{record.ifCode}}</template>
|
||||
</template>
|
||||
|
||||
<!-- 状态(本系统) -->
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<div v-if="record.state == 0" ><a-badge status="error" text="暂停分账" /></div>
|
||||
<div v-else-if="record.state == 1" ><a-badge status="processing" text="正常分账" /></div>
|
||||
<div v-else ><a-badge status="warning" text="未知" /></div>
|
||||
</template>
|
||||
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a v-if="$access('ENT_DIVISION_RECEIVER_EDIT')" @click="editFunc(record.receiverId)">修改</a>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
|
||||
<!-- 新增收款账号页面 -->
|
||||
<ReceiverAdd ref="receiverAdd" :callbackFunc="searchFunc"/>
|
||||
|
||||
<!-- 修改 页面组件 -->
|
||||
<ReceiverEdit ref="receiverEdit" :callbackFunc="searchFunc"/>
|
||||
</a-card>
|
||||
|
||||
</page-header-wrapper>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import JeepayTable from '@/components/JeepayTable/JeepayTable'
|
||||
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
||||
import { API_URL_DIVISION_RECEIVER, API_URL_MCH_APP, req } from '@/api/manage'
|
||||
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' // 文字上移组件
|
||||
import ReceiverAdd from './ReceiverAdd'
|
||||
import ReceiverEdit from './ReceiverEdit'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ key: 'receiverId', dataIndex: 'receiverId', title: '绑定ID' },
|
||||
{ key: 'ifCode', title: '渠道类型', scopedSlots: { customRender: 'ifCodeSlot' } },
|
||||
{ key: 'receiverAlias', dataIndex: 'receiverAlias', title: '账号别名' },
|
||||
{ key: 'receiverGroupName', dataIndex: 'receiverGroupName', title: '组名称' },
|
||||
{ key: 'accNo', dataIndex: 'accNo', title: '分账接收账号' },
|
||||
{ key: 'accName', dataIndex: 'accName', title: '分账接收账号名称' },
|
||||
{ key: 'relationTypeName', dataIndex: 'relationTypeName', title: '分账关系类型' },
|
||||
{ title: '状态', scopedSlots: { customRender: 'stateSlot' }, align: 'center' },
|
||||
{ key: 'bindSuccessTime', dataIndex: 'bindSuccessTime', title: '绑定成功时间' },
|
||||
{ key: 'divisionProfit', dataIndex: 'divisionProfit', title: '默认分账比例', customRender: (text, record, index) => (text * 100).toFixed(2) + '%' },
|
||||
{ key: 'op', title: '操作', width: '200px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
components: { JeepayTable, JeepayTableColumns, JeepayTextUp, ReceiverAdd, ReceiverEdit },
|
||||
data () {
|
||||
return {
|
||||
tableColumns: tableColumns,
|
||||
searchData: { appId: '' },
|
||||
btnLoading: false,
|
||||
|
||||
mchAppList: [] // 商户app列表
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
const that = this // 提前保留this
|
||||
// 请求接口,获取所有的appid,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1 }).then(res => {
|
||||
that.mchAppList = res.records
|
||||
|
||||
// 默认选中第一个 & 更新列表
|
||||
if (that.mchAppList && that.mchAppList.length > 0) {
|
||||
that.searchData.appId = that.mchAppList[0].appId + ''
|
||||
that.searchFunc()
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 请求table接口数据
|
||||
reqTableDataFunc: (params) => {
|
||||
return req.list(API_URL_DIVISION_RECEIVER, params)
|
||||
},
|
||||
|
||||
searchFunc: function () { // 点击【查询】按钮点击事件
|
||||
this.btnLoading = true // 打开查询按钮上的loading
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
|
||||
addFunc: function () { // 业务通用【新增】 函数
|
||||
if (this.mchAppList.length <= 0) {
|
||||
return this.$message.error('当前商户无任何应用,请先创建应用后再试。')
|
||||
}
|
||||
if (!this.searchData.appId) {
|
||||
return this.$message.error('请先选择应用。')
|
||||
}
|
||||
|
||||
// 打开弹层
|
||||
this.$refs.receiverAdd.show(this.mchAppList.filter((item) => item.appId === this.searchData.appId)[0])
|
||||
},
|
||||
|
||||
editFunc: function (recordId) { // 业务通用【修改】 函数
|
||||
this.$refs.receiverEdit.show(recordId)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,356 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
v-if="visible"
|
||||
:visible="visible"
|
||||
@close="onClose"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
:drawer-style="{ backgroundColor: '#f0f2f5' }"
|
||||
width="80%"
|
||||
>
|
||||
|
||||
<a-descriptions title="绑定分账接收者账号">
|
||||
<a-descriptions-item label="当前应用">
|
||||
<span style="color: red">{{ appInfo.appName }} [{{ appInfo.appId }}]</span>
|
||||
</a-descriptions-item>
|
||||
|
||||
<a-descriptions-item label="选择要加入到的账号分组">
|
||||
<a-select style="width: 210px" placeholder="账号分组" v-model="selectedReceiverGroupId">
|
||||
<a-select-option v-for="(item) in allReceiverGroup" :key="item.receiverGroupId" :value="item.receiverGroupId">{{ item.receiverGroupName }}</a-select-option>
|
||||
</a-select>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<a-divider></a-divider>
|
||||
|
||||
<a-card title="微信账号" v-show="appSupportIfCodes.indexOf('wxpay') >= 0">
|
||||
<a slot="extra" href="#">
|
||||
<a-button style="background: green; color: white" icon="wechat" @click="addReceiverRow('wxpay')">添加【微信官方】分账接收账号</a-button>
|
||||
</a>
|
||||
<a-table :columns="accTableColumns" :data-source="receiverTableData.filter((item) => item.ifCode == 'wxpay')" :pagination="false" rowKey="rowKey">
|
||||
|
||||
<!-- 账号类型 -->
|
||||
<template slot="reqBindStateSlot" slot-scope="record">
|
||||
<div style="color: salmon " v-show="record.reqBindState == 0">
|
||||
<a-icon type="info-circle" /> 待绑定
|
||||
</div>
|
||||
<div style="color: green; " v-show="record.reqBindState == 1">
|
||||
<a-icon type="check-circle" /> 绑定成功
|
||||
</div>
|
||||
<div style="color: red; " v-show="record.reqBindState == 2">
|
||||
<a-icon type="close-circle" /> 绑定异常
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<!-- 账号别名 -->
|
||||
<template slot="receiverAliasSlot" slot-scope="record">
|
||||
<a-input v-model="record.receiverAlias" style="width: 150px" placeholder="(选填)默认为账号"/>
|
||||
</template>
|
||||
|
||||
<!-- 账号类型 -->
|
||||
<template slot="accTypeSlot" slot-scope="record">
|
||||
<a-select style="width: 110px" v-model="record.accType" placeholder="账号类型" default-value="0">
|
||||
<a-select-option value="0">个人</a-select-option>
|
||||
<a-select-option value="1">微信商户</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<!-- 接收方账号 -->
|
||||
<template slot="accNoSlot" slot-scope="record">
|
||||
<a-input v-model="record.accNo" style="width: 150px"/>
|
||||
<a-button type="link" v-if="record.accType == 0" @click="showChannelUserModal('wxpay', record)">扫码获取</a-button>
|
||||
</template>
|
||||
|
||||
<!-- 接收方姓名 -->
|
||||
<template slot="accNameSlot" slot-scope="record">
|
||||
<a-input v-model="record.accName"/>
|
||||
</template>
|
||||
|
||||
<!-- 分账关系 -->
|
||||
<template slot="relationTypeSlot" slot-scope="record">
|
||||
<a-select style="width: 110px" labelInValue placeholder="分账关系类型" :defaultValue="{key: 'PARTNER'}" @change="changeRelationType(record, $event)">
|
||||
<a-select-option key="PARTNER">合作伙伴</a-select-option>
|
||||
<a-select-option key="SERVICE_PROVIDER">服务商</a-select-option>
|
||||
<a-select-option key="STORE">门店</a-select-option>
|
||||
<a-select-option key="STAFF">员工</a-select-option>
|
||||
<a-select-option key="STORE_OWNER">店主</a-select-option>
|
||||
<a-select-option key="HEADQUARTER">总部</a-select-option>
|
||||
<a-select-option key="BRAND">品牌方</a-select-option>
|
||||
<a-select-option key="DISTRIBUTOR">分销商</a-select-option>
|
||||
<a-select-option key="USER">用户</a-select-option>
|
||||
<a-select-option key="SUPPLIER">供应商</a-select-option>
|
||||
<a-select-option key="CUSTOM">自定义</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<!-- 关系名称 -->
|
||||
<template slot="relationTypeNameSlot" slot-scope="record">
|
||||
<a-input :disabled="record.relationType !== 'CUSTOM'" v-model="record.relationTypeName"/>
|
||||
</template>
|
||||
|
||||
<!-- 默认分账比例 -->
|
||||
<template slot="divisionProfitSlot" slot-scope="record">
|
||||
<a-input v-model="record.divisionProfit" style="width: 65px"/> %
|
||||
</template>
|
||||
|
||||
<template slot="opSlot" slot-scope="record"><a-button type="link" @click="delRow(record)">删除</a-button></template>
|
||||
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<br />
|
||||
<a-card title="支付宝账号" v-show="appSupportIfCodes.indexOf('alipay') >= 0">
|
||||
<a slot="extra" href="#">
|
||||
<a-button style="background: dodgerblue; color: white" icon="alipay-circle" @click="addReceiverRow('alipay')" >添加【支付宝官方】分账接收账号</a-button>
|
||||
</a>
|
||||
<a-table :columns="accTableColumns" :data-source="receiverTableData.filter((item) => item.ifCode == 'alipay')" :pagination="false" rowKey="rowKey">
|
||||
|
||||
<!-- 账号类型 -->
|
||||
<template slot="reqBindStateSlot" slot-scope="record">
|
||||
<div style="color: salmon " v-show="record.reqBindState == 0">
|
||||
<a-icon type="info-circle" /> 待绑定
|
||||
</div>
|
||||
<div style="color: green; " v-show="record.reqBindState == 1">
|
||||
<a-icon type="check-circle" /> 绑定成功
|
||||
</div>
|
||||
<div style="color: red; " v-show="record.reqBindState == 2">
|
||||
<a-icon type="close-circle" /> 绑定异常
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<!-- 账号别名 -->
|
||||
<template slot="receiverAliasSlot" slot-scope="record">
|
||||
<a-input v-model="record.receiverAlias" style="width: 150px" placeholder="(选填)默认为账号"/>
|
||||
</template>
|
||||
|
||||
<!-- 账号类型 -->
|
||||
<template slot="accTypeSlot" slot-scope="record">
|
||||
<a-select style="width: 110px" v-model="record.accType" placeholder="账号类型" default-value="0">
|
||||
<a-select-option value="0">个人</a-select-option>
|
||||
<a-select-option value="1">商户</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<!-- 接收方账号 -->
|
||||
<template slot="accNoSlot" slot-scope="record">
|
||||
<a-input v-model="record.accNo" style="width: 150px"/>
|
||||
<a-button type="link" v-if="record.accType == 0" @click="showChannelUserModal('alipay', record)">扫码获取</a-button>
|
||||
</template>
|
||||
|
||||
<!-- 接收方姓名 -->
|
||||
<template slot="accNameSlot" slot-scope="record">
|
||||
<a-input v-model="record.accName"/>
|
||||
</template>
|
||||
|
||||
<!-- 分账关系 -->
|
||||
<template slot="relationTypeSlot" slot-scope="record">
|
||||
<a-select style="width: 110px" labelInValue placeholder="分账关系类型" :defaultValue="{key: 'PARTNER'}" @change="changeRelationType(record, $event)">
|
||||
<a-select-option key="PARTNER">合作伙伴</a-select-option>
|
||||
<a-select-option key="SERVICE_PROVIDER">服务商</a-select-option>
|
||||
<a-select-option key="STORE">门店</a-select-option>
|
||||
<a-select-option key="STAFF">员工</a-select-option>
|
||||
<a-select-option key="STORE_OWNER">店主</a-select-option>
|
||||
<a-select-option key="HEADQUARTER">总部</a-select-option>
|
||||
<a-select-option key="BRAND">品牌方</a-select-option>
|
||||
<a-select-option key="DISTRIBUTOR">分销商</a-select-option>
|
||||
<a-select-option key="USER">用户</a-select-option>
|
||||
<a-select-option key="SUPPLIER">供应商</a-select-option>
|
||||
<a-select-option key="CUSTOM">自定义</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
|
||||
<!-- 关系名称 -->
|
||||
<template slot="relationTypeNameSlot" slot-scope="record">
|
||||
<a-input :disabled="record.relationType !== 'CUSTOM'" v-model="record.relationTypeName"/>
|
||||
</template>
|
||||
|
||||
<!-- 默认分账比例 -->
|
||||
<template slot="divisionProfitSlot" slot-scope="record">
|
||||
<a-input v-model="record.divisionProfit" style="width: 65px"/> %
|
||||
</template>
|
||||
|
||||
<template slot="opSlot" slot-scope="record"><a-button type="link" @click="delRow(record)">删除</a-button></template>
|
||||
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<div class="drawer-btn-center ">
|
||||
<a-button type="primary" icon="rocket" :style="{ marginRight: '8px' }" @click="reqBatchBindReceiver(0)">发起绑定请求</a-button>
|
||||
<a-button icon="close" @click="onClose">关闭</a-button>
|
||||
</div>
|
||||
|
||||
<ChannelUserModal ref="channelUserModal" @changeChannelUserId="changeChannelUserIdFunc($event)"/>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { genRowKey } from '@/utils/util'
|
||||
import ChannelUserModal from '@/components/ChannelUser/ChannelUserModal'
|
||||
import { API_URL_DIVISION_RECEIVER, API_URL_DIVISION_RECEIVER_GROUP, req, getIfCodeByAppId } from '@/api/manage'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const accTableColumns = [
|
||||
{ key: 'reqBindState', title: '状态', scopedSlots: { customRender: 'reqBindStateSlot' } },
|
||||
{ key: 'receiverAlias', title: '账号别名', scopedSlots: { customRender: 'receiverAliasSlot' } },
|
||||
{ key: 'accType', title: '账号类型', scopedSlots: { customRender: 'accTypeSlot' } },
|
||||
{ key: 'accNo', width: '300px', title: '接收方账号', scopedSlots: { customRender: 'accNoSlot' } },
|
||||
{ key: 'accName', width: '180px', title: '接收方姓名', scopedSlots: { customRender: 'accNameSlot' } },
|
||||
{ key: 'relationType', title: '分账关系', scopedSlots: { customRender: 'relationTypeSlot' } },
|
||||
{ key: 'relationTypeName', width: '200px', title: '关系名称', scopedSlots: { customRender: 'relationTypeNameSlot' } },
|
||||
{ key: 'divisionProfit', title: '默认分账比例', scopedSlots: { customRender: 'divisionProfitSlot' } },
|
||||
{ key: 'op', title: '操作', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
const defaultReceiverTemplate = {
|
||||
reqBindState: 0, // 默认待绑定
|
||||
receiverAlias: '',
|
||||
receiverGroupId: '',
|
||||
appId: '',
|
||||
ifCode: '',
|
||||
accType: '0',
|
||||
accNo: '',
|
||||
accName: '',
|
||||
relationType: 'PARTNER', // 默认合作伙伴, 需要同时更改select的defaultValue
|
||||
relationTypeName: '合作伙伴',
|
||||
divisionProfit: ''
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { ChannelUserModal },
|
||||
props: {
|
||||
callbackFunc: {
|
||||
type: Function,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
visible: false, // 是否显示抽屉
|
||||
appInfo: null, // 应用app信息
|
||||
accTableColumns: accTableColumns, // 表头模板(微信支付宝公用)
|
||||
|
||||
allReceiverGroup: [], // 当前商户所有的接收账号的分组情况
|
||||
selectedReceiverGroupId: '', // 当前选择的分组ID
|
||||
appSupportIfCodes: [], // 应用支持的支付方式
|
||||
receiverTableData: [] // 微信支付的分账用户列表集合
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show (appInfo) {
|
||||
const that = this // 提前保留this
|
||||
|
||||
this.appSupportIfCodes = [] // 初始化
|
||||
this.receiverTableData = [] // 置空表格
|
||||
|
||||
// 请求接口,获取所有分组信息,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_DIVISION_RECEIVER_GROUP, { pageSize: -1 }).then(res => {
|
||||
that.allReceiverGroup = res.records
|
||||
if (that.allReceiverGroup && that.allReceiverGroup.length > 0) { // 默认选中第一个 & 更新列表
|
||||
that.selectedReceiverGroupId = that.allReceiverGroup[0].receiverGroupId
|
||||
}
|
||||
})
|
||||
|
||||
// 查询支持的分账接口
|
||||
getIfCodeByAppId(appInfo.appId).then((res) => {
|
||||
that.appSupportIfCodes = res
|
||||
})
|
||||
|
||||
this.appInfo = appInfo // 应用信息
|
||||
|
||||
this.visible = true // 显示弹层
|
||||
},
|
||||
// 抽屉关闭
|
||||
onClose () {
|
||||
this.callbackFunc() // 刷新列表
|
||||
this.visible = false
|
||||
},
|
||||
// 删除某一行
|
||||
delRow (item) {
|
||||
const index = this.receiverTableData.indexOf(item)
|
||||
if (index > -1) {
|
||||
this.receiverTableData.splice(index, 1)
|
||||
}
|
||||
},
|
||||
changeRelationType (record, value) {
|
||||
record.relationType = value.key
|
||||
if (value.key !== 'CUSTOM') {
|
||||
record.relationTypeName = value.label
|
||||
} else {
|
||||
record.relationTypeName = ''
|
||||
}
|
||||
},
|
||||
|
||||
// 显示获取用户ID的弹层
|
||||
showChannelUserModal (ifCode, record) {
|
||||
this.$refs.channelUserModal.showModal(this.appInfo.appId, ifCode, record)
|
||||
},
|
||||
|
||||
// 接收到当前渠道用户ID信息
|
||||
changeChannelUserIdFunc ({ channelUserId, extObject }) {
|
||||
console.log(channelUserId, extObject)
|
||||
extObject.accNo = channelUserId
|
||||
},
|
||||
|
||||
// 添加一行账号信息
|
||||
addReceiverRow (ifCode) {
|
||||
if (!this.selectedReceiverGroupId) {
|
||||
return this.$message.error('请选选择要加入的分组')
|
||||
}
|
||||
this.receiverTableData.push(Object.assign({}, defaultReceiverTemplate, { rowKey: genRowKey(), ifCode: ifCode, appId: this.appInfo.appId }))
|
||||
},
|
||||
|
||||
// 单条绑定 返回是否成功
|
||||
reqBatchBindReceiver (i) {
|
||||
const that = this
|
||||
|
||||
if (that.receiverTableData.length <= 0) {
|
||||
return that.$message.error('请先添加账号')
|
||||
}
|
||||
|
||||
// 完成了所有的绑定操作
|
||||
if (i >= that.receiverTableData.length) {
|
||||
return this.$message.success('已完成所有账号的绑定操作')
|
||||
}
|
||||
|
||||
// 当前的账号
|
||||
const currentReceiver = that.receiverTableData[i]
|
||||
currentReceiver.receiverGroupId = that.selectedReceiverGroupId // 设置分组ID
|
||||
|
||||
if (currentReceiver.reqBindState === 1) { // 已经绑定成功, 不在重复发起
|
||||
return that.reqBatchBindReceiver(++i) // 递归继续绑定
|
||||
}
|
||||
|
||||
if (!currentReceiver.accNo) {
|
||||
return this.$message.error(`第${i + 1 }条: 接收方账号不能为空`)
|
||||
}
|
||||
|
||||
if (currentReceiver.relationType === 'CUSTOM' && !currentReceiver.relationTypeName) {
|
||||
return this.$message.error(`第${i + 1 }条: 自定义类型时接收方账号名称不能为空`)
|
||||
}
|
||||
|
||||
if (!currentReceiver.divisionProfit || currentReceiver.divisionProfit <= 0 || currentReceiver.divisionProfit > 100) {
|
||||
return this.$message.error(`第${i + 1 }条: 默认分账比例请设置在[0.01% ~ 100% ] 之间`)
|
||||
}
|
||||
|
||||
req.add(API_URL_DIVISION_RECEIVER, currentReceiver).then(apiRes => {
|
||||
// 绑定成功
|
||||
if (apiRes.bindState === 1) {
|
||||
that.reqBatchBindReceiver(++i) // 递归继续绑定
|
||||
currentReceiver.reqBindState = 1 // 成功
|
||||
} else {
|
||||
currentReceiver.reqBindState = 2 // 异常
|
||||
that.$infoBox.modalError(`第${i + 1 }条: 绑定异常`, <div><div>错误码:{ apiRes.errCode}</div><div>错误信息:{ apiRes.errMsg}</div></div>)
|
||||
}
|
||||
}).catch(() => {
|
||||
currentReceiver.reqBindState = 2 // 异常
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<a-drawer :visible="isShow" title="修改分账用户信息" width="30%" :maskClosable="false" @close="isShow = false">
|
||||
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" :label-col="{span: 6}" :wrapper-col="{span: 15}" :rules="rules">
|
||||
|
||||
<a-form-model-item label="账号别名:" prop="receiverAlias">
|
||||
<a-input v-model="saveObject.receiverAlias" />
|
||||
</a-form-model-item>
|
||||
|
||||
<a-form-model-item label="默认分账比例:" prop="divisionProfit">
|
||||
<a-input v-model="saveObject.divisionProfit" style="width: 100px" /> %
|
||||
</a-form-model-item>
|
||||
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
<a-radio :value="1">正常分账</a-radio> <a-radio :value="0">暂停分账</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
|
||||
<a-form-model-item label="分组变更:" prop="receiverGroupId">
|
||||
<a-select style="width: 210px" placeholder="账号分组" v-model="saveObject.receiverGroupId">
|
||||
<a-select-option v-for="(item) in allReceiverGroup" :key="item.receiverGroupId" :value="item.receiverGroupId">{{ item.receiverGroupName }}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
|
||||
</a-form-model>
|
||||
|
||||
<div class="drawer-btn-center">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="isShow = false" icon="close">取消</a-button>
|
||||
<a-button type="primary" @click="handleOkFunc" :loading="confirmLoading" icon="check">保存</a-button>
|
||||
</div>
|
||||
|
||||
</a-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { API_URL_DIVISION_RECEIVER, API_URL_DIVISION_RECEIVER_GROUP, req } from '@/api/manage'
|
||||
export default {
|
||||
props: {
|
||||
callbackFunc: { type: Function }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
confirmLoading: false, // 显示确定按钮loading图标
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
saveObject: {}, // 数据对象
|
||||
recordId: null, // 更新对象ID
|
||||
allReceiverGroup: [], // 当前商户所有的接收账号的分组情况
|
||||
rules: {
|
||||
receiverAlias: [{ required: true, message: '请输入别名', trigger: 'blur' }],
|
||||
receiverGroupId: [{ required: true, message: '请选择分组', trigger: 'blur' }],
|
||||
divisionProfit: [{ required: true, message: '请录入默认分账比例', trigger: 'blur' }],
|
||||
state: [{ required: true, message: '请选择状态', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
show: function (recordId) { // 弹层打开事件
|
||||
this.saveObject = {} // 数据清空
|
||||
this.confirmLoading = false // 关闭loading
|
||||
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
|
||||
const that = this
|
||||
|
||||
that.recordId = recordId
|
||||
|
||||
// 查询账号信息
|
||||
req.getById(API_URL_DIVISION_RECEIVER, recordId).then(res => {
|
||||
res.divisionProfit = (res.divisionProfit * 100).toFixed(2)
|
||||
that.saveObject = res
|
||||
})
|
||||
|
||||
// 请求接口,获取所有分组信息,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_DIVISION_RECEIVER_GROUP, { pageSize: -1 }).then(res => { that.allReceiverGroup = res.records })
|
||||
|
||||
this.isShow = true
|
||||
},
|
||||
|
||||
handleOkFunc: function () { // 点击【确认】按钮事件
|
||||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
if (valid) { // 验证通过
|
||||
that.confirmLoading = true // 显示loading
|
||||
|
||||
var reqObject = {
|
||||
receiverAlias: that.saveObject.receiverAlias,
|
||||
receiverGroupId: that.saveObject.receiverGroupId,
|
||||
divisionProfit: that.saveObject.divisionProfit,
|
||||
state: that.saveObject.state
|
||||
}
|
||||
|
||||
req.updateById(API_URL_DIVISION_RECEIVER, that.recordId, reqObject).then(res => {
|
||||
that.$message.success('修改成功')
|
||||
that.isShow = false
|
||||
that.callbackFunc() // 刷新列表
|
||||
}).catch(res => { that.confirmLoading = false })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<!-- 详情抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
width="50%"
|
||||
:closable="true"
|
||||
:visible="visible"
|
||||
title="记录详情"
|
||||
@close="visible = false"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账记录ID">{{ detailData.recordId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="商户号">{{ detailData.mchNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="应用ID">{{ detailData.appId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付接口代码">{{ detailData.ifCode }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统支付订单号">{{ detailData.payOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="支付订单渠道支付订单号">{{ detailData.payOrderChannelOrderNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="订单金额">{{ detailData.payOrderAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账基数">{{ detailData.payOrderDivisionAmount / 100 }} (订单金额-手续费-退款金额)</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="系统分账批次号">{{ detailData.batchOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="上游分账批次号">{{ detailData.channelBatchOrderId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="状态">
|
||||
|
||||
<a-tag v-if="detailData.state === 0" :key="detailData.state" color="orange">分账中</a-tag>
|
||||
<a-tag v-if="detailData.state === 1" :key="detailData.state" color="blue">分账成功</a-tag>
|
||||
<a-tag v-if="detailData.state === 2" :key="detailData.state" color="volcano">分账失败</a-tag>
|
||||
<a-tag v-if="detailData.state === 3" :key="detailData.state" color="purple">已受理</a-tag>
|
||||
|
||||
</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收者ID">{{ detailData.receiverId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号组ID">{{ detailData.receiverGroupId }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="收款账号别名">{{ detailData.receiverAlias }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号类型">{{ detailData.accType == 0 ? '个人' : '商户' }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号">{{ detailData.accNo }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账接收账号名称">{{ detailData.accName }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型">{{ detailData.relationType }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账关系类型名称">{{ detailData.relationTypeName }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="实际分账比例">{{ (detailData.divisionProfit * 100).toFixed(2) }}%</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="分账金额">{{ detailData.calDivisionAmount / 100 }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="创建时间">{{ detailData.createdAt }}</a-descriptions-item></a-descriptions></a-col>
|
||||
<a-col :sm="12"><a-descriptions><a-descriptions-item label="更新时间">{{ detailData.updatedAt }}</a-descriptions-item></a-descriptions></a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-row justify="start" type="flex">
|
||||
<a-col :sm="24">
|
||||
<a-form-model-item label="上游返回数据包">
|
||||
<a-input type="textarea" disabled="disabled" style="height: 100px;color: black" v-model="detailData.channelRespResult"/>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script>
|
||||
import { API_URL_PAY_ORDER_DIVISION_RECORD_LIST, req } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
visible: false,
|
||||
detailData: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show: function (recordId) {
|
||||
const that = this
|
||||
req.getById(API_URL_PAY_ORDER_DIVISION_RECORD_LIST, recordId).then(res => {
|
||||
that.detailData = res
|
||||
})
|
||||
this.visible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<div class="table-page-search-wrapper">
|
||||
<a-form layout="inline" class="table-head-ground">
|
||||
<div class="table-layer">
|
||||
<a-form-item label="" class="table-head-layout" style="max-width:350px;min-width:300px">
|
||||
<a-range-picker
|
||||
@change="onChange"
|
||||
:show-time="{ format: 'HH:mm:ss' }"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
:disabled-date="disabledDate"
|
||||
>
|
||||
<a-icon slot="suffixIcon" type="sync" />
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
<jeepay-text-up placeholder="分账接受者ID" :msg="searchData.receiverId" v-model="searchData.receiverId" />
|
||||
<jeepay-text-up placeholder="分账账号组ID" :msg="searchData.receiverGroupId" v-model="searchData.receiverGroupId" />
|
||||
<jeepay-text-up placeholder="应用AppId" :msg="searchData.appId" v-model="searchData.appId"/>
|
||||
<jeepay-text-up placeholder="支付订单号" :msg="searchData.payOrderId" v-model="searchData.payOrderId"/>
|
||||
<jeepay-text-up placeholder="分账接收账号" :msg="searchData.accNo" v-model="searchData.accNo"/>
|
||||
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.state" placeholder="分账状态" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">待分账</a-select-option>
|
||||
<a-select-option value="1">分账成功</a-select-option>
|
||||
<a-select-option value="2">分账失败</a-select-option>
|
||||
<a-select-option value="3">已受理</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<span class="table-page-search-submitButtons">
|
||||
<a-button type="primary" icon="search" @click="queryFunc" :loading="btnLoading">搜索</a-button>
|
||||
<a-button style="margin-left: 8px" icon="reload" @click="() => this.searchData = {}">重置</a-button>
|
||||
</span>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
@btnLoadClose="btnLoading=false"
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="recordId"
|
||||
>
|
||||
<template slot="amountSlot" slot-scope="{record}"><b>¥{{ record.calDivisionAmount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
|
||||
<a-tag v-if="record.state === 0" :key="record.state" color="orange">分账中</a-tag>
|
||||
<a-tag v-if="record.state === 1" :key="record.state" color="blue">分账成功</a-tag>
|
||||
<a-tag v-if="record.state === 2" :key="record.state" color="volcano">分账失败</a-tag>
|
||||
<a-tag v-if="record.state === 3" :key="record.state" color="purple">已受理</a-tag>
|
||||
|
||||
</template>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" v-if="$access('ENT_DIVISION_RECORD_VIEW')" @click="detailFunc(record.recordId)">详情</a-button>
|
||||
<a-button type="link" v-if="record.state == 2 && $access('ENT_DIVISION_RECORD_RESEND')" @click="redivFunc(record.recordId)">重试</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<Detail ref="recordDetail" />
|
||||
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script>
|
||||
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' // 文字上移组件
|
||||
import JeepayTable from '@/components/JeepayTable/JeepayTable'
|
||||
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
||||
import { API_URL_PAY_ORDER_DIVISION_RECORD_LIST, req, resendDivision } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
import Detail from './Detail'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ key: 'calDivisionAmount', title: '分账金额', scopedSlots: { customRender: 'amountSlot' } },
|
||||
{ key: 'batchOrderId', title: '分账批次号', dataIndex: 'batchOrderId' },
|
||||
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
{ key: 'ifCode', title: '接口代码', dataIndex: 'ifCode' },
|
||||
{ key: 'payOrderAmount', dataIndex: 'payOrderAmount', title: '订单金额', customRender: (text) => (text / 100).toFixed(2) },
|
||||
{ key: 'payOrderDivisionAmount', dataIndex: 'payOrderDivisionAmount', title: '分账基数', customRender: (text) => (text / 100).toFixed(2) },
|
||||
{ key: 'receiverAlias', title: '账号别名', dataIndex: 'receiverAlias' },
|
||||
{ key: 'accNo', title: '接收账号', dataIndex: 'accNo' },
|
||||
{ key: 'accName', title: '账号姓名', dataIndex: 'accName' },
|
||||
{ key: 'relationTypeName', title: '分账关系类型', dataIndex: 'relationTypeName' },
|
||||
{ key: 'divisionProfit', dataIndex: 'divisionProfit', title: '分账比例', customRender: (text, record, index) => (text * 100).toFixed(2) + '%' },
|
||||
{ key: 'state', title: '分账状态', scopedSlots: { customRender: 'stateSlot' } },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
components: { JeepayTable, JeepayTableColumns, JeepayTextUp, Detail },
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {},
|
||||
createdStart: '', // 选择开始时间
|
||||
createdEnd: '' // 选择结束时间
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
methods: {
|
||||
queryFunc () {
|
||||
this.btnLoading = true
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
// 请求table接口数据
|
||||
reqTableDataFunc: (params) => {
|
||||
return req.list(API_URL_PAY_ORDER_DIVISION_RECORD_LIST, params)
|
||||
},
|
||||
searchFunc: function () { // 点击【查询】按钮点击事件
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
detailFunc: function (recordId) {
|
||||
this.$refs.recordDetail.show(recordId)
|
||||
},
|
||||
// 重新发起分账
|
||||
redivFunc: function (recordId) {
|
||||
const that = this
|
||||
this.$infoBox.confirmPrimary('确认重新分账?', '重新分账将按照订单维度重新发起(仅限分账失败订单)。', () => {
|
||||
resendDivision(recordId).then(res => {
|
||||
that.$refs.infoTable.refTable(false)
|
||||
that.$message.warning('请等待接口最新状态')
|
||||
})
|
||||
})
|
||||
},
|
||||
moment,
|
||||
onChange (date, dateString) {
|
||||
this.searchData.createdStart = dateString[0] // 开始时间
|
||||
this.searchData.createdEnd = dateString[1] // 结束时间
|
||||
},
|
||||
disabledDate (current) { // 今日之后日期不可选
|
||||
return current && current > moment().endOf('day')
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="私钥 AppSecret" prop="appSecret" >
|
||||
<a-input v-model="saveObject.appSecret" placeholder="请输入" type="textarea" />
|
||||
<a-input v-model="saveObject.appSecret" :placeholder="saveObject.appSecret_ph" type="textarea" />
|
||||
<a-button type="primary" ghost @click="randomKey(false, 128, 0)"><a-icon type="file-sync" />随机生成私钥</a-button>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
|
|
@ -68,8 +68,7 @@ export default {
|
|||
appId: '', // 应用AppId
|
||||
saveObject: {}, // 数据对象
|
||||
rules: {
|
||||
appName: [{ required: true, message: '请输入应用名称', trigger: 'blur' }],
|
||||
appSecret: [{ required: true, message: '请输入私钥或点击随机生成私钥' }]
|
||||
appName: [{ required: true, message: '请输入应用名称', trigger: 'blur' }]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -80,7 +79,8 @@ export default {
|
|||
// 数据清空
|
||||
this.saveObject = {
|
||||
'state': 1,
|
||||
'appSecret': ''
|
||||
'appSecret': '',
|
||||
'appSecret_ph': '请输入'
|
||||
}
|
||||
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
|
|
@ -88,17 +88,24 @@ export default {
|
|||
}
|
||||
|
||||
const that = this
|
||||
that.rules.appSecret = []
|
||||
if (!this.isAdd) { // 修改信息 延迟展示弹层
|
||||
that.appId = appId
|
||||
// 拉取详情
|
||||
req.getById(API_URL_MCH_APP, appId).then(res => {
|
||||
that.saveObject = res
|
||||
if (!that.saveObject.appSecret) { // 解决商户私钥为空无法写入的问题
|
||||
that.saveObject.appSecret = ''
|
||||
}
|
||||
that.saveObject.appSecret_ph = res.appSecret
|
||||
that.saveObject.appSecret = ''
|
||||
})
|
||||
this.visible = true
|
||||
} else {
|
||||
// 新增时,appSecret必填
|
||||
that.rules.appSecret.push({
|
||||
required: true,
|
||||
message: '请输入私钥或点击随机生成私钥',
|
||||
trigger: 'blur'
|
||||
})
|
||||
|
||||
that.visible = true // 展示弹层信息
|
||||
}
|
||||
},
|
||||
|
|
@ -107,6 +114,7 @@ export default {
|
|||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
if (valid) { // 验证通过
|
||||
delete that.saveObject.appSecret_ph
|
||||
// 请求接口
|
||||
if (that.isAdd) {
|
||||
req.add(API_URL_MCH_APP, that.saveObject).then(res => {
|
||||
|
|
@ -115,6 +123,9 @@ export default {
|
|||
that.callbackFunc() // 刷新列表
|
||||
})
|
||||
} else {
|
||||
if (that.saveObject.appSecret === '') {
|
||||
delete that.saveObject.appSecret
|
||||
}
|
||||
req.updateById(API_URL_MCH_APP, that.appId, that.saveObject).then(res => {
|
||||
that.$message.success('修改成功')
|
||||
that.visible = false
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<a-modal v-model="isShow" title="支付宝子商户扫码授权" @ok="handleOkFunc" @cancel="handleOkFunc">
|
||||
|
||||
<div style="text-align: center">
|
||||
<p>方式1: <br/> 使用商家账号登录【支付宝】APP, 扫描如下二维码, 按提示授权: </p>
|
||||
<img style="margin-bottom: 10px" :src="apiResData.authQrImgUrl">
|
||||
<hr/>
|
||||
|
||||
<p style="margin-top: 10px">
|
||||
方式2: <br/> <a-button size="small" class="copy-btn" v-clipboard:copy="apiResData.authUrl" v-clipboard:success="onCopySuccess" >点击复制</a-button>
|
||||
或点击以下链接,按照页面提示自主授权:
|
||||
</p>
|
||||
<a target="_blank" :href="apiResData.authUrl">{{ apiResData.authUrl }}</a>
|
||||
</div>
|
||||
</a-modal>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { queryAlipayIsvsubMchAuthUrl } from '@/api/manage'
|
||||
export default {
|
||||
|
||||
props: {
|
||||
callbackFunc: { type: Function }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
appId: '',
|
||||
apiResData: {}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
show: function (appId) { // 弹层打开事件
|
||||
this.apiResData = {}
|
||||
this.appId = appId
|
||||
const that = this
|
||||
queryAlipayIsvsubMchAuthUrl(appId).then(res => {
|
||||
that.apiResData = res
|
||||
this.isShow = true
|
||||
})
|
||||
},
|
||||
|
||||
handleOkFunc: function () { // 点击【确认】按钮事件
|
||||
this.isShow = false
|
||||
if (this.callbackFunc) {
|
||||
this.callbackFunc()
|
||||
}
|
||||
},
|
||||
|
||||
onCopySuccess () {
|
||||
this.$message.success('复制成功')
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -33,8 +33,7 @@
|
|||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
:scrollX="1200"
|
||||
rowKey="mchName"
|
||||
rowKey="appId"
|
||||
>
|
||||
<template slot="appIdSlot" slot-scope="{record}">
|
||||
<b>{{ record.appId }}</b>
|
||||
|
|
@ -51,6 +50,11 @@
|
|||
支付测试
|
||||
</router-link>
|
||||
</a-button>
|
||||
<a-button type="link" v-if="$access('ENT_MCH_TRANSFER')">
|
||||
<router-link :to="{name:'ENT_MCH_TRANSFER', params:{appId:record.appId}}">
|
||||
发起转账
|
||||
</router-link>
|
||||
</a-button>
|
||||
<a-button type="link" v-if="$access('ENT_MCH_APP_DEL')" style="color: red" @click="delFunc(record.appId)">删除</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -10,11 +10,6 @@
|
|||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="支付接口费率" prop="ifRate">
|
||||
<a-input v-model="saveObject.ifRate" placeholder="请输入" suffix="%" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
|
|
@ -43,7 +38,8 @@
|
|||
<a-row :gutter="16">
|
||||
<a-col v-for="(item, key) in mchParams" :key="key" :span="item.type === 'text' ? 12 : 24">
|
||||
<a-form-model-item :label="item.desc" :prop="item.name" v-if="item.type === 'text' || item.type === 'textarea'">
|
||||
<a-input v-model="ifParams[item.name]" placeholder="请输入" :type="item.type" />
|
||||
<a-input v-if="item.star === '1'" v-model="ifParams[item.name]" :placeholder="ifParams[item.name + '_ph']" :type="item.type" />
|
||||
<a-input v-else v-model="ifParams[item.name]" placeholder="请输入" :type="item.type" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item :label="item.desc" :prop="item.name" v-else-if="item.type === 'radio'">
|
||||
<a-radio-group v-model="ifParams[item.name]">
|
||||
|
|
@ -101,12 +97,17 @@ export default {
|
|||
ifParams: {}, // 参数配置对象
|
||||
rules: {
|
||||
infoId: [{ required: true, trigger: 'blur' }],
|
||||
ifCode: [{ required: true, trigger: 'blur' }],
|
||||
ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
ifCode: [{ required: true, trigger: 'blur' }]
|
||||
// ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
ifParams: function (o, n) {
|
||||
this.$set(this.ifParams, 'appSecret', this.ifParams.appSecret) // 解决appSecret 双向绑定数据不显示的问题
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (appId, record) {
|
||||
|
|
@ -133,35 +134,45 @@ export default {
|
|||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
}
|
||||
})
|
||||
|
||||
const newItems = [] // 重新加载支付接口配置定义描述json
|
||||
let radioItems = [] // 存放单选框value title
|
||||
const mchParams = record.mchParams // 根据商户类型获取接口定义描述
|
||||
JSON.parse(mchParams).forEach(item => {
|
||||
radioItems = []
|
||||
if (item.type === 'radio') {
|
||||
const valueItems = item.values.split(',')
|
||||
const titleItems = item.titles.split(',')
|
||||
for (const i in valueItems) {
|
||||
radioItems.push({
|
||||
value: valueItems[i],
|
||||
title: titleItems[i]
|
||||
})
|
||||
const newItems = [] // 重新加载支付接口配置定义描述json
|
||||
let radioItems = [] // 存放单选框value title
|
||||
const mchParams = record.mchParams // 根据商户类型获取接口定义描述
|
||||
JSON.parse(mchParams).forEach(item => {
|
||||
radioItems = []
|
||||
if (item.type === 'radio') {
|
||||
const valueItems = item.values.split(',')
|
||||
const titleItems = item.titles.split(',')
|
||||
for (const i in valueItems) {
|
||||
// 检查参数是否为数字类型 然后赋值给radio值
|
||||
let radioVal = valueItems[i]
|
||||
if (!isNaN((radioVal))) { radioVal = Number(radioVal) }
|
||||
radioItems.push({
|
||||
value: radioVal,
|
||||
title: titleItems[i]
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
newItems.push({
|
||||
name: item.name,
|
||||
desc: item.desc,
|
||||
type: item.type,
|
||||
verify: item.verify,
|
||||
values: radioItems
|
||||
})
|
||||
})
|
||||
|
||||
that.mchParams = newItems // 重新赋值接口定义描述
|
||||
that.visible = true // 打开支付参数配置抽屉
|
||||
that.generoterRules()
|
||||
if (item.star === '1') {
|
||||
that.ifParams[item.name + '_ph'] = that.ifParams[item.name] ? that.ifParams[item.name] : '请输入'
|
||||
that.ifParams[item.name] = ''
|
||||
}
|
||||
|
||||
newItems.push({
|
||||
name: item.name,
|
||||
desc: item.desc,
|
||||
type: item.type,
|
||||
verify: item.verify,
|
||||
values: radioItems,
|
||||
star: item.star // 脱敏标识 1-是
|
||||
})
|
||||
})
|
||||
|
||||
that.mchParams = newItems // 重新赋值接口定义描述
|
||||
that.visible = true // 打开支付参数配置抽屉
|
||||
that.generoterRules()
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
|
|
@ -173,7 +184,7 @@ export default {
|
|||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
reqParams.ifRate = that.saveObject.ifRate
|
||||
// reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
|
|
@ -181,6 +192,13 @@ export default {
|
|||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.mchParams.forEach(item => {
|
||||
if (item.star === '1' && that.ifParams[item.name] === '') {
|
||||
that.ifParams[item.name] = undefined
|
||||
}
|
||||
that.ifParams[item.name + '_ph'] = undefined
|
||||
})
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
|
|
@ -208,7 +226,7 @@ export default {
|
|||
let newItems = []
|
||||
this.mchParams.forEach(item => {
|
||||
newItems = []
|
||||
if (item.verify === 'required') {
|
||||
if (item.verify === 'required' && item.star !== '1') {
|
||||
newItems.push({
|
||||
required: true,
|
||||
message: '请输入' + item.desc,
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
</div>
|
||||
<!-- 卡片底部操作栏 -->
|
||||
<div class="jeepay-card-ops">
|
||||
<a v-if="record.mchType == 2 && record.ifCode == 'alipay' && $access('ENT_MCH_PAY_CONFIG_ADD')" @click="toAlipayAuthPageFunc(record)">扫码授权 <a-icon key="right" type="right" style="fontSize: 13px"></a-icon></a>
|
||||
|
||||
<a v-if="$access('ENT_MCH_PAY_CONFIG_ADD')" @click="editPayIfConfigFunc(record)">填写参数 <a-icon key="right" type="right" style="fontSize: 13px"></a-icon></a>
|
||||
<a v-else>暂无操作</a>
|
||||
</div>
|
||||
|
|
@ -73,6 +75,7 @@
|
|||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData2"
|
||||
rowKey="wayCode"
|
||||
>
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<a-badge :status="record.passageState === 0?'error':'processing'" :text="record.passageState === 0?'禁用':'启用'" />
|
||||
|
|
@ -91,10 +94,16 @@
|
|||
<a-button type="primary" icon="arrow-right" v-if="$access('ENT_MCH_PAY_PASSAGE_LIST') && currentStep ===0" @click="stepChange(1)">下一步</a-button>
|
||||
</div>
|
||||
|
||||
<!-- 支付参数配置页面组件 -->
|
||||
<!-- 支付参数配置JSON渲染页面组件 -->
|
||||
<MchPayConfigAddOrEdit ref="mchPayConfigAddOrEdit" :callbackFunc="refCardList" />
|
||||
<!-- 支付参数配置自定义页面组件 wxpay -->
|
||||
<WxpayPayConfig ref="wxpayPayConfig" :callbackFunc="refCardList" />
|
||||
<!-- 支付参数配置自定义页面组件 alipay -->
|
||||
<AlipayPayConfig ref="alipayPayConfig" :callbackFunc="refCardList" />
|
||||
<!-- 支付通道配置页面组件 -->
|
||||
<MchPayPassageAddOrEdit ref="mchPayPassageAddOrEdit" :callbackFunc="searchFunc"/>
|
||||
<!-- 支付宝授权弹层 -->
|
||||
<AlipayAuth ref="alipayAuthPage" :callbackFunc="refCardList"/>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
|
|
@ -105,6 +114,9 @@ import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
|||
import { API_URL_MCH_PAYCONFIGS_LIST, API_URL_MCH_PAYPASSAGE_LIST, req, getAvailablePayInterfaceList } from '@/api/manage'
|
||||
import MchPayConfigAddOrEdit from './MchPayConfigAddOrEdit'
|
||||
import MchPayPassageAddOrEdit from './MchPayPassageAddOrEdit'
|
||||
import WxpayPayConfig from './custom/WxpayPayConfig'
|
||||
import AlipayPayConfig from './custom/AlipayPayConfig'
|
||||
import AlipayAuth from './AlipayAuth'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
|
|
@ -120,7 +132,10 @@ export default {
|
|||
JeepayTable,
|
||||
JeepayTableColumns,
|
||||
MchPayConfigAddOrEdit,
|
||||
MchPayPassageAddOrEdit
|
||||
MchPayPassageAddOrEdit,
|
||||
WxpayPayConfig,
|
||||
AlipayPayConfig,
|
||||
AlipayAuth
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
|
|
@ -155,7 +170,9 @@ export default {
|
|||
},
|
||||
// 刷新支付接口card列表
|
||||
refCardList () {
|
||||
this.$refs.infoCard.refCardList()
|
||||
if (this.$refs.infoCard) {
|
||||
this.$refs.infoCard.refCardList()
|
||||
}
|
||||
},
|
||||
// 请求支付通道数据
|
||||
reqTableDataFunc (params) {
|
||||
|
|
@ -175,9 +192,11 @@ export default {
|
|||
title: '提示',
|
||||
content: '服务商未配置,请联系服务商配置支付参数!'
|
||||
})
|
||||
return
|
||||
} else if (record.configPageType === 1) {
|
||||
this.$refs.mchPayConfigAddOrEdit.show(this.appId, record)
|
||||
} else if (record.configPageType === 2) {
|
||||
this.$refs[record.ifCode + 'PayConfig'].show(this.appId, record)
|
||||
}
|
||||
this.$refs.mchPayConfigAddOrEdit.show(this.appId, record)
|
||||
},
|
||||
// 支付通道配置
|
||||
editPayPassageFunc (record) {
|
||||
|
|
@ -196,6 +215,21 @@ export default {
|
|||
// 抽屉关闭
|
||||
onClose () {
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
// 支付宝子商户 扫码授权
|
||||
toAlipayAuthPageFunc (record) {
|
||||
if (!record) {
|
||||
return
|
||||
}
|
||||
if (record.subMchIsvConfig === 0) {
|
||||
this.$error({
|
||||
title: '提示',
|
||||
content: '当前应用所属商户为特约商户,请先配置服务商支付参数!'
|
||||
})
|
||||
return
|
||||
}
|
||||
this.$refs.alipayAuthPage.show(this.appId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,328 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
title="填写参数"
|
||||
width="40%"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:visible="visible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
<a-radio :value="1">
|
||||
启用
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
停用
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="备注" prop="remark">
|
||||
<a-input v-model="saveObject.remark" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
{{ saveObject.ifCode }} 商户参数配置
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
<a-form-model ref="mchParamFormModel" :model="ifParams" layout="vertical" :rules="ifParamsRules">
|
||||
<a-row :gutter="16" v-if="mchType === 1">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="环境配置" prop="sandbox">
|
||||
<a-radio-group v-model="ifParams.sandbox">
|
||||
<a-radio :value="1">沙箱环境</a-radio>
|
||||
<a-radio :value="0">生产环境</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppID" prop="appId">
|
||||
<a-input v-model="ifParams.appId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="应用私钥" prop="privateKey">
|
||||
<a-input v-model="ifParams.privateKey" :placeholder="ifParams.privateKey_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝公钥" prop="alipayPublicKey">
|
||||
<a-input v-model="ifParams.alipayPublicKey" :placeholder="ifParams.alipayPublicKey_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="接口签名方式(推荐使用RSA2)" prop="signType">
|
||||
<a-radio-group v-model="ifParams.signType" defaultValue="RSA">
|
||||
<a-radio value="RSA">RSA</a-radio>
|
||||
<a-radio value="RSA2">RSA2</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="公钥证书" prop="useCert">
|
||||
<a-radio-group v-model="ifParams.useCert" defaultValue="1">
|
||||
<a-radio :value="1">使用证书(请使用RSA2私钥)</a-radio>
|
||||
<a-radio :value="0">不使用证书</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="应用公钥证书(.crt格式)" prop="appPublicCert">
|
||||
<a-input v-model="ifParams.appPublicCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.appPublicCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'appPublicCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝公钥证书(.crt格式)" prop="alipayPublicCert">
|
||||
<a-input v-model="ifParams.alipayPublicCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.alipayPublicCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'alipayPublicCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="支付宝根证书(.crt格式)" prop="alipayRootCert">
|
||||
<a-input v-model="ifParams.alipayRootCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.alipayRootCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'alipayRootCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" v-else-if="mchType === 2">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="子商户app_auth_token" prop="appAuthToken">
|
||||
<a-input v-model="ifParams.appAuthToken" placeholder="请输入子商户app_auth_token" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<div class="drawer-btn-center" v-if="$access('ENT_MCH_PAY_CONFIG_ADD')">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose" icon="close">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit" icon="check" :loading="btnLoading">保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JeepayCard from '@/components/JeepayCard/JeepayCard'
|
||||
import JeepayUpload from '@/components/JeepayUpload/JeepayUpload'
|
||||
import { API_URL_MCH_PAYCONFIGS_LIST, req, getMchPayConfigUnique, upload } from '@/api/manage'
|
||||
export default {
|
||||
components: {
|
||||
JeepayCard,
|
||||
JeepayUpload
|
||||
},
|
||||
props: {
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
visible: false, // 抽屉开关
|
||||
isAdd: true,
|
||||
mchType: 1,
|
||||
action: upload.cert, // 上传文件地址
|
||||
saveObject: {}, // 保存的对象
|
||||
ifParams: {}, // 参数配置对象
|
||||
rules: {
|
||||
// ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {
|
||||
appId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入应用AppID'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
privateKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.isAdd && !value) {
|
||||
callback(new Error('请输入应用私钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayPublicKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.isAdd && this.ifParams.useCert === 0 && !value) {
|
||||
callback(new Error('请输入支付宝公钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appPublicCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.ifParams.useCert === 1 && !this.ifParams.appPublicCert) {
|
||||
callback(new Error('请上传应用公钥证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayPublicCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.ifParams.useCert === 1 && !this.ifParams.alipayPublicCert) {
|
||||
callback(new Error('请上传支付宝公钥证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
alipayRootCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && this.ifParams.useCert === 1 && !this.ifParams.alipayRootCert) {
|
||||
callback(new Error('请上传支付宝根证书(.crt格式)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appAuthToken: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 2 && !value) {
|
||||
callback(new Error('请输入子商户app_auth_token'))
|
||||
}
|
||||
callback()
|
||||
} }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (appId, record) {
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.mchParamFormModel !== undefined) {
|
||||
this.$refs.mchParamFormModel.resetFields()
|
||||
}
|
||||
|
||||
this.mchType = record.mchType
|
||||
|
||||
// 数据初始化
|
||||
this.saveObject = {
|
||||
infoId: appId,
|
||||
ifCode: record.ifCode,
|
||||
state: record.ifConfigState === 0 ? 0 : 1
|
||||
}
|
||||
|
||||
// 参数配置对象,数据初始化
|
||||
this.ifParams = {
|
||||
sandbox: 0,
|
||||
signType: 'RSA2',
|
||||
useCert: 0,
|
||||
privateKey: '',
|
||||
privateKey_ph: '请输入',
|
||||
alipayPublicKey: '',
|
||||
alipayPublicKey_ph: '请输入',
|
||||
appPublicCert: '',
|
||||
alipayPublicCert: '',
|
||||
alipayRootCert: ''
|
||||
}
|
||||
this.visible = true
|
||||
this.getMchPayConfig()
|
||||
},
|
||||
// 支付参数配置
|
||||
getMchPayConfig () {
|
||||
const that = this
|
||||
// 获取支付参数
|
||||
getMchPayConfigUnique(that.saveObject.infoId, that.saveObject.ifCode).then(res => {
|
||||
if (res && res.ifParams) {
|
||||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
|
||||
that.ifParams.privateKey_ph = that.ifParams.privateKey
|
||||
that.ifParams.privateKey = ''
|
||||
|
||||
that.ifParams.alipayPublicKey_ph = that.ifParams.alipayPublicKey
|
||||
that.ifParams.alipayPublicKey = ''
|
||||
|
||||
that.isAdd = false
|
||||
} else if (res === undefined) {
|
||||
that.isAdd = true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
const that = this
|
||||
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
this.$refs.mchParamFormModel.validate(valid2 => {
|
||||
if (valid && valid2) { // 验证通过
|
||||
that.btnLoading = true
|
||||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
// reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
if (Object.keys(that.ifParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.clearEmptyKey('privateKey')
|
||||
that.clearEmptyKey('alipayPublicKey')
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
req.add(API_URL_MCH_PAYCONFIGS_LIST, reqParams).then(res => {
|
||||
that.$message.success('保存成功')
|
||||
that.visible = false
|
||||
that.btnLoading = false
|
||||
that.callbackFunc()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 脱敏数据为空时,删除对应key
|
||||
clearEmptyKey (key) {
|
||||
if (!this.ifParams[key]) {
|
||||
this.ifParams[key] = undefined
|
||||
}
|
||||
this.ifParams[key + '_ph'] = undefined
|
||||
},
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
uploadSuccess (value, name) {
|
||||
this.ifParams[name] = value
|
||||
this.$forceUpdate()
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,364 @@
|
|||
<template>
|
||||
<a-drawer
|
||||
title="填写参数"
|
||||
width="40%"
|
||||
:closable="true"
|
||||
:maskClosable="false"
|
||||
:visible="visible"
|
||||
:body-style="{ paddingBottom: '80px' }"
|
||||
@close="onClose"
|
||||
>
|
||||
<a-form-model ref="infoFormModel" :model="saveObject" layout="vertical" :rules="rules">
|
||||
<a-row :gutter="16">
|
||||
<a-col :span="12">
|
||||
<a-form-model-item label="状态" prop="state">
|
||||
<a-radio-group v-model="saveObject.state">
|
||||
<a-radio :value="1">
|
||||
启用
|
||||
</a-radio>
|
||||
<a-radio :value="0">
|
||||
停用
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col :span="24">
|
||||
<a-form-model-item label="备注" prop="remark">
|
||||
<a-input v-model="saveObject.remark" placeholder="请输入" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<a-divider orientation="left">
|
||||
<a-tag color="#FF4B33">
|
||||
{{ saveObject.ifCode }} 商户参数配置
|
||||
</a-tag>
|
||||
</a-divider>
|
||||
<a-form-model ref="mchParamFormModel" :model="ifParams" layout="vertical" :rules="ifParamsRules">
|
||||
<a-row :gutter="16" v-if="mchType === 1">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="微信支付商户号" prop="mchId">
|
||||
<a-input v-model="ifParams.mchId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppID" prop="appId">
|
||||
<a-input v-model="ifParams.appId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="应用AppSecret" prop="appSecret">
|
||||
<a-input v-model="ifParams.appSecret" :placeholder="ifParams.appSecret_ph" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="oauth2地址(置空将使用官方)" prop="oauth2Url">
|
||||
<a-input v-model="ifParams.oauth2Url" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="微信支付API版本" prop="apiVersion">
|
||||
<a-radio-group v-model="ifParams.apiVersion" defaultValue="V2">
|
||||
<a-radio value="V2">V2</a-radio>
|
||||
<a-radio value="V3">V3</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="APIv2密钥" prop="key">
|
||||
<a-input v-model="ifParams.key" :placeholder="ifParams.key_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="APIv3秘钥" prop="apiV3Key">
|
||||
<a-input v-model="ifParams.apiV3Key" :placeholder="ifParams.apiV3Key_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="序列号" prop="serialNo">
|
||||
<a-input v-model="ifParams.serialNo" :placeholder="ifParams.serialNo_ph" type="textarea" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="API证书(apiclient_cert.p12)" prop="cert">
|
||||
<a-input v-model="ifParams.cert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.cert"
|
||||
@uploadSuccess="uploadSuccess($event, 'cert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="证书文件(apiclient_cert.pem)" prop="apiClientCert">
|
||||
<a-input v-model="ifParams.apiClientCert" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.apiClientCert"
|
||||
@uploadSuccess="uploadSuccess($event, 'apiClientCert')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="24">
|
||||
<a-form-model-item label="私钥文件(apiclient_key.pem)" prop="apiClientKey">
|
||||
<a-input v-model="ifParams.apiClientKey" disabled="disabled" />
|
||||
<JeepayUpload
|
||||
:action="action"
|
||||
:fileUrl="ifParams.apiClientKey"
|
||||
@uploadSuccess="uploadSuccess($event, 'apiClientKey')"
|
||||
>
|
||||
<template slot="uploadSlot" slot-scope="{loading}">
|
||||
<a-button style="marginTop:5px;"> <a-icon :type="loading ? 'loading' : 'upload'" /> {{ loading ? '正在上传' : '点击上传' }} </a-button>
|
||||
</template>
|
||||
</JeepayUpload>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-row :gutter="16" v-else-if="mchType === 2">
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="子商户ID" prop="subMchId">
|
||||
<a-input v-model="ifParams.subMchId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-col span="12">
|
||||
<a-form-model-item label="子账户appID(线上支付必填)" prop="subMchAppId">
|
||||
<a-input v-model="ifParams.subMchAppId" placeholder="请输入" />
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form-model>
|
||||
<div class="drawer-btn-center" v-if="$access('ENT_MCH_PAY_CONFIG_ADD')">
|
||||
<a-button :style="{ marginRight: '8px' }" @click="onClose" icon="close">取消</a-button>
|
||||
<a-button type="primary" @click="onSubmit" icon="check" :loading="btnLoading">保存</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import JeepayCard from '@/components/JeepayCard/JeepayCard'
|
||||
import JeepayUpload from '@/components/JeepayUpload/JeepayUpload'
|
||||
import { API_URL_MCH_PAYCONFIGS_LIST, req, getMchPayConfigUnique, upload } from '@/api/manage'
|
||||
export default {
|
||||
components: {
|
||||
JeepayCard,
|
||||
JeepayUpload
|
||||
},
|
||||
props: {
|
||||
callbackFunc: { type: Function, default: () => ({}) }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
visible: false, // 抽屉开关
|
||||
isAdd: true,
|
||||
mchType: 1,
|
||||
action: upload.cert, // 上传文件地址
|
||||
saveObject: {}, // 保存的对象
|
||||
ifParams: { apiVersion: 'V2' }, // 参数配置对象
|
||||
rules: {
|
||||
// ifRate: [{ required: false, pattern: /^(([1-9]{1}\d{0,1})|(0{1}))(\.\d{1,4})?$/, message: '请输入0-100之间的数字,最多四位小数', trigger: 'blur' }]
|
||||
},
|
||||
ifParamsRules: {
|
||||
mchId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入微信支付商户号'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入应用AppID'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
appSecret: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入应用AppSecret'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
key: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V2' && this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入API密钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiV3Key: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入API V3秘钥'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
serialNo: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && this.mchType === 1 && !value) {
|
||||
callback(new Error('请输入序列号'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
cert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请上传API证书(apiclient_cert.p12)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiClientCert: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.isAdd && !value) {
|
||||
callback(new Error('请上传证书文件(apiclient_cert.pem)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
apiClientKey: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.ifParams.apiVersion === 'V3' && this.mchType === 1 && !this.ifParams.apiClientKey) {
|
||||
callback(new Error('请上传私钥文件(apiclient_key.pem)'))
|
||||
}
|
||||
callback()
|
||||
} }],
|
||||
subMchId: [{ trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (this.mchType === 2 && !value) {
|
||||
callback(new Error('请输入子商户ID'))
|
||||
}
|
||||
callback()
|
||||
} }]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 弹层打开事件
|
||||
show: function (appId, record) {
|
||||
if (this.$refs.infoFormModel !== undefined) {
|
||||
this.$refs.infoFormModel.resetFields()
|
||||
}
|
||||
if (this.$refs.mchParamFormModel !== undefined) {
|
||||
this.$refs.mchParamFormModel.resetFields()
|
||||
}
|
||||
|
||||
this.mchType = record.mchType
|
||||
|
||||
// 数据初始化
|
||||
this.saveObject = {
|
||||
infoId: appId,
|
||||
ifCode: record.ifCode,
|
||||
state: record.ifConfigState === 0 ? 0 : 1
|
||||
}
|
||||
|
||||
// 参数配置对象,数据初始化
|
||||
this.ifParams = {
|
||||
apiVersion: 'V2',
|
||||
appSecret: '',
|
||||
appSecret_ph: '请输入',
|
||||
key: '',
|
||||
key_ph: '请输入',
|
||||
apiV3Key: '',
|
||||
apiV3Key_ph: '请输入',
|
||||
serialNo: '',
|
||||
serialNo_ph: '请输入'
|
||||
}
|
||||
this.visible = true
|
||||
this.getMchPayConfig()
|
||||
},
|
||||
// 支付参数配置
|
||||
getMchPayConfig () {
|
||||
const that = this
|
||||
// 获取支付参数
|
||||
getMchPayConfigUnique(that.saveObject.infoId, that.saveObject.ifCode).then(res => {
|
||||
if (res && res.ifParams) {
|
||||
that.saveObject = res
|
||||
that.ifParams = JSON.parse(res.ifParams)
|
||||
|
||||
that.ifParams.appSecret_ph = that.ifParams.appSecret
|
||||
that.ifParams.appSecret = ''
|
||||
|
||||
that.ifParams.key_ph = that.ifParams.key
|
||||
that.ifParams.key = ''
|
||||
|
||||
that.ifParams.apiV3Key_ph = that.ifParams.apiV3Key
|
||||
that.ifParams.apiV3Key = ''
|
||||
|
||||
that.ifParams.serialNo_ph = that.ifParams.serialNo
|
||||
that.ifParams.serialNo = ''
|
||||
|
||||
that.isAdd = false
|
||||
} else if (res === undefined) {
|
||||
that.isAdd = true
|
||||
}
|
||||
})
|
||||
},
|
||||
// 表单提交
|
||||
onSubmit () {
|
||||
const that = this
|
||||
this.$refs.infoFormModel.validate(valid => {
|
||||
this.$refs.mchParamFormModel.validate(valid2 => {
|
||||
if (valid && valid2) { // 验证通过
|
||||
that.btnLoading = true
|
||||
const reqParams = {}
|
||||
reqParams.infoId = that.saveObject.infoId
|
||||
reqParams.ifCode = that.saveObject.ifCode
|
||||
// reqParams.ifRate = that.saveObject.ifRate
|
||||
reqParams.state = that.saveObject.state
|
||||
reqParams.remark = that.saveObject.remark
|
||||
// 支付参数配置不能为空
|
||||
if (Object.keys(that.ifParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
// 脱敏数据为空时,删除该key
|
||||
that.clearEmptyKey('appSecret')
|
||||
that.clearEmptyKey('key')
|
||||
that.clearEmptyKey('apiV3Key')
|
||||
that.clearEmptyKey('serialNo')
|
||||
reqParams.ifParams = JSON.stringify(that.ifParams)
|
||||
// 请求接口
|
||||
if (Object.keys(reqParams).length === 0) {
|
||||
this.$message.error('参数不能为空!')
|
||||
return
|
||||
}
|
||||
req.add(API_URL_MCH_PAYCONFIGS_LIST, reqParams).then(res => {
|
||||
that.$message.success('保存成功')
|
||||
that.visible = false
|
||||
that.btnLoading = false
|
||||
that.callbackFunc()
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
// 脱敏数据为空时,删除对应key
|
||||
clearEmptyKey (key) {
|
||||
if (!this.ifParams[key]) {
|
||||
this.ifParams[key] = undefined
|
||||
}
|
||||
this.ifParams[key + '_ph'] = undefined
|
||||
},
|
||||
// 上传文件成功回调方法,参数value为文件地址,name是自定义参数
|
||||
uploadSuccess (value, name) {
|
||||
this.ifParams[name] = value
|
||||
this.$forceUpdate()
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
</style>
|
||||
|
|
@ -14,9 +14,18 @@
|
|||
<a-icon slot="suffixIcon" type="sync" />
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
<jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />
|
||||
<jeepay-text-up :placeholder="'商户订单号'" :msg="searchData.mchOrderNo" v-model="searchData.mchOrderNo" />
|
||||
<jeepay-text-up :placeholder="'支付/商户/渠道订单号'" :msg="searchData.unionOrderId" v-model="searchData.unionOrderId" />
|
||||
<!-- <jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'商户订单号'" :msg="searchData.mchOrderNo" v-model="searchData.mchOrderNo" />-->
|
||||
<jeepay-text-up :placeholder="'应用AppId'" :msg="searchData.appId" v-model="searchData.appId"/>
|
||||
<a-form-item v-if="$access('ENT_PAY_ORDER_SEARCH_PAY_WAY')" label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.wayCode" placeholder="支付方式" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option :key="item.wayCode" v-for="item in payWayList" :value="item.wayCode">
|
||||
{{ item.wayName }}
|
||||
</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.state" placeholder="支付状态" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
|
|
@ -31,11 +40,12 @@
|
|||
</a-form-item>
|
||||
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.wayCode" placeholder="支付方式" default-value="">
|
||||
<a-select v-model="searchData.divisionState" placeholder="分账状态" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option :key="item.wayCode" v-for="item in payWayList" :value="item.wayCode">
|
||||
{{ item.wayName }}
|
||||
</a-select-option>
|
||||
<a-select-option value="0">未发生分账</a-select-option>
|
||||
<a-select-option value="1">等待分账任务处理</a-select-option>
|
||||
<a-select-option value="2">分账处理中</a-select-option>
|
||||
<a-select-option value="3">分账任务已结束(状态请看分账记录)</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
|
|
@ -56,24 +66,63 @@
|
|||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="payOrderId"
|
||||
:scrollX="1000"
|
||||
:tableRowCrossColor="true"
|
||||
>
|
||||
<template slot="amountSlot" slot-scope="{record}"><b>¥{{ record.amount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="refundAmountSlot" slot-scope="{record}">¥{{ record.refundAmount/100 }}</template> <!-- 自定义插槽 -->
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':record.state === 6?'':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'支付中':record.state === 2?'支付成功':record.state === 3?'支付失败':record.state === 4?'已撤销':record.state === 5?'已退款':record.state === 6?'订单关闭':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template slot="divisionStateSlot" slot-scope="{record}">
|
||||
<span v-if="record.divisionState == 0">-</span>
|
||||
<a-tag color="orange" v-else-if="record.divisionState == 1">待分账</a-tag>
|
||||
<a-tag color="red" v-else-if="record.divisionState == 2">分账处理中</a-tag>
|
||||
<a-tag color="green" v-else-if="record.divisionState == 3">任务已结束</a-tag>
|
||||
<span v-else>未知</span>
|
||||
</template>
|
||||
|
||||
<template slot="orderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">支付</span>{{ record.payOrderId }}</p>
|
||||
<p style="margin-bottom: 0">
|
||||
<span style="color:#56cf56;background:#d8eadf">商户</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.mchOrderNo.length > record.payOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.mchOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.mchOrderNo, record.payOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.mchOrderNo }}</span>
|
||||
</p>
|
||||
<p v-if="record.channelOrderNo" style="margin-bottom: 0;margin-top: 10px">
|
||||
<span style="color:#fff;background:#E09C4D">渠道</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.channelOrderNo.length > record.payOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.channelOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.channelOrderNo, record.payOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.channelOrderNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" v-if="$access('ENT_PAY_ORDER_VIEW')" @click="detailFunc(record.payOrderId)">详情</a-button>
|
||||
<a-button type="link" v-if="$access('ENT_PAY_ORDER_REFUND')" style="color: red" v-show="(record.state === 2 && record.refundState !== 2)" @click="openFunc(record, record.payOrderId)">退款</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
<!-- 退款弹出框 -->
|
||||
<refund-modal ref="refundModalInfo" :callbackFunc="searchFunc"></refund-modal>
|
||||
<!-- 日志详情抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
|
|
@ -132,7 +181,7 @@
|
|||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':'volcano'">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':detailData.state === 6?'':'volcano'">
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'支付中':detailData.state === 2?'支付成功':detailData.state === 3?'支付失败':detailData.state === 4?'已撤销':detailData.state === 5?'已退款':detailData.state === 6?'订单关闭':'未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
|
|
@ -147,6 +196,12 @@
|
|||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="手续费"><a-tag color="pink">{{ detailData.mchFeeAmount/100 }}</a-tag></a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="商家费率">{{ (detailData.mchFeeRate*100).toFixed(2) }}%</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付错误码">
|
||||
|
|
@ -276,6 +331,28 @@
|
|||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="订单分账模式">
|
||||
<span v-if="detailData.divisionMode == 0">该笔订单不允许分账</span>
|
||||
<span v-else-if="detailData.divisionMode == 1">支付成功按配置自动完成分账</span>
|
||||
<span v-else-if="detailData.divisionMode == 2">商户手动分账(解冻商户金额)</span>
|
||||
<span v-else>未知</span>
|
||||
</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="分账状态">
|
||||
<a-tag color="blue" v-if="detailData.divisionState == 0">未发生分账</a-tag>
|
||||
<a-tag color="orange" v-else-if="detailData.divisionState == 1">待分账</a-tag>
|
||||
<a-tag color="red" v-else-if="detailData.divisionState == 2">分账处理中</a-tag>
|
||||
<a-tag color="green" v-else-if="detailData.divisionState == 3">任务已结束</a-tag>
|
||||
<a-tag color="#f50" v-else>未知</a-tag>
|
||||
</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions><a-descriptions-item label="最新分账发起时间">{{ detailData.divisionLastTime }}</a-descriptions-item></a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-row justify="start" type="flex">
|
||||
|
|
@ -298,23 +375,28 @@
|
|||
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' // 文字上移组件
|
||||
import JeepayTable from '@/components/JeepayTable/JeepayTable'
|
||||
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
||||
import RefundModal from './RefundModal' // 退款弹出框
|
||||
import { API_URL_PAY_ORDER_LIST, API_URL_PAYWAYS_LIST, req } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ key: 'amount', title: '支付金额', scopedSlots: { customRender: 'amountSlot' } },
|
||||
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
{ key: 'mchOrderNo', title: '商户订单号', dataIndex: 'mchOrderNo' },
|
||||
{ key: 'refundAmount', title: '退款金额', scopedSlots: { customRender: 'refundAmountSlot' } },
|
||||
{ key: 'mchFeeAmount', dataIndex: 'mchFeeAmount', title: '手续费', customRender: (text) => '¥' + (text / 100).toFixed(2) },
|
||||
{ key: 'orderNo', title: '订单号', scopedSlots: { customRender: 'orderSlot' }, width: '260px' },
|
||||
// { key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
// { key: 'mchOrderNo', title: '商户订单号', dataIndex: 'mchOrderNo' },
|
||||
{ key: 'wayName', title: '支付方式', dataIndex: 'wayName', width: 150 },
|
||||
{ key: 'state', title: '支付状态', scopedSlots: { customRender: 'stateSlot' } },
|
||||
{ key: 'divisionState', title: '分账状态', scopedSlots: { customRender: 'divisionStateSlot' }, align: 'center' },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
{ key: 'op', title: '操作', width: '120px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'IsvListPage',
|
||||
components: { JeepayTable, JeepayTableColumns, JeepayTextUp },
|
||||
components: { JeepayTable, JeepayTableColumns, JeepayTextUp, RefundModal },
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
|
|
@ -330,7 +412,9 @@ export default {
|
|||
computed: {
|
||||
},
|
||||
mounted () {
|
||||
this.initPayWay()
|
||||
if (this.$access('ENT_PAY_ORDER_SEARCH_PAY_WAY')) {
|
||||
this.initPayWay()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
queryFunc () {
|
||||
|
|
@ -342,7 +426,14 @@ export default {
|
|||
return req.list(API_URL_PAY_ORDER_LIST, params)
|
||||
},
|
||||
searchFunc: function () { // 点击【查询】按钮点击事件
|
||||
this.$refs.infoTable.refTable(true)
|
||||
this.$refs.infoTable.refTable(false)
|
||||
},
|
||||
// 打开退款弹出框
|
||||
openFunc (record, recordId) {
|
||||
if (record.refundState === 2) {
|
||||
return this.$infoBox.modalError('订单无可退款金额', '')
|
||||
}
|
||||
this.$refs.refundModalInfo.show(recordId)
|
||||
},
|
||||
detailFunc: function (recordId) {
|
||||
const that = this
|
||||
|
|
@ -367,7 +458,42 @@ export default {
|
|||
req.list(API_URL_PAYWAYS_LIST, { 'pageSize': -1 }).then(res => { // 支付方式下拉列表
|
||||
that.payWayList = res.records
|
||||
})
|
||||
},
|
||||
changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = parseInt(baseLength / 2)
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
|
||||
///deep/ .ant-table-fixed{
|
||||
// tr{
|
||||
// th{
|
||||
// padding: 0px 0px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-modal
|
||||
title="退款"
|
||||
:visible="visible"
|
||||
:confirm-loading="confirmLoading"
|
||||
@ok="handleOk"
|
||||
@cancel="handleCancel"
|
||||
:closable="false"
|
||||
>
|
||||
<a-row>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付订单号">
|
||||
<a-tag color="purple">
|
||||
{{ detailData.payOrderId }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="支付金额">
|
||||
<a-tag color="green">
|
||||
{{ detailData.amount/100 }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="可退金额">
|
||||
<a-tag color="pink">
|
||||
{{ nowRefundAmount }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
|
||||
<a-form-model :rules="rules" :model="refund" ref="refundInfo" >
|
||||
|
||||
<a-form-model-item label="退款金额" prop="refundAmount">
|
||||
<a-input-number v-model="refund.refundAmount" :precision="2" style="width:100%"/>
|
||||
</a-form-model-item>
|
||||
|
||||
<a-form-model-item label="退款原因" prop="refundReason">
|
||||
<a-input v-model="refund.refundReason" type="textarea" />
|
||||
</a-form-model-item>
|
||||
|
||||
</a-form-model>
|
||||
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { API_URL_PAY_ORDER_LIST, req, payOrderRefund } from '@/api/manage'
|
||||
export default {
|
||||
|
||||
props: {
|
||||
callbackFunc: { type: Function, default: () => () => ({}) }
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
recordId: '',
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 16 },
|
||||
visible: false,
|
||||
confirmLoading: false,
|
||||
detailData: {
|
||||
},
|
||||
refund: {
|
||||
// refundReason: '', // 退款原因
|
||||
// refundAmount: '' // 退款金额
|
||||
},
|
||||
rules: {
|
||||
refundReason: [{ min: 0, max: 256, required: true, trigger: 'blur', message: '请输入退款原因,最长不超过256个字符' }],
|
||||
refundAmount: [{ required: true, message: '请输入金额', trigger: 'blur' },
|
||||
{
|
||||
validator: (rule, value, callBack) => {
|
||||
if (value < 0.01 || value > this.nowRefundAmount) {
|
||||
callBack('退款金额不能小于0.01,或者大于可退金额')
|
||||
}
|
||||
callBack()
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
nowRefundAmount () {
|
||||
return (this.detailData.amount - this.detailData.refundAmount) / 100
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show (recordId) {
|
||||
if (this.$refs.refundInfo !== undefined) {
|
||||
this.$refs.refundInfo.resetFields()
|
||||
}
|
||||
this.recordId = recordId
|
||||
this.visible = true
|
||||
this.refund = {}
|
||||
const that = this
|
||||
req.getById(API_URL_PAY_ORDER_LIST, recordId).then(res => {
|
||||
that.detailData = res
|
||||
})
|
||||
},
|
||||
handleOk (e) {
|
||||
this.$refs.refundInfo.validate(valid => {
|
||||
if (valid) {
|
||||
this.confirmLoading = true
|
||||
const that = this
|
||||
// 退款接口
|
||||
payOrderRefund(that.recordId, that.refund.refundAmount, that.refund.refundReason).then(res => {
|
||||
that.visible = false // 关闭弹窗
|
||||
that.confirmLoading = false // 取消按钮转圈
|
||||
|
||||
if (res.state === 0 || res.state === 3) { // 订单生成 || 失败
|
||||
const refundErrorModal = that.$infoBox.modalError('退款失败', (h) => that.buildModalText(res, h, () => { refundErrorModal.destroy() }))
|
||||
} else if (res.state === 1) { // 退款中
|
||||
const refundErrorModal = that.$infoBox.modalWarning('退款中', (h) => that.buildModalText(res, h, () => { refundErrorModal.destroy() }))
|
||||
that.callbackFunc()
|
||||
} else if (res.state === 2) { // 退款成功
|
||||
that.$message.success('退款成功')
|
||||
that.callbackFunc()
|
||||
} else {
|
||||
const refundErrorModal = that.$infoBox.modalWarning('退款状态未知', (h) => that.buildModalText(res, h, () => { refundErrorModal.destroy() }))
|
||||
}
|
||||
}).catch(() => {
|
||||
that.confirmLoading = false // 取消按钮转圈
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleCancel (e) {
|
||||
this.visible = false
|
||||
},
|
||||
|
||||
buildModalText (res, h, callbackFunc) {
|
||||
// 跳转退款列表Btn
|
||||
const toRefundPageBtn = h('a', { on: { click: () => {
|
||||
callbackFunc()
|
||||
this.$router.push({ name: 'ENT_REFUND_ORDER' })
|
||||
} } })
|
||||
toRefundPageBtn.text = '退款列表'
|
||||
return h('div', [
|
||||
h('div', res.errCode ? `错误码:${res.errCode}` : ''),
|
||||
h('div', res.errMsg ? `错误信息:${res.errMsg}` : ''),
|
||||
h('div', [h('span', '请到'), toRefundPageBtn, h('span', '中查看详细信息')])
|
||||
])
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
|
|
@ -14,10 +14,11 @@
|
|||
<a-icon slot="suffixIcon" type="sync" />
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
<jeepay-text-up :placeholder="'退款订单号'" :msg="searchData.refundOrderId" v-model="searchData.refundOrderId" />
|
||||
<jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />
|
||||
<jeepay-text-up :placeholder="'渠道支付订单号'" :msg="searchData.channelPayOrderNo" v-model="searchData.channelPayOrderNo" />
|
||||
<jeepay-text-up :placeholder="'服务商号'" :msg="searchData.isvNo" v-model="searchData.isvNo" />
|
||||
<jeepay-text-up :placeholder="'支付/退款列订单号'" :msg="searchData.unionOrderId" v-model="searchData.unionOrderId" />
|
||||
<!-- <jeepay-text-up :placeholder="'退款订单号'" :msg="searchData.refundOrderId" v-model="searchData.refundOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'商户退款单号'" :msg="searchData.mchRefundNo" v-model="searchData.mchRefundNo" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'支付订单号'" :msg="searchData.payOrderId" v-model="searchData.payOrderId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'渠道订单号'" :msg="searchData.channelPayOrderNo" v-model="searchData.channelPayOrderNo" />-->
|
||||
<jeepay-text-up :placeholder="'应用AppId'" :msg="searchData.appId" v-model="searchData.appId"/>
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.state" placeholder="退款状态" default-value="">
|
||||
|
|
@ -28,13 +29,6 @@
|
|||
<a-select-option value="3">退款失败</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.mchType" placeholder="商户类型" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="1">普通商户</a-select-option>
|
||||
<a-select-option value="2">特约商户</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
|
||||
<span class="table-page-search-submitButtons">
|
||||
<a-button type="primary" icon="search" @click="queryFunc" :loading="btnLoading">搜索</a-button>
|
||||
|
|
@ -50,10 +44,11 @@
|
|||
ref="infoTable"
|
||||
:initData="true"
|
||||
:closable="true"
|
||||
:searchData="searchData"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
rowKey="refundOrderId"
|
||||
:scrollX="1300"
|
||||
:tableRowCrossColor="true"
|
||||
>
|
||||
<template slot="payAmountSlot" slot-scope="{record}"><b>¥{{ record.payAmount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="refundAmountSlot" slot-scope="{record}"><b>¥{{ record.refundAmount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
|
|
@ -62,10 +57,42 @@
|
|||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'退款中':record.state === 2?'退款成功':record.state === 3?'退款失败':'未知' }}
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'退款中':record.state === 2?'退款成功':record.state === 3?'退款失败':record.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template slot="payOrderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">支付</span>{{ record.payOrderId }}</p>
|
||||
<p v-if="record.channelPayOrderNo" style="margin-bottom: 0;">
|
||||
<span style="color:#fff;background:#E09C4D">渠道</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.channelPayOrderNo.length > record.payOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.channelPayOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.channelPayOrderNo, record.payOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.channelPayOrderNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template slot="refundOrderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">退款</span>{{ record.refundOrderId }}</p>
|
||||
<p style="margin-bottom: 0;">
|
||||
<span style="color:#56cf56;background:#d8eadf">商户</span>
|
||||
<a-tooltip placement="bottom" style="font-weight: normal;" v-if="record.mchRefundNo.length > record.refundOrderId.length">
|
||||
<template slot="title">
|
||||
<span>{{ record.mchRefundNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.mchRefundNo, record.refundOrderId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.mchRefundNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" v-if="$access('ENT_REFUND_ORDER_VIEW')" @click="detailFunc(record.refundOrderId)">详情</a-button>
|
||||
|
|
@ -164,7 +191,7 @@
|
|||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':'volcano'">
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'退款中':detailData.state === 2?'退款成功':detailData.state === 3?'退款失败':'未知' }}
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'退款中':detailData.state === 2?'退款成功':detailData.state === 3?'退款失败':detailData.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
|
|
@ -295,10 +322,12 @@
|
|||
const tableColumns = [
|
||||
{ key: 'payAmount', title: '支付金额', scopedSlots: { customRender: 'payAmountSlot' } },
|
||||
{ key: 'refundAmount', title: '退款金额', scopedSlots: { customRender: 'refundAmountSlot' } },
|
||||
{ key: 'refundOrderId', title: '退款订单号', dataIndex: 'refundOrderId' },
|
||||
{ key: 'channelPayOrderNo', title: '渠道订单号', dataIndex: 'channelPayOrderNo' },
|
||||
{ key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
{ key: 'mchRefundNo', title: '商户退款单号', dataIndex: 'mchRefundNo' },
|
||||
{ key: 'pay', title: '退款订单号', scopedSlots: { customRender: 'refundOrderSlot' }, width: '260px' },
|
||||
{ key: 'refund', title: '支付订单号', scopedSlots: { customRender: 'payOrderSlot' }, width: '260px' },
|
||||
// { key: 'refundOrderId', title: '退款订单号', dataIndex: 'refundOrderId' },
|
||||
// { key: 'mchRefundNo', title: '商户退款单号', dataIndex: 'mchRefundNo' },
|
||||
// { key: 'payOrderId', title: '支付订单号', dataIndex: 'payOrderId' },
|
||||
// { key: 'channelPayOrderNo', title: '渠道订单号', dataIndex: 'channelPayOrderNo' },
|
||||
{ key: 'state', title: '支付状态', scopedSlots: { customRender: 'stateSlot' } },
|
||||
{ key: 'createdAt', dataIndex: 'createdAt', title: '创建日期' },
|
||||
{ key: 'op', title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
|
|
@ -351,7 +380,33 @@
|
|||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
},
|
||||
changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = parseInt(baseLength / 2)
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,172 @@
|
|||
<!-- 订单详情抽屉 -->
|
||||
<template>
|
||||
<a-drawer
|
||||
width="50%"
|
||||
placement="right"
|
||||
:closable="true"
|
||||
:visible="isShow"
|
||||
title="转账订单详情"
|
||||
@close="isShow = false"
|
||||
>
|
||||
<a-row justify="space-between" type="flex">
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="应用APPID">{{ detailData.appId }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账订单号">
|
||||
<a-tag color="purple">{{ detailData.transferId }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="商户转账单号">{{ detailData.mchOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">{{ detailData.channelOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="金额">
|
||||
<a-tag color="green">{{ detailData.amount/100 }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="货币代码">{{ detailData.currency }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款账号">
|
||||
<a-tag color="green">{{ detailData.accountNo }}</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="收款人姓名">{{ detailData.accountName }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账备注">{{ detailData.transferDesc }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="订单状态">
|
||||
<a-tag :color="detailData.state === 0?'blue':detailData.state === 1?'orange':detailData.state === 2?'green':'volcano'">
|
||||
{{ detailData.state === 0?'订单生成':detailData.state === 1?'转账中':detailData.state === 2?'转账成功':detailData.state === 3?'转账失败':detailData.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="转账成功时间">{{ detailData.successTime }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="创建时间">{{ detailData.createdAt }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="更新时间">{{ detailData.updatedAt }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="接口代码">{{ detailData.ifCode }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="入账类型">{{ detailData.entryType }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="客户端IP">{{ detailData.clientIp }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="异步通知地址">{{ detailData.notifyUrl }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
</a-row>
|
||||
<a-divider />
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道订单号">{{ detailData.channelOrderNo }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道错误码">{{ detailData.errCode }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="12">
|
||||
<a-descriptions>
|
||||
<a-descriptions-item label="渠道错误描述">{{ detailData.errMsg }}</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</a-col>
|
||||
<a-col :sm="24">
|
||||
<a-form-model-item label="渠道额外参数">
|
||||
<a-input
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black"
|
||||
v-model="detailData.channelExtra"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
<a-divider />
|
||||
<a-col :sm="24">
|
||||
<a-form-model-item label="扩展参数">
|
||||
<a-input
|
||||
type="textarea"
|
||||
disabled="disabled"
|
||||
style="height: 100px;color: black"
|
||||
v-model="detailData.extParam"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
</a-col>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script>
|
||||
import { API_URL_TRANSFER_ORDER_LIST, req } from '@/api/manage'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
detailData: {},
|
||||
isShow: false, // 是否显示弹层/抽屉
|
||||
recordId: null // 更新对象ID
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show: function (recordId) {
|
||||
const that = this
|
||||
req.getById(API_URL_TRANSFER_ORDER_LIST, recordId).then(res => {
|
||||
that.detailData = res
|
||||
})
|
||||
this.isShow = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
<template>
|
||||
<page-header-wrapper>
|
||||
<a-card>
|
||||
<div class="table-page-search-wrapper">
|
||||
<a-form layout="inline" class="table-head-ground">
|
||||
<div class="table-layer">
|
||||
<a-form-item label="" class="table-head-layout" style="max-width:350px;min-width:300px">
|
||||
<a-range-picker
|
||||
@change="onChange"
|
||||
:show-time="{ format: 'HH:mm:ss' }"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
:disabled-date="disabledDate"
|
||||
>
|
||||
<a-icon slot="suffixIcon" type="sync" />
|
||||
</a-range-picker>
|
||||
</a-form-item>
|
||||
<jeepay-text-up :placeholder="'转账/商户/渠道订单号'" :msg="searchData.unionOrderId" v-model="searchData.unionOrderId" />
|
||||
<!-- <jeepay-text-up :placeholder="'转账订单号'" :msg="searchData.transferId" v-model="searchData.transferId" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'商户订单号'" :msg="searchData.mchOrderNo" v-model="searchData.mchOrderNo" />-->
|
||||
<!-- <jeepay-text-up :placeholder="'渠道支付订单号'" :msg="searchData.channelOrderNo" v-model="searchData.channelOrderNo" />-->
|
||||
<jeepay-text-up :placeholder="'应用AppId'" :msg="searchData.appId" v-model="searchData.appId"/>
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="searchData.state" placeholder="转账状态" default-value="">
|
||||
<a-select-option value="">全部</a-select-option>
|
||||
<a-select-option value="0">订单生成</a-select-option>
|
||||
<a-select-option value="1">转账中</a-select-option>
|
||||
<a-select-option value="2">转账成功</a-select-option>
|
||||
<a-select-option value="3">转账失败</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<span class="table-page-search-submitButtons">
|
||||
<a-button type="primary" icon="search" @click="queryFunc" :loading="btnLoading">搜索</a-button>
|
||||
<a-button style="margin-left: 8px" icon="reload" @click="() => this.searchData = {}">重置</a-button>
|
||||
</span>
|
||||
</div>
|
||||
</a-form>
|
||||
</div>
|
||||
|
||||
<!-- 列表渲染 -->
|
||||
<JeepayTable
|
||||
@btnLoadClose="btnLoading=false"
|
||||
ref="infoTable"
|
||||
:initData="true"
|
||||
:reqTableDataFunc="reqTableDataFunc"
|
||||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="transferId"
|
||||
:tableRowCrossColor="true"
|
||||
>
|
||||
<template slot="transferAmountSlot" slot-scope="{record}"><b>¥{{ record.amount/100 }}</b></template> <!-- 自定义插槽 -->
|
||||
<template slot="stateSlot" slot-scope="{record}">
|
||||
<a-tag
|
||||
:key="record.state"
|
||||
:color="record.state === 0?'blue':record.state === 1?'orange':record.state === 2?'green':'volcano'"
|
||||
>
|
||||
{{ record.state === 0?'订单生成':record.state === 1?'转账中':record.state === 2?'转账成功':record.state === 3?'转账失败':record.state === 4?'任务关闭':'未知' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
<template slot="orderSlot" slot-scope="{record}">
|
||||
<div class="order-list">
|
||||
<p><span style="color:#729ED5;background:#e7f5f7">转账</span>{{ record.transferId }}</p>
|
||||
<p style="margin-bottom: 0">
|
||||
<span style="color:#56cf56;background:#d8eadf">商户</span>
|
||||
<a-tooltip v-if="record.mchOrderNo.length > record.transferId.length" placement="bottom" style="font-weight: normal;">
|
||||
<template slot="title">
|
||||
<span>{{ record.mchOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.mchOrderNo, record.transferId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.mchOrderNo }}</span>
|
||||
</p>
|
||||
<p v-if="record.channelOrderNo" style="margin-bottom: 0;margin-top: 10px">
|
||||
<span style="color:#fff;background:#E09C4D">渠道</span>
|
||||
<a-tooltip v-if="record.channelOrderNo.length > record.transferId.length" placement="bottom" style="font-weight: normal;">
|
||||
<template slot="title">
|
||||
<span>{{ record.channelOrderNo }}</span>
|
||||
</template>
|
||||
{{ changeStr2ellipsis(record.channelOrderNo, record.transferId.length) }}
|
||||
</a-tooltip>
|
||||
<span style="font-weight: normal;" v-else>{{ record.channelOrderNo }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
<template slot="opSlot" slot-scope="{record}"> <!-- 操作列插槽 -->
|
||||
<JeepayTableColumns>
|
||||
<a-button type="link" v-if="$access('ENT_TRANSFER_ORDER_VIEW')" @click="detailFunc(record.transferId)">详情</a-button>
|
||||
</JeepayTableColumns>
|
||||
</template>
|
||||
</JeepayTable>
|
||||
</a-card>
|
||||
|
||||
<!-- 订单详情 页面组件 -->
|
||||
<TransferOrderDetail ref="transferOrderDetail" />
|
||||
|
||||
</page-header-wrapper>
|
||||
</template>
|
||||
<script>
|
||||
import JeepayTable from '@/components/JeepayTable/JeepayTable'
|
||||
import JeepayTextUp from '@/components/JeepayTextUp/JeepayTextUp' // 文字上移组件
|
||||
import JeepayTableColumns from '@/components/JeepayTable/JeepayTableColumns'
|
||||
import TransferOrderDetail from './TransferOrderDetail'
|
||||
import { API_URL_TRANSFER_ORDER_LIST, req } from '@/api/manage'
|
||||
import moment from 'moment'
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const tableColumns = [
|
||||
{ title: '转账金额', scopedSlots: { customRender: 'transferAmountSlot' } },
|
||||
{ key: 'orderNo', title: '订单号', scopedSlots: { customRender: 'orderSlot' }, width: 260 },
|
||||
// { title: '转账订单号', dataIndex: 'transferId' },
|
||||
// { title: '商户转账单号', dataIndex: 'mchOrderNo' },
|
||||
// { title: '渠道订单号', dataIndex: 'channelOrderNo' },
|
||||
{ title: '收款账号', dataIndex: 'accountNo', width: 200 },
|
||||
{ title: '收款人姓名', dataIndex: 'accountName' },
|
||||
{ title: '转账备注', dataIndex: 'transferDesc' },
|
||||
{ title: '状态', scopedSlots: { customRender: 'stateSlot' }, width: 100 },
|
||||
{ title: '创建日期', dataIndex: 'createdAt' },
|
||||
{ title: '操作', width: '100px', fixed: 'right', align: 'center', scopedSlots: { customRender: 'opSlot' } }
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'IsvListPage',
|
||||
components: { JeepayTable, JeepayTableColumns, JeepayTextUp, TransferOrderDetail },
|
||||
data () {
|
||||
return {
|
||||
btnLoading: false,
|
||||
tableColumns: tableColumns,
|
||||
searchData: {},
|
||||
createdStart: '', // 选择开始时间
|
||||
createdEnd: '' // 选择结束时间
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
queryFunc () {
|
||||
this.btnLoading = true
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
// 请求table接口数据
|
||||
reqTableDataFunc: (params) => {
|
||||
return req.list(API_URL_TRANSFER_ORDER_LIST, params)
|
||||
},
|
||||
searchFunc: function () { // 点击【查询】按钮点击事件
|
||||
this.$refs.infoTable.refTable(true)
|
||||
},
|
||||
detailFunc: function (recordId) {
|
||||
this.$refs.transferOrderDetail.show(recordId)
|
||||
},
|
||||
moment,
|
||||
onChange (date, dateString) {
|
||||
this.searchData.createdStart = dateString[0] // 开始时间
|
||||
this.searchData.createdEnd = dateString[1] // 结束时间
|
||||
},
|
||||
disabledDate (current) { // 今日之后日期不可选
|
||||
return current && current > moment().endOf('day')
|
||||
},
|
||||
changeStr2ellipsis (orderNo, baseLength) {
|
||||
const halfLengh = parseInt(baseLength / 2)
|
||||
return orderNo.substring(0, halfLengh - 1) + '...' + orderNo.substring(orderNo.length - halfLengh, orderNo.length)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less" scoped>
|
||||
.order-list {
|
||||
-webkit-text-size-adjust:none;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
p {
|
||||
white-space:nowrap;
|
||||
span {
|
||||
display: inline-block;
|
||||
font-weight: 800;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
width: 35px;
|
||||
border-radius: 5px;
|
||||
text-align: center;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -69,14 +69,18 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="paydemo-type-name article-title" v-show="showJhTitle()">聚合支付</div>
|
||||
<div class="paydemo-type-name article-title" v-show="showQtTitle()">其它支付</div>
|
||||
<div class="paydemo-type-body">
|
||||
<div class="paydemo-type color-change" v-show="appPaywayList.indexOf('WX_JSAPI') >= 0 || appPaywayList.indexOf('ALI_JSAPI') >= 0" @click="changeCurrentWayCode('QR_CASHIER', 'codeImgUrl')" :class="{this:(currentWayCode === 'QR_CASHIER')}">
|
||||
<img src="@/assets/payTestImg/qr_cashier.svg" class="paydemo-type-img"><span class="color-change">聚合扫码(用户扫商家)</span>
|
||||
<img src="@/assets/payTestImg/qr_cashier.svg" class="paydemo-type-img"><span class="color-change">聚合主扫</span>
|
||||
</div>
|
||||
|
||||
<div class="paydemo-type color-change" v-show="appPaywayList.indexOf('WX_BAR') >= 0 || appPaywayList.indexOf('ALI_BAR') >= 0" @click="changeCurrentWayCode('AUTO_BAR', 'codeImgUrl')" :class="{this:(currentWayCode === 'AUTO_BAR')}">
|
||||
<img src="@/assets/payTestImg/auto_bar.svg" class="paydemo-type-img"><span class="color-change">聚合条码(商家扫用户)</span>
|
||||
<img src="@/assets/payTestImg/auto_bar.svg" class="paydemo-type-img"><span class="color-change">聚合被扫</span>
|
||||
</div>
|
||||
|
||||
<div class="paydemo-type color-change" v-show="appPaywayList.indexOf('PP_PC') >= 0" @click="changeCurrentWayCode('PP_PC', 'payurl')" :class="{this:(currentWayCode === 'PP_PC')}">
|
||||
<img src="@/assets/payTestImg/pp_pc.svg" class="paydemo-type-img"><span class="color-change">PayPal支付</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
|
@ -92,9 +96,23 @@
|
|||
<span @click="randomOrderNo" class=" paydemo-btn" style="padding:0 3px">刷新订单号</span>
|
||||
</div>
|
||||
<div class="paydemo-form-item">
|
||||
<label>商品名称:</label>
|
||||
<span id="paySubject">支付接口演示</span>
|
||||
<label>订单标题:</label>
|
||||
<a-input v-model="orderTitle" style="width: 200px"/>
|
||||
</div>
|
||||
|
||||
<div class="paydemo-form-item">
|
||||
<label>分账方式:</label>
|
||||
<a-radio-group v-model="divisionMode" style="display:flex">
|
||||
<div style="display:flex">
|
||||
<a-radio :value="0">订单不分账</a-radio>
|
||||
<a-radio :value="1">支付完成自动分账</a-radio>
|
||||
<a-radio :value="2">手动分账(冻结商户资金, 只能通过API发起分账后解冻)</a-radio>
|
||||
</div>
|
||||
</a-radio-group>
|
||||
</div>
|
||||
|
||||
<a-divider ></a-divider>
|
||||
|
||||
<div class="paydemo-form-item">
|
||||
<span>支付金额(元):</span>
|
||||
|
||||
|
|
@ -118,8 +136,8 @@
|
|||
</a-input-number>
|
||||
</a-radio>
|
||||
</a-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="margin-top:20px;text-align: left">
|
||||
<!-- <span style="color: #FD482C;font-size: 18px;padding-right: 10px;" id="amountShow">{{ paytestAmount }}</span> -->
|
||||
<a-button @click="immediatelyPay" style="padding:5px 20px;background-color: #1953ff;border-radius: 5px;color:#fff">立即支付</a-button>
|
||||
|
|
@ -154,7 +172,9 @@ export default {
|
|||
authCode: '', // 条码的值
|
||||
paytestAmount: '0.01', // 支付金额,默认为0.01
|
||||
amountInput: false, // 自定金额输入框是否展示
|
||||
noConfigText: false // 尚无任何配置分割线提示文字
|
||||
noConfigText: false, // 尚无任何配置分割线提示文字
|
||||
divisionMode: 0, // 订单分账模式
|
||||
orderTitle: '接口调试' // 订单标题
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -170,6 +190,12 @@ export default {
|
|||
// 请求接口,获取所有的appid,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1 }).then(res => {
|
||||
that.mchAppList = res.records
|
||||
if (that.mchAppList.length > 0) {
|
||||
// 赋予默认值
|
||||
that.appId = that.mchAppList[0].appId
|
||||
// 根据appId的值,动态显示支付方式
|
||||
this.appPaywayListHandle(that.appId)
|
||||
}
|
||||
})
|
||||
|
||||
// 在进入页面时刷新订单号
|
||||
|
|
@ -236,6 +262,11 @@ export default {
|
|||
return this.$message.error('请选择支付方式')
|
||||
}
|
||||
|
||||
// 请输入订单标题
|
||||
if (!this.orderTitle || this.orderTitle.length > 20) {
|
||||
return this.$message.error('请输入正确的订单标题[20字以内]')
|
||||
}
|
||||
|
||||
// 判断是否为条码支付
|
||||
if (!this.$refs.payTestBarCode.getVisible() && (this.currentWayCode === 'WX_BAR' || this.currentWayCode === 'ALI_BAR' || this.currentWayCode === 'AUTO_BAR')) {
|
||||
this.$refs.payTestBarCode.showModal()
|
||||
|
|
@ -250,7 +281,9 @@ export default {
|
|||
appId: this.appId, // appId
|
||||
mchOrderNo: this.mchOrderNo, // 订单编号
|
||||
payDataType: this.currentPayDataType, // 支付参数(二维码,条码)
|
||||
authCode: this.authCode
|
||||
authCode: this.authCode,
|
||||
divisionMode: this.divisionMode,
|
||||
orderTitle: this.orderTitle
|
||||
}).then(res => {
|
||||
that.$refs.payTestModal.showModal(this.currentWayCode, res) // 打开弹窗
|
||||
that.randomOrderNo() // 刷新订单号
|
||||
|
|
@ -269,8 +302,8 @@ export default {
|
|||
}
|
||||
},
|
||||
// 聚合支付标题显示
|
||||
showJhTitle () {
|
||||
if (this.appPaywayList.toString().indexOf('WX') !== -1 || this.appPaywayList.toString().indexOf('ALI') !== -1) {
|
||||
showQtTitle () {
|
||||
if (this.appPaywayList.toString().indexOf('WX') !== -1 || this.appPaywayList.toString().indexOf('ALI') !== -1 || this.appPaywayList.toString().indexOf('PP_PC') !== -1) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
@btnLoadClose="btnLoading=false"
|
||||
:scrollX="500"
|
||||
rowKey="roleId"
|
||||
>
|
||||
<template slot="roleIdSlot" slot-scope="{record}"><b>{{ record.roleId }}</b></template> <!-- 自定义插槽 -->
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
:tableColumns="tableColumns"
|
||||
:searchData="searchData"
|
||||
rowKey="sysUserId"
|
||||
:scrollX="1300"
|
||||
>
|
||||
|
||||
<template slot="avatarSlot" slot-scope="{record}">
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
.paydemo .content {
|
||||
max-width: 1120px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.paydemo .paydemo-type-content {
|
||||
padding:20px 0;
|
||||
margin-bottom:20px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.paydemo .paydemo-type-name {
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .paydemo-type-body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.paydemo .paydemo-type {
|
||||
padding: 12px;
|
||||
border: solid 1px #e2e2e2;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.paydemo .paydemo-type-h5 {
|
||||
padding: 12px;
|
||||
border: solid 1px #e2e2e2;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.paydemo .codeImg_wx_h5 {
|
||||
position: absolute;
|
||||
z-index:1001;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: #ffffff;
|
||||
width: 160px;
|
||||
}
|
||||
.paydemo .paydemo-type-img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
vertical-align: center;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.paydemo .this {
|
||||
color: #1953ff;
|
||||
border-color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-input {
|
||||
width: 50%;
|
||||
display: inline;
|
||||
font-size: 14px;
|
||||
}
|
||||
.paydemo .paydemo-form-item {
|
||||
height: 38px;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .layui-form-radio i:hover, .layui-form-radioed i {
|
||||
color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-anim.layui-icon {
|
||||
margin-top: 3px;
|
||||
}
|
||||
.paydemo .layui-form-radio {
|
||||
margin-top: 2px;
|
||||
}
|
||||
.paydemo .paydemo-scan {
|
||||
padding-top: 30px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.paydemo .layui-laypage .layui-laypage-curr .layui-laypage-em {
|
||||
background-color: #1953ff;
|
||||
}
|
||||
.paydemo .layui-laypage a:hover {
|
||||
color: #1953ff;
|
||||
}
|
||||
.paydemo-type-content p {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.paydemo .layui-table-view .layui-table {
|
||||
width: 100%;
|
||||
}
|
||||
.paydemo .paydemo-btn {
|
||||
border: 1px solid #e2e2e2;
|
||||
background-color: #ffffff;
|
||||
color:#000000;
|
||||
margin-left: 8px;
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.paydemo #paydemo-amount {
|
||||
display: flex;
|
||||
align-items: inherit;
|
||||
}
|
||||
.paydemo #paydemo-amount .layui-unselect{
|
||||
margin-right:15px
|
||||
}
|
||||
|
||||
#randomOrderNo:hover {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.paydemo-form-item label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right:15px;
|
||||
flex-wrap:wrap
|
||||
}
|
||||
.paydemo-form-item label input {
|
||||
margin-left:3px;
|
||||
}
|
||||
|
||||
.paydemo .article-title {
|
||||
font-weight: 600
|
||||
}
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-card style="box-sizing:border-box;padding:30px">
|
||||
|
||||
<!-- 选择下单的应用列表 -->
|
||||
<a-form>
|
||||
<div style="display:flex;flex-direction:row">
|
||||
<a-form-item label="" class="table-head-layout">
|
||||
<a-select v-model="reqData.appId" @change="changeAppId" style="width:300px">
|
||||
<a-select-option key="" >请选择应用APPID</a-select-option>
|
||||
<a-select-option v-for="(item) in mchAppList" :key="item.appId" >{{ item.appName }} [{{ item.appId }}]</a-select-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</div>
|
||||
</a-form>
|
||||
|
||||
<!-- 未配置支付方式提示框 -->
|
||||
<a-divider v-if="!reqData.appId">请选择应用APPID</a-divider>
|
||||
<a-divider v-else-if="ifCodeList.length == 0">该应用尚未配置任何通道</a-divider>
|
||||
<div v-else>
|
||||
|
||||
<div style="width: 100%;" class="paydemo">
|
||||
<div class="paydemo-type-content">
|
||||
<div class="paydemo-type-name article-title" >选择通道</div>
|
||||
<div class="paydemo-type-body">
|
||||
|
||||
<template v-for="(item) in ifCodeList">
|
||||
<div :key="item.ifCode" :class="{ 'paydemo-type': true, 'color-change': true, 'this':(reqData.ifCode === item.ifCode) }" @click="changeCurrentIfCode(item.ifCode)">
|
||||
<span class="color-change">{{ item.ifName }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="paydemo-form-item">
|
||||
<span>入账方式:</span>
|
||||
<a-radio-group v-model="reqData.entryType" style="display:flex">
|
||||
<div style="display:flex">
|
||||
<a-radio value="WX_CASH" :disabled="reqData.ifCode != 'wxpay'" >微信零钱</a-radio>
|
||||
<a-radio value="ALIPAY_CASH" :disabled="reqData.ifCode != 'alipay'">支付宝余额</a-radio>
|
||||
<a-radio value="BANK_CARD" disabled >银行卡(暂未支持)</a-radio>
|
||||
</div>
|
||||
</a-radio-group>
|
||||
|
||||
</div>
|
||||
|
||||
<a-divider ></a-divider>
|
||||
<!-- 订单信息 -->
|
||||
<div class="paydemo-type-content">
|
||||
<div class="paydemo-type-name article-title">转账信息</div>
|
||||
<form class="layui-form">
|
||||
<div class="paydemo-form-item">
|
||||
<label>订单编号:</label><span id="payMchOrderNo">{{ reqData.mchOrderNo }}</span>
|
||||
<span @click="randomOrderNo" class=" paydemo-btn" style="padding:0 3px">刷新订单号</span>
|
||||
</div>
|
||||
<div class="paydemo-form-item">
|
||||
<span>转账金额(元):</span>
|
||||
<a-input-number :max="100000" :min="0.01" v-model="reqData.amount" :precision="2" />
|
||||
</div>
|
||||
|
||||
<div class="paydemo-form-item">
|
||||
<span>收款账号:</span><a-input v-model="reqData.accountNo" style="width: 200px; margin-right: 10px"/>
|
||||
<a-button v-show="reqData.entryType=='WX_CASH'" size="small" type="danger" @click="showChannelUserQR">自动获取openID</a-button>
|
||||
</div>
|
||||
<div style="margin-left: 10px; color: red">提示:【微信官方】需要填入对应应用收款方的openID</div>
|
||||
<div style="margin-left: 10px; color: red"> 【支付宝官方】需要填入支付宝登录账号</div>
|
||||
|
||||
<div class="paydemo-form-item" style="margin-top: 10px">
|
||||
<span>收款人姓名:</span><a-input v-model="reqData.accountName" style="width: 200px"/>
|
||||
<div style="margin-left: 10px; color: red">提示: 填入则验证,否则不验证收款人姓名</div>
|
||||
</div>
|
||||
|
||||
<div class="paydemo-form-item">
|
||||
<span>转账备注:</span><a-input v-model="reqData.transferDesc" style="width: 200px"/>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:20px;text-align: left">
|
||||
<a-button @click="immediatelyPay" style="padding:5px 20px;background-color: #1953ff;border-radius: 5px;color:#fff">立即转账</a-button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</a-card>
|
||||
|
||||
<!-- 获取用户二维码 -->
|
||||
<ChannelUserModal ref="channelUserModal" @changeChannelUserId="changeChannelUserIdFunc($event)"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { API_URL_MCH_APP, req, queryMchTransferIfCode, doTransfer } from '@/api/manage' // 接口
|
||||
import ChannelUserModal from '@/components/ChannelUser/ChannelUserModal'
|
||||
export default {
|
||||
components: { ChannelUserModal },
|
||||
data () {
|
||||
return {
|
||||
|
||||
ifCodeList: [], // 支持的支付接口
|
||||
|
||||
reqData: {
|
||||
appId: '', // 已选择的appId
|
||||
mchOrderNo: '', // 模拟商户订单号
|
||||
ifCode: '', // 当前选择的支付接口
|
||||
entryType: '', // 当前选择的入账方式
|
||||
amount: 0.01, // 转账金额
|
||||
accountNo: '', // 收款账号
|
||||
accountName: '', // 收款人姓名
|
||||
transferDesc: '打款' // 转账备注
|
||||
},
|
||||
|
||||
mchAppList: [] // app列表
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
// 获取传入的参数,如果参数存在,则为appId 重新赋值
|
||||
const appId = this.$route.params.appId
|
||||
if (appId) {
|
||||
this.reqData.appId = appId // appId赋值
|
||||
this.changeAppId(appId)
|
||||
}
|
||||
|
||||
const that = this // 提前保留this
|
||||
// 请求接口,获取所有的appid,只有此处进行pageSize=-1传参
|
||||
req.list(API_URL_MCH_APP, { pageSize: -1 }).then(res => {
|
||||
that.mchAppList = res.records
|
||||
if (that.mchAppList.length > 0) {
|
||||
// 赋予默认值
|
||||
that.reqData.appId = that.mchAppList[0].appId
|
||||
// 根据不同的appId展示不同的支付方式
|
||||
this.changeAppId(that.reqData.appId)
|
||||
}
|
||||
})
|
||||
|
||||
// 在进入页面时刷新订单号
|
||||
this.randomOrderNo()
|
||||
},
|
||||
methods: {
|
||||
|
||||
// 变更 appId的事件
|
||||
changeAppId (value) {
|
||||
if (!value) {
|
||||
this.ifCodeList = []
|
||||
return false
|
||||
}
|
||||
const that = this
|
||||
queryMchTransferIfCode(value).then(res => { // 查询所有的支付接口
|
||||
that.ifCodeList = res
|
||||
})
|
||||
},
|
||||
|
||||
// 刷新订单号
|
||||
randomOrderNo () {
|
||||
this.reqData.mchOrderNo = 'M' + new Date().getTime() + Math.floor(Math.random() * (9999 - 1000) + 1000)
|
||||
},
|
||||
|
||||
// 立即支付按钮
|
||||
immediatelyPay () {
|
||||
// 判断金额
|
||||
if (!this.reqData.amount || this.reqData.amount <= 0) {
|
||||
return this.$message.error('请输入转账金额')
|
||||
}
|
||||
|
||||
if (!this.reqData.ifCode) {
|
||||
return this.$message.error('请选择转账通道')
|
||||
}
|
||||
|
||||
if (!this.reqData.entryType) {
|
||||
return this.$message.error('请选择入账方式')
|
||||
}
|
||||
|
||||
if (!this.reqData.accountNo) {
|
||||
return this.$message.error('请输入收款账号')
|
||||
}
|
||||
|
||||
if (!this.reqData.transferDesc) {
|
||||
return this.$message.error('请输入转账备注')
|
||||
}
|
||||
|
||||
const that = this
|
||||
doTransfer(this.reqData).then(apiRes => {
|
||||
that.randomOrderNo() // 刷新订单号
|
||||
|
||||
if (apiRes.state === 2) {
|
||||
const succModal = that.$infoBox.modalSuccess('转账成功', <div>2s后自动关闭...</div>)
|
||||
setTimeout(() => { succModal.destroy() }, 2000)
|
||||
} else if (apiRes.state === 1) {
|
||||
that.$infoBox.modalWarning('转账处理中', <div>请前往转账订单列表查看最终状态</div>)
|
||||
} else if (apiRes.state === 3) {
|
||||
that.$infoBox.modalError('转账处理失败', <div><div>错误码:{ apiRes.errCode}</div>
|
||||
<div>错误信息:{ apiRes.errMsg}</div></div>)
|
||||
} else {
|
||||
return this.$message.error('转账异常')
|
||||
}
|
||||
}).catch(() => {
|
||||
that.randomOrderNo() // 刷新订单号
|
||||
})
|
||||
},
|
||||
|
||||
// 切换ifCode
|
||||
changeCurrentIfCode (ifCode) {
|
||||
this.reqData.ifCode = ifCode
|
||||
|
||||
if (ifCode === 'wxpay') {
|
||||
this.reqData.entryType = 'WX_CASH'
|
||||
} else if (ifCode === 'alipay') {
|
||||
this.reqData.entryType = 'ALIPAY_CASH'
|
||||
} else {
|
||||
this.reqData.entryType = '' // 入账方式清除
|
||||
}
|
||||
},
|
||||
|
||||
// 显示自动获取渠道用户ID的二维码地址
|
||||
showChannelUserQR () {
|
||||
this.$refs.channelUserModal.showModal(this.reqData.appId, this.reqData.ifCode) // 打开弹窗
|
||||
},
|
||||
|
||||
// 更新账户
|
||||
changeChannelUserIdFunc ({ channelUserId }) {
|
||||
this.$message.success('成功获取渠道用户ID')
|
||||
this.reqData.accountNo = channelUserId
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="css">
|
||||
@import './MchTransferPage.css';
|
||||
</style>
|
||||
|
|
@ -53,8 +53,9 @@
|
|||
<img :src="vercodeIcon" slot="prefix" class="user" alt="user" />
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
<div class="code-img">
|
||||
<div class="code-img" style="position: relative;background:#ddd">
|
||||
<img v-show="vercodeImgSrc" :src="vercodeImgSrc" @click="refVercode()"/>
|
||||
<div class="vercode-mask" v-show="isOverdue" @click="refVercode()">已过期 请刷新</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -90,6 +91,7 @@ export default {
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
isOverdue: false, // 设置过期样式
|
||||
isAutoLogin: true, // 是否是自动登录
|
||||
loginBtnLoadingFlag: false, // 登录按钮是否显示 加载状态
|
||||
showLoginErrorInfo: '', // 是否显示登录错误面板信息
|
||||
|
|
@ -154,6 +156,17 @@ export default {
|
|||
vercode().then(res => {
|
||||
that.vercodeImgSrc = res.imageBase64Data
|
||||
that.vercodeToken = res.vercodeToken
|
||||
|
||||
this.isOverdue = false
|
||||
if (this.timer) clearInterval(this.timer) // 如果多次点击则清除已有的定时器
|
||||
// 超过60秒提示过期刷新
|
||||
this.timer = setInterval(() => {
|
||||
res.expireTime--
|
||||
if (res.expireTime <= 0) {
|
||||
that.isOverdue = true
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -220,5 +233,19 @@ export default {
|
|||
margin-top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.vercode-mask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000;
|
||||
opacity: 0.8;
|
||||
text-align:center;
|
||||
line-height: 40px;
|
||||
color:#fff;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -16,25 +16,7 @@ function getGitHash () {
|
|||
return 'unknown'
|
||||
}
|
||||
|
||||
const isProd = process.env.NODE_ENV === 'production'
|
||||
|
||||
const assetsCDN = {
|
||||
// webpack build externals
|
||||
externals: {
|
||||
vue: 'Vue',
|
||||
'vue-router': 'VueRouter',
|
||||
vuex: 'Vuex',
|
||||
axios: 'axios'
|
||||
},
|
||||
css: [],
|
||||
// https://unpkg.com/browse/vue@2.6.10/
|
||||
js: [
|
||||
'//cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.min.js',
|
||||
'//cdn.jsdelivr.net/npm/vue-router@3.1.3/dist/vue-router.min.js',
|
||||
'//cdn.jsdelivr.net/npm/vuex@3.1.1/dist/vuex.min.js',
|
||||
'//cdn.jsdelivr.net/npm/axios@0.19.0/dist/axios.min.js'
|
||||
]
|
||||
}
|
||||
// const isProd = process.env.NODE_ENV === 'production'
|
||||
|
||||
// vue.config.js
|
||||
const vueConfig = {
|
||||
|
|
@ -53,7 +35,7 @@ const vueConfig = {
|
|||
// 代码调试
|
||||
devtool: 'source-map',
|
||||
// if prod, add externals
|
||||
externals: isProd ? assetsCDN.externals : {}
|
||||
externals: {}
|
||||
},
|
||||
|
||||
chainWebpack: (config) => {
|
||||
|
|
@ -74,17 +56,9 @@ const vueConfig = {
|
|||
.use('file-loader')
|
||||
.loader('file-loader')
|
||||
.options({
|
||||
limit: 100000,
|
||||
name: 'assets/[name].[hash:8].[ext]'
|
||||
})
|
||||
|
||||
// if prod is on
|
||||
// assets require on cdn
|
||||
if (isProd) {
|
||||
config.plugin('html').tap(args => {
|
||||
args[0].cdn = assetsCDN
|
||||
return args
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
css: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue