diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a1187db --- /dev/null +++ b/.gitignore @@ -0,0 +1,55 @@ +# [ java 字节码 ] +*.class + +# [ 日志文件 ] +*.log + +# [ 打包压缩文件 ] +*.jar +*.war +*.zip +*.tar.gz +*.rar + +# [ java 虚拟机异常日志 see http://www.java.com/en/download/help/error_hotspot.xml ] +hs_err_pid* + +# [ 操作系统缓存和备份 ] +tmp/ +*.tmp +*.bak +*.swp +*~.nib + +# [ eclipse ] +.metadata +bin/ +.settings +.classpath +.project + +# [ IDEA ] +.idea/ +*.iml + +# [ MAVEN ] +target/ + +# [Jrebel] +rebel.xml + +# ################################################ 前端 ################### +# [npm包管理依赖] +node_modules/ + +# [dist目录] +dist/ + +# [HBuilderX 编译目录 ] +unpackage/ + +# [vscode IDE] +.vscode/ + +# [package-lock.json 无需提交 ] +package-lock.json \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3462706 --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/README.md b/README.md index af95ef8..cfc8715 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,152 @@ -# jeepay-ui -jeepay对应的前端UI项目 +

+ +

+

+ 适合互联网企业使用的开源支付系统 +

+

+ 👉 https://www.jeepay.vip 👈 +

+ +

+ + + + + + + + + + + star + + + github star + +

+ +
+

+ + + +

+ +------------------------------------------------------------------------------- + +## 📚 项目介绍 + +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计全支付系统架构图 + +![Jeepay系统架构图](https://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/jeepay_framework.png "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代码 +``` + +> 开发部署 + +- 系统开发:[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) + +## 🍿 功能模块 + +> Jeepay运营平台功能 + +![Jeepay运营平台功能](https://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/jeepay_mgr.png "Jeepay运营平台功能") + +> Jeepay商户系统功能 + +![Jeepay商户系统功能](https://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/jeepay_mch.png "Jeepay商户系统功能") + +## 🍯 系统截图 + +`以下截图是从实际已完成功能界面截取,截图时间为:2021-05-29 02:05` + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/001.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/002.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/005.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/006.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/009.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/010.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/011.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/012.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/013.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/014.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/015.png "Jeepay演示界面") + +![Jeepay演示界面](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/yanshi/022.png "Jeepay演示界面") + +## 🥪 关于我们 +*** +微信扫描下面二维码,关注官方公众号:计全科技,获取更多精彩内容。 + +![计全科技公众号](http://jeequan.oss-cn-beijing.aliyuncs.com/jeepay/img/jee-qrcode.jpg "计全科技公众号") \ No newline at end of file diff --git a/jeepay-ui-cashier/.env b/jeepay-ui-cashier/.env new file mode 100644 index 0000000..0deec75 --- /dev/null +++ b/jeepay-ui-cashier/.env @@ -0,0 +1,3 @@ +NODE_ENV=production +VUE_APP_BASE_URL=/ +VUE_APP_API_BASE_URL= \ No newline at end of file diff --git a/jeepay-ui-cashier/.env.development b/jeepay-ui-cashier/.env.development new file mode 100644 index 0000000..fe44d39 --- /dev/null +++ b/jeepay-ui-cashier/.env.development @@ -0,0 +1,3 @@ +NODE_ENV=development +VUE_APP_BASE_URL=/ +VUE_APP_API_BASE_URL=http://192.168.0.199:8030 \ No newline at end of file diff --git a/jeepay-ui-cashier/.gitignore b/jeepay-ui-cashier/.gitignore new file mode 100644 index 0000000..403adbc --- /dev/null +++ b/jeepay-ui-cashier/.gitignore @@ -0,0 +1,23 @@ +.DS_Store +node_modules +/dist + + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/jeepay-ui-cashier/.postcssrc.js b/jeepay-ui-cashier/.postcssrc.js new file mode 100644 index 0000000..4abbaef --- /dev/null +++ b/jeepay-ui-cashier/.postcssrc.js @@ -0,0 +1,21 @@ +/* + * @Author: your name + * @Date: 2020-12-14 16:32:48 + * @LastEditors: 王会峰 + * @LastEditTime: 2020-12-24 16:02:58 + * @FilePath: \pay\.postcssrc.js + * @SendWord: 永无BUG vite⚡ + */ +// https://github.com/michael-ciniawsky/postcss-load-config + +module.exports = { + "plugins": { + "postcss-import": {}, + "postcss-url": {}, + // to edit target browsers: use "browserslist" field in package.json + "autoprefixer": {}, + "postcss-px2rem": { + "remUnit": 75 + } + } +} \ No newline at end of file diff --git a/jeepay-ui-cashier/README.md b/jeepay-ui-cashier/README.md new file mode 100644 index 0000000..fa0a278 --- /dev/null +++ b/jeepay-ui-cashier/README.md @@ -0,0 +1,24 @@ +# jeepay-ui-cashier + +## Project setup +``` +npm install +``` + +### Compiles and hot-reloads for development +``` +npm run serve +``` + +### Compiles and minifies for production +``` +npm run build +``` + +### Lints and fixes files +``` +npm run lint +``` + +### Customize configuration +See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/jeepay-ui-cashier/babel.config.js b/jeepay-ui-cashier/babel.config.js new file mode 100644 index 0000000..e955840 --- /dev/null +++ b/jeepay-ui-cashier/babel.config.js @@ -0,0 +1,5 @@ +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset' + ] +} diff --git a/jeepay-ui-cashier/package.json b/jeepay-ui-cashier/package.json new file mode 100644 index 0000000..749f300 --- /dev/null +++ b/jeepay-ui-cashier/package.json @@ -0,0 +1,49 @@ +{ + "name": "jeepay-ui-cashier", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "lint": "vue-cli-service lint" + }, + "dependencies": { + "amfe-flexible": "^2.2.1", + "axios": "^0.19.0", + "core-js": "^3.6.5", + "lib-flexible": "^0.3.2", + "postcss-px2rem": "^0.3.0", + "px2rem-loader": "^0.1.9", + "vue": "^2.6.11", + "vue-router": "^3.2.0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "~4.5.0", + "@vue/cli-plugin-eslint": "~4.5.0", + "@vue/cli-plugin-router": "^4.5.13", + "@vue/cli-service": "~4.5.0", + "babel-eslint": "^10.1.0", + "eslint": "^6.7.2", + "eslint-plugin-vue": "^6.2.2", + "vue-template-compiler": "^2.6.11" + }, + "eslintConfig": { + "root": true, + "env": { + "node": true + }, + "extends": [ + "plugin:vue/essential", + "eslint:recommended" + ], + "parserOptions": { + "parser": "babel-eslint" + }, + "rules": {} + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ] +} diff --git a/jeepay-ui-cashier/public/favicon.ico b/jeepay-ui-cashier/public/favicon.ico new file mode 100644 index 0000000..cdce95c Binary files /dev/null and b/jeepay-ui-cashier/public/favicon.ico differ diff --git a/jeepay-ui-cashier/public/index.html b/jeepay-ui-cashier/public/index.html new file mode 100644 index 0000000..13853ea --- /dev/null +++ b/jeepay-ui-cashier/public/index.html @@ -0,0 +1,17 @@ + + + + + + + + Jeepay-收银台 + + + +
+ + + diff --git a/jeepay-ui-cashier/src/App.vue b/jeepay-ui-cashier/src/App.vue new file mode 100644 index 0000000..855c4d3 --- /dev/null +++ b/jeepay-ui-cashier/src/App.vue @@ -0,0 +1,28 @@ + + + diff --git a/jeepay-ui-cashier/src/api/api.js b/jeepay-ui-cashier/src/api/api.js new file mode 100644 index 0000000..4b68a1e --- /dev/null +++ b/jeepay-ui-cashier/src/api/api.js @@ -0,0 +1,58 @@ +import request from '@/http/request' +import wayCode from "@/utils/wayCode"; +import channelUserIdUtil from "@/utils/channelUserId"; +import config from '@/config' + +/** 获取url **/ +export function getRedirectUrl () { + return request.request({ + url: '/api/cashier/redirectUrl', + method: 'POST', + data: { wayCode: wayCode.getPayWay().wayCode, token: config.cacheToken } + }) +} + +/** 获取url **/ +export function getChannelUserId (redirectData) { + return request.request({ + url: '/api/cashier/channelUserId', + method: 'POST', + data: Object.assign({ wayCode: wayCode.getPayWay().wayCode, token: config.cacheToken }, redirectData) + }) +} + +/** 调起支付接口, 获取支付数据包 **/ +export function getPayPackage (amount) { + return request.request({ + url: '/api/cashier/pay', + method: 'POST', + data: { + wayCode: wayCode.getPayWay().wayCode, + token: config.cacheToken, + amount: amount, + channelUserId: channelUserIdUtil.getChannelUserId() + } + }) +} + +/** 调起支付接口, 获取订单信息 **/ +export function getPayOrderInfo () { + return request.request({ + url: '/api/cashier/payOrderInfo', + method: 'POST', + data: { + token: config.cacheToken + } + }) +} + +/** 取消订单 **/ +export function cancelPay () { + return request.request({ + url: '/api/cashier/cancelPay', + method: 'POST', + data: { + token: config.cacheToken + } + }) +} diff --git a/jeepay-ui-cashier/src/assets/icon/S.svg b/jeepay-ui-cashier/src/assets/icon/S.svg new file mode 100644 index 0000000..ce32df7 --- /dev/null +++ b/jeepay-ui-cashier/src/assets/icon/S.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/assets/icon/error.svg b/jeepay-ui-cashier/src/assets/icon/error.svg new file mode 100644 index 0000000..2085e42 --- /dev/null +++ b/jeepay-ui-cashier/src/assets/icon/error.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/assets/icon/wx.svg b/jeepay-ui-cashier/src/assets/icon/wx.svg new file mode 100644 index 0000000..213f4fa --- /dev/null +++ b/jeepay-ui-cashier/src/assets/icon/wx.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/assets/images/empty.svg b/jeepay-ui-cashier/src/assets/images/empty.svg new file mode 100644 index 0000000..757aaa2 --- /dev/null +++ b/jeepay-ui-cashier/src/assets/images/empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/assets/images/loading.gif b/jeepay-ui-cashier/src/assets/images/loading.gif new file mode 100644 index 0000000..5bb90fd Binary files /dev/null and b/jeepay-ui-cashier/src/assets/images/loading.gif differ diff --git a/jeepay-ui-cashier/src/assets/images/ysf.jpg b/jeepay-ui-cashier/src/assets/images/ysf.jpg new file mode 100644 index 0000000..0570754 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/images/ysf.jpg differ diff --git a/jeepay-ui-cashier/src/assets/images/zfb.jpeg b/jeepay-ui-cashier/src/assets/images/zfb.jpeg new file mode 100644 index 0000000..abba662 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/images/zfb.jpeg differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Bold.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Bold.ttf new file mode 100644 index 0000000..094f059 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Bold.ttf differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Light.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Light.ttf new file mode 100644 index 0000000..3deba26 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Light.ttf differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Medium.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Medium.ttf new file mode 100644 index 0000000..e4b1aaa Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Medium.ttf differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Regular.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Regular.ttf new file mode 100644 index 0000000..9a4b070 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansSS-Regular.ttf differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Bold.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Bold.ttf new file mode 100644 index 0000000..c3732d1 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Bold.ttf differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Light.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Light.ttf new file mode 100644 index 0000000..30f1d27 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Light.ttf differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Medium.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Medium.ttf new file mode 100644 index 0000000..35d7797 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Medium.ttf differ diff --git a/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Regular.ttf b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Regular.ttf new file mode 100644 index 0000000..7dd4c31 Binary files /dev/null and b/jeepay-ui-cashier/src/assets/wx-zt/WeChatSansStd-Regular.ttf differ diff --git a/jeepay-ui-cashier/src/config/index.js b/jeepay-ui-cashier/src/config/index.js new file mode 100644 index 0000000..2284663 --- /dev/null +++ b/jeepay-ui-cashier/src/config/index.js @@ -0,0 +1,24 @@ +/* + * 全局定义信息 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ + +const errorPageRouteName = 'Error' //错误页面名称定义 +const passGuardRouteList = [errorPageRouteName] // 不进入路由守卫的name + +/** 定义支付方式 **/ +const payWay = { + WXPAY : {wayCode: "WX_JSAPI", routeName: "CashierWxpay"}, + ALIPAY : {wayCode: "ALI_JSAPI", routeName: "CashierAlipay"} +} + +export default { + errorPageRouteName: errorPageRouteName, + passGuardRouteList: passGuardRouteList, + urlTokenName: "jeepayToken", //URL传递的token名称 + payWay: payWay, + cacheToken: "" +} \ No newline at end of file diff --git a/jeepay-ui-cashier/src/config/rem.js b/jeepay-ui-cashier/src/config/rem.js new file mode 100644 index 0000000..9e7a8e3 --- /dev/null +++ b/jeepay-ui-cashier/src/config/rem.js @@ -0,0 +1,15 @@ +// 基准大小 +const baseSize = 32 +// 设置 rem 函数 +function setRem () { + // 当前页面宽度相对于 750 宽的缩放比例,可根据自己需要修改。 + const scale = document.documentElement.clientWidth / 750 + // 设置页面根节点字体大小 + document.documentElement.style.fontSize = (baseSize * Math.min(scale, 2)) + 'px' +} +// 初始化 +setRem() +// 改变窗口大小时重新设置 rem +window.onresize = function () { + setRem() +} \ No newline at end of file diff --git a/jeepay-ui-cashier/src/http/HttpRequest.js b/jeepay-ui-cashier/src/http/HttpRequest.js new file mode 100644 index 0000000..d14cc7e --- /dev/null +++ b/jeepay-ui-cashier/src/http/HttpRequest.js @@ -0,0 +1,81 @@ +/** + * Http请求包装对象 + * 参考: iview https://gitee.com/icarusion/iview-admin/blob/master/src/libs/axios.js + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ + +import axios from 'axios' +class HttpRequest { + constructor (baseUrl = process.env.VUE_APP_API_BASE_URL) { + this.baseUrl = baseUrl + this.queue = {} // 发送队列, 格式为: {请求url: true}, 可以做一些验证之类 + } + // 基础配置信息 + baseConfig () { + const headers = {} + return { + baseURL: this.baseUrl, + headers: headers + } + } + destroy (url) { + delete this.queue[url] + } + interceptors (instance, url, showErrorMsg, showLoading) { + // 请求拦截 + instance.interceptors.request.use(config => { + // 添加全局的loading... + if (!Object.keys(this.queue).length && showLoading) { + //console.log("") + } + this.queue[url] = true + return config + }, error => { + return Promise.reject(error) + }) + + // 响应拦截 + instance.interceptors.response.use(res => { + this.destroy(url, showLoading) + const resData = res.data // 接口实际返回数据 格式为:{code: '', msg: '', data: ''}, res.data 是axios封装对象的返回数据; + + if (resData.code !== 0) { // 相应结果不为0, 说明异常 + if (showErrorMsg) { + // + } + + return Promise.reject(resData) + } else { + return resData.data + } + }, error => { + this.destroy(url, showLoading) + let errorInfo = error.response && error.response.data && error.response.data.data + if (!errorInfo) { + errorInfo = error.response.data + } + + if (showErrorMsg) { + //Vue.prototype.$message.error(JSON.stringify(errorInfo)) // 显示异常信息 + } + + return Promise.reject(errorInfo) + }) + } + // interceptorsFlag: 是否进行自定义拦截器处理,默认为: true + // showErrorMsg 发送请求出现异常是否全局提示错误信息 + // showLoading 发送请求前后显示全局loading + request (options, interceptorsFlag = true, showErrorMsg = true, showLoading = false) { + const instance = axios.create() + options = Object.assign(this.baseConfig(), options) + if (interceptorsFlag) { // 注入 req, respo 拦截器 + this.interceptors(instance, options.url, showErrorMsg, showLoading) + } + + return instance(options) + } +} +export default HttpRequest diff --git a/jeepay-ui-cashier/src/http/request.js b/jeepay-ui-cashier/src/http/request.js new file mode 100644 index 0000000..7b66cad --- /dev/null +++ b/jeepay-ui-cashier/src/http/request.js @@ -0,0 +1,4 @@ +import HttpRequest from '@/http/HttpRequest' + +const request = new HttpRequest() +export default request diff --git a/jeepay-ui-cashier/src/main.js b/jeepay-ui-cashier/src/main.js new file mode 100644 index 0000000..b036230 --- /dev/null +++ b/jeepay-ui-cashier/src/main.js @@ -0,0 +1,57 @@ +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import wayCode from './utils/wayCode'; +import config from './config' +import 'amfe-flexible' +Vue.config.productionTip = false + +/** + * 路由守卫 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +router.beforeEach((to, from, next) => { + + console.log("进入路由守卫",from, to) + + // from: 当前导航正要离开的路由 + // to: 即将要进入的目标路由对象 + + // 如果在免登录页面则直接放行 + if (config.errorPageRouteName.includes(to.name)) { + // 在免登录名单,直接进入 + next() + return false + } + + //获取不到参数 + let token = to.params[config.urlTokenName]; + // let token = 'test'; // 不提交 + if(token){ //放置token信息 + config.cacheToken = token; + } + + if(!config.cacheToken) { + next({ name: config.errorPageRouteName, params: { errInfo: "token参数有误!" } }) + return false; + } + + //获取不到支付类型, 需要跳转到错误页面 + if( ! wayCode.getPayWay() ) { + next({ name: config.errorPageRouteName, params: { errInfo: "不支持的支付方式!" } }) + return false; + } + + next() +}) + + +Vue.prototype.$config = config; + +new Vue({ + router, + render: h => h(App) +}).$mount('#app') diff --git a/jeepay-ui-cashier/src/router/index.js b/jeepay-ui-cashier/src/router/index.js new file mode 100644 index 0000000..57fbe31 --- /dev/null +++ b/jeepay-ui-cashier/src/router/index.js @@ -0,0 +1,42 @@ +/** + * 路由配置信息 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ + +import Vue from 'vue' +import VueRouter from 'vue-router' + +// hack router push callback +// [解决 vue-router跳转相同路径报错 ] +const originalPush = VueRouter.prototype.push +VueRouter.prototype.push = function push (location, onResolve, onReject) { + if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) + return originalPush.call(this, location).catch(err => err) +} + + +Vue.use(VueRouter) + +const routes = [ + {path: '/hub/:jeepayToken', name: 'Hub', component: () => import('../views/Hub.vue')}, //自动分发器 + {path: '/error', name: 'Error', component: () => import('../views/Error.vue')}, + {path: '/oauth2Callback/:jeepayToken', name: 'Oauth2Callback', component: () => import('../views/Oauth2Callback.vue')}, //oauth回调地址 + {path: '/cashier', name: 'Cashier', component: () => import('../views/Cashier.vue'), //收银台(该地址无意义) + children: [ + { path: '/cashier/wxpay', name: 'CashierWxpay', component: () => import('../views/payway/Wxpay.vue') }, + { path: '/cashier/alipay', name: 'CashierAlipay', component: () => import('../views/payway/Alipay.vue') }, + { path: '/cashier/ysfpay', name: 'CashierYsfpay', component: () => import('../views/payway/Ysfpay.vue') } + ] + } +] + +const router = new VueRouter({ + mode: 'hash', //history 需要nginx适配 hash:是#的格式。 + base: "", + routes +}) + +export default router diff --git a/jeepay-ui-cashier/src/utils/channelUserId.js b/jeepay-ui-cashier/src/utils/channelUserId.js new file mode 100644 index 0000000..599a7eb --- /dev/null +++ b/jeepay-ui-cashier/src/utils/channelUserId.js @@ -0,0 +1,19 @@ +/** + * 获取渠道用户 工具类 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +const getChannelUserId = function () { + return localStorage.getItem("channelUserId") +} + +const setChannelUserId = function (channelUserId) { + localStorage.setItem("channelUserId", channelUserId) +} + +export default { + getChannelUserId: getChannelUserId, + setChannelUserId: setChannelUserId +} diff --git a/jeepay-ui-cashier/src/utils/wayCode.js b/jeepay-ui-cashier/src/utils/wayCode.js new file mode 100644 index 0000000..a25766b --- /dev/null +++ b/jeepay-ui-cashier/src/utils/wayCode.js @@ -0,0 +1,36 @@ +/** + * 获取支付方式工具类 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ + +import config from '@/config' + +const getToPageRouteName = function () { + const payWay = getPayWay(); + return payWay? payWay.routeName : null +} + +const getPayWay = function () { + + const userAgent = navigator.userAgent; + + if(userAgent.indexOf("MicroMessenger") >= 0){ + return config.payWay.WXPAY; + } + + if(userAgent.indexOf("AlipayClient") >= 0){ + return config.payWay.ALIPAY; + } + + return null; + +} + + +export default { getToPageRouteName: getToPageRouteName, + getPayWay: getPayWay + +} diff --git a/jeepay-ui-cashier/src/views/Cashier.vue b/jeepay-ui-cashier/src/views/Cashier.vue new file mode 100644 index 0000000..e6b4740 --- /dev/null +++ b/jeepay-ui-cashier/src/views/Cashier.vue @@ -0,0 +1,15 @@ + + + diff --git a/jeepay-ui-cashier/src/views/Error.vue b/jeepay-ui-cashier/src/views/Error.vue new file mode 100644 index 0000000..fb667f1 --- /dev/null +++ b/jeepay-ui-cashier/src/views/Error.vue @@ -0,0 +1,38 @@ + + + + diff --git a/jeepay-ui-cashier/src/views/Hub.vue b/jeepay-ui-cashier/src/views/Hub.vue new file mode 100644 index 0000000..811f009 --- /dev/null +++ b/jeepay-ui-cashier/src/views/Hub.vue @@ -0,0 +1,61 @@ + + + + diff --git a/jeepay-ui-cashier/src/views/Oauth2Callback.vue b/jeepay-ui-cashier/src/views/Oauth2Callback.vue new file mode 100644 index 0000000..48b0bfc --- /dev/null +++ b/jeepay-ui-cashier/src/views/Oauth2Callback.vue @@ -0,0 +1,56 @@ + + + diff --git a/jeepay-ui-cashier/src/views/dialog/dialog.vue b/jeepay-ui-cashier/src/views/dialog/dialog.vue new file mode 100644 index 0000000..dcb38ed --- /dev/null +++ b/jeepay-ui-cashier/src/views/dialog/dialog.vue @@ -0,0 +1,133 @@ + + + + + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/views/dialog/index.js b/jeepay-ui-cashier/src/views/dialog/index.js new file mode 100644 index 0000000..b272ce5 --- /dev/null +++ b/jeepay-ui-cashier/src/views/dialog/index.js @@ -0,0 +1,39 @@ +/* + * @Author: your name + * @Date: 2020-12-23 09:05:40 + * @LastEditors: 王会峰 + * @LastEditTime: 2020-12-23 09:12:16 + * @FilePath: \pay\src\components\dialog\index.js + * @SendWord: 永无BUG vite⚡ + */ +import Vue from 'vue' +import Dialog from './dialog.vue' + +const dialog = Vue.extend(Dialog) + +Dialog.install = function(options, type) { + if (options === undefined || options === null) { + options = { + content: '' + } + } else if (typeof options === 'string' || typeof options === 'number') { + options = { + content: options + } + if (type != undefined && options != null) { + options.type = type; + } + } + + let instance = new dialog({ + data: options + }).$mount() + // document.querySelector('#app') + + document.body.appendChild(instance.$el) + Vue.nextTick(() => { + instance.visible = true + }) +} + +export default Dialog \ No newline at end of file diff --git a/jeepay-ui-cashier/src/views/keyboard/keyboard.vue b/jeepay-ui-cashier/src/views/keyboard/keyboard.vue new file mode 100644 index 0000000..6341d71 --- /dev/null +++ b/jeepay-ui-cashier/src/views/keyboard/keyboard.vue @@ -0,0 +1,374 @@ + + + + + + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/views/payway/Alipay.vue b/jeepay-ui-cashier/src/views/payway/Alipay.vue new file mode 100644 index 0000000..4c862e1 --- /dev/null +++ b/jeepay-ui-cashier/src/views/payway/Alipay.vue @@ -0,0 +1,149 @@ + + + + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/views/payway/Wxpay.vue b/jeepay-ui-cashier/src/views/payway/Wxpay.vue new file mode 100644 index 0000000..a327212 --- /dev/null +++ b/jeepay-ui-cashier/src/views/payway/Wxpay.vue @@ -0,0 +1,203 @@ + + + + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/views/payway/Ysfpay.vue b/jeepay-ui-cashier/src/views/payway/Ysfpay.vue new file mode 100644 index 0000000..431b7dc --- /dev/null +++ b/jeepay-ui-cashier/src/views/payway/Ysfpay.vue @@ -0,0 +1,108 @@ + + + + \ No newline at end of file diff --git a/jeepay-ui-cashier/src/views/payway/pay.css b/jeepay-ui-cashier/src/views/payway/pay.css new file mode 100644 index 0000000..3623bae --- /dev/null +++ b/jeepay-ui-cashier/src/views/payway/pay.css @@ -0,0 +1,323 @@ +@font-face { + font-family: "wxFirstFont"; + src: url("../../assets/wx-zt/WeChatSansSS-Bold.ttf"); /* IE9 */ +} +@keyframes blink { + 0% { + opacity: 0; + } + + 50% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} +* { + box-sizing: border-box; +} +body { + background-color: #ededed; +} +.header { + box-sizing: border-box; + display: flex; + width: 100%; + height: 88px; + padding: 50px; + justify-content: space-between; + align-items: center; +} +.margin-top-30 { + margin-top: 30px; +} + +.header-text { + width: calc(100% - 120px); + height: 50px; + line-height: 50px; + text-align: left; + height: 50px; + font-size: 36px; + font-family: PingFang SC, PingFang SC-Medium; + font-weight: 500; + color: #323232; + letter-spacing: 1px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.header-img { + flex-shrink: 0; + width: 80px; + height: 80px; + border-radius: 40px; + /* background-color: #ff7b7b; */ + overflow: hidden; +} +.header-img img { + width: 100%; + height: 100%; +} +.plus-input { + padding-top: 60px; + display: flex; + flex-shrink: 0; + justify-content: safe; + margin: 0 auto; + border-bottom: 1px solid #cccccc; + width: calc(100vw - 140px); + min-width: 160px; + height: 180px; +} +.plus-input .S { + position: relative; + width: 30px; + height: 40px; + margin: 15px 15px 15px 0; +} +.plus-input .S img { + position: absolute; + top: 15px; + left: 0; + width: 100%; + height: 100%; + /* margin-top: 10px; */ +} +.plus-input input { + height: 98px; + width: 90%; + font-size: 70px; + font-family: wxFirstFont SC, PingFang SC, PingFang SC-Medium; + font-weight: 800; + text-align: left; + color: #000000; + letter-spacing: 2px; + border: none; + outline: none; + /* background-color: #ededed; */ + background-color: rgba(220, 20, 60, 0); +} + +.ttt { + display: flex; + align-items: center; + height: 98px; + width: 4px; + font-size: 70px; + font-family: wxFirstFont SC, PingFang SC, PingFang SC-Medium; + font-weight: 800; + text-align: center; + color: #000000; + letter-spacing: 2px; + border: none; + outline: none; + background-color: #ededed00; +} +.input-c { + display: flex; + align-items: center; + + height: 98px; + width: 40px; + font-size: 70px; + font-family: wxFirstFont SC, PingFang SC, PingFang SC-Medium; + font-weight: 800; + text-align: center; + color: #000000; + letter-spacing: 2px; + border: none; + outline: none; + background-color: #ededed00; + /* background-color: rgb(255, 7, 57); */ +} +.input-c-div-1 { + flex-shrink: 0; + width: 36px; + padding-left: 2px; + text-align: center; + /* width: auto; */ +} +.input-c-div { + position: relative; + flex-shrink: 0; + margin-left: 5px; + margin-right: 5px; + width: auto; + height: 66px; + /* background: #07c160; */ + animation: blink 1s linear infinite; + border: 1px solid #07c160; +} + +.placeholder { + color: #6b6b6b; + font-weight: 400; + text-align: left; + padding-top: 4px; + font-size: 60px; +} +.plus-input input::-webkit-input-placeholder { + /* placeholder颜色 */ + color: #6b6b6b; + font-weight: 400; + /* placeholder字体大小 */ + /* font-size: 12px; */ + /* placeholder位置 */ + text-align: left; +} +.plus-ul { + margin-top: 20px; + margin-bottom: 0; + padding: 30px; + width: 100%; +} +.plus-ul li { + position: relative; + background: #fafafa; + padding: 41px 30px; + display: flex; + justify-content: space-between; +} +.plus-li { + margin-bottom: 20px; + border-radius: 15px; +} +.border-radius-top { + border-radius: 15px 15px 0 0; +} +.border-radius-bottom { + border-radius: 0 0 15px 15px; +} +.xian { + position: absolute; + bottom: 0px; + right: 0; + width: calc(100% - 103px); + height: 1px; + background: #ebebeb; +} +.img-div { + display: flex; + flex-flow: row; +} +.img-div img { + width: 42px; + height: 42px; + margin-right: 30px; +} +.img-div .div-text { + height: 42px; + font-size: 30px; + font-family: PingFang SC, PingFang SC-Medium; + font-weight: 500; + text-align: left; + color: #323232; + letter-spacing: 1px; +} +.div-go { + display: flex; + flex-flow: row; + align-items: center; +} +.div-go img { + width: 30px; + height: 30px; +} +.div-go-div { + margin-right: 10px; + font-size: 27px; + font-family: PingFang SC, PingFang SC-Medium; + font-weight: 500; + text-align: right; + color: #808080; + letter-spacing: 1px; +} + +.pitch-on { + display: flex; + flex-flow: row; +} +.pitch-on-ok { + display: flex; + justify-content: center; + align-items: center; + border-radius: 21px; + width: 42px; + height: 42px; + background: #11c930; +} +.pitch-on-ok img { + width: 22px; + height: 16px; +} +.pitch-on-on { + border-radius: 21px; + width: 42px; + height: 42px; + background: rgba(17, 201, 48, 0); + border: 1px solid #bfbfbf; +} +.remark-k { + margin-top: 30px; + width: 100%; + display: flex; + justify-content: center; + font-size: 25px; + font-family: PingFang SC, PingFang SC-Medium; + font-weight: 500; + text-align: left; + color: #587cca; + letter-spacing: 1px; +} +.remark { + display: flex; + flex-flow: row; +} +.remark-hui { + width: auto; + height: 36px; + font-size: 25px; + font-family: PingFang SC, PingFang SC-Medium; + font-weight: 500; + text-align: left; + color: #808080; + letter-spacing: 1px; + margin-right: 30px; +} +.remark-hu { + font-size: 25px; + font-family: PingFang SC, PingFang SC-Medium; + font-weight: 500; + text-align: left; + color: #808080; + letter-spacing: 1px; + margin-right: 30px; +} +.keyboard-plus { + width: 100%; + position: fixed; + left: 0; + bottom: 0; +} +.bnt-pay { + position: fixed; + display: flex; + justify-content: center; + align-items: center; + bottom: 100px; + width: 100vw; + z-index: 1; +} +.bnt-pay-text { + width: 300px; + color: #fff; + height: 100px; + border-radius: 16px; + background-color: darkgreen; + text-align: center; + line-height: 100px; + font-size: 40px; +} \ No newline at end of file diff --git a/jeepay-ui-cashier/vue.config.js b/jeepay-ui-cashier/vue.config.js new file mode 100644 index 0000000..27db81a --- /dev/null +++ b/jeepay-ui-cashier/vue.config.js @@ -0,0 +1,20 @@ + +// vue.config.js +const vueConfig = { + + publicPath: process.env.VUE_APP_BASE_URL, // 前端资源访问根目录, 可配置到cdn目录下。 建议使用命令行环境变量进行替换。 + devServer: { + disableHostCheck: true //不检查域名是否正确 + }, + css: { + loaderOptions: { + postcss: { + plugins: [ + require('postcss-px2rem')({ remUnit: 75 }), // 换算的基数 + ] + } + } + } +} + +module.exports = vueConfig diff --git a/jeepay-ui-manager/.browserslistrc b/jeepay-ui-manager/.browserslistrc new file mode 100644 index 0000000..8f96043 --- /dev/null +++ b/jeepay-ui-manager/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not ie <= 10 diff --git a/jeepay-ui-manager/.env b/jeepay-ui-manager/.env new file mode 100644 index 0000000..1e734a7 --- /dev/null +++ b/jeepay-ui-manager/.env @@ -0,0 +1,4 @@ +NODE_ENV=production +VUE_APP_PREVIEW=false +VUE_APP_BASE_URL=/ +VUE_APP_API_BASE_URL= \ No newline at end of file diff --git a/jeepay-ui-manager/.env.development b/jeepay-ui-manager/.env.development new file mode 100644 index 0000000..1134191 --- /dev/null +++ b/jeepay-ui-manager/.env.development @@ -0,0 +1,4 @@ +NODE_ENV=development +VUE_APP_PREVIEW=true +VUE_APP_BASE_URL=/ +VUE_APP_API_BASE_URL=http://localhost:9217 \ No newline at end of file diff --git a/jeepay-ui-manager/.eslintrc.js b/jeepay-ui-manager/.eslintrc.js new file mode 100644 index 0000000..2e7a313 --- /dev/null +++ b/jeepay-ui-manager/.eslintrc.js @@ -0,0 +1,100 @@ +/** + 默认eslint规则: + 代码末尾不能加分号 ;(强迫症的我受不了 哭) + 代码中不能存在多行空行;(这个我更也忍不了大哭) + tab键不能使用,必须换成两个空格;(超级不习惯) + 代码中不能存在声明了但未使用的变量;(这个我觉得可以有) + * **/ + +module.exports = { + root: true, + env: { + node: true + }, + 'extends': [ + 'plugin:vue/strongly-recommended', + '@vue/standard' + ], + rules: { + 'no-console': 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'generator-star-spacing': 'off', + 'no-mixed-operators': 0, + 'vue/max-attributes-per-line': [ + 2, + { + 'singleline': 5, //单行的情况下可以接受的属性数量 + 'multiline': { + 'max': 1, //多行的情况下每行最多属性数量 + 'allowFirstLine': false //不允许在多行的情况下第一行有属性 + } + } + ], + 'vue/attribute-hyphenation': 0, + 'vue/html-self-closing': 0, + 'vue/component-name-in-template-casing': 0, + 'vue/html-closing-bracket-spacing': 0, + 'vue/singleline-html-element-content-newline': 0, + 'vue/no-unused-components': 0, + 'vue/multiline-html-element-content-newline': 0, + 'vue/no-use-v-if-with-v-for': 0, + 'vue/html-closing-bracket-newline': 0, + 'vue/no-parsing-error': 0, + 'no-tabs': 0, + 'quotes': [ + 2, + 'single', + { + 'avoidEscape': true, + 'allowTemplateLiterals': true + } + ], + + /** + * 分号配置项: + * 第一个参数: + " off"或0 - 关闭规则 + " warn"或1 - 将该规则作为警告打开(不影响退出代码) + " error"或2 - 将规则作为错误打开(退出代码将为1) + * + *第二个参数 + always(默认):在语句末尾需要分号 + never:不允许加分号 + * + * 第三个参数: + "beforeStatementContinuationChars": "any"(默认)如果下一行语句以 [,(,/,+,或 - 开头,忽略语句末尾的分号(或缺失分号), + "beforeStatementContinuationChars": "always" 如果下一行语句以 [,(,/,+,或 - 开头,在语句末尾需要添加分号。 + "beforeStatementContinuationChars": "never" 如果该语句不会因为ASI而带来风险,那么即使它的下一行语句以 [,(,/,+,或 - 开头,也不允许在语句末尾添加分号。 + * **/ + 'semi': [ + 2, + 'never', + { + 'beforeStatementContinuationChars': 'never' + } + ], + 'no-delete-var': 2, + 'prefer-const': [ + 2, + { + 'ignoreReadBeforeAssign': false + } + ], + 'template-curly-spacing': 'off', + 'indent': 'off' + }, + parserOptions: { + parser: 'babel-eslint' + }, + overrides: [ + { + files: [ + '**/__tests__/*.{j,t}s?(x)', + '**/tests/unit/**/*.spec.{j,t}s?(x)' + ], + env: { + jest: true + } + } + ] +} diff --git a/jeepay-ui-manager/babel.config.js b/jeepay-ui-manager/babel.config.js new file mode 100644 index 0000000..c5ef55e --- /dev/null +++ b/jeepay-ui-manager/babel.config.js @@ -0,0 +1,37 @@ +const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV) + +const plugins = [] +if (IS_PROD) { + plugins.push('transform-remove-console') +} + +// lazy load ant-design-vue +// if your use import on Demand, Use this code +plugins.push(['import', { + 'libraryName': 'ant-design-vue', + 'libraryDirectory': 'es', + 'style': true // `style: true` 会加载 less 文件 +}]) + +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset', + [ + '@babel/preset-env', + { + 'useBuiltIns': 'entry', + 'corejs': 3 + } + ] + ], + 'plugins': [ + [ + 'import', + { + 'libraryName': 'ant-design-vue', + 'libraryDirectory': 'es', + 'style': 'css' + } + ] + ] +} diff --git a/jeepay-ui-manager/package.json b/jeepay-ui-manager/package.json new file mode 100644 index 0000000..03ff463 --- /dev/null +++ b/jeepay-ui-manager/package.json @@ -0,0 +1,69 @@ +{ + "name": "jeepay-ui-manager", + "version": "1.0.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "test:unit": "vue-cli-service test:unit", + "lint": "vue-cli-service lint", + "build:preview": "vue-cli-service build --mode preview", + "lint:nofix": "vue-cli-service lint --no-fix" + }, + "dependencies": { + "@ant-design-vue/pro-layout": "^1.0.7", + "@antv/data-set": "^0.10.2", + "@antv/g2plot": "^2.3.21", + "@antv/util": "^2.0.13", + "ant-design-vue": "^1.7.2", + "axios": "^0.19.0", + "core-js": "^3.1.2", + "enquire.js": "^2.1.6", + "js-base64": "^2.5.2", + "lodash.clonedeep": "^4.5.0", + "lodash.get": "^4.4.2", + "lodash.pick": "^4.4.0", + "md5": "^2.2.1", + "mockjs2": "1.0.8", + "moment": "^2.24.0", + "nprogress": "^0.2.0", + "store": "^2.0.12", + "viser-vue": "^2.4.6", + "vue": "^2.6.10", + "vue-clipboard2": "^0.2.1", + "vue-cropper": "0.4.9", + "vue-i18n": "^8.17.4", + "vue-quill-editor": "^3.0.6", + "vue-router": "^3.1.2", + "vue-svg-component-runtime": "^1.0.1", + "vuex": "^3.1.1", + "wangeditor": "^3.1.1" + }, + "devDependencies": { + "@ant-design/colors": "^3.2.1", + "@vue/cli-plugin-babel": "^4.0.4", + "@vue/cli-plugin-eslint": "^4.0.4", + "@vue/cli-plugin-router": "^4.0.4", + "@vue/cli-plugin-unit-jest": "^4.0.4", + "@vue/cli-plugin-vuex": "^4.0.4", + "@vue/cli-service": "^4.0.4", + "@vue/eslint-config-standard": "^4.0.0", + "@vue/test-utils": "^1.0.0-beta.29", + "babel-eslint": "^10.0.1", + "babel-plugin-import": "^1.12.2", + "babel-plugin-transform-remove-console": "^6.9.4", + "eslint": "^5.16.0", + "eslint-plugin-html": "^5.0.0", + "eslint-plugin-vue": "^5.2.3", + "git-revision-webpack-plugin": "^3.0.6", + "less": "^3.0.4", + "less-loader": "^5.0.0", + "opencollective": "^1.0.3", + "opencollective-postinstall": "^2.0.2", + "style-resources-loader": "^1.4.1", + "vue-cli-plugin-style-resources-loader": "^0.1.5", + "vue-svg-icon-loader": "^2.1.1", + "vue-template-compiler": "^2.6.10", + "webpack-theme-color-replacer": "^1.3.12" + } +} diff --git a/jeepay-ui-manager/postcss.config.js b/jeepay-ui-manager/postcss.config.js new file mode 100644 index 0000000..961986e --- /dev/null +++ b/jeepay-ui-manager/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/jeepay-ui-manager/public/imgs/defava_f.png b/jeepay-ui-manager/public/imgs/defava_f.png new file mode 100644 index 0000000..5848989 Binary files /dev/null and b/jeepay-ui-manager/public/imgs/defava_f.png differ diff --git a/jeepay-ui-manager/public/imgs/defava_m.png b/jeepay-ui-manager/public/imgs/defava_m.png new file mode 100644 index 0000000..287ff9c Binary files /dev/null and b/jeepay-ui-manager/public/imgs/defava_m.png differ diff --git a/jeepay-ui-manager/public/imgs/favicon.ico b/jeepay-ui-manager/public/imgs/favicon.ico new file mode 100644 index 0000000..cdce95c Binary files /dev/null and b/jeepay-ui-manager/public/imgs/favicon.ico differ diff --git a/jeepay-ui-manager/public/imgs/logo.svg b/jeepay-ui-manager/public/imgs/logo.svg new file mode 100644 index 0000000..7e60317 --- /dev/null +++ b/jeepay-ui-manager/public/imgs/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/public/index.html b/jeepay-ui-manager/public/index.html new file mode 100644 index 0000000..f9da76f --- /dev/null +++ b/jeepay-ui-manager/public/index.html @@ -0,0 +1,36 @@ + + + + + + + + 运营平台 - Jeepay计全支付 + + + <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> + + <% } %> + + + +
+
+ <% { %> + + <% } %> +
+ +
+
计全科技
+
+
+ + <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> + + <% } %> + + + diff --git a/jeepay-ui-manager/src/App.vue b/jeepay-ui-manager/src/App.vue new file mode 100644 index 0000000..92650ff --- /dev/null +++ b/jeepay-ui-manager/src/App.vue @@ -0,0 +1,31 @@ + + + diff --git a/jeepay-ui-manager/src/api/login.js b/jeepay-ui-manager/src/api/login.js new file mode 100644 index 0000000..5831030 --- /dev/null +++ b/jeepay-ui-manager/src/api/login.js @@ -0,0 +1,35 @@ +import request from '@/http/request' +import { Base64 } from 'js-base64' + +// 登录认证接口 +export function login ({ username, password, vercode, vercodeToken }) { + const data = { + ia: Base64.encode(username), // 账号 + ip: Base64.encode(password), // 密码 + vc: Base64.encode(vercode), // 验证码值 + vt: Base64.encode(vercodeToken) // 验证码token + } + return request.request({ + url: '/api/anon/auth/validate', + method: 'post', + data: data + }, true, false, false) +} + +// 获取图形验证码信息接口 +export function vercode () { + return request.request({ url: '/api/anon/auth/vercode', method: 'get' }, true, true, true) +} + +// 获取当前用户信息 +export function getInfo () { + return request.request({ + url: '/api/current/user', + method: 'get' + }) +} + +// 退出接口 +export function logout () { + return new Promise(resolve => { resolve() }) +} diff --git a/jeepay-ui-manager/src/api/manage.js b/jeepay-ui-manager/src/api/manage.js new file mode 100644 index 0000000..62cb407 --- /dev/null +++ b/jeepay-ui-manager/src/api/manage.js @@ -0,0 +1,275 @@ +import request from '@/http/request' + +/* + * 全系列 restful api格式, 定义通用req对象 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +export const req = { + + // 通用列表查询接口 + list: (url, params) => { + return request.request({ url: url, method: 'GET', params: params }, true, true, false) + }, + + // 通用新增接口 + add: (url, data) => { + return request.request({ url: url, method: 'POST', data: data }, true, true, false) + }, + + // 通用查询单条数据接口 + getById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'GET' }, true, true, false) + }, + + // 通用修改接口 + updateById: (url, bizId, data) => { + return request.request({ url: url + '/' + bizId, method: 'PUT', data: data }, true, true, false) + }, + + // 通用删除接口 + delById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'DELETE' }, true, true, false) + } +} + +// 全系列 restful api格式 (全局loading方式) +export const reqLoad = { + + // 通用列表查询接口 + list: (url, params) => { + return request.request({ url: url, method: 'GET', params: params }, true, true, true) + }, + + // 通用新增接口 + add: (url, data) => { + return request.request({ url: url, method: 'POST', data: data }, true, true, true) + }, + + // 通用查询单条数据接口 + getById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'GET' }, true, true, true) + }, + + // 通用修改接口 + updateById: (url, bizId, data) => { + return request.request({ url: url + '/' + bizId, method: 'PUT', data: data }, true, true, true) + }, + + // 通用删除接口 + delById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'DELETE' }, true, true, true) + } +} + +/** 角色管理页面 **/ +export const API_URL_ENT_LIST = '/api/sysEnts' +export const API_URL_ROLE_LIST = '/api/sysRoles' +export const API_URL_ROLE_ENT_RELA_LIST = '/api/sysRoleEntRelas' +export const API_URL_SYS_USER_LIST = '/api/sysUsers' +export const API_URL_USER_ROLE_RELA_LIST = '/api/sysUserRoleRelas' + +/** 服务商、商户管理 **/ +export const API_URL_ISV_LIST = '/api/isvInfo' +export const API_URL_MCH_LIST = '/api/mchInfo' +/** 支付订单管理 **/ +export const API_URL_PAY_ORDER_LIST = '/api/payOrder' +/** 退款订单管理 **/ +export const API_URL_REFUND_ORDER_LIST = '/api/refundOrder' +/** 商户通知管理 **/ +export const API_URL_MCH_NOTIFY_LIST = '/api/mchNotify' +/** 系统日志 **/ +export const API_URL_SYS_LOG = 'api/sysLog' +/** 系统配置 **/ +export const API_URL_SYS_CONFIG = 'api/sysConfigs' +/** 首页统计 **/ +export const API_URL_MAIN_STATISTIC = 'api/mainChart' + +/** 支付接口定义页面 **/ +export const API_URL_IFDEFINES_LIST = '/api/payIfDefines' +export const API_URL_PAYWAYS_LIST = '/api/payWays' +/** 服务商、商户支付参数配置 **/ +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 upload = { + avatar: request.baseUrl + '/api/ossFiles/avatar', + ifBG: request.baseUrl + '/api/ossFiles/ifBG', + cert: request.baseUrl + '/api/ossFiles/cert' +} + +const api = { + user: '/user', + role_list: '/role', + service: '/service', + permission: '/permission', + permissionNoPager: '/permission/no-pager', + orgTree: '/org/tree' +} + +export default api + +/** 获取权限树状结构图 **/ +export function getEntTree (system) { + return request.request({ url: '/api/sysEnts/showTree?system=' + system, method: 'GET' }) +} + +/** 更新用户角色信息 */ +export function uSysUserRoleRela (sysUserId, roleIdList) { + return request.request({ + url: 'api/sysUserRoleRelas/relas/' + sysUserId, + method: 'POST', + data: { roleIdListStr: JSON.stringify(roleIdList) } + }) +} + +export function getRoleList (parameter) { + return request({ + url: '/api/sysRoles', + method: 'get', + params: parameter + }) +} + +export function getServiceList (parameter) { + return request({ + url: api.service, + method: 'get', + params: parameter + }) +} + +export function getPermissions (parameter) { + return request({ + url: api.permissionNoPager, + method: 'get', + params: parameter + }) +} + +export function getOrgTree (parameter) { + return request({ + url: api.orgTree, + method: 'get', + params: parameter + }) +} + +// id == 0 add post +// id != 0 update put +export function saveService (parameter) { + return request({ + url: api.service, + method: parameter.id === 0 ? 'post' : 'put', + data: parameter + }) +} + +export function saveSub (sub) { + return request({ + url: '/sub', + method: sub.id === 0 ? 'post' : 'put', + data: sub + }) +} + +export function getIsvPayConfigUnique (infoId, ifCode) { + return request.request({ + url: '/api/isv/payConfigs/' + infoId + '/' + ifCode, + method: 'get' + }) +} + +export function getMcgPayConfigUnique (infoId, ifCode) { + return request.request({ + url: '/api/mch/payConfigs/' + infoId + '/' + ifCode, + method: 'get' + }) +} + +export function getAvailablePayInterfaceList (mchNo, wayCode) { + return request.request({ + url: '/api/mch/payPassages/availablePayInterface/' + mchNo + '/' + wayCode, + method: 'GET' + }) +} + +export function getPayAmountWeek () { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/payAmountWeek', + method: 'GET' + }) +} + +export function getNumCount () { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/numCount', + method: 'GET' + }) +} + +export function getPayCount (parameter) { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/payCount', + method: 'GET', + params: parameter + }) +} + +export function getPayType (parameter) { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/payTypeCount', + method: 'GET', + params: parameter + }) +} + +export function getMainUserInfo (parameter) { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/' + parameter, + method: 'GET' + }) +} + +export function updateUserPass (parameter) { + return request.request({ + url: '/api/current/modifyPwd', + method: 'put', + data: parameter + }) +} + +export function updateUserInfo (parameter) { + return request.request({ + url: '/api/current/user', + method: 'put', + data: parameter + }) +} + +export function getUserInfo () { + return request.request({ + url: '/api/current/user', + method: 'get' + }) +} + +export function getConfigs (parameter) { + return request.request({ + url: API_URL_SYS_CONFIG + '/' + parameter, + method: 'GET' + }) +} + +export function getEntBySystem (entId, system) { + return request.request({ + url: '/api/sysEnts/bySystem', + method: 'GET', + params: { entId: entId, system: system } + }) +} diff --git a/jeepay-ui-manager/src/assets/logo-j.svg b/jeepay-ui-manager/src/assets/logo-j.svg new file mode 100644 index 0000000..ac7edf7 --- /dev/null +++ b/jeepay-ui-manager/src/assets/logo-j.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/jeepay-ui-manager/src/assets/logo.svg b/jeepay-ui-manager/src/assets/logo.svg new file mode 100644 index 0000000..7e60317 --- /dev/null +++ b/jeepay-ui-manager/src/assets/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/styles/color.css b/jeepay-ui-manager/src/assets/styles/color.css new file mode 100644 index 0000000..e69de29 diff --git a/jeepay-ui-manager/src/assets/styles/color.less b/jeepay-ui-manager/src/assets/styles/color.less new file mode 100644 index 0000000..786843e --- /dev/null +++ b/jeepay-ui-manager/src/assets/styles/color.less @@ -0,0 +1,17 @@ +@jee-theme: #1A53FF; //主题色 + +@jee-back: #F0F2F5; //主要背景色 + +@jee-card-back: #FFF; //卡片底色 + +@jee-theme-mask: rgba(26,83,255,0.1); //主体遮罩色(10% 透明度) + +@jee-strengthen: #596380; //强化色 + +@jee-theme-hover: #0033CC; //主题Hover + +@jee-warning: #FF4B33; //危险,强化警告色 + +@jee-inside-link: #1A79FF; //内部链接 + +@jee-external-link: #AE1B6E; //外部链接 diff --git a/jeepay-ui-manager/src/assets/svg/403.svg b/jeepay-ui-manager/src/assets/svg/403.svg new file mode 100644 index 0000000..c552ca6 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/403.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/404.svg b/jeepay-ui-manager/src/assets/svg/404.svg new file mode 100644 index 0000000..3854e5b --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/404.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/500.svg b/jeepay-ui-manager/src/assets/svg/500.svg new file mode 100644 index 0000000..ffa8b08 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/500.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/add-icon-hover.svg b/jeepay-ui-manager/src/assets/svg/add-icon-hover.svg new file mode 100644 index 0000000..ec8469e --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/add-icon-hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/add-icon.svg b/jeepay-ui-manager/src/assets/svg/add-icon.svg new file mode 100644 index 0000000..6f167ab --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/add-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/background.svg b/jeepay-ui-manager/src/assets/svg/background.svg new file mode 100644 index 0000000..6fcadcc --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/background.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/backgroundold.svg b/jeepay-ui-manager/src/assets/svg/backgroundold.svg new file mode 100644 index 0000000..89c2597 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/backgroundold.svg @@ -0,0 +1,69 @@ + + + + Group 21 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/code.svg b/jeepay-ui-manager/src/assets/svg/code.svg new file mode 100644 index 0000000..5f9154e --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/empty.svg b/jeepay-ui-manager/src/assets/svg/empty.svg new file mode 100644 index 0000000..757aaa2 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/jeepay.svg b/jeepay-ui-manager/src/assets/svg/jeepay.svg new file mode 100644 index 0000000..2acc4c6 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/jeepay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/lock.svg b/jeepay-ui-manager/src/assets/svg/lock.svg new file mode 100644 index 0000000..e16119f --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/mini-logo.svg b/jeepay-ui-manager/src/assets/svg/mini-logo.svg new file mode 100644 index 0000000..47e17a2 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/mini-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/more.svg b/jeepay-ui-manager/src/assets/svg/more.svg new file mode 100644 index 0000000..558442e --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/more.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/operate.svg b/jeepay-ui-manager/src/assets/svg/operate.svg new file mode 100644 index 0000000..ba110c8 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/operate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/scroll_down.svg b/jeepay-ui-manager/src/assets/svg/scroll_down.svg new file mode 100644 index 0000000..f8288fe --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/scroll_down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/scroll_left.svg b/jeepay-ui-manager/src/assets/svg/scroll_left.svg new file mode 100644 index 0000000..ca7632e --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/scroll_left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/scroll_right.svg b/jeepay-ui-manager/src/assets/svg/scroll_right.svg new file mode 100644 index 0000000..222198f --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/scroll_right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/scroll_up.svg b/jeepay-ui-manager/src/assets/svg/scroll_up.svg new file mode 100644 index 0000000..6f84cdd --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/scroll_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/select-code.svg b/jeepay-ui-manager/src/assets/svg/select-code.svg new file mode 100644 index 0000000..8d9ad51 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/select-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/select-lock.svg b/jeepay-ui-manager/src/assets/svg/select-lock.svg new file mode 100644 index 0000000..d2771b0 --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/select-lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/select-user.svg b/jeepay-ui-manager/src/assets/svg/select-user.svg new file mode 100644 index 0000000..1f3338a --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/select-user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/assets/svg/user.svg b/jeepay-ui-manager/src/assets/svg/user.svg new file mode 100644 index 0000000..738fd9d --- /dev/null +++ b/jeepay-ui-manager/src/assets/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-manager/src/components/GlobalFooter/index.vue b/jeepay-ui-manager/src/components/GlobalFooter/index.vue new file mode 100644 index 0000000..59caf52 --- /dev/null +++ b/jeepay-ui-manager/src/components/GlobalFooter/index.vue @@ -0,0 +1,20 @@ + + + diff --git a/jeepay-ui-manager/src/components/GlobalHeader/AvatarDropdown.vue b/jeepay-ui-manager/src/components/GlobalHeader/AvatarDropdown.vue new file mode 100644 index 0000000..bb1a52c --- /dev/null +++ b/jeepay-ui-manager/src/components/GlobalHeader/AvatarDropdown.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/jeepay-ui-manager/src/components/GlobalHeader/RightContent.vue b/jeepay-ui-manager/src/components/GlobalHeader/RightContent.vue new file mode 100644 index 0000000..36d2be8 --- /dev/null +++ b/jeepay-ui-manager/src/components/GlobalHeader/RightContent.vue @@ -0,0 +1,55 @@ + + + diff --git a/jeepay-ui-manager/src/components/GlobalLoad/GlobalLoad.vue b/jeepay-ui-manager/src/components/GlobalLoad/GlobalLoad.vue new file mode 100644 index 0000000..b984a98 --- /dev/null +++ b/jeepay-ui-manager/src/components/GlobalLoad/GlobalLoad.vue @@ -0,0 +1,30 @@ + + + diff --git a/jeepay-ui-manager/src/components/JeepayCard/JeepayCard.vue b/jeepay-ui-manager/src/components/JeepayCard/JeepayCard.vue new file mode 100644 index 0000000..0b68dc4 --- /dev/null +++ b/jeepay-ui-manager/src/components/JeepayCard/JeepayCard.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/jeepay-ui-manager/src/components/JeepayTable/JeepayTable.vue b/jeepay-ui-manager/src/components/JeepayTable/JeepayTable.vue new file mode 100644 index 0000000..e828a26 --- /dev/null +++ b/jeepay-ui-manager/src/components/JeepayTable/JeepayTable.vue @@ -0,0 +1,119 @@ + + + diff --git a/jeepay-ui-manager/src/components/JeepayTable/JeepayTableColState.vue b/jeepay-ui-manager/src/components/JeepayTable/JeepayTableColState.vue new file mode 100644 index 0000000..e240209 --- /dev/null +++ b/jeepay-ui-manager/src/components/JeepayTable/JeepayTableColState.vue @@ -0,0 +1,57 @@ + + + + diff --git a/jeepay-ui-manager/src/components/JeepayTable/JeepayTableColumns.vue b/jeepay-ui-manager/src/components/JeepayTable/JeepayTableColumns.vue new file mode 100644 index 0000000..b52cc8e --- /dev/null +++ b/jeepay-ui-manager/src/components/JeepayTable/JeepayTableColumns.vue @@ -0,0 +1,43 @@ + + + diff --git a/jeepay-ui-manager/src/components/JeepayTextUp/JeepayTextUp.vue b/jeepay-ui-manager/src/components/JeepayTextUp/JeepayTextUp.vue new file mode 100644 index 0000000..a754e63 --- /dev/null +++ b/jeepay-ui-manager/src/components/JeepayTextUp/JeepayTextUp.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/jeepay-ui-manager/src/components/JeepayUpload/JeepayUpload.vue b/jeepay-ui-manager/src/components/JeepayUpload/JeepayUpload.vue new file mode 100644 index 0000000..e3216a8 --- /dev/null +++ b/jeepay-ui-manager/src/components/JeepayUpload/JeepayUpload.vue @@ -0,0 +1,86 @@ + + + diff --git a/jeepay-ui-manager/src/components/NProgress/nprogress.less b/jeepay-ui-manager/src/components/NProgress/nprogress.less new file mode 100644 index 0000000..13b40aa --- /dev/null +++ b/jeepay-ui-manager/src/components/NProgress/nprogress.less @@ -0,0 +1,74 @@ +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: @primary-color; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 2px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color; + opacity: 1.0; + + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: @primary-color; + border-left-color: @primary-color; + border-radius: 50%; + + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} +@keyframes nprogress-spinner { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + diff --git a/jeepay-ui-manager/src/config/appConfig.js b/jeepay-ui-manager/src/config/appConfig.js new file mode 100644 index 0000000..8e36138 --- /dev/null +++ b/jeepay-ui-manager/src/config/appConfig.js @@ -0,0 +1,36 @@ +/** + * 全局配置信息, 包含网站标题, 动态组件定义 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ + +/** 应用配置项 **/ +export default { + APP_TITLE: 'Jeepay运营平台', // 设置浏览器title + ACCESS_TOKEN_NAME: 'iToken' // 设置请求token的名字, 用于请求header 和 localstorage中存在名称 +} + +/** + * 与后端开发人员的路由名称及配置项 + * 组件名称 :{ 默认跳转路径(如果后端配置则已动态配置为准), 组件渲染 } + * */ +export const asyncRouteDefine = { + + 'CurrentUserInfo': { defaultPath: '/current/userinfo', component: () => import('@/views/current/UserinfoPage') }, // 用户设置 + + 'MainPage': { defaultPath: '/main', component: () => import('@/views/dashboard/Analysis') }, + 'SysUserPage': { defaultPath: '/users', component: () => import('@/views/sysuser/SysUserPage') }, + 'RolePage': { defaultPath: '/roles', component: () => import('@/views/role/RolePage') }, + 'EntPage': { defaultPath: '/ents', component: () => import('@/views/ent/EntPage') }, + 'PayWayPage': { defaultPath: '/payways', component: () => import('@/views/payconfig/payWay/List') }, + 'IfDefinePage': { defaultPath: '/ifdefines', component: () => import('@/views/payconfig/payIfDefine/List') }, + 'IsvListPage': { defaultPath: '/isv', component: () => import('@/views/isv/IsvList') }, // 服务商列表 + 'MchListPage': { defaultPath: '/mch', component: () => import('@/views/mch/MchList') }, // 商户列表 + 'PayOrderListPage': { defaultPath: '/payOrder', component: () => import('@/views/order/pay/PayOrderList') }, // 支付订单列表 + 'RefundOrderListPage': { defaultPath: '/refundOrder', component: () => import('@/views/order/refund/RefundOrderList') }, // 退款订单列表 + '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') } // 系统日志 +} diff --git a/jeepay-ui-manager/src/core/bootstrap.js b/jeepay-ui-manager/src/core/bootstrap.js new file mode 100644 index 0000000..077c21d --- /dev/null +++ b/jeepay-ui-manager/src/core/bootstrap.js @@ -0,0 +1,5 @@ +import { printANSI } from '@/utils/screenLog' + +export default function Initializer () { + printANSI() // 请自行移除该行. please remove this line +} diff --git a/jeepay-ui-manager/src/core/lazy_use.js b/jeepay-ui-manager/src/core/lazy_use.js new file mode 100644 index 0000000..e49fa11 --- /dev/null +++ b/jeepay-ui-manager/src/core/lazy_use.js @@ -0,0 +1,115 @@ +import Vue from 'vue' + +// base library +import { + ConfigProvider, + Layout, + Input, + InputNumber, + Button, + Switch, + Radio, + Checkbox, + Select, + Card, + Form, + FormModel, + Row, + Col, + Modal, + Table, + Tabs, + Icon, + Badge, + Popover, + Dropdown, + List, + Avatar, + Breadcrumb, + Steps, + Spin, + Menu, + Drawer, + Tooltip, + Alert, + Tag, + Divider, + DatePicker, + TimePicker, + Upload, + Progress, + Skeleton, + Popconfirm, + PageHeader, + Result, + Statistic, + Descriptions, + Space, + Pagination, + message, + notification, + Tree +} from 'ant-design-vue' +import Viser from 'viser-vue' + +// ext library +import VueCropper from 'vue-cropper' + +Vue.use(ConfigProvider) +Vue.use(Layout) +Vue.use(Input) +Vue.use(InputNumber) +Vue.use(Button) +Vue.use(Switch) +Vue.use(Radio) +Vue.use(Checkbox) +Vue.use(Select) +Vue.use(Card) +Vue.use(Form) +Vue.use(FormModel) +Vue.use(Row) +Vue.use(Col) +Vue.use(Modal) +Vue.use(Table) +Vue.use(Tabs) +Vue.use(Icon) +Vue.use(Badge) +Vue.use(Popover) +Vue.use(Dropdown) +Vue.use(List) +Vue.use(Avatar) +Vue.use(Breadcrumb) +Vue.use(Steps) +Vue.use(Spin) +Vue.use(Menu) +Vue.use(Drawer) +Vue.use(Tooltip) +Vue.use(Alert) +Vue.use(Tag) +Vue.use(Divider) +Vue.use(DatePicker) +Vue.use(TimePicker) +Vue.use(Upload) +Vue.use(Progress) +Vue.use(Skeleton) +Vue.use(Popconfirm) +Vue.use(PageHeader) +Vue.use(Result) +Vue.use(Statistic) +Vue.use(Descriptions) +Vue.use(Space) +Vue.use(Pagination) +Vue.use(Tree) + +Vue.prototype.$confirm = Modal.confirm +Vue.prototype.$message = message +Vue.prototype.$notification = notification +Vue.prototype.$info = Modal.info +Vue.prototype.$success = Modal.success +Vue.prototype.$error = Modal.error +Vue.prototype.$warning = Modal.warning + +Vue.use(Viser) +Vue.use(VueCropper) + +process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] NOTICE: Antd use lazy-load.') diff --git a/jeepay-ui-manager/src/core/use.js b/jeepay-ui-manager/src/core/use.js new file mode 100644 index 0000000..f332c6f --- /dev/null +++ b/jeepay-ui-manager/src/core/use.js @@ -0,0 +1,20 @@ +import Vue from 'vue' + +// base library +import Antd from 'ant-design-vue' +import Viser from 'viser-vue' +import VueCropper from 'vue-cropper' +import 'ant-design-vue/dist/antd.less' + +// ext library +import VueClipboard from 'vue-clipboard2' +import './directives/action' + +VueClipboard.config.autoSetContainer = true + +Vue.use(Antd) +Vue.use(Viser) +Vue.use(VueClipboard) +Vue.use(VueCropper) + +process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] WARNING: Antd now use fulled imported.') diff --git a/jeepay-ui-manager/src/global.less b/jeepay-ui-manager/src/global.less new file mode 100644 index 0000000..d9ad49a --- /dev/null +++ b/jeepay-ui-manager/src/global.less @@ -0,0 +1,372 @@ +@import '../node_modules/ant-design-vue/es/style/themes/default.less'; +// @import './default.less'; + +html, +body, +#app, #root { + height: 100%; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,PingFang SC,Hiragino Sans GB,Helvetica Neue,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; + letter-spacing: 0.4px; +} +// jee主题颜色class列表, 用于文字颜色 +.jee-theme { + color: @jee-theme; //主题色 +} +.jee-back { + color: @jee-back; //主要背景色 +} +.jee-card-back { + color: @jee-card-back; //卡片底色 +} +.jee-theme-mask { + color: @jee-theme-mask; //主体遮罩色(10% 透明度) +} +.jee-strengthen { + color: @jee-strengthen;//强化色 +} +.jee-theme-hover { + color: @jee-theme-hover;//主题Hover +} +.jee-warning { + color: @jee-warning; //危险,强化警告色 +} +.jee-inside-link { + color: @jee-inside-link; //内部链接 +} +.jee-external-link { + color: @jee-external-link; //外部链接 +} +// jee主题颜色class列表, 用于文字颜色 +.jee-theme { + color: @jee-theme; //主题色 +} +.jee-back { + color: @jee-back; //主要背景色 +} +.jee-card-back { + color: @jee-card-back; //卡片底色 +} +.jee-theme-mask { + color: @jee-theme-mask; //主体遮罩色(10% 透明度) +} +.jee-strengthen { + color: @jee-strengthen;//强化色 +} +.jee-theme-hover { + color: @jee-theme-hover;//主题Hover +} +.jee-warning { + color: @jee-warning; //危险,强化警告色 +} +.jee-inside-link { + color: @jee-inside-link; //内部链接 +} +.jee-external-link { + color: @jee-external-link; //外部链接 +} + +// jee主题颜色class列表, 用于背景颜色 +.jee-theme-back-color { + background-color: @jee-theme; //主题色 +} +.jee-back-color { + background-color: @jee-back; //主要背景色 +} +.jee-card-back-color { + background-color: @jee-card-back; //卡片底色 +} +.jee-theme-mask-back-color { + background-color: @jee-theme-mask; //主体遮罩色(10% 透明度) +} +.jee-strengthen-back-color { + background-color: @jee-strengthen;//强化色 +} +.jee-theme-hover-back-color { + background-color: @jee-theme-hover;//主题Hover +} +.jee-warning-back-color { + background-color: @jee-warning; //危险,强化警告色 +} +.jee-inside-link-back-color { + background-color: @jee-inside-link; //内部链接 +} +.jee-external-link-back-color { + background-color: @jee-external-link; //外部链接 +} + +.colorWeak { + filter: invert(80%); +} + +.ant-layout{ + .layout-basic { + height: 100vh; + min-height: 100vh; + } +} + +canvas { + display: block; +} + +body { + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background: #f0f2f5; +} + +ul, ol { + list-style: none; +} +// 滚动条高度 和宽度 +::-webkit-scrollbar { + width: 10px; + height: 10px; +} +// 滚动条颜色 +::-webkit-scrollbar-thumb { + background: #B3B3B3; +} +// 滑块区域底色 +::-webkit-scrollbar-track { + background: rgba(0, 0, 0, 0.03) +} +// 滚动条hover色 +::-webkit-scrollbar-thumb:hover { + background: #A6A6A6; +} +// 滚动条选中色 +::-webkit-scrollbar-thumb:active { + background: #8C8C8C; +} +// 结合 表格组件中的 :scroll ,让表格在收缩时,展示滚动条 +.ant-table-body{ + overflow-x: auto !important; +} +// /*显示滚动条上方以及下方的渐增按钮*/ +// ::-webkit-scrollbar-button:start:decrement, +// ::-webkit-scrollbar-button:end:increment { +// display: block; +// } +// /* 定义垂直滚动条渐增按扭的样式 */ +// ::-webkit-scrollbar-button:vertical:end:increment { +// background-image: url(~@/assets/svg/scroll_down.svg); +// background-size: cover; +// background-position: center; +// } +// /* 定义垂直滚动条渐减按扭的样式 */ +// ::-webkit-scrollbar-button:vertical:start:decrement { +// background-image: url(~@/assets/svg/scroll_up.svg); +// background-size: cover; +// background-position: center; +// } +// /* 定义水平滚动条渐增按扭的样式 */ +// ::-webkit-scrollbar-button:horizontal:end:increment { +// background-image: url(~@/assets/svg/scroll_right.svg); +// background-size: cover; +// background-position: center; +// } +// /* 定义水平滚动条渐减按扭的样式 */ +// ::-webkit-scrollbar-button:horizontal:start:decrement { +// background-image: url(~@/assets/svg/scroll_left.svg); +// background-size: cover; +// background-position: center; +// } + +// 隐藏面包屑底下的标题 +.ant-page-header-heading { + display: none; +} + +// 数据列表 样式 +.table-alert { + margin-bottom: 16px; +} +// 数据列表 操作 +.table-operator { + margin-bottom: 18px; + + button { + margin-right: 8px; + } +} +// 数据列表 搜索条件 +.table-page-search-wrapper { + border-top-left-radius: 10px; + border-top-right-radius: 10px; + padding: 30px; + padding-bottom: 0; + border-bottom: 1px solid #e8e8e8; + background: #fafafa; + + .ant-form-inline { + .ant-form-item { + display: flex; + // margin-bottom: 24px; + margin-right: 0; + + .ant-form-item-control-wrapper { + flex: 1 1; + display: inline-block; + vertical-align: middle; + } + + > .ant-form-item-label { + line-height: 32px; + padding-right: 8px; + width: auto; + } + .ant-form-item-control { + height: 32px; + line-height: 32px; + } + } + } + + .table-page-search-submitButtons { + display: block; + margin-bottom: 24px; + white-space: nowrap; + } +} + +@media (max-width: @screen-xs) { + .ant-table { + width: 100%; + overflow-x: auto; + &-thead > tr, + &-tbody > tr { + > th, + > td { + white-space: pre; + > span { + display: block; + } + } + } + } +} + +// 修改侧边栏宽度为230 +.ant-pro-sider-menu-sider { + // min-width: 80px !important; + // max-width: 230px !important; + + // 去掉侧边栏阴影 + .light { + box-shadow: none; + } +} + +// 删除表格的内边距 +.ant-card-body { + padding: 0 !important; +} +// 增加内容区域的边框圆角 +.ant-card { + border-radius: 10px; + overflow: hidden; +} + +// 登录页输入框fcous hover事件,边框为jee主题蓝 +.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled) { + border-color: @jee-theme +} +.ant-input:focus { + border-color: @jee-theme +} + +// 抽屉,按钮板块,居中 +.drawer-btn-center { + position: absolute; + right: 0px; + bottom: 0px; + width: 100%; + border-top: 1px solid rgb(233, 233, 233); + padding: 10px 16px; + background: rgb(255, 255, 255); + text-align: center; + z-index: 1; + + &:first-child { + margin-right: 80px; + } + button { + margin: 0; + padding: 3px 20px; + } +} + +.els { + overflow: hidden; + text-overflow:ellipsis; + white-space: nowrap +} + +// 内容区域去掉最外层的magin 24px ,改为 padding 15px +.ant-pro-basicLayout-content { + margin: 0 ; + padding: 15px; +} + +// 表格页面的间距 +.ant-table-pagination.ant-pagination { + margin: 20px; +} + +// 去掉表格边框线 +.ant-card-bordered { + border:none !important; +} + +.ant-table-align-left { + padding-left: 38px; +} +// 向下的30外边距 +.mg-b-30 { + margin-bottom: 30px +} + +// 表格,搜索框板块布局 +.table-head-ground { + display: flex; + justify-content: start; + flex-wrap: wrap; + .table-layer { + display: flex; + flex-wrap: wrap; + flex-grow: 1; + flex-shrink: 1; + } +} +.table-head-layout { + min-width: 220px; + max-width: 240px; + flex-grow: 1; + flex-shrink: 1; + margin-bottom:30px !important; + margin-right: 16px !important; +} + + +// 404 500 403 +.result-err { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; + width: 100%; + overflow: auto; + div { + margin: 20px 0; + text-align:center; + font-size: 16px; + p.big-text { + font-size: 36px; + font-weight: 700; + } + } + +} \ No newline at end of file diff --git a/jeepay-ui-manager/src/http/HttpRequest.js b/jeepay-ui-manager/src/http/HttpRequest.js new file mode 100644 index 0000000..e391b3a --- /dev/null +++ b/jeepay-ui-manager/src/http/HttpRequest.js @@ -0,0 +1,117 @@ +/** + * Http请求包装对象 + * 参考: iview https://gitee.com/icarusion/iview-admin/blob/master/src/libs/axios.js + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ + +import axios from 'axios' +import storage from '@/utils/jeepayStorageWrapper' +import appConfig from '@/config/appConfig' +import { Vue } from 'vue' +import store from '@/store/index' +class HttpRequest { + constructor (baseUrl = process.env.VUE_APP_API_BASE_URL) { + this.baseUrl = baseUrl + this.queue = {} // 发送队列, 格式为: {请求url: true}, 可以做一些验证之类 + } + // 基础配置信息 + baseConfig () { + const headers = {} + headers[appConfig.ACCESS_TOKEN_NAME] = storage.getToken() + return { + baseURL: this.baseUrl, + headers: headers + } + } + destroy (url, showLoading) { + delete this.queue[url] + } + interceptors (instance, url, showErrorMsg, showLoading) { + // 请求拦截 + instance.interceptors.request.use(config => { + // 添加全局的loading... + if (!Object.keys(this.queue).length && showLoading) { + store.commit('showLoading') // 加载中显示loading组件 + } + this.queue[url] = true + return config + }, error => { + store.commit('hideLoading') // 报错关闭loading组件 + return Promise.reject(error) + }) + + // 响应拦截 + instance.interceptors.response.use(res => { + this.destroy(url, showLoading) + + if (showLoading) { + store.commit('hideLoading') // 报错关闭loading组件 + } + + const resData = res.data // 接口实际返回数据 格式为:{code: '', msg: '', data: ''}, res.data 是axios封装对象的返回数据; + + if (resData.code !== 0) { // 相应结果不为0, 说明异常 + if (showErrorMsg) { + Vue.prototype.$message.error(resData.msg) // 显示异常信息 + } + + return Promise.reject(resData) + } else { + return resData.data + } + }, error => { + this.destroy(url, showLoading) + + if (showLoading) { + store.commit('hideLoading') // 报错关闭loading组件 + } + + let errorInfo = error.response && error.response.data && error.response.data.data + if (!errorInfo) { + errorInfo = error.response.data + } + + if (error.response.status === 401) { // 无访问权限,会话超时, 提示用户信息 & 退出系统 + const toLoginTimeout = setTimeout(function () { + store.dispatch('Logout').then(() => { + window.location.reload() + }) + }, 3000) + + Vue.prototype.$infoBox.confirmDanger( + '会话超时,请重新登录', '3s后将自动退出...', + () => { + store.dispatch('Logout').then(() => { + window.location.reload() + }) + }, + () => { + clearTimeout(toLoginTimeout) + }, + { okText: '重新登录', cancelText: '关闭对话' }) + } else { + if (showErrorMsg) { + Vue.prototype.$message.error(JSON.stringify(errorInfo)) // 显示异常信息 + } + } + + return Promise.reject(errorInfo) + }) + } + // interceptorsFlag: 是否进行自定义拦截器处理,默认为: true + // showErrorMsg 发送请求出现异常是否全局提示错误信息 + // showLoading 发送请求前后显示全局loading + request (options, interceptorsFlag = true, showErrorMsg = true, showLoading = false) { + const instance = axios.create() + options = Object.assign(this.baseConfig(), options) + if (interceptorsFlag) { // 注入 req, respo 拦截器 + this.interceptors(instance, options.url, showErrorMsg, showLoading) + } + + return instance(options) + } +} +export default HttpRequest diff --git a/jeepay-ui-manager/src/http/request.js b/jeepay-ui-manager/src/http/request.js new file mode 100644 index 0000000..7b66cad --- /dev/null +++ b/jeepay-ui-manager/src/http/request.js @@ -0,0 +1,4 @@ +import HttpRequest from '@/http/HttpRequest' + +const request = new HttpRequest() +export default request diff --git a/jeepay-ui-manager/src/layouts/BasicLayout.less b/jeepay-ui-manager/src/layouts/BasicLayout.less new file mode 100644 index 0000000..d193ad1 --- /dev/null +++ b/jeepay-ui-manager/src/layouts/BasicLayout.less @@ -0,0 +1,59 @@ +@import "~ant-design-vue/es/style/themes/default.less"; + +// 清除头部栏下方阴影 +.ant-layout-header, .ant-pro-basicLayout .ant-layout-header:not(.ant-pro-top-menu) { + background: initial; +} +// 清除头部栏下方阴影 修改背景色 +.ant-pro-global-header { + background: initial; + box-shadow: initial; +} +// 面包屑导航部分 修改背景色 +.ant-pro-page-header-wrap-page-header-warp { + background: initial; +} + +//左上角 logo 图标样式 +.ant-pro-sider-menu-logo { + padding-left: 30px; +} +.ant-pro-sider-menu-logo svg { + height: 26px; + width: initial; +} + +.ant-pro-global-header-index-right { + margin-right: 8px; + + &.ant-pro-global-header-index-dark { + .ant-pro-global-header-index-action { + color: hsla(0, 0%, 100%, .85); + + &:hover { + background: #1890ff; + } + } + } + + .ant-pro-account-avatar { + .antd-pro-global-header-index-avatar { + margin: ~'calc((@{layout-header-height} - 24px) / 2)' 0; + margin-right: 8px; + color: @primary-color; + vertical-align: top; + background: rgba(255, 255, 255, 0.85); + } + } + + .menu { + .anticon { + margin-right: 8px; + } + + .ant-dropdown-menu-item { + min-width: 100px; + } + } +} + diff --git a/jeepay-ui-manager/src/layouts/BasicLayout.vue b/jeepay-ui-manager/src/layouts/BasicLayout.vue new file mode 100644 index 0000000..6bacdf4 --- /dev/null +++ b/jeepay-ui-manager/src/layouts/BasicLayout.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/jeepay-ui-manager/src/layouts/BlankLayout.vue b/jeepay-ui-manager/src/layouts/BlankLayout.vue new file mode 100644 index 0000000..1bfbfbf --- /dev/null +++ b/jeepay-ui-manager/src/layouts/BlankLayout.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/jeepay-ui-manager/src/layouts/PageView.vue b/jeepay-ui-manager/src/layouts/PageView.vue new file mode 100644 index 0000000..86df485 --- /dev/null +++ b/jeepay-ui-manager/src/layouts/PageView.vue @@ -0,0 +1,12 @@ + + + diff --git a/jeepay-ui-manager/src/layouts/RouteView.vue b/jeepay-ui-manager/src/layouts/RouteView.vue new file mode 100644 index 0000000..984e2a8 --- /dev/null +++ b/jeepay-ui-manager/src/layouts/RouteView.vue @@ -0,0 +1,32 @@ + diff --git a/jeepay-ui-manager/src/layouts/UserLayout.vue b/jeepay-ui-manager/src/layouts/UserLayout.vue new file mode 100644 index 0000000..5c5b652 --- /dev/null +++ b/jeepay-ui-manager/src/layouts/UserLayout.vue @@ -0,0 +1,179 @@ + + + + + diff --git a/jeepay-ui-manager/src/layouts/index.js b/jeepay-ui-manager/src/layouts/index.js new file mode 100644 index 0000000..1d62d6c --- /dev/null +++ b/jeepay-ui-manager/src/layouts/index.js @@ -0,0 +1,7 @@ +import UserLayout from './UserLayout' +import BlankLayout from './BlankLayout' +import BasicLayout from './BasicLayout' +import RouteView from './RouteView' +import PageView from './PageView' + +export { UserLayout, BasicLayout, BlankLayout, RouteView, PageView } diff --git a/jeepay-ui-manager/src/main.js b/jeepay-ui-manager/src/main.js new file mode 100644 index 0000000..04642c0 --- /dev/null +++ b/jeepay-ui-manager/src/main.js @@ -0,0 +1,43 @@ +// with polyfills +import 'core-js/stable' +import 'regenerator-runtime/runtime' + +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import store from './store/' +import ProLayout, { PageHeaderWrapper } from '@ant-design-vue/pro-layout' + +import bootstrap from './core/bootstrap' +import './core/lazy_use' // use lazy load components +import './permission' // permission control 路由守卫 +import './utils/filter' // global filter +import './global.less' // global style +import 'ant-design-vue/dist/antd.less' +import infoBox from '@/utils/infoBox' + +Vue.config.productionTip = false + +// mount axios to `Vue.$http` and `this.$http` +// use pro-layout components +Vue.component('pro-layout', ProLayout) +Vue.component('page-container', PageHeaderWrapper) +Vue.component('page-header-wrapper', PageHeaderWrapper) + +/** + * @description 全局注册权限验证 + */ +Vue.prototype.$access = (entId) => { + // eslint-disable-next-line eqeqeq + return store.state.user.accessList.some(item => item == entId) +} + +Vue.prototype.$infoBox = infoBox + +new Vue({ + router, + store, + // init localstorage, vuex + created: bootstrap, + render: h => h(App) +}).$mount('#app') diff --git a/jeepay-ui-manager/src/permission.js b/jeepay-ui-manager/src/permission.js new file mode 100644 index 0000000..aec7379 --- /dev/null +++ b/jeepay-ui-manager/src/permission.js @@ -0,0 +1,63 @@ +import router from './router' +import store from './store' +import storage from '@/utils/jeepayStorageWrapper' +import NProgress from 'nprogress' // progress bar +import '@/components/NProgress/nprogress.less' // progress bar custom style +import { setDocumentTitle } from '@/utils/domUtil' +import { getInfo } from '@/api/login' +import appConfig from '@/config/appConfig' + +NProgress.configure({ showSpinner: false }) // NProgress Configuration + +const allowList = ['login', 'register', 'registerResult'] // no redirect allowList +const loginRoutePath = '/user/login' + +// 路由守卫 +router.beforeEach((to, from, next) => { + NProgress.start() // start progress bar + + to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${appConfig.APP_TITLE}`)) // 设置浏览器标题 + + // 如果在免登录页面则直接放行 + if (allowList.includes(to.name)) { + // 在免登录名单,直接进入 + next() + NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it + return false + } + + // 不包含Token 则直接跳转到登录页面 + if (!storage.getToken()) { + next({ path: loginRoutePath, query: { redirect: to.fullPath } }) + NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it + return false + } + + // 以下为包含Token的情况 + // 如果用户信息不存在, 则重新获取 [用户登录成功 & 强制刷新浏览器时 会执行该函数] + if (!store.state.user.userId) { + // request login userInfo + + getInfo().then(bizData => { + store.commit('SET_USER_INFO', bizData) // 调用vuex设置用户基本信息 + + // 动态添加路由 + store.dispatch('GenerateRoutes', {}).then(() => { + router.addRoutes(store.state.asyncRouter.addRouters) + }) + + next() + }).catch(() => { + // 失败时,获取用户信息失败时,调用登出,来清空历史保留信息 + store.dispatch('Logout').then(() => { + next({ path: loginRoutePath, query: { redirect: to.fullPath } }) + }) + }) + } else { + next() + } +}) + +router.afterEach(() => { + NProgress.done() // finish progress bar +}) diff --git a/jeepay-ui-manager/src/router/generator-routers.js b/jeepay-ui-manager/src/router/generator-routers.js new file mode 100644 index 0000000..ec6665e --- /dev/null +++ b/jeepay-ui-manager/src/router/generator-routers.js @@ -0,0 +1,136 @@ +import { BasicLayout, BlankLayout, PageView, RouteView } from '@/layouts' +import store from '@/store' +import { asyncRouteDefine } from '@/config/appConfig' + +// 前端路由表 = 基础定义 + 动态组件 +const constantRouterComponents = Object.assign({ + // 基础页面 layout 必须引入 + BasicLayout: { component: BasicLayout }, + BlankLayout: { component: BlankLayout }, + RouteView: { component: RouteView }, + PageView: { component: PageView }, + '403': () => import('@/views/exception/403'), + '404': () => import('@/views/exception/404'), + '500': () => import('@/views/exception/500') + }, asyncRouteDefine) + +// 前端未找到页面路由 +const notFoundRouter = { + path: '*', component: () => import('@/views/exception/404') +} + +// 根级菜单 +const rootRouter = { + name: 'index', + path: '/', + component: BasicLayout, + redirect: redirectFunc, // 根页面【/】默认跳转 地址 + children: [], + meta: { title: '主页' } +} + +// 动态跳转路径 func +function redirectFunc () { + let mainPageUri = '' + store.state.user.allMenuRouteTree.forEach(item => { + if (item.entId === 'ENT_C_MAIN') { // 当前用户是否拥有主页权限, 如果有直接跳转到该路径 + mainPageUri = item.menuUri + return false + } + }) + + if (mainPageUri) { + return mainPageUri + } + + return getOneUri(store.state.user.allMenuRouteTree) +} + +// 获取到第一个uri (递归查找) +function getOneUri (item) { + let result = '' + for (let i = 0; i < item.length; i++) { + if (item[i].menuUri && item[i].entType === 'ML') { + return item[i].menuUri + } + + if (item[i].children) { + result = getOneUri(item[i].children) + if (result) { + return result + } + } + } + return result +} + +/** + * 动态生成菜单 + * @param token + * @returns {Promise} + */ +export const generatorDynamicRouter = () => { + return new Promise((resolve, reject) => { + // 根据树状结构生成路由格式 + rootRouter.children = generator(store.state.user.allMenuRouteTree) + + // 构建完整路由 + resolve([rootRouter, notFoundRouter]) + }) +} + +/** + * 格式化树形结构数据 生成 vue-router 层级路由表 + * + * @param routerMap + * @returns {*} + */ +export const generator = (allMenuRouteTreeArray) => { + const menuResult = [] + + // 遍历map + allMenuRouteTreeArray.map(item => { + const defComponent = constantRouterComponents[item.componentName || item.entId] + + // 找不到组件 || 其他菜单 + if (!defComponent) { + return + } + + // 跳转uri + let path = item.menuUri || defComponent.defaultPath + + // 没有配置path, 如果为目录则允许为空, 否则不在加载此配置 + if (!path) { + if (item.children && item.children.length > 0) { + path = `/${item.entId}` + } else { + return // 不再加载此配置项 + } + } + + const currentRouter = { + // 如果路由设置了 path,则作为默认 path,否则 路由地址 为默认配置 + path: path, + // 路由名称,建议唯一 + name: item.entId, + // 该路由对应页面的 组件 :方案2 (动态加载) + component: ((defComponent && defComponent.component) || (() => import(`@/views/${item.componentName}`))), + // meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉) + meta: { + title: item.entName, + icon: item.menuIcon, + keepAlive: false + }, + hidden: item.entType === 'MO' // 当其他菜单时需要隐藏显示 + } + // 是否有子菜单,并递归处理 + if (item.children && item.children.length > 0) { + // Recursion + currentRouter.children = generator(item.children) + } + menuResult.push(currentRouter) + }) + + return menuResult +} diff --git a/jeepay-ui-manager/src/router/index.js b/jeepay-ui-manager/src/router/index.js new file mode 100644 index 0000000..416b5c4 --- /dev/null +++ b/jeepay-ui-manager/src/router/index.js @@ -0,0 +1,29 @@ +import Vue from 'vue' +import Router from 'vue-router' +import { UserLayout } from '@/layouts' + +// hack router push callback +// [解决 vue-router跳转相同路径报错 ] +const originalPush = Router.prototype.push +Router.prototype.push = function push (location, onResolve, onReject) { + if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) + return originalPush.call(this, location).catch(err => err) +} + +Vue.use(Router) + +// 纯静态路由配置项 +const constantRouterMap = [ + { + path: '/user', + component: UserLayout, + children: [ + { path: 'login', name: 'login', component: () => import('@/views/user/Login') } + ] + } +] + +export default new Router({ + mode: 'history', + routes: constantRouterMap +}) diff --git a/jeepay-ui-manager/src/store/index.js b/jeepay-ui-manager/src/store/index.js new file mode 100644 index 0000000..e4aff3e --- /dev/null +++ b/jeepay-ui-manager/src/store/index.js @@ -0,0 +1,32 @@ +import Vue from 'vue' +import Vuex from 'vuex' + +import user from './modules/user' + +// default router permission control +import asyncRouter from './modules/async-router' + +Vue.use(Vuex) + +export default new Vuex.Store({ + modules: { + user, // 用户相关状态机 + asyncRouter // 动态菜单 + }, + state: { + // 定义全局loading 为false + globalLoading: false + }, + mutations: { + // 显示与关闭 全局 loading + showLoading (state) { + state.globalLoading = true + }, + hideLoading (state) { + state.globalLoading = false + } + }, + actions: { + + } +}) diff --git a/jeepay-ui-manager/src/store/modules/async-router.js b/jeepay-ui-manager/src/store/modules/async-router.js new file mode 100644 index 0000000..6282ce6 --- /dev/null +++ b/jeepay-ui-manager/src/store/modules/async-router.js @@ -0,0 +1,27 @@ +/** + * 向后端请求用户的菜单,动态生成路由 + */ +import { generatorDynamicRouter } from '@/router/generator-routers' + +const asyncRouter = { + state: { + addRouters: [] + }, + mutations: { + SET_ROUTERS: (state, routers) => { + state.addRouters = routers + } + }, + actions: { + GenerateRoutes ({ commit }, data) { + return new Promise(resolve => { + generatorDynamicRouter().then(routers => { + commit('SET_ROUTERS', routers) + resolve() + }) + }) + } + } +} + +export default asyncRouter diff --git a/jeepay-ui-manager/src/store/modules/user.js b/jeepay-ui-manager/src/store/modules/user.js new file mode 100644 index 0000000..42ceb33 --- /dev/null +++ b/jeepay-ui-manager/src/store/modules/user.js @@ -0,0 +1,78 @@ +import storage from '@/utils/jeepayStorageWrapper' +import { login, logout } from '@/api/login' +import appConfig from '@/config/appConfig' + +const user = { + state: { + token: '', + userName: '', // 真实姓名 + userId: '', // 用户ID + avatarImgPath: '', // 头像 + allMenuRouteTree: [], // 全部动态 router + accessList: [], // 用户权限集合 + isAdmin: '', // 是否是超级管理员 + loginUsername: '', // 登录用户名 + state: '', // 用户状态 + system: '', // 所属系统 + telphone: '', // 手机号 + sex: '' // 性别 + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + // 设置头像 + SET_AVATAR (state, avatarPath) { + state.avatarImgPath = avatarPath + }, + // 设置用户信息 + SET_USER_INFO: (state, userInfo) => { + state.userId = userInfo.sysUserId // 用户ID + state.userName = userInfo.realname // 真实姓名 + state.avatarImgPath = userInfo.avatarUrl // 头像 + state.accessList = userInfo.entIdList // 权限集合 + state.allMenuRouteTree = userInfo.allMenuRouteTree // 全部路由集合 + state.isAdmin = userInfo.isAdmin // 是否是超级管理员 + state.loginUsername = userInfo.loginUsername // 登录用户名 + state.state = userInfo.state // 用户状态 + state.system = userInfo.system // 所属系统 + state.telphone = userInfo.telphone // 手机号 + state.sex = userInfo.sex // 性别 + } + }, + + actions: { + // 登录 + Login ({ commit }, { loginParams, isSaveStorage }) { + return new Promise((resolve, reject) => { + login(loginParams).then(bizData => { + storage.setToken(bizData[appConfig.ACCESS_TOKEN_NAME], isSaveStorage) + commit('SET_TOKEN', bizData[appConfig.ACCESS_TOKEN_NAME]) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 登出 + Logout ({ commit, state }) { + return new Promise((resolve) => { + logout(state.token).then(() => { + commit('SET_TOKEN', '') + storage.cleanToken() + location.reload() // 退出时 重置缓存 + resolve() + }).catch(() => { + resolve() + }).finally(() => { + + }) + }) + } + + } +} + +export default user diff --git a/jeepay-ui-manager/src/utils/domUtil.js b/jeepay-ui-manager/src/utils/domUtil.js new file mode 100644 index 0000000..f820754 --- /dev/null +++ b/jeepay-ui-manager/src/utils/domUtil.js @@ -0,0 +1,17 @@ +export const setDocumentTitle = function (title) { + document.title = title + const ua = navigator.userAgent + // eslint-disable-next-line + const regex = /\bMicroMessenger\/([\d\.]+)/ + if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) { + const i = document.createElement('iframe') + i.src = '/favicon.ico' + i.style.display = 'none' + i.onload = function () { + setTimeout(function () { + i.remove() + }, 9) + } + document.body.appendChild(i) + } +} diff --git a/jeepay-ui-manager/src/utils/filter.js b/jeepay-ui-manager/src/utils/filter.js new file mode 100644 index 0000000..45702c6 --- /dev/null +++ b/jeepay-ui-manager/src/utils/filter.js @@ -0,0 +1,20 @@ +import Vue from 'vue' +import moment from 'moment' +import 'moment/locale/zh-cn' +moment.locale('zh-cn') + +Vue.filter('NumberFormat', function (value) { + if (!value) { + return '0' + } + const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断 + return intPartFormat +}) + +Vue.filter('dayjs', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { + return moment(dataStr).format(pattern) +}) + +Vue.filter('moment', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { + return moment(dataStr).format(pattern) +}) diff --git a/jeepay-ui-manager/src/utils/infoBox.js b/jeepay-ui-manager/src/utils/infoBox.js new file mode 100644 index 0000000..ca59a8a --- /dev/null +++ b/jeepay-ui-manager/src/utils/infoBox.js @@ -0,0 +1,33 @@ +/** + * 通用信息弹层 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +import { Modal } from 'ant-design-vue' + +// 确认提示: 标题, 内容, 点击确定回调函数, 取消回调, 扩展参数 +export const confirmResult = { + confirm: function (title, content, okFunc, cancelFunc = (() => {}), extConfig = {}) { + Modal.confirm( + Object.assign({ + okText: '确定', + cancelText: '取消', + title: title || '提示', + content: content, + onOk: okFunc, + onCancel: cancelFunc, + confirmLoading: true + }, extConfig)) + }, + confirmPrimary: function (title, content, okFunc, cancelFunc = (() => {}), extConfig = {}) { + this.confirm(title, content, okFunc, cancelFunc, Object.assign({ okType: 'primary' }, extConfig)) + }, + + confirmDanger: function (title, content, okFunc, cancelFunc = (() => {}), extConfig = {}) { + this.confirm(title, content, okFunc, cancelFunc, Object.assign({ okType: 'danger' }, extConfig)) + } +} + +export default confirmResult diff --git a/jeepay-ui-manager/src/utils/jeepayStorageWrapper.js b/jeepay-ui-manager/src/utils/jeepayStorageWrapper.js new file mode 100644 index 0000000..7da8c45 --- /dev/null +++ b/jeepay-ui-manager/src/utils/jeepayStorageWrapper.js @@ -0,0 +1,34 @@ +/** + * storage 存储包装类 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +import storage from 'store' +import appConfig from '@/config/appConfig' + +var SESSION_TOKEN = '' + +const wrapper = { + + /* 获取当前Token **/ + getToken: () => { + return SESSION_TOKEN || storage.get(appConfig.ACCESS_TOKEN_NAME) + }, + + /* 清空Token **/ + cleanToken: () => { + SESSION_TOKEN = '' + storage.remove(appConfig.ACCESS_TOKEN_NAME) + }, + + /* 设置token信息 **/ + setToken (tokenVal, isSaveStorage) { + SESSION_TOKEN = tokenVal + if (isSaveStorage) { + storage.set(appConfig.ACCESS_TOKEN_NAME, tokenVal, 7 * 24 * 60 * 60 * 1000) + } + } +} +export default wrapper diff --git a/jeepay-ui-manager/src/utils/screenLog.js b/jeepay-ui-manager/src/utils/screenLog.js new file mode 100644 index 0000000..ff48ac3 --- /dev/null +++ b/jeepay-ui-manager/src/utils/screenLog.js @@ -0,0 +1,18 @@ +/* eslint-disable */ +export const printANSI = () => { + let text = ` + __ + / /___ ___ ____ ____ ___ __ + __ / // _ \\/ _ \\/ __ \\/ __ \`/ / / / +/ /_/ // __/ __/ /_/ / /_/ / /_/ / +\\____/ \\___/\\___/ .___/\\__,_/\\__, / + /_/ /____/ + :: Jeepay :: (v1.0.0.RELEASE) + 适合互联网企业使用的开源支付系统 : https://www.jeepay.vip +` + +console.log(`%c${text}`, 'color: #fc4d50') + +console.log('%cThanks for using Jeepay!', 'color: #fff; font-size: 14px; font-weight: 300; text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0;') + +} diff --git a/jeepay-ui-manager/src/utils/util.js b/jeepay-ui-manager/src/utils/util.js new file mode 100644 index 0000000..afbc127 --- /dev/null +++ b/jeepay-ui-manager/src/utils/util.js @@ -0,0 +1,12 @@ +export function timeFix () { + const time = new Date() + const hour = time.getHours() + return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好' +} + +export function isIE () { + const bw = window.navigator.userAgent + const compare = (s) => bw.indexOf(s) >= 0 + const ie11 = (() => 'ActiveXObject' in window)() + return compare('MSIE') || ie11 +} diff --git a/jeepay-ui-manager/src/utils/utils.less b/jeepay-ui-manager/src/utils/utils.less new file mode 100644 index 0000000..ba75a67 --- /dev/null +++ b/jeepay-ui-manager/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + word-break: break-all; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + position: relative; + max-height: @line * 1.5em; + margin-right: -1em; + padding-right: 1em; + overflow: hidden; + line-height: 1.5em; + text-align: justify; + &::before { + position: absolute; + right: 14px; + bottom: 0; + padding: 0 1px; + background: @bg; + content: '...'; + } + &::after { + position: absolute; + right: 14px; + width: 1em; + height: 1em; + margin-top: 0.2em; + background: white; + content: ''; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &::before, + &::after { + display: table; + content: ' '; + } + &::after { + clear: both; + height: 0; + font-size: 0; + visibility: hidden; + } +} \ No newline at end of file diff --git a/jeepay-ui-manager/src/views/current/AvatarModal.vue b/jeepay-ui-manager/src/views/current/AvatarModal.vue new file mode 100644 index 0000000..c822a1e --- /dev/null +++ b/jeepay-ui-manager/src/views/current/AvatarModal.vue @@ -0,0 +1,202 @@ + + + + diff --git a/jeepay-ui-manager/src/views/current/UserinfoPage.vue b/jeepay-ui-manager/src/views/current/UserinfoPage.vue new file mode 100644 index 0000000..a330ce6 --- /dev/null +++ b/jeepay-ui-manager/src/views/current/UserinfoPage.vue @@ -0,0 +1,265 @@ + + + diff --git a/jeepay-ui-manager/src/views/dashboard/Analysis.vue b/jeepay-ui-manager/src/views/dashboard/Analysis.vue new file mode 100644 index 0000000..9bd2094 --- /dev/null +++ b/jeepay-ui-manager/src/views/dashboard/Analysis.vue @@ -0,0 +1,772 @@ + + + + + diff --git a/jeepay-ui-manager/src/views/dashboard/empty.vue b/jeepay-ui-manager/src/views/dashboard/empty.vue new file mode 100644 index 0000000..d406f7b --- /dev/null +++ b/jeepay-ui-manager/src/views/dashboard/empty.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/jeepay-ui-manager/src/views/dashboard/index.css b/jeepay-ui-manager/src/views/dashboard/index.css new file mode 100644 index 0000000..743aa38 --- /dev/null +++ b/jeepay-ui-manager/src/views/dashboard/index.css @@ -0,0 +1,162 @@ +#chart-card { + width: 100%; +} +#chart-card .top-left { + min-height: 250px; +} +#chart-card .chart-data { + min-height: 100px; + height: 100%; + width: 100%; + border-radius: 6px; + background-color: #fff; +} +#chart-card .chart-top, +#chart-card .chart-bottom { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} +#chart-card .chart-top .middle-smaller, +#chart-card .chart-bottom .middle-smaller, +#chart-card .chart-top .middle-larger, +#chart-card .chart-bottom .middle-larger { + height: 100%; +} +#chart-card .chart-top .top-left, +#chart-card .chart-bottom .top-left { + min-height: 238px; +} +#chart-card .chart-item { + width: 100%; + box-sizing: border-box; + padding: 12px; +} +@media screen and (max-width: 767px) { + #chart-card .chart-top .top-left { + order: 1; + } + #chart-card .chart-top .top-middle { + order: 2; + width: 100%; + } + #chart-card .chart-top .top-middle .middle-top, + #chart-card .chart-top .top-middle .middle-bottom { + display: flex; + flex-direction: column; + } + #chart-card .chart-top .top-middle .middle-top .middle-larger, + #chart-card .chart-top .top-middle .middle-bottom .middle-larger, + #chart-card .chart-top .top-middle .middle-top .middle-smaller, + #chart-card .chart-top .top-middle .middle-bottom .middle-smaller { + width: 100%; + } + #chart-card .chart-top .top-right { + order: 0; + } +} +@media screen and (min-width: 768px) { + #chart-card .top-left, + #chart-card .top-middle { + order: 1; + } + #chart-card .top-middle { + width: 100%; + } + #chart-card .top-middle .middle-top, + #chart-card .top-middle .middle-bottom { + display: flex; + flex-direction: row; + } + #chart-card .top-middle .middle-top .middle-larger, + #chart-card .top-middle .middle-bottom .middle-larger { + flex-grow: 1; + } + #chart-card .top-middle .middle-top .middle-smaller, + #chart-card .top-middle .middle-bottom .middle-smaller { + max-width: 170px; + min-width: 150px; + } + #chart-card .top-right { + order: 0; + } +} +@media screen and (min-width: 1200px) { + #chart-card .top-left { + order: 1; + width: 50%; + } + #chart-card .top-middle { + width: 50%; + order: 2; + } + #chart-card .top-middle .middle-top, + #chart-card .top-middle .middle-bottom { + display: flex; + flex-direction: row; + } + #chart-card .top-middle .middle-top .middle-larger, + #chart-card .top-middle .middle-bottom .middle-larger { + flex-grow: 1; + } + #chart-card .top-middle .middle-top .middle-smaller, + #chart-card .top-middle .middle-bottom .middle-smaller { + max-width: 170px; + min-width: 150px; + } + #chart-card .top-right { + width: 100%; + order: 0; + } +} +@media screen and (min-width: 1500px) { + #chart-card { + flex-direction: row; + } + #chart-card .chart-top { + width: 100%; + order: 0; + flex-wrap: nowrap; + } + #chart-card .chart-top .top-left, + #chart-card .chart-top .top-middle { + width: 500px; + min-width: 460px; + order: 0; + } + #chart-card .chart-top .top-middle { + order: 1; + } + #chart-card .chart-top .top-middle .middle-top, + #chart-card .chart-top .top-middle .middle-bottom { + display: flex; + width: 100%; + height: 50%; + flex-wrap: nowrap; + } + #chart-card .chart-top .top-middle .middle-smaller { + min-width: 170px; + } + #chart-card .chart-top .top-middle .middle-larger { + width: 200px; + flex-grow: 1; + } + #chart-card .chart-top .top-right { + order: 2; + flex-grow: 1; + } + #chart-card .chart-bottom { + order: 1; + width: 100%; + flex-wrap: nowrap; + } + #chart-card .chart-bottom .bottom-right { + flex-shrink: 1; + max-width: 500px; + min-width: 330px; + } + #chart-card .chart-bottom .bottom-left { + min-width: 900px; + flex-grow: 1; + } +} diff --git a/jeepay-ui-manager/src/views/dashboard/index.less b/jeepay-ui-manager/src/views/dashboard/index.less new file mode 100644 index 0000000..5073a06 --- /dev/null +++ b/jeepay-ui-manager/src/views/dashboard/index.less @@ -0,0 +1,167 @@ +#chart-card { + width: 100%; + .top-left { + min-height: 250px; + } + .chart-data { + min-height: 100px; + height: 100%; + width: 100%; + border-radius: 6px; + background-color: #fff; + } + .chart-top, .chart-bottom { + display: flex; + flex-direction: row; + flex-wrap: wrap; + + .middle-smaller, .middle-larger { // 较小的区域 + height: 100%; + } + .top-left { + min-height: 238px; + } + } + .chart-item { + width: 100%; + box-sizing: border-box; + padding: 12px; + } +} +@media screen and (max-width:767px){ +#chart-card { + .chart-top { + .top-left { + order: 1; + } + .top-middle { + order: 2; + width: 100%; + + .middle-top, .middle-bottom { + display: flex; + flex-direction: column; + + .middle-larger, .middle-smaller { + width: 100%; + } + } + + } + .top-right { + order: 0; + } + } +} +} +@media screen and (min-width:768px){ +#chart-card { + .top-left, .top-middle { + order: 1; + } + .top-middle { + width: 100%; + .middle-top, .middle-bottom { + display: flex; + flex-direction: row; + + .middle-larger { + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + .middle-smaller { + max-width: 170px; + min-width: 150px; + } + } + } + + .top-right { + order: 0; + } +} +} + +@media screen and (min-width:1200px){ +#chart-card { + .top-left { + order: 1; + width: 50%; + } + .top-middle { + width: 50%; + order: 2; + + .middle-top, .middle-bottom { + display: flex; + flex-direction: row; + + .middle-larger { + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + .middle-smaller { + max-width: 170px; + min-width: 150px; + } + } + } + + .top-right { + width: 100%; + order: 0; + } + } +} + +@media screen and (min-width:1500px){ + #chart-card { + flex-direction: row; + + .chart-top { + width:100%; + order: 0; + flex-wrap: nowrap; // 禁止换行 + + .top-left, .top-middle { + width:500px; + min-width: 460px; + order: 0; + } + .top-middle { + order: 1; + .middle-top, .middle-bottom { + display: flex; + width: 100%; + height: 50%; + flex-wrap: nowrap; // 禁止换行 + } + .middle-smaller { // 较小的区域 + min-width: 170px; + } + .middle-larger { // 较大的区域 + width: 200px; + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + } + .top-right { + order: 2; + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + } + + .chart-bottom { + order: 1; + width:100%; + + flex-wrap: nowrap; + .bottom-right { + flex-shrink: 1; + max-width: 500px; + min-width: 330px; + } + .bottom-left { + min-width: 900px; + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + } + } +} \ No newline at end of file diff --git a/jeepay-ui-manager/src/views/ent/AddOrEdit.vue b/jeepay-ui-manager/src/views/ent/AddOrEdit.vue new file mode 100644 index 0000000..a7508da --- /dev/null +++ b/jeepay-ui-manager/src/views/ent/AddOrEdit.vue @@ -0,0 +1,105 @@ + + + diff --git a/jeepay-ui-manager/src/views/ent/EntPage.vue b/jeepay-ui-manager/src/views/ent/EntPage.vue new file mode 100644 index 0000000..b2decf2 --- /dev/null +++ b/jeepay-ui-manager/src/views/ent/EntPage.vue @@ -0,0 +1,105 @@ + + diff --git a/jeepay-ui-manager/src/views/exception/403.vue b/jeepay-ui-manager/src/views/exception/403.vue new file mode 100644 index 0000000..6df8f43 --- /dev/null +++ b/jeepay-ui-manager/src/views/exception/403.vue @@ -0,0 +1,22 @@ + + + diff --git a/jeepay-ui-manager/src/views/exception/404.vue b/jeepay-ui-manager/src/views/exception/404.vue new file mode 100644 index 0000000..824644c --- /dev/null +++ b/jeepay-ui-manager/src/views/exception/404.vue @@ -0,0 +1,22 @@ + + + diff --git a/jeepay-ui-manager/src/views/exception/500.vue b/jeepay-ui-manager/src/views/exception/500.vue new file mode 100644 index 0000000..08f2dc1 --- /dev/null +++ b/jeepay-ui-manager/src/views/exception/500.vue @@ -0,0 +1,22 @@ + + + diff --git a/jeepay-ui-manager/src/views/isv/AddOrEdit.vue b/jeepay-ui-manager/src/views/isv/AddOrEdit.vue new file mode 100644 index 0000000..25d230b --- /dev/null +++ b/jeepay-ui-manager/src/views/isv/AddOrEdit.vue @@ -0,0 +1,174 @@ + + + diff --git a/jeepay-ui-manager/src/views/isv/IsvList.vue b/jeepay-ui-manager/src/views/isv/IsvList.vue new file mode 100644 index 0000000..5e860a0 --- /dev/null +++ b/jeepay-ui-manager/src/views/isv/IsvList.vue @@ -0,0 +1,118 @@ + + diff --git a/jeepay-ui-manager/src/views/isv/IsvPayIfConfigList.vue b/jeepay-ui-manager/src/views/isv/IsvPayIfConfigList.vue new file mode 100644 index 0000000..e83f373 --- /dev/null +++ b/jeepay-ui-manager/src/views/isv/IsvPayIfConfigList.vue @@ -0,0 +1,323 @@ + + + + + diff --git a/jeepay-ui-manager/src/views/mch/AddOrEdit.vue b/jeepay-ui-manager/src/views/mch/AddOrEdit.vue new file mode 100644 index 0000000..5b257e9 --- /dev/null +++ b/jeepay-ui-manager/src/views/mch/AddOrEdit.vue @@ -0,0 +1,272 @@ + + + + diff --git a/jeepay-ui-manager/src/views/mch/Detail.vue b/jeepay-ui-manager/src/views/mch/Detail.vue new file mode 100644 index 0000000..ab2f6d5 --- /dev/null +++ b/jeepay-ui-manager/src/views/mch/Detail.vue @@ -0,0 +1,163 @@ + + + diff --git a/jeepay-ui-manager/src/views/mch/MchList.vue b/jeepay-ui-manager/src/views/mch/MchList.vue new file mode 100644 index 0000000..8a74b55 --- /dev/null +++ b/jeepay-ui-manager/src/views/mch/MchList.vue @@ -0,0 +1,144 @@ + + diff --git a/jeepay-ui-manager/src/views/mch/MchPayConfigAddOrEdit.vue b/jeepay-ui-manager/src/views/mch/MchPayConfigAddOrEdit.vue new file mode 100644 index 0000000..fb1f602 --- /dev/null +++ b/jeepay-ui-manager/src/views/mch/MchPayConfigAddOrEdit.vue @@ -0,0 +1,268 @@ + + + + diff --git a/jeepay-ui-manager/src/views/mch/MchPayIfConfigList.vue b/jeepay-ui-manager/src/views/mch/MchPayIfConfigList.vue new file mode 100644 index 0000000..256efbc --- /dev/null +++ b/jeepay-ui-manager/src/views/mch/MchPayIfConfigList.vue @@ -0,0 +1,246 @@ + + + + + diff --git a/jeepay-ui-manager/src/views/mch/MchPayPassageAddOrEdit.vue b/jeepay-ui-manager/src/views/mch/MchPayPassageAddOrEdit.vue new file mode 100644 index 0000000..8d1e372 --- /dev/null +++ b/jeepay-ui-manager/src/views/mch/MchPayPassageAddOrEdit.vue @@ -0,0 +1,219 @@ + + + + diff --git a/jeepay-ui-manager/src/views/order/notify/MchNotifyList.vue b/jeepay-ui-manager/src/views/order/notify/MchNotifyList.vue new file mode 100644 index 0000000..2526dc0 --- /dev/null +++ b/jeepay-ui-manager/src/views/order/notify/MchNotifyList.vue @@ -0,0 +1,263 @@ + + diff --git a/jeepay-ui-manager/src/views/order/pay/PayOrderList.vue b/jeepay-ui-manager/src/views/order/pay/PayOrderList.vue new file mode 100644 index 0000000..13f9eb9 --- /dev/null +++ b/jeepay-ui-manager/src/views/order/pay/PayOrderList.vue @@ -0,0 +1,393 @@ + + diff --git a/jeepay-ui-manager/src/views/order/refund/RefundOrderList.vue b/jeepay-ui-manager/src/views/order/refund/RefundOrderList.vue new file mode 100644 index 0000000..2ea6dc8 --- /dev/null +++ b/jeepay-ui-manager/src/views/order/refund/RefundOrderList.vue @@ -0,0 +1,389 @@ + + diff --git a/jeepay-ui-manager/src/views/payconfig/payIfDefine/AddOrEdit.vue b/jeepay-ui-manager/src/views/payconfig/payIfDefine/AddOrEdit.vue new file mode 100644 index 0000000..e6c2ef9 --- /dev/null +++ b/jeepay-ui-manager/src/views/payconfig/payIfDefine/AddOrEdit.vue @@ -0,0 +1,255 @@ + + + + + diff --git a/jeepay-ui-manager/src/views/payconfig/payIfDefine/List.vue b/jeepay-ui-manager/src/views/payconfig/payIfDefine/List.vue new file mode 100644 index 0000000..44b97b2 --- /dev/null +++ b/jeepay-ui-manager/src/views/payconfig/payIfDefine/List.vue @@ -0,0 +1,127 @@ + + + + + diff --git a/jeepay-ui-manager/src/views/payconfig/payWay/AddOrEdit.vue b/jeepay-ui-manager/src/views/payconfig/payWay/AddOrEdit.vue new file mode 100644 index 0000000..8147f48 --- /dev/null +++ b/jeepay-ui-manager/src/views/payconfig/payWay/AddOrEdit.vue @@ -0,0 +1,80 @@ + + diff --git a/jeepay-ui-manager/src/views/payconfig/payWay/List.vue b/jeepay-ui-manager/src/views/payconfig/payWay/List.vue new file mode 100644 index 0000000..070b7f2 --- /dev/null +++ b/jeepay-ui-manager/src/views/payconfig/payWay/List.vue @@ -0,0 +1,114 @@ + + diff --git a/jeepay-ui-manager/src/views/role/Add.vue b/jeepay-ui-manager/src/views/role/Add.vue new file mode 100644 index 0000000..a8e094d --- /dev/null +++ b/jeepay-ui-manager/src/views/role/Add.vue @@ -0,0 +1,63 @@ + + + diff --git a/jeepay-ui-manager/src/views/role/AddOrEdit.vue b/jeepay-ui-manager/src/views/role/AddOrEdit.vue new file mode 100644 index 0000000..0e14ded --- /dev/null +++ b/jeepay-ui-manager/src/views/role/AddOrEdit.vue @@ -0,0 +1,105 @@ + + + diff --git a/jeepay-ui-manager/src/views/role/RoleDist.vue b/jeepay-ui-manager/src/views/role/RoleDist.vue new file mode 100644 index 0000000..42e4957 --- /dev/null +++ b/jeepay-ui-manager/src/views/role/RoleDist.vue @@ -0,0 +1,100 @@ + + + diff --git a/jeepay-ui-manager/src/views/role/RolePage.vue b/jeepay-ui-manager/src/views/role/RolePage.vue new file mode 100644 index 0000000..392a014 --- /dev/null +++ b/jeepay-ui-manager/src/views/role/RolePage.vue @@ -0,0 +1,123 @@ + + diff --git a/jeepay-ui-manager/src/views/sys/config/SysConfig.vue b/jeepay-ui-manager/src/views/sys/config/SysConfig.vue new file mode 100644 index 0000000..9a2f608 --- /dev/null +++ b/jeepay-ui-manager/src/views/sys/config/SysConfig.vue @@ -0,0 +1,79 @@ + + diff --git a/jeepay-ui-manager/src/views/sys/log/SysLog.vue b/jeepay-ui-manager/src/views/sys/log/SysLog.vue new file mode 100644 index 0000000..6626545 --- /dev/null +++ b/jeepay-ui-manager/src/views/sys/log/SysLog.vue @@ -0,0 +1,260 @@ + + diff --git a/jeepay-ui-manager/src/views/sysuser/AddOrEdit.vue b/jeepay-ui-manager/src/views/sysuser/AddOrEdit.vue new file mode 100644 index 0000000..9ee6482 --- /dev/null +++ b/jeepay-ui-manager/src/views/sysuser/AddOrEdit.vue @@ -0,0 +1,158 @@ + + + diff --git a/jeepay-ui-manager/src/views/sysuser/RoleDist.vue b/jeepay-ui-manager/src/views/sysuser/RoleDist.vue new file mode 100644 index 0000000..ecba44c --- /dev/null +++ b/jeepay-ui-manager/src/views/sysuser/RoleDist.vue @@ -0,0 +1,101 @@ + + + diff --git a/jeepay-ui-manager/src/views/sysuser/SysUserPage.vue b/jeepay-ui-manager/src/views/sysuser/SysUserPage.vue new file mode 100644 index 0000000..7ec4bca --- /dev/null +++ b/jeepay-ui-manager/src/views/sysuser/SysUserPage.vue @@ -0,0 +1,142 @@ + + diff --git a/jeepay-ui-manager/src/views/user/Login.vue b/jeepay-ui-manager/src/views/user/Login.vue new file mode 100644 index 0000000..36e132a --- /dev/null +++ b/jeepay-ui-manager/src/views/user/Login.vue @@ -0,0 +1,217 @@ + + + + + diff --git a/jeepay-ui-manager/tests/unit/.eslintrc.js b/jeepay-ui-manager/tests/unit/.eslintrc.js new file mode 100644 index 0000000..958d51b --- /dev/null +++ b/jeepay-ui-manager/tests/unit/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + env: { + jest: true + } +} diff --git a/jeepay-ui-manager/vue.config.js b/jeepay-ui-manager/vue.config.js new file mode 100644 index 0000000..c0207d8 --- /dev/null +++ b/jeepay-ui-manager/vue.config.js @@ -0,0 +1,127 @@ +const path = require('path') +const webpack = require('webpack') +const GitRevisionPlugin = require('git-revision-webpack-plugin') +const GitRevision = new GitRevisionPlugin() +const buildDate = JSON.stringify(new Date().toLocaleString()) + +function resolve (dir) { + return path.join(__dirname, dir) +} + +// check Git +function getGitHash () { + try { + return GitRevision.version() + } catch (e) { } + 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' + ] +} + +// vue.config.js +const vueConfig = { + publicPath: process.env.VUE_APP_BASE_URL, // 前端资源访问根目录, 可配置到cdn目录下。 建议使用命令行环境变量进行替换。 + configureWebpack: { + // webpack plugins + plugins: [ + // Ignore all locale files of moment.js + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + new webpack.DefinePlugin({ + APP_VERSION: `"${require('./package.json').version}"`, + GIT_HASH: JSON.stringify(getGitHash()), + BUILD_DATE: buildDate + }) + ], + // if prod, add externals + externals: isProd ? assetsCDN.externals : {} + }, + + chainWebpack: (config) => { + config.resolve.alias + .set('@$', resolve('src')) + + const svgRule = config.module.rule('svg') + svgRule.uses.clear() + svgRule + .oneOf('inline') + .resourceQuery(/inline/) + .use('vue-svg-icon-loader') + .loader('vue-svg-icon-loader') + .end() + .end() + .oneOf('external') + .use('file-loader') + .loader('file-loader') + .options({ + 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: { + loaderOptions: { + less: { + modifyVars: { + 'primary-color': '#1a53ff', + 'link-color': '#1A79FF', + 'border-radius-base': '4px' + }, + javascriptEnabled: true + } + } + }, + + devServer: { + // development server port 8000 + port: 8000 + // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11 + // proxy: { + // '/api': { + // target: 'https://mock.ihx.me/mock/5baf3052f7da7e07e04a5116/antd-pro', + // ws: false, + // changeOrigin: true + // } + // } + }, + + // disable source map in production + productionSourceMap: false, + lintOnSave: undefined, + // babel-loader no-ignore node_modules/* + transpileDependencies: [], + + pluginOptions: { // 第三方插件配置 + 'style-resources-loader': { + preProcessor: 'less', + patterns: [path.resolve(__dirname, 'src/assets/styles/color.less')] // less所在文件路径 + } + } +} + +module.exports = vueConfig diff --git a/jeepay-ui-merchant/.browserslistrc b/jeepay-ui-merchant/.browserslistrc new file mode 100644 index 0000000..8f96043 --- /dev/null +++ b/jeepay-ui-merchant/.browserslistrc @@ -0,0 +1,3 @@ +> 1% +last 2 versions +not ie <= 10 diff --git a/jeepay-ui-merchant/.env b/jeepay-ui-merchant/.env new file mode 100644 index 0000000..1e734a7 --- /dev/null +++ b/jeepay-ui-merchant/.env @@ -0,0 +1,4 @@ +NODE_ENV=production +VUE_APP_PREVIEW=false +VUE_APP_BASE_URL=/ +VUE_APP_API_BASE_URL= \ No newline at end of file diff --git a/jeepay-ui-merchant/.env.development b/jeepay-ui-merchant/.env.development new file mode 100644 index 0000000..711f7d0 --- /dev/null +++ b/jeepay-ui-merchant/.env.development @@ -0,0 +1,4 @@ +NODE_ENV=development +VUE_APP_PREVIEW=true +VUE_APP_BASE_URL=/ +VUE_APP_API_BASE_URL=http://localhost:9218 \ No newline at end of file diff --git a/jeepay-ui-merchant/.eslintrc.js b/jeepay-ui-merchant/.eslintrc.js new file mode 100644 index 0000000..2e7a313 --- /dev/null +++ b/jeepay-ui-merchant/.eslintrc.js @@ -0,0 +1,100 @@ +/** + 默认eslint规则: + 代码末尾不能加分号 ;(强迫症的我受不了 哭) + 代码中不能存在多行空行;(这个我更也忍不了大哭) + tab键不能使用,必须换成两个空格;(超级不习惯) + 代码中不能存在声明了但未使用的变量;(这个我觉得可以有) + * **/ + +module.exports = { + root: true, + env: { + node: true + }, + 'extends': [ + 'plugin:vue/strongly-recommended', + '@vue/standard' + ], + rules: { + 'no-console': 'off', + 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', + 'generator-star-spacing': 'off', + 'no-mixed-operators': 0, + 'vue/max-attributes-per-line': [ + 2, + { + 'singleline': 5, //单行的情况下可以接受的属性数量 + 'multiline': { + 'max': 1, //多行的情况下每行最多属性数量 + 'allowFirstLine': false //不允许在多行的情况下第一行有属性 + } + } + ], + 'vue/attribute-hyphenation': 0, + 'vue/html-self-closing': 0, + 'vue/component-name-in-template-casing': 0, + 'vue/html-closing-bracket-spacing': 0, + 'vue/singleline-html-element-content-newline': 0, + 'vue/no-unused-components': 0, + 'vue/multiline-html-element-content-newline': 0, + 'vue/no-use-v-if-with-v-for': 0, + 'vue/html-closing-bracket-newline': 0, + 'vue/no-parsing-error': 0, + 'no-tabs': 0, + 'quotes': [ + 2, + 'single', + { + 'avoidEscape': true, + 'allowTemplateLiterals': true + } + ], + + /** + * 分号配置项: + * 第一个参数: + " off"或0 - 关闭规则 + " warn"或1 - 将该规则作为警告打开(不影响退出代码) + " error"或2 - 将规则作为错误打开(退出代码将为1) + * + *第二个参数 + always(默认):在语句末尾需要分号 + never:不允许加分号 + * + * 第三个参数: + "beforeStatementContinuationChars": "any"(默认)如果下一行语句以 [,(,/,+,或 - 开头,忽略语句末尾的分号(或缺失分号), + "beforeStatementContinuationChars": "always" 如果下一行语句以 [,(,/,+,或 - 开头,在语句末尾需要添加分号。 + "beforeStatementContinuationChars": "never" 如果该语句不会因为ASI而带来风险,那么即使它的下一行语句以 [,(,/,+,或 - 开头,也不允许在语句末尾添加分号。 + * **/ + 'semi': [ + 2, + 'never', + { + 'beforeStatementContinuationChars': 'never' + } + ], + 'no-delete-var': 2, + 'prefer-const': [ + 2, + { + 'ignoreReadBeforeAssign': false + } + ], + 'template-curly-spacing': 'off', + 'indent': 'off' + }, + parserOptions: { + parser: 'babel-eslint' + }, + overrides: [ + { + files: [ + '**/__tests__/*.{j,t}s?(x)', + '**/tests/unit/**/*.spec.{j,t}s?(x)' + ], + env: { + jest: true + } + } + ] +} diff --git a/jeepay-ui-merchant/babel.config.js b/jeepay-ui-merchant/babel.config.js new file mode 100644 index 0000000..e80ad97 --- /dev/null +++ b/jeepay-ui-merchant/babel.config.js @@ -0,0 +1,28 @@ +const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV) + +const plugins = [] +if (IS_PROD) { + plugins.push('transform-remove-console') +} + +// lazy load ant-design-vue +// if your use import on Demand, Use this code +plugins.push(['import', { + 'libraryName': 'ant-design-vue', + 'libraryDirectory': 'es', + 'style': true // `style: true` 会加载 less 文件 +}]) + +module.exports = { + presets: [ + '@vue/cli-plugin-babel/preset', + [ + '@babel/preset-env', + { + 'useBuiltIns': 'entry', + 'corejs': 3 + } + ] + ], + plugins +} diff --git a/jeepay-ui-merchant/package.json b/jeepay-ui-merchant/package.json new file mode 100644 index 0000000..86611fe --- /dev/null +++ b/jeepay-ui-merchant/package.json @@ -0,0 +1,71 @@ +{ + "name": "jeepay-ui-merchant", + "version": "1.0.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "test:unit": "vue-cli-service test:unit", + "lint": "vue-cli-service lint", + "build:preview": "vue-cli-service build --mode preview", + "lint:nofix": "vue-cli-service lint --no-fix" + }, + "dependencies": { + "@ant-design-vue/pro-layout": "^1.0.7", + "@antv/data-set": "^0.10.2", + "ant-design-vue": "^1.7.2", + "@antv/g2plot": "^2.3.21", + "@antv/util": "^2.0.13", + "axios": "^0.19.0", + "core-js": "^3.1.2", + "enquire.js": "^2.1.6", + "lodash.clonedeep": "^4.5.0", + "lodash.get": "^4.4.2", + "lodash.pick": "^4.4.0", + "md5": "^2.2.1", + "mockjs2": "1.0.8", + "moment": "^2.24.0", + "nprogress": "^0.2.0", + "store": "^2.0.12", + "viser-vue": "^2.4.6", + "vue": "^2.6.10", + "vue-clipboard2": "^0.2.1", + "vue-cropper": "0.4.9", + "vue-i18n": "^8.17.4", + "vue-quill-editor": "^3.0.6", + "vue-router": "^3.1.2", + "vue-svg-component-runtime": "^1.0.1", + "vuex": "^3.1.1", + "wangeditor": "^3.1.1", + "js-base64": "^2.5.2" + }, + "devDependencies": { + "@ant-design/colors": "^3.2.1", + "@vue/cli-plugin-babel": "^4.0.4", + "@vue/cli-plugin-eslint": "^4.0.4", + "@vue/cli-plugin-router": "^4.0.4", + "@vue/cli-plugin-unit-jest": "^4.0.4", + "@vue/cli-plugin-vuex": "^4.0.4", + "@vue/cli-service": "^4.0.4", + "@vue/eslint-config-standard": "^4.0.0", + "@vue/test-utils": "^1.0.0-beta.29", + "babel-eslint": "^10.0.1", + "babel-plugin-import": "^1.12.2", + "babel-plugin-transform-remove-console": "^6.9.4", + "eslint": "^5.16.0", + "eslint-plugin-html": "^5.0.0", + "eslint-plugin-vue": "^5.2.3", + "git-revision-webpack-plugin": "^3.0.6", + "image-webpack-loader": "^7.0.1", + "less": "^3.0.4", + "less-loader": "^5.0.0", + "opencollective": "^1.0.3", + "opencollective-postinstall": "^2.0.2", + "style-resources-loader": "^1.4.1", + "url-loader": "^4.1.1", + "vue-cli-plugin-style-resources-loader": "^0.1.5", + "vue-svg-icon-loader": "^2.1.1", + "vue-template-compiler": "^2.6.10", + "webpack-theme-color-replacer": "^1.3.12" + } +} diff --git a/jeepay-ui-merchant/postcss.config.js b/jeepay-ui-merchant/postcss.config.js new file mode 100644 index 0000000..961986e --- /dev/null +++ b/jeepay-ui-merchant/postcss.config.js @@ -0,0 +1,5 @@ +module.exports = { + plugins: { + autoprefixer: {} + } +} diff --git a/jeepay-ui-merchant/public/imgs/defava_f.png b/jeepay-ui-merchant/public/imgs/defava_f.png new file mode 100644 index 0000000..5848989 Binary files /dev/null and b/jeepay-ui-merchant/public/imgs/defava_f.png differ diff --git a/jeepay-ui-merchant/public/imgs/defava_m.png b/jeepay-ui-merchant/public/imgs/defava_m.png new file mode 100644 index 0000000..287ff9c Binary files /dev/null and b/jeepay-ui-merchant/public/imgs/defava_m.png differ diff --git a/jeepay-ui-merchant/public/imgs/favicon.ico b/jeepay-ui-merchant/public/imgs/favicon.ico new file mode 100644 index 0000000..cdce95c Binary files /dev/null and b/jeepay-ui-merchant/public/imgs/favicon.ico differ diff --git a/jeepay-ui-merchant/public/imgs/logo.svg b/jeepay-ui-merchant/public/imgs/logo.svg new file mode 100644 index 0000000..7e60317 --- /dev/null +++ b/jeepay-ui-merchant/public/imgs/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/public/index.html b/jeepay-ui-merchant/public/index.html new file mode 100644 index 0000000..d9cb5c9 --- /dev/null +++ b/jeepay-ui-merchant/public/index.html @@ -0,0 +1,36 @@ + + + + + + + + 商户系统 - Jeepay计全支付 + + + <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %> + + <% } %> + + + +
+
+ <% { %> + + <% } %> +
+ +
+
计全科技
+
+
+ + <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.js) { %> + + <% } %> + + + diff --git a/jeepay-ui-merchant/src/App.vue b/jeepay-ui-merchant/src/App.vue new file mode 100644 index 0000000..92650ff --- /dev/null +++ b/jeepay-ui-merchant/src/App.vue @@ -0,0 +1,31 @@ + + + diff --git a/jeepay-ui-merchant/src/api/login.js b/jeepay-ui-merchant/src/api/login.js new file mode 100644 index 0000000..583d3cf --- /dev/null +++ b/jeepay-ui-merchant/src/api/login.js @@ -0,0 +1,35 @@ +import request from '@/http/request' +import { Base64 } from 'js-base64' + +// 登录认证接口 +export function login ({ username, password, vercode, vercodeToken }) { + const data = { + ia: Base64.encode(username), // 账号 + ip: Base64.encode(password), // 密码 + vc: Base64.encode(vercode), // 验证码值 + vt: Base64.encode(vercodeToken) // 验证码token + } + return request.request({ + url: '/api/anon/auth/validate', + method: 'post', + data: data + }, true, true, false) +} + +// 获取图形验证码信息接口 +export function vercode () { + return request.request({ url: '/api/anon/auth/vercode', method: 'get' }, true, true, true) +} + +// 获取当前用户信息 +export function getInfo () { + return request.request({ + url: '/api/current/user', + method: 'get' + }) +} + +// 退出接口 +export function logout () { + return new Promise(resolve => { resolve() }) +} diff --git a/jeepay-ui-merchant/src/api/manage.js b/jeepay-ui-merchant/src/api/manage.js new file mode 100644 index 0000000..3912125 --- /dev/null +++ b/jeepay-ui-merchant/src/api/manage.js @@ -0,0 +1,259 @@ +/* + * 全系列 restful api格式, 定义通用req对象 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ + +import request from '@/http/request' + +export const req = { + + // 通用列表查询接口 + list: (url, params) => { + return request.request({ url: url, method: 'GET', params: params }, true, true, false) + }, + + // 通用新增接口 + add: (url, data) => { + return request.request({ url: url, method: 'POST', data: data }, true, true, false) + }, + + // 通用查询单条数据接口 + getById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'GET' }, true, true, false) + }, + + // 通用修改接口 + updateById: (url, bizId, data) => { + return request.request({ url: url + '/' + bizId, method: 'PUT', data: data }, true, true, false) + }, + + // 通用删除接口 + delById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'DELETE' }, true, true, false) + } +} + +// 全系列 restful api格式 (全局loading方式) +export const reqLoad = { + + // 通用列表查询接口 + list: (url, params) => { + return request.request({ url: url, method: 'GET', params: params }, true, true, true) + }, + + // 通用新增接口 + add: (url, data) => { + return request.request({ url: url, method: 'POST', data: data }, true, true, true) + }, + + // 通用查询单条数据接口 + getById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'GET' }, true, true, true) + }, + + // 通用修改接口 + updateById: (url, bizId, data) => { + return request.request({ url: url + '/' + bizId, method: 'PUT', data: data }, true, true, true) + }, + + // 通用删除接口 + delById: (url, bizId) => { + return request.request({ url: url + '/' + bizId, method: 'DELETE' }, true, true, true) + } +} + +/** 角色管理页面 **/ +export const API_URL_ENT_LIST = '/api/sysEnts' +export const API_URL_ROLE_LIST = '/api/sysRoles' +export const API_URL_ROLE_ENT_RELA_LIST = '/api/sysRoleEntRelas' +export const API_URL_SYS_USER_LIST = '/api/sysUsers' +export const API_URL_USER_ROLE_RELA_LIST = '/api/sysUserRoleRelas' +/** 首页统计 **/ +export const API_URL_MAIN_STATISTIC = 'api/mainChart' + +/** 支付订单管理 **/ +export const API_URL_PAY_ORDER_LIST = '/api/payOrder' +/** 退款订单管理 **/ +export const API_URL_REFUND_ORDER_LIST = '/api/refundOrder' +/** 支付方式列表 **/ +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 upload = { + avatar: request.baseUrl + '/api/ossFiles/avatar', + cert: request.baseUrl + '/api/ossFiles/cert' +} + +const api = { + user: '/user', + role_list: '/role', + service: '/service', + permission: '/permission', + permissionNoPager: '/permission/no-pager', + orgTree: '/org/tree' +} + +export default api + +/** 获取权限树状结构图 **/ +export function getEntTree (system) { + return request.request({ url: '/api/sysEnts/showTree?system=' + system, method: 'GET' }) +} + +/** 更新用户角色信息 */ +export function uSysRoleEntRela (sysRoleId, entIdList) { + return request.request({ + url: 'api/sysRoleEntRelas/relas/' + sysRoleId, + method: 'POST', + data: { entIdListStr: JSON.stringify(entIdList) } + }) +} + +/** 更新用户角色信息 */ +export function uSysUserRoleRela (sysUserId, roleIdList) { + return request.request({ + url: 'api/sysUserRoleRelas/relas/' + sysUserId, + method: 'POST', + data: { roleIdListStr: JSON.stringify(roleIdList) } + }) +} + +export function getRoleList (parameter) { + return request({ + url: '/api/sysRoles', + method: 'get', + params: parameter + }) +} + +export function getServiceList (parameter) { + return request({ + url: api.service, + method: 'get', + params: parameter + }) +} + +export function getPermissions (parameter) { + return request({ + url: api.permissionNoPager, + method: 'get', + params: parameter + }) +} + +export function getOrgTree (parameter) { + return request({ + url: api.orgTree, + method: 'get', + params: parameter + }) +} + +// id == 0 add post +// id != 0 update put +export function saveService (parameter) { + return request({ + url: api.service, + method: parameter.id === 0 ? 'post' : 'put', + data: parameter + }) +} + +export function saveSub (sub) { + return request({ + url: '/sub', + method: sub.id === 0 ? 'post' : 'put', + data: sub + }) +} + +export function getIsvPayConfigUnique (infoId, ifCode) { + return request.request({ + url: '/api/isv/payConfigs/' + infoId + '/' + ifCode, + method: 'get' + }) +} + +/** 根据支付接口查询支付参数配置 **/ +export function getMcgPayConfigUnique (ifCode) { + return request.request({ + url: '/api/mch/payConfigs/' + ifCode, + method: 'get' + }) +} + +/** 根据支付方式查询可用支付接口 **/ +export function getAvailablePayInterfaceList (wayCode) { + return request.request({ + url: '/api/mch/payPassages/availablePayInterface/' + wayCode, + method: 'GET' + }) +} + +export function getPayAmountWeek () { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/payAmountWeek', + method: 'GET' + }) +} + +export function getNumCount () { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/numCount', + method: 'GET' + }) +} + +export function getPayCount (parameter) { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/payCount', + method: 'GET', + params: parameter + }) +} + +export function getPayType (parameter) { + return request.request({ + url: API_URL_MAIN_STATISTIC + '/payTypeCount', + method: 'GET', + params: parameter + }) +} + +export function getMainUserInfo () { + return request.request({ + url: API_URL_MAIN_STATISTIC, + method: 'GET' + }) +} + +export function updateUserPass (parameter) { + return request.request({ + url: '/api/current/modifyPwd', + method: 'put', + data: parameter + }) +} + +export function updateUserInfo (parameter) { + return request.request({ + url: '/api/current/user', + method: 'put', + data: parameter + }) +} + +export function getUserInfo () { + return request.request({ + url: '/api/current/user', + method: 'get' + }) +} diff --git a/jeepay-ui-merchant/src/assets/images/background.png b/jeepay-ui-merchant/src/assets/images/background.png new file mode 100644 index 0000000..7428345 Binary files /dev/null and b/jeepay-ui-merchant/src/assets/images/background.png differ diff --git a/jeepay-ui-merchant/src/assets/logo-j.svg b/jeepay-ui-merchant/src/assets/logo-j.svg new file mode 100644 index 0000000..ac7edf7 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/logo-j.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/jeepay-ui-merchant/src/assets/logo.svg b/jeepay-ui-merchant/src/assets/logo.svg new file mode 100644 index 0000000..7e60317 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/styles/color.css b/jeepay-ui-merchant/src/assets/styles/color.css new file mode 100644 index 0000000..e69de29 diff --git a/jeepay-ui-merchant/src/assets/styles/color.less b/jeepay-ui-merchant/src/assets/styles/color.less new file mode 100644 index 0000000..786843e --- /dev/null +++ b/jeepay-ui-merchant/src/assets/styles/color.less @@ -0,0 +1,17 @@ +@jee-theme: #1A53FF; //主题色 + +@jee-back: #F0F2F5; //主要背景色 + +@jee-card-back: #FFF; //卡片底色 + +@jee-theme-mask: rgba(26,83,255,0.1); //主体遮罩色(10% 透明度) + +@jee-strengthen: #596380; //强化色 + +@jee-theme-hover: #0033CC; //主题Hover + +@jee-warning: #FF4B33; //危险,强化警告色 + +@jee-inside-link: #1A79FF; //内部链接 + +@jee-external-link: #AE1B6E; //外部链接 diff --git a/jeepay-ui-merchant/src/assets/svg/403.svg b/jeepay-ui-merchant/src/assets/svg/403.svg new file mode 100644 index 0000000..c552ca6 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/403.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/404.svg b/jeepay-ui-merchant/src/assets/svg/404.svg new file mode 100644 index 0000000..3854e5b --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/404.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/500.svg b/jeepay-ui-merchant/src/assets/svg/500.svg new file mode 100644 index 0000000..ffa8b08 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/500.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/add-icon.svg b/jeepay-ui-merchant/src/assets/svg/add-icon.svg new file mode 100644 index 0000000..6f167ab --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/add-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/background.svg b/jeepay-ui-merchant/src/assets/svg/background.svg new file mode 100644 index 0000000..6fcadcc --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/background.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/backgroundold.svg b/jeepay-ui-merchant/src/assets/svg/backgroundold.svg new file mode 100644 index 0000000..89c2597 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/backgroundold.svg @@ -0,0 +1,69 @@ + + + + Group 21 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/code.svg b/jeepay-ui-merchant/src/assets/svg/code.svg new file mode 100644 index 0000000..5f9154e --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/empty.svg b/jeepay-ui-merchant/src/assets/svg/empty.svg new file mode 100644 index 0000000..757aaa2 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/jeepay.svg b/jeepay-ui-merchant/src/assets/svg/jeepay.svg new file mode 100644 index 0000000..2acc4c6 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/jeepay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/lock.svg b/jeepay-ui-merchant/src/assets/svg/lock.svg new file mode 100644 index 0000000..e16119f --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/mini-logo.svg b/jeepay-ui-merchant/src/assets/svg/mini-logo.svg new file mode 100644 index 0000000..47e17a2 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/mini-logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/more.svg b/jeepay-ui-merchant/src/assets/svg/more.svg new file mode 100644 index 0000000..558442e --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/more.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/operate.svg b/jeepay-ui-merchant/src/assets/svg/operate.svg new file mode 100644 index 0000000..ba110c8 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/operate.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/scroll_down.svg b/jeepay-ui-merchant/src/assets/svg/scroll_down.svg new file mode 100644 index 0000000..f8288fe --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/scroll_down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/scroll_left.svg b/jeepay-ui-merchant/src/assets/svg/scroll_left.svg new file mode 100644 index 0000000..ca7632e --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/scroll_left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/scroll_right.svg b/jeepay-ui-merchant/src/assets/svg/scroll_right.svg new file mode 100644 index 0000000..222198f --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/scroll_right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/scroll_up.svg b/jeepay-ui-merchant/src/assets/svg/scroll_up.svg new file mode 100644 index 0000000..6f84cdd --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/scroll_up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/select-code.svg b/jeepay-ui-merchant/src/assets/svg/select-code.svg new file mode 100644 index 0000000..8d9ad51 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/select-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/select-lock.svg b/jeepay-ui-merchant/src/assets/svg/select-lock.svg new file mode 100644 index 0000000..d2771b0 --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/select-lock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/select-user.svg b/jeepay-ui-merchant/src/assets/svg/select-user.svg new file mode 100644 index 0000000..1f3338a --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/select-user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/assets/svg/user.svg b/jeepay-ui-merchant/src/assets/svg/user.svg new file mode 100644 index 0000000..738fd9d --- /dev/null +++ b/jeepay-ui-merchant/src/assets/svg/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/jeepay-ui-merchant/src/components/GlobalFooter/index.vue b/jeepay-ui-merchant/src/components/GlobalFooter/index.vue new file mode 100644 index 0000000..59caf52 --- /dev/null +++ b/jeepay-ui-merchant/src/components/GlobalFooter/index.vue @@ -0,0 +1,20 @@ + + + diff --git a/jeepay-ui-merchant/src/components/GlobalHeader/AvatarDropdown.vue b/jeepay-ui-merchant/src/components/GlobalHeader/AvatarDropdown.vue new file mode 100644 index 0000000..dd71413 --- /dev/null +++ b/jeepay-ui-merchant/src/components/GlobalHeader/AvatarDropdown.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/jeepay-ui-merchant/src/components/GlobalHeader/RightContent.vue b/jeepay-ui-merchant/src/components/GlobalHeader/RightContent.vue new file mode 100644 index 0000000..36d2be8 --- /dev/null +++ b/jeepay-ui-merchant/src/components/GlobalHeader/RightContent.vue @@ -0,0 +1,55 @@ + + + diff --git a/jeepay-ui-merchant/src/components/GlobalLoad/GlobalLoad.vue b/jeepay-ui-merchant/src/components/GlobalLoad/GlobalLoad.vue new file mode 100644 index 0000000..b984a98 --- /dev/null +++ b/jeepay-ui-merchant/src/components/GlobalLoad/GlobalLoad.vue @@ -0,0 +1,30 @@ + + + diff --git a/jeepay-ui-merchant/src/components/JeepayCard/JeepayCard.vue b/jeepay-ui-merchant/src/components/JeepayCard/JeepayCard.vue new file mode 100644 index 0000000..c04dc75 --- /dev/null +++ b/jeepay-ui-merchant/src/components/JeepayCard/JeepayCard.vue @@ -0,0 +1,85 @@ + + + + + diff --git a/jeepay-ui-merchant/src/components/JeepayTable/JeepayTable.vue b/jeepay-ui-merchant/src/components/JeepayTable/JeepayTable.vue new file mode 100644 index 0000000..a15bc57 --- /dev/null +++ b/jeepay-ui-merchant/src/components/JeepayTable/JeepayTable.vue @@ -0,0 +1,119 @@ + + + diff --git a/jeepay-ui-merchant/src/components/JeepayTable/JeepayTableColState.vue b/jeepay-ui-merchant/src/components/JeepayTable/JeepayTableColState.vue new file mode 100644 index 0000000..e240209 --- /dev/null +++ b/jeepay-ui-merchant/src/components/JeepayTable/JeepayTableColState.vue @@ -0,0 +1,57 @@ + + + + diff --git a/jeepay-ui-merchant/src/components/JeepayTable/JeepayTableColumns.vue b/jeepay-ui-merchant/src/components/JeepayTable/JeepayTableColumns.vue new file mode 100644 index 0000000..5e629f2 --- /dev/null +++ b/jeepay-ui-merchant/src/components/JeepayTable/JeepayTableColumns.vue @@ -0,0 +1,42 @@ + + diff --git a/jeepay-ui-merchant/src/components/JeepayTextUp/JeepayTextUp.vue b/jeepay-ui-merchant/src/components/JeepayTextUp/JeepayTextUp.vue new file mode 100644 index 0000000..f36c59b --- /dev/null +++ b/jeepay-ui-merchant/src/components/JeepayTextUp/JeepayTextUp.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/jeepay-ui-merchant/src/components/JeepayUpload/JeepayUpload.vue b/jeepay-ui-merchant/src/components/JeepayUpload/JeepayUpload.vue new file mode 100644 index 0000000..0505e58 --- /dev/null +++ b/jeepay-ui-merchant/src/components/JeepayUpload/JeepayUpload.vue @@ -0,0 +1,79 @@ + + + diff --git a/jeepay-ui-merchant/src/components/NProgress/nprogress.less b/jeepay-ui-merchant/src/components/NProgress/nprogress.less new file mode 100644 index 0000000..13b40aa --- /dev/null +++ b/jeepay-ui-merchant/src/components/NProgress/nprogress.less @@ -0,0 +1,74 @@ +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: @primary-color; + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 2px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: 0 0 10px @primary-color, 0 0 5px @primary-color; + opacity: 1.0; + + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: @primary-color; + border-left-color: @primary-color; + border-radius: 50%; + + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} +@keyframes nprogress-spinner { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + diff --git a/jeepay-ui-merchant/src/config/appConfig.js b/jeepay-ui-merchant/src/config/appConfig.js new file mode 100644 index 0000000..3a4ab43 --- /dev/null +++ b/jeepay-ui-merchant/src/config/appConfig.js @@ -0,0 +1,31 @@ +/** +* 全局配置信息, 包含网站标题, 动态组件定义 +* +* @author terrfly +* @site https://www.jeepay.vip +* @date 2021/5/8 07:18 +*/ + +/** 应用配置项 **/ +export default { + APP_TITLE: 'Jeepay商户系统', // 设置浏览器title + ACCESS_TOKEN_NAME: 'iToken' // 设置请求token的名字, 用于请求header 和 localstorage中存在名称 +} + +/** + * 与后端开发人员的路由名称及配置项 + * 组件名称 :{ 默认跳转路径(如果后端配置则已动态配置为准), 组件渲染 } + * */ +export const asyncRouteDefine = { + + 'CurrentUserInfo': { defaultPath: '/current/userinfo', component: () => import('@/views/current/UserinfoPage') }, // 用户设置 + + 'MainPage': { defaultPath: '/main', component: () => import('@/views/dashboard/Analysis') }, + 'SysUserPage': { defaultPath: '/users', component: () => import('@/views/sysuser/SysUserPage') }, + 'RolePage': { defaultPath: '/roles', component: () => import('@/views/role/RolePage') }, + + 'PayOrderListPage': { defaultPath: '/payOrder', component: () => import('@/views/order/pay/PayOrderList') }, // 支付订单列表 + 'RefundOrderListPage': { defaultPath: '/refundOrder', component: () => import('@/views/order/refund/RefundOrderList') }, // 退款订单列表 + 'PayConfigPage': { defaultPath: '/pay/config', component: () => import('@/views/pay/PayConfigList') }, // 支付参数配置 + 'PayPassagePage': { defaultPath: '/pay/passage', component: () => import('@/views/pay/PayPassageList') } // 支付通道配置 +} diff --git a/jeepay-ui-merchant/src/core/bootstrap.js b/jeepay-ui-merchant/src/core/bootstrap.js new file mode 100644 index 0000000..17f0ca8 --- /dev/null +++ b/jeepay-ui-merchant/src/core/bootstrap.js @@ -0,0 +1,6 @@ +import { printANSI } from '@/utils/screenLog' + +export default function Initializer () { + printANSI() // 请自行移除该行. please remove this line + // last step +} diff --git a/jeepay-ui-merchant/src/core/lazy_use.js b/jeepay-ui-merchant/src/core/lazy_use.js new file mode 100644 index 0000000..e49fa11 --- /dev/null +++ b/jeepay-ui-merchant/src/core/lazy_use.js @@ -0,0 +1,115 @@ +import Vue from 'vue' + +// base library +import { + ConfigProvider, + Layout, + Input, + InputNumber, + Button, + Switch, + Radio, + Checkbox, + Select, + Card, + Form, + FormModel, + Row, + Col, + Modal, + Table, + Tabs, + Icon, + Badge, + Popover, + Dropdown, + List, + Avatar, + Breadcrumb, + Steps, + Spin, + Menu, + Drawer, + Tooltip, + Alert, + Tag, + Divider, + DatePicker, + TimePicker, + Upload, + Progress, + Skeleton, + Popconfirm, + PageHeader, + Result, + Statistic, + Descriptions, + Space, + Pagination, + message, + notification, + Tree +} from 'ant-design-vue' +import Viser from 'viser-vue' + +// ext library +import VueCropper from 'vue-cropper' + +Vue.use(ConfigProvider) +Vue.use(Layout) +Vue.use(Input) +Vue.use(InputNumber) +Vue.use(Button) +Vue.use(Switch) +Vue.use(Radio) +Vue.use(Checkbox) +Vue.use(Select) +Vue.use(Card) +Vue.use(Form) +Vue.use(FormModel) +Vue.use(Row) +Vue.use(Col) +Vue.use(Modal) +Vue.use(Table) +Vue.use(Tabs) +Vue.use(Icon) +Vue.use(Badge) +Vue.use(Popover) +Vue.use(Dropdown) +Vue.use(List) +Vue.use(Avatar) +Vue.use(Breadcrumb) +Vue.use(Steps) +Vue.use(Spin) +Vue.use(Menu) +Vue.use(Drawer) +Vue.use(Tooltip) +Vue.use(Alert) +Vue.use(Tag) +Vue.use(Divider) +Vue.use(DatePicker) +Vue.use(TimePicker) +Vue.use(Upload) +Vue.use(Progress) +Vue.use(Skeleton) +Vue.use(Popconfirm) +Vue.use(PageHeader) +Vue.use(Result) +Vue.use(Statistic) +Vue.use(Descriptions) +Vue.use(Space) +Vue.use(Pagination) +Vue.use(Tree) + +Vue.prototype.$confirm = Modal.confirm +Vue.prototype.$message = message +Vue.prototype.$notification = notification +Vue.prototype.$info = Modal.info +Vue.prototype.$success = Modal.success +Vue.prototype.$error = Modal.error +Vue.prototype.$warning = Modal.warning + +Vue.use(Viser) +Vue.use(VueCropper) + +process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] NOTICE: Antd use lazy-load.') diff --git a/jeepay-ui-merchant/src/core/use.js b/jeepay-ui-merchant/src/core/use.js new file mode 100644 index 0000000..f332c6f --- /dev/null +++ b/jeepay-ui-merchant/src/core/use.js @@ -0,0 +1,20 @@ +import Vue from 'vue' + +// base library +import Antd from 'ant-design-vue' +import Viser from 'viser-vue' +import VueCropper from 'vue-cropper' +import 'ant-design-vue/dist/antd.less' + +// ext library +import VueClipboard from 'vue-clipboard2' +import './directives/action' + +VueClipboard.config.autoSetContainer = true + +Vue.use(Antd) +Vue.use(Viser) +Vue.use(VueClipboard) +Vue.use(VueCropper) + +process.env.NODE_ENV !== 'production' && console.warn('[antd-pro] WARNING: Antd now use fulled imported.') diff --git a/jeepay-ui-merchant/src/global.less b/jeepay-ui-merchant/src/global.less new file mode 100644 index 0000000..a6c4ee2 --- /dev/null +++ b/jeepay-ui-merchant/src/global.less @@ -0,0 +1,375 @@ +@import '../node_modules/ant-design-vue/es/style/themes/default.less'; +// @import './default.less'; + +html, +body, +#app, #root { + height: 100%; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Microsoft YaHei,PingFang SC,Hiragino Sans GB,Helvetica Neue,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol; + letter-spacing: 0.4px; +} +// jee主题颜色class列表, 用于文字颜色 +.jee-theme { + color: @jee-theme; //主题色 +} +.jee-back { + color: @jee-back; //主要背景色 +} +.jee-card-back { + color: @jee-card-back; //卡片底色 +} +.jee-theme-mask { + color: @jee-theme-mask; //主体遮罩色(10% 透明度) +} +.jee-strengthen { + color: @jee-strengthen;//强化色 +} +.jee-theme-hover { + color: @jee-theme-hover;//主题Hover +} +.jee-warning { + color: @jee-warning; //危险,强化警告色 +} +.jee-inside-link { + color: @jee-inside-link; //内部链接 +} +.jee-external-link { + color: @jee-external-link; //外部链接 +} +// jee主题颜色class列表, 用于文字颜色 +.jee-theme { + color: @jee-theme; //主题色 +} +.jee-back { + color: @jee-back; //主要背景色 +} +.jee-card-back { + color: @jee-card-back; //卡片底色 +} +.jee-theme-mask { + color: @jee-theme-mask; //主体遮罩色(10% 透明度) +} +.jee-strengthen { + color: @jee-strengthen;//强化色 +} +.jee-theme-hover { + color: @jee-theme-hover;//主题Hover +} +.jee-warning { + color: @jee-warning; //危险,强化警告色 +} +.jee-inside-link { + color: @jee-inside-link; //内部链接 +} +.jee-external-link { + color: @jee-external-link; //外部链接 +} + +// jee主题颜色class列表, 用于背景颜色 +.jee-theme-back-color { + background-color: @jee-theme; //主题色 +} +.jee-back-color { + background-color: @jee-back; //主要背景色 +} +.jee-card-back-color { + background-color: @jee-card-back; //卡片底色 +} +.jee-theme-mask-back-color { + background-color: @jee-theme-mask; //主体遮罩色(10% 透明度) +} +.jee-strengthen-back-color { + background-color: @jee-strengthen;//强化色 +} +.jee-theme-hover-back-color { + background-color: @jee-theme-hover;//主题Hover +} +.jee-warning-back-color { + background-color: @jee-warning; //危险,强化警告色 +} +.jee-inside-link-back-color { + background-color: @jee-inside-link; //内部链接 +} +.jee-external-link-back-color { + background-color: @jee-external-link; //外部链接 +} + +.colorWeak { + filter: invert(80%); +} + +.ant-layout{ + .layout-basic { + height: 100vh; + min-height: 100vh; + } +} + +canvas { + display: block; +} + +body { + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + background: #f0f2f5; +} + +ul, +ol { + list-style: none; +} +// 滚动条高度 和宽度 +::-webkit-scrollbar { + width: 10px; + height: 10px; +} +// 滚动条颜色 +::-webkit-scrollbar-thumb { + background: #B3B3B3; +} +// 滑块区域底色 +::-webkit-scrollbar-track { + background: rgba(0,0,0,0.03); +} +// 滚动条hover色 +::-webkit-scrollbar-thumb:hover { + background: #A6A6A6; +} +// 滚动条选中色 +::-webkit-scrollbar-thumb:active { + background: #8C8C8C; +} +// 结合 表格组件中的 :scroll ,让表格在收缩时,展示滚动条 +.ant-table-body{ + overflow-x: auto !important; +} +// /*显示滚动条上方以及下方的渐增按钮*/ +// ::-webkit-scrollbar-button:start:decrement, +// ::-webkit-scrollbar-button:end:increment { +// display: block; +// } +// /* 定义垂直滚动条渐增按扭的样式 */ +// ::-webkit-scrollbar-button:vertical:end:increment { +// background-image: url(~@/assets/svg/scroll_down.svg); +// background-size: cover; +// background-position: center; +// } +// /* 定义垂直滚动条渐减按扭的样式 */ +// ::-webkit-scrollbar-button:vertical:start:decrement { +// background-image: url(~@/assets/svg/scroll_up.svg); +// background-size: cover; +// background-position: center; +// } +// /* 定义水平滚动条渐增按扭的样式 */ +// ::-webkit-scrollbar-button:horizontal:end:increment { +// background-image: url(~@/assets/svg/scroll_right.svg); +// background-size: cover; +// background-position: center; +// } +// /* 定义水平滚动条渐减按扭的样式 */ +// ::-webkit-scrollbar-button:horizontal:start:decrement { +// background-image: url(~@/assets/svg/scroll_left.svg); +// background-size: cover; +// background-position: center; +// } + +// 隐藏面包屑底下的标题 +.ant-page-header-heading { + display: none; +} + +// 数据列表 样式 +.table-alert { + margin-bottom: 16px; +} +// 数据列表 操作 +.table-operator { + margin-bottom: 18px; + + button { + margin-right: 8px; + } +} +// 数据列表 搜索条件 +.table-page-search-wrapper { + border-top-left-radius: 10px; + border-top-right-radius: 10px; + padding: 30px; + padding-bottom: 0; + border-bottom: 1px solid #e8e8e8; + background: #fafafa; + + .ant-form-inline { + .ant-form-item { + display: flex; + margin-bottom: 24px; + margin-right: 0; + + .ant-form-item-control-wrapper { + flex: 1 1; + display: inline-block; + vertical-align: middle; + } + + > .ant-form-item-label { + line-height: 32px; + padding-right: 8px; + width: auto; + } + .ant-form-item-control { + height: 32px; + line-height: 32px; + } + } + } + + .table-page-search-submitButtons { + display: block; + margin-bottom: 24px; + white-space: nowrap; + } +} + +@media (max-width: @screen-xs) { + .ant-table { + width: 100%; + overflow-x: auto; + &-thead > tr, + &-tbody > tr { + > th, + > td { + white-space: pre; + > span { + display: block; + } + } + } + } +} + +// 修改侧边栏宽度为230 +.ant-pro-sider-menu-sider { + // min-width: 80px !important; + // max-width: 230px !important; + + // 去掉侧边栏阴影 + .light { + box-shadow: none; + } +} + +// 删除表格的内边距 +.ant-card-body { + padding: 0 !important; +} +// 增加内容区域的边框圆角 +.ant-card { + border-radius: 10px; + overflow: hidden; +} + +// 登录页输入框fcous hover事件,边框为jee主题蓝 +.ant-input-affix-wrapper:hover .ant-input:not(.ant-input-disabled) { + border-color: @jee-theme +} +.ant-input:focus { + border-color: @jee-theme +} + +// 抽屉,按钮板块,居中 +.drawer-btn-center { + position: absolute; + right: 0px; + bottom: 0px; + width: 100%; + border-top: 1px solid rgb(233, 233, 233); + padding: 10px 16px; + background: rgb(255, 255, 255); + text-align: center; + z-index: 1; + + &:first-child { + margin-right: 80px; + } + button { + margin: 0; + padding: 3px 20px; + } +} + +.els { + overflow: hidden; + text-overflow:ellipsis; + white-space: nowrap +} + +// 内容区域去掉最外层的magin 24px ,改为 padding 15px +.ant-pro-basicLayout-content { + margin: 0 ; + padding: 15px; +} + +// 表格页面的间距 +.ant-table-pagination.ant-pagination { + margin: 20px; +} + +// 去掉表格边框线 +.ant-card-bordered { + border:none; +} + +.ant-table-align-left { + padding-left: 38px; +} +// 向下的30外边距 +.mg-b-30 { + margin-bottom: 30px +} + +.ant-card-bordered { + border: none !important; +} + +// 表格,搜索框板块布局 +.table-head-ground { + display: flex; + justify-content: start; + flex-wrap: wrap; + .table-layer { + display: flex; + flex-wrap: wrap; + flex-grow: 1; + flex-shrink: 1; + } +} +.table-head-layout { + min-width: 220px; + max-width: 240px; + flex-grow: 1; + flex-shrink: 1; + margin-bottom:30px !important; + margin-right: 16px !important; +} + +// 404 500 403 +.result-err { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; + width: 100%; + overflow: auto; + div { + margin: 20px 0; + text-align:center; + font-size: 16px; + p.big-text { + font-size: 36px; + font-weight: 700; + } + } +} \ No newline at end of file diff --git a/jeepay-ui-merchant/src/http/HttpRequest.js b/jeepay-ui-merchant/src/http/HttpRequest.js new file mode 100644 index 0000000..0c5255d --- /dev/null +++ b/jeepay-ui-merchant/src/http/HttpRequest.js @@ -0,0 +1,116 @@ +/** + * Http请求包装对象 + * 参考: iview https://gitee.com/icarusion/iview-admin/blob/master/src/libs/axios.js + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +import axios from 'axios' +import storage from '@/utils/jeepayStorageWrapper' +import appConfig from '@/config/appConfig' +import Vue from 'vue' +import store from '@/store/index' +class HttpRequest { + constructor (baseUrl = process.env.VUE_APP_API_BASE_URL) { + this.baseUrl = baseUrl + this.queue = {} // 发送队列, 格式为: {请求url: true}, 可以做一些验证之类 + } + // 基础配置信息 + baseConfig () { + const headers = {} + headers[appConfig.ACCESS_TOKEN_NAME] = storage.getToken() + return { + baseURL: this.baseUrl, + headers: headers + } + } + destroy (url, showLoading) { + delete this.queue[url] + } + interceptors (instance, url, showErrorMsg, showLoading) { + // 请求拦截 + instance.interceptors.request.use(config => { + // 添加全局的loading... + if (!Object.keys(this.queue).length && showLoading) { + store.commit('showLoading') // 加载中显示loading组件 + } + this.queue[url] = true + return config + }, error => { + store.commit('hideLoading') // 报错关闭loading组件 + return Promise.reject(error) + }) + + // 响应拦截 + instance.interceptors.response.use(res => { + this.destroy(url, showLoading) + + if (showLoading) { + store.commit('hideLoading') // 报错关闭loading组件 + } + + const resData = res.data // 接口实际返回数据 格式为:{code: '', msg: '', data: ''}, res.data 是axios封装对象的返回数据; + + if (resData.code !== 0) { // 相应结果不为0, 说明异常 + if (showErrorMsg) { + Vue.prototype.$message.error(resData.msg) // 显示异常信息 + } + + return Promise.reject(resData) + } else { + return resData.data + } + }, error => { + this.destroy(url, showLoading) + + if (showLoading) { + store.commit('hideLoading') // 报错关闭loading组件 + } + + let errorInfo = error.response && error.response.data && error.response.data.data + if (!errorInfo) { + errorInfo = error.response.data + } + + if (error.response.status === 401) { // 无访问权限,会话超时, 提示用户信息 & 退出系统 + const toLoginTimeout = setTimeout(function () { + store.dispatch('Logout').then(() => { + window.location.reload() + }) + }, 3000) + + Vue.prototype.$infoBox.confirmDanger( + '会话超时,请重新登录', '3s后将自动退出...', + () => { + store.dispatch('Logout').then(() => { + window.location.reload() + }) + }, + () => { + clearTimeout(toLoginTimeout) + }, + { okText: '重新登录', cancelText: '关闭对话' }) + } else { + if (showErrorMsg) { + Vue.prototype.$message.error(JSON.stringify(errorInfo)) // 显示异常信息 + } + } + + return Promise.reject(errorInfo) + }) + } + // interceptorsFlag: 是否进行自定义拦截器处理,默认为: true + // showErrorMsg 发送请求出现异常是否全局提示错误信息 + // showLoading 发送请求前后显示全局loading + request (options, interceptorsFlag = true, showErrorMsg = true, showLoading = false) { + const instance = axios.create() + options = Object.assign(this.baseConfig(), options) + if (interceptorsFlag) { // 注入 req, respo 拦截器 + this.interceptors(instance, options.url, showErrorMsg, showLoading) + } + + return instance(options) + } +} +export default HttpRequest diff --git a/jeepay-ui-merchant/src/http/request.js b/jeepay-ui-merchant/src/http/request.js new file mode 100644 index 0000000..7b66cad --- /dev/null +++ b/jeepay-ui-merchant/src/http/request.js @@ -0,0 +1,4 @@ +import HttpRequest from '@/http/HttpRequest' + +const request = new HttpRequest() +export default request diff --git a/jeepay-ui-merchant/src/layouts/BasicLayout.less b/jeepay-ui-merchant/src/layouts/BasicLayout.less new file mode 100644 index 0000000..d193ad1 --- /dev/null +++ b/jeepay-ui-merchant/src/layouts/BasicLayout.less @@ -0,0 +1,59 @@ +@import "~ant-design-vue/es/style/themes/default.less"; + +// 清除头部栏下方阴影 +.ant-layout-header, .ant-pro-basicLayout .ant-layout-header:not(.ant-pro-top-menu) { + background: initial; +} +// 清除头部栏下方阴影 修改背景色 +.ant-pro-global-header { + background: initial; + box-shadow: initial; +} +// 面包屑导航部分 修改背景色 +.ant-pro-page-header-wrap-page-header-warp { + background: initial; +} + +//左上角 logo 图标样式 +.ant-pro-sider-menu-logo { + padding-left: 30px; +} +.ant-pro-sider-menu-logo svg { + height: 26px; + width: initial; +} + +.ant-pro-global-header-index-right { + margin-right: 8px; + + &.ant-pro-global-header-index-dark { + .ant-pro-global-header-index-action { + color: hsla(0, 0%, 100%, .85); + + &:hover { + background: #1890ff; + } + } + } + + .ant-pro-account-avatar { + .antd-pro-global-header-index-avatar { + margin: ~'calc((@{layout-header-height} - 24px) / 2)' 0; + margin-right: 8px; + color: @primary-color; + vertical-align: top; + background: rgba(255, 255, 255, 0.85); + } + } + + .menu { + .anticon { + margin-right: 8px; + } + + .ant-dropdown-menu-item { + min-width: 100px; + } + } +} + diff --git a/jeepay-ui-merchant/src/layouts/BasicLayout.vue b/jeepay-ui-merchant/src/layouts/BasicLayout.vue new file mode 100644 index 0000000..90c141b --- /dev/null +++ b/jeepay-ui-merchant/src/layouts/BasicLayout.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/jeepay-ui-merchant/src/layouts/BlankLayout.vue b/jeepay-ui-merchant/src/layouts/BlankLayout.vue new file mode 100644 index 0000000..1bfbfbf --- /dev/null +++ b/jeepay-ui-merchant/src/layouts/BlankLayout.vue @@ -0,0 +1,16 @@ + + + + + diff --git a/jeepay-ui-merchant/src/layouts/PageView.vue b/jeepay-ui-merchant/src/layouts/PageView.vue new file mode 100644 index 0000000..86df485 --- /dev/null +++ b/jeepay-ui-merchant/src/layouts/PageView.vue @@ -0,0 +1,12 @@ + + + diff --git a/jeepay-ui-merchant/src/layouts/RouteView.vue b/jeepay-ui-merchant/src/layouts/RouteView.vue new file mode 100644 index 0000000..9e9d98b --- /dev/null +++ b/jeepay-ui-merchant/src/layouts/RouteView.vue @@ -0,0 +1,32 @@ + diff --git a/jeepay-ui-merchant/src/layouts/UserLayout.vue b/jeepay-ui-merchant/src/layouts/UserLayout.vue new file mode 100644 index 0000000..3c97dba --- /dev/null +++ b/jeepay-ui-merchant/src/layouts/UserLayout.vue @@ -0,0 +1,179 @@ + + + + + diff --git a/jeepay-ui-merchant/src/layouts/index.js b/jeepay-ui-merchant/src/layouts/index.js new file mode 100644 index 0000000..1d62d6c --- /dev/null +++ b/jeepay-ui-merchant/src/layouts/index.js @@ -0,0 +1,7 @@ +import UserLayout from './UserLayout' +import BlankLayout from './BlankLayout' +import BasicLayout from './BasicLayout' +import RouteView from './RouteView' +import PageView from './PageView' + +export { UserLayout, BasicLayout, BlankLayout, RouteView, PageView } diff --git a/jeepay-ui-merchant/src/main.js b/jeepay-ui-merchant/src/main.js new file mode 100644 index 0000000..0796e6c --- /dev/null +++ b/jeepay-ui-merchant/src/main.js @@ -0,0 +1,43 @@ +// with polyfills +import 'core-js/stable' +import 'regenerator-runtime/runtime' + +import Vue from 'vue' +import App from './App.vue' +import router from './router' +import store from './store/' +import ProLayout, { PageHeaderWrapper } from '@ant-design-vue/pro-layout' + +import bootstrap from './core/bootstrap' +import './core/lazy_use' // use lazy load components +import './permission' // permission control 路由守卫 +import './utils/filter' // global filter + +import './global.less' // global style +import 'ant-design-vue/dist/antd.less' +import infoBox from '@/utils/infoBox' + +Vue.config.productionTip = false + +// use pro-layout components +Vue.component('pro-layout', ProLayout) +Vue.component('page-container', PageHeaderWrapper) +Vue.component('page-header-wrapper', PageHeaderWrapper) + +/** + * @description 全局注册权限验证 + */ +Vue.prototype.$access = (entId) => { + // eslint-disable-next-line eqeqeq + return store.state.user.accessList.some(item => item == entId) +} + +Vue.prototype.$infoBox = infoBox + +new Vue({ + router, + store, + // init localstorage, vuex + created: bootstrap, + render: h => h(App) +}).$mount('#app') diff --git a/jeepay-ui-merchant/src/permission.js b/jeepay-ui-merchant/src/permission.js new file mode 100644 index 0000000..cce65b3 --- /dev/null +++ b/jeepay-ui-merchant/src/permission.js @@ -0,0 +1,65 @@ +import router from './router' +import store from './store' +import storage from '@/utils/jeepayStorageWrapper' +import NProgress from 'nprogress' // progress bar +import '@/components/NProgress/nprogress.less' // progress bar custom style +import { setDocumentTitle, domTitle } from '@/utils/domUtil' + +import { getInfo } from '@/api/login' + +NProgress.configure({ showSpinner: false }) // NProgress Configuration + +const allowList = ['login', 'register', 'registerResult'] // no redirect allowList +const loginRoutePath = '/user/login' + +// 路由守卫 +router.beforeEach((to, from, next) => { + NProgress.start() // start progress bar + + to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${domTitle}`)) // 设置浏览器标题 + + // 如果在免登录页面则直接放行 + if (allowList.includes(to.name)) { + // 在免登录名单,直接进入 + next() + NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it + return false + } + + // 不包含Token 则直接跳转到登录页面 + if (!storage.getToken()) { + next({ path: loginRoutePath, query: { redirect: to.fullPath } }) + NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it + return false + } + + // 以下为包含Token的情况 + // 如果用户信息不存在, 则重新获取 [用户登录成功 & 强制刷新浏览器时 会执行该函数] + if (!store.state.user.userId) { + // request login userInfo + + getInfo().then(bizData => { + store.commit('SET_USER_INFO', bizData) // 调用vuex设置用户基本信息 + // TODO 生成菜单 + + store.dispatch('GenerateRoutes', {}).then(() => { + // 根据roles权限生成可访问的路由表 + // 动态添加可访问路由表 + router.addRoutes(store.state.asyncRouter.addRouters) + }) + + next() + }).catch(() => { + // 失败时,获取用户信息失败时,调用登出,来清空历史保留信息 + store.dispatch('Logout').then(() => { + next({ path: loginRoutePath, query: { redirect: to.fullPath } }) + }) + }) + } else { + next() + } +}) + +router.afterEach(() => { + NProgress.done() // finish progress bar +}) diff --git a/jeepay-ui-merchant/src/router/generator-routers.js b/jeepay-ui-merchant/src/router/generator-routers.js new file mode 100644 index 0000000..96f4386 --- /dev/null +++ b/jeepay-ui-merchant/src/router/generator-routers.js @@ -0,0 +1,139 @@ +// eslint-disable-next-line +import * as loginService from '@/api/login' +// eslint-disable-next-line +import { BasicLayout, BlankLayout, PageView, RouteView } from '@/layouts' +import store from '@/store' +import { asyncRouteDefine } from '@/config/appConfig' + +// 前端路由表 = 基础定义 + 动态组件 +const constantRouterComponents = Object.assign({ + // 基础页面 layout 必须引入 + BasicLayout: { component: BasicLayout }, + BlankLayout: { component: BlankLayout }, + RouteView: { component: RouteView }, + PageView: { component: PageView }, + '403': () => import('@/views/exception/403'), + '404': () => import('@/views/exception/404'), + '500': () => import('@/views/exception/500') +}, asyncRouteDefine) + +// 前端未找到页面路由(固定不用改) +const notFoundRouter = { + path: '*', component: () => import('@/views/exception/404') +} + +// 根级菜单 +const rootRouter = { + name: 'index', + path: '/', + component: BasicLayout, + redirect: redirectFunc, // 根页面【/】默认跳转 地址 + children: [], + meta: { title: '主页' } +} + +// 动态跳转路径 func +function redirectFunc () { + let mainPageUri = '' + store.state.user.allMenuRouteTree.forEach(item => { + if (item.entId === 'ENT_MCH_MAIN') { // 当前用户是否拥有主页权限, 如果有直接跳转到该路径 + mainPageUri = item.menuUri + return false + } + }) + + if (mainPageUri) { + return mainPageUri + } + + return getOneUri(store.state.user.allMenuRouteTree) +} + +// 获取到第一个uri (递归查找) +function getOneUri (item) { + let result = '' + for (let i = 0; i < item.length; i++) { + if (item[i].menuUri && item[i].entType === 'ML') { + return item[i].menuUri + } + + if (item[i].children) { + result = getOneUri(item[i].children) + if (result) { + return result + } + } + } + return result +} + +/** + * 动态生成菜单 + * @param token + * @returns {Promise} + */ +export const generatorDynamicRouter = () => { + return new Promise((resolve, reject) => { + // 根据树状结构生成路由格式 + rootRouter.children = generator(store.state.user.allMenuRouteTree) + + // 构建完整路由 + resolve([rootRouter, notFoundRouter]) + }) +} + +/** + * 格式化树形结构数据 生成 vue-router 层级路由表 + * + * @param routerMap + * @returns {*} + */ +export const generator = (allMenuRouteTreeArray) => { + const menuResult = [] + + // 遍历map + allMenuRouteTreeArray.map(item => { + const defComponent = constantRouterComponents[item.componentName || item.entId] + + // 找不到组件 || 其他菜单 + if (!defComponent) { + return + } + + // 跳转uri + let path = item.menuUri || defComponent.defaultPath + + // 没有配置path, 如果为目录则允许为空, 否则不在加载此配置 + if (!path) { + if (item.children && item.children.length > 0) { + path = `/${item.entId}` + } else { + return // 不再加载此配置项 + } + } + + const currentRouter = { + // 如果路由设置了 path,则作为默认 path,否则 路由地址 为默认配置 + path: path, + // 路由名称,建议唯一 + name: item.entId, + // 该路由对应页面的 组件 :方案2 (动态加载) + component: ((defComponent && defComponent.component) || (() => import(`@/views/${item.componentName}`))), + // meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉) + meta: { + title: item.entName, + icon: item.menuIcon, + keepAlive: false + }, + hidden: item.entType === 'MO' // 当其他菜单时需要隐藏显示 + } + // 是否有子菜单,并递归处理 + if (item.children && item.children.length > 0) { + // Recursion + currentRouter.children = generator(item.children) + } + menuResult.push(currentRouter) + }) + + return menuResult +} diff --git a/jeepay-ui-merchant/src/router/index.js b/jeepay-ui-merchant/src/router/index.js new file mode 100644 index 0000000..416b5c4 --- /dev/null +++ b/jeepay-ui-merchant/src/router/index.js @@ -0,0 +1,29 @@ +import Vue from 'vue' +import Router from 'vue-router' +import { UserLayout } from '@/layouts' + +// hack router push callback +// [解决 vue-router跳转相同路径报错 ] +const originalPush = Router.prototype.push +Router.prototype.push = function push (location, onResolve, onReject) { + if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject) + return originalPush.call(this, location).catch(err => err) +} + +Vue.use(Router) + +// 纯静态路由配置项 +const constantRouterMap = [ + { + path: '/user', + component: UserLayout, + children: [ + { path: 'login', name: 'login', component: () => import('@/views/user/Login') } + ] + } +] + +export default new Router({ + mode: 'history', + routes: constantRouterMap +}) diff --git a/jeepay-ui-merchant/src/store/index.js b/jeepay-ui-merchant/src/store/index.js new file mode 100644 index 0000000..539a1be --- /dev/null +++ b/jeepay-ui-merchant/src/store/index.js @@ -0,0 +1,29 @@ +import Vue from 'vue' +import Vuex from 'vuex' +import user from './modules/user' +import asyncRouter from './modules/async-router' + +Vue.use(Vuex) + +export default new Vuex.Store({ + modules: { + user, // 用户相关状态机 + asyncRouter // 动态菜单 + }, + state: { + // 定义全局loading 为false + globalLoading: false + }, + mutations: { + // 显示与关闭 全局 loading + showLoading (state) { + state.globalLoading = true + }, + hideLoading (state) { + state.globalLoading = false + } + }, + actions: { + + } +}) diff --git a/jeepay-ui-merchant/src/store/modules/async-router.js b/jeepay-ui-merchant/src/store/modules/async-router.js new file mode 100644 index 0000000..6282ce6 --- /dev/null +++ b/jeepay-ui-merchant/src/store/modules/async-router.js @@ -0,0 +1,27 @@ +/** + * 向后端请求用户的菜单,动态生成路由 + */ +import { generatorDynamicRouter } from '@/router/generator-routers' + +const asyncRouter = { + state: { + addRouters: [] + }, + mutations: { + SET_ROUTERS: (state, routers) => { + state.addRouters = routers + } + }, + actions: { + GenerateRoutes ({ commit }, data) { + return new Promise(resolve => { + generatorDynamicRouter().then(routers => { + commit('SET_ROUTERS', routers) + resolve() + }) + }) + } + } +} + +export default asyncRouter diff --git a/jeepay-ui-merchant/src/store/modules/user.js b/jeepay-ui-merchant/src/store/modules/user.js new file mode 100644 index 0000000..0fba4ff --- /dev/null +++ b/jeepay-ui-merchant/src/store/modules/user.js @@ -0,0 +1,75 @@ +import storage from '@/utils/jeepayStorageWrapper' +import { login, logout } from '@/api/login' +import appConfig from '@/config/appConfig' + +const user = { + state: { + token: '', + userName: '', // 用户名 + userId: '', // 用户ID + avatarImgPath: '', // 头像 + allMenuRouteTree: [], // 全部动态 router + accessList: [], // 用户权限集合 + isAdmin: '', // 是否是超级管理员 + loginUsername: '', // 登录用户名 + state: '', // 用户状态 + system: '', // 所属系统 + telphone: '' // 手机号 + }, + + mutations: { + SET_TOKEN: (state, token) => { + state.token = token + }, + // 设置头像 + SET_AVATAR (state, avatarPath) { + state.avatarImgPath = avatarPath + }, + // 设置用户信息 + SET_USER_INFO: (state, userInfo) => { + state.userId = userInfo.sysUserId // 用户ID + state.userName = userInfo.realname // 昵称 + state.avatarImgPath = userInfo.avatarUrl // 头像 + state.accessList = userInfo.entIdList // 权限集合 + state.allMenuRouteTree = userInfo.allMenuRouteTree // 全部路由集合 + state.isAdmin = userInfo.isAdmin // 是否是超级管理员 + state.loginUsername = userInfo.loginUsername // 登录用户名 + state.state = userInfo.state // 用户状态 + state.system = userInfo.system // 所属系统 + state.telphone = userInfo.telphone // 手机号 + } + }, + + actions: { + // 登录 + Login ({ commit }, { loginParams, isSaveStorage }) { + return new Promise((resolve, reject) => { + login(loginParams).then(bizData => { + storage.setToken(bizData[appConfig.ACCESS_TOKEN_NAME], isSaveStorage) + commit('SET_TOKEN', bizData[appConfig.ACCESS_TOKEN_NAME]) + resolve() + }).catch(error => { + reject(error) + }) + }) + }, + + // 登出 + Logout ({ commit, state }) { + return new Promise((resolve) => { + logout(state.token).then(() => { + commit('SET_TOKEN', '') + storage.cleanToken() + location.reload() // 退出时 重置缓存 + resolve() + }).catch(() => { + resolve() + }).finally(() => { + }) + }) + } + + } +} + +export default user diff --git a/jeepay-ui-merchant/src/utils/domUtil.js b/jeepay-ui-merchant/src/utils/domUtil.js new file mode 100644 index 0000000..f820754 --- /dev/null +++ b/jeepay-ui-merchant/src/utils/domUtil.js @@ -0,0 +1,17 @@ +export const setDocumentTitle = function (title) { + document.title = title + const ua = navigator.userAgent + // eslint-disable-next-line + const regex = /\bMicroMessenger\/([\d\.]+)/ + if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) { + const i = document.createElement('iframe') + i.src = '/favicon.ico' + i.style.display = 'none' + i.onload = function () { + setTimeout(function () { + i.remove() + }, 9) + } + document.body.appendChild(i) + } +} diff --git a/jeepay-ui-merchant/src/utils/filter.js b/jeepay-ui-merchant/src/utils/filter.js new file mode 100644 index 0000000..45702c6 --- /dev/null +++ b/jeepay-ui-merchant/src/utils/filter.js @@ -0,0 +1,20 @@ +import Vue from 'vue' +import moment from 'moment' +import 'moment/locale/zh-cn' +moment.locale('zh-cn') + +Vue.filter('NumberFormat', function (value) { + if (!value) { + return '0' + } + const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断 + return intPartFormat +}) + +Vue.filter('dayjs', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { + return moment(dataStr).format(pattern) +}) + +Vue.filter('moment', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') { + return moment(dataStr).format(pattern) +}) diff --git a/jeepay-ui-merchant/src/utils/infoBox.js b/jeepay-ui-merchant/src/utils/infoBox.js new file mode 100644 index 0000000..ca59a8a --- /dev/null +++ b/jeepay-ui-merchant/src/utils/infoBox.js @@ -0,0 +1,33 @@ +/** + * 通用信息弹层 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +import { Modal } from 'ant-design-vue' + +// 确认提示: 标题, 内容, 点击确定回调函数, 取消回调, 扩展参数 +export const confirmResult = { + confirm: function (title, content, okFunc, cancelFunc = (() => {}), extConfig = {}) { + Modal.confirm( + Object.assign({ + okText: '确定', + cancelText: '取消', + title: title || '提示', + content: content, + onOk: okFunc, + onCancel: cancelFunc, + confirmLoading: true + }, extConfig)) + }, + confirmPrimary: function (title, content, okFunc, cancelFunc = (() => {}), extConfig = {}) { + this.confirm(title, content, okFunc, cancelFunc, Object.assign({ okType: 'primary' }, extConfig)) + }, + + confirmDanger: function (title, content, okFunc, cancelFunc = (() => {}), extConfig = {}) { + this.confirm(title, content, okFunc, cancelFunc, Object.assign({ okType: 'danger' }, extConfig)) + } +} + +export default confirmResult diff --git a/jeepay-ui-merchant/src/utils/jeepayStorageWrapper.js b/jeepay-ui-merchant/src/utils/jeepayStorageWrapper.js new file mode 100644 index 0000000..7da8c45 --- /dev/null +++ b/jeepay-ui-merchant/src/utils/jeepayStorageWrapper.js @@ -0,0 +1,34 @@ +/** + * storage 存储包装类 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/8 07:18 + */ +import storage from 'store' +import appConfig from '@/config/appConfig' + +var SESSION_TOKEN = '' + +const wrapper = { + + /* 获取当前Token **/ + getToken: () => { + return SESSION_TOKEN || storage.get(appConfig.ACCESS_TOKEN_NAME) + }, + + /* 清空Token **/ + cleanToken: () => { + SESSION_TOKEN = '' + storage.remove(appConfig.ACCESS_TOKEN_NAME) + }, + + /* 设置token信息 **/ + setToken (tokenVal, isSaveStorage) { + SESSION_TOKEN = tokenVal + if (isSaveStorage) { + storage.set(appConfig.ACCESS_TOKEN_NAME, tokenVal, 7 * 24 * 60 * 60 * 1000) + } + } +} +export default wrapper diff --git a/jeepay-ui-merchant/src/utils/screenLog.js b/jeepay-ui-merchant/src/utils/screenLog.js new file mode 100644 index 0000000..ce51de1 --- /dev/null +++ b/jeepay-ui-merchant/src/utils/screenLog.js @@ -0,0 +1,18 @@ +/* eslint-disable */ +export const printANSI = () => { + let text = ` + __ + / /___ ___ ____ ____ ___ __ + __ / // _ \\/ _ \\/ __ \\/ __ \`/ / / / +/ /_/ // __/ __/ /_/ / /_/ / /_/ / +\\____/ \\___/\\___/ .___/\\__,_/\\__, / + /_/ /____/ + :: Jeepay :: (v1.0.0.RELEASE) + 适合互联网企业使用的开源支付系统 : https://www.jeepay.vip +` + + console.log(`%c${text}`, 'color: #fc4d50') + + console.log('%cThanks for using Jeepay!', 'color: #fff; font-size: 14px; font-weight: 300; text-shadow:#000 1px 0 0,#000 0 1px 0,#000 -1px 0 0,#000 0 -1px 0;') + +} diff --git a/jeepay-ui-merchant/src/utils/util.js b/jeepay-ui-merchant/src/utils/util.js new file mode 100644 index 0000000..afbc127 --- /dev/null +++ b/jeepay-ui-merchant/src/utils/util.js @@ -0,0 +1,12 @@ +export function timeFix () { + const time = new Date() + const hour = time.getHours() + return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好' +} + +export function isIE () { + const bw = window.navigator.userAgent + const compare = (s) => bw.indexOf(s) >= 0 + const ie11 = (() => 'ActiveXObject' in window)() + return compare('MSIE') || ie11 +} diff --git a/jeepay-ui-merchant/src/utils/utils.less b/jeepay-ui-merchant/src/utils/utils.less new file mode 100644 index 0000000..ba75a67 --- /dev/null +++ b/jeepay-ui-merchant/src/utils/utils.less @@ -0,0 +1,50 @@ +.textOverflow() { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + word-break: break-all; +} + +.textOverflowMulti(@line: 3, @bg: #fff) { + position: relative; + max-height: @line * 1.5em; + margin-right: -1em; + padding-right: 1em; + overflow: hidden; + line-height: 1.5em; + text-align: justify; + &::before { + position: absolute; + right: 14px; + bottom: 0; + padding: 0 1px; + background: @bg; + content: '...'; + } + &::after { + position: absolute; + right: 14px; + width: 1em; + height: 1em; + margin-top: 0.2em; + background: white; + content: ''; + } +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &::before, + &::after { + display: table; + content: ' '; + } + &::after { + clear: both; + height: 0; + font-size: 0; + visibility: hidden; + } +} \ No newline at end of file diff --git a/jeepay-ui-merchant/src/views/current/AvatarModal.vue b/jeepay-ui-merchant/src/views/current/AvatarModal.vue new file mode 100644 index 0000000..40d3550 --- /dev/null +++ b/jeepay-ui-merchant/src/views/current/AvatarModal.vue @@ -0,0 +1,202 @@ + + + + diff --git a/jeepay-ui-merchant/src/views/current/UserinfoPage.vue b/jeepay-ui-merchant/src/views/current/UserinfoPage.vue new file mode 100644 index 0000000..5a8284e --- /dev/null +++ b/jeepay-ui-merchant/src/views/current/UserinfoPage.vue @@ -0,0 +1,253 @@ + + + diff --git a/jeepay-ui-merchant/src/views/dashboard/Analysis.vue b/jeepay-ui-merchant/src/views/dashboard/Analysis.vue new file mode 100644 index 0000000..508192a --- /dev/null +++ b/jeepay-ui-merchant/src/views/dashboard/Analysis.vue @@ -0,0 +1,749 @@ + + + + + diff --git a/jeepay-ui-merchant/src/views/dashboard/Workplace.less b/jeepay-ui-merchant/src/views/dashboard/Workplace.less new file mode 100644 index 0000000..005b73a --- /dev/null +++ b/jeepay-ui-merchant/src/views/dashboard/Workplace.less @@ -0,0 +1,107 @@ +@import '~ant-design-vue/es/style/themes/default.less'; + +.text-overflow() { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + word-break: break-all; +} + +// mixins for clearfix +// ------------------------ +.clearfix() { + zoom: 1; + &::before, + &::after { + display: table; + content: ' '; + } + &::after { + clear: both; + height: 0; + font-size: 0; + visibility: hidden; + } +} + + +.page-header-content { + display: flex; + + .avatar { + flex: 0 1 72px; + + & > span { + display: block; + width: 72px; + height: 72px; + border-radius: 72px; + } + } + + .content { + position: relative; + top: 4px; + flex: 1 1 auto; + margin-left: 24px; + color: @text-color-secondary; + line-height: 22px; + + .content-title { + margin-bottom: 12px; + color: @heading-color; + font-weight: 500; + font-size: 20px; + line-height: 28px; + } + } +} + +.extra-content { + .clearfix(); + float: right; + white-space: nowrap; + + .stat-item { + position: relative; + display: inline-block; + padding: 0 32px; + + > p:first-child { + margin-bottom: 4px; + color: @text-color-secondary; + font-size: @font-size-base; + line-height: 22px; + } + + > p { + margin: 0; + color: @heading-color; + font-size: 30px; + line-height: 38px; + + > span { + color: @text-color-secondary; + font-size: 20px; + } + } + + &::after { + position: absolute; + top: 8px; + right: 0; + width: 1px; + height: 40px; + background-color: @border-color-split; + content: ''; + } + + &:last-child { + padding-right: 0; + + &::after { + display: none; + } + } + } +} \ No newline at end of file diff --git a/jeepay-ui-merchant/src/views/dashboard/empty.vue b/jeepay-ui-merchant/src/views/dashboard/empty.vue new file mode 100644 index 0000000..d406f7b --- /dev/null +++ b/jeepay-ui-merchant/src/views/dashboard/empty.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/jeepay-ui-merchant/src/views/dashboard/index.css b/jeepay-ui-merchant/src/views/dashboard/index.css new file mode 100644 index 0000000..d59c3bd --- /dev/null +++ b/jeepay-ui-merchant/src/views/dashboard/index.css @@ -0,0 +1,159 @@ +#chart-card { + width: 100%; +} +#chart-card .chart-data { + min-height: 100px; + height: 100%; + width: 100%; + border-radius: 6px; + background-color: #fff; +} +#chart-card .chart-top, +#chart-card .chart-bottom { + display: flex; + flex-direction: row; + flex-wrap: wrap; +} +#chart-card .chart-top .middle-smaller, +#chart-card .chart-bottom .middle-smaller, +#chart-card .chart-top .middle-larger, +#chart-card .chart-bottom .middle-larger { + height: 100%; +} +#chart-card .chart-top .top-left, +#chart-card .chart-bottom .top-left { + min-height: 238px; +} +#chart-card .chart-item { + width: 100%; + box-sizing: border-box; + padding: 12px; +} +@media screen and (max-width: 767px) { + #chart-card .chart-top .top-left { + order: 1; + } + #chart-card .chart-top .top-middle { + order: 2; + width: 100%; + } + #chart-card .chart-top .top-middle .middle-top, + #chart-card .chart-top .top-middle .middle-bottom { + display: flex; + flex-direction: column; + } + #chart-card .chart-top .top-middle .middle-top .middle-larger, + #chart-card .chart-top .top-middle .middle-bottom .middle-larger, + #chart-card .chart-top .top-middle .middle-top .middle-smaller, + #chart-card .chart-top .top-middle .middle-bottom .middle-smaller { + width: 100%; + } + #chart-card .chart-top .top-right { + order: 0; + } +} +@media screen and (min-width: 768px) { + #chart-card .top-left, + #chart-card .top-middle { + order: 1; + } + #chart-card .top-middle { + width: 100%; + } + #chart-card .top-middle .middle-top, + #chart-card .top-middle .middle-bottom { + display: flex; + flex-direction: row; + } + #chart-card .top-middle .middle-top .middle-larger, + #chart-card .top-middle .middle-bottom .middle-larger { + flex-grow: 1; + } + #chart-card .top-middle .middle-top .middle-smaller, + #chart-card .top-middle .middle-bottom .middle-smaller { + max-width: 170px; + min-width: 130px; + } + #chart-card .top-right { + order: 0; + } +} +@media screen and (min-width: 1200px) { + #chart-card .top-left { + order: 1; + width: 50%; + } + #chart-card .top-middle { + width: 50%; + order: 2; + } + #chart-card .top-middle .middle-top, + #chart-card .top-middle .middle-bottom { + display: flex; + flex-direction: row; + } + #chart-card .top-middle .middle-top .middle-larger, + #chart-card .top-middle .middle-bottom .middle-larger { + flex-grow: 1; + } + #chart-card .top-middle .middle-top .middle-smaller, + #chart-card .top-middle .middle-bottom .middle-smaller { + max-width: 170px; + min-width: 130px; + } + #chart-card .top-right { + width: 100%; + order: 0; + } +} +@media screen and (min-width: 1500px) { + #chart-card { + flex-direction: row; + } + #chart-card .chart-top { + width: 100%; + order: 0; + flex-wrap: nowrap; + } + #chart-card .chart-top .top-left, + #chart-card .chart-top .top-middle { + width: 500px; + min-width: 460px; + order: 0; + } + #chart-card .chart-top .top-middle { + order: 1; + } + #chart-card .chart-top .top-middle .middle-top, + #chart-card .chart-top .top-middle .middle-bottom { + display: flex; + width: 100%; + height: 50%; + flex-wrap: nowrap; + } + #chart-card .chart-top .top-middle .middle-smaller { + width: 150px; + min-width: 150px; + } + #chart-card .chart-top .top-middle .middle-larger { + width: 300px; + flex-grow: 1; + } + #chart-card .chart-top .top-right { + order: 2; + flex-grow: 1; + } + #chart-card .chart-bottom { + order: 1; + width: 100%; + flex-wrap: nowrap; + } + #chart-card .chart-bottom .bottom-right { + max-width: 500px; + min-width: 330px; + } + #chart-card .chart-bottom .bottom-left { + min-width: 900px; + flex-grow: 1; + } +} diff --git a/jeepay-ui-merchant/src/views/dashboard/index.less b/jeepay-ui-merchant/src/views/dashboard/index.less new file mode 100644 index 0000000..47fb624 --- /dev/null +++ b/jeepay-ui-merchant/src/views/dashboard/index.less @@ -0,0 +1,165 @@ +#chart-card { + width: 100%; + + .chart-data { + min-height: 100px; + height: 100%; + width: 100%; + border-radius: 6px; + background-color: #fff; + } + .chart-top, .chart-bottom { + display: flex; + flex-direction: row; + flex-wrap: wrap; + + .middle-smaller, .middle-larger { // 较小的区域 + height: 100%; + } + .top-left { + min-height: 238px; + } + } + .chart-item { + width: 100%; + box-sizing: border-box; + padding: 12px; + } +} +@media screen and (max-width:767px){ +#chart-card { + .chart-top { + .top-left { + order: 1; + } + .top-middle { + order: 2; + width: 100%; + + .middle-top, .middle-bottom { + display: flex; + flex-direction: column; + + .middle-larger, .middle-smaller { + width: 100%; + } + } + + } + .top-right { + order: 0; + } + } +} +} +@media screen and (min-width:768px){ +#chart-card { + .top-left, .top-middle { + order: 1; + } + .top-middle { + width: 100%; + .middle-top, .middle-bottom { + display: flex; + flex-direction: row; + + .middle-larger { + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + .middle-smaller { + max-width: 170px; + min-width: 130px; + } + } + } + + .top-right { + order: 0; + } +} +} + +@media screen and (min-width:1200px){ +#chart-card { + .top-left { + order: 1; + width: 50%; + } + .top-middle { + width: 50%; + order: 2; + + .middle-top, .middle-bottom { + display: flex; + flex-direction: row; + + .middle-larger { + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + .middle-smaller { + max-width: 170px; + min-width: 130px; + } + } + } + + .top-right { + width: 100%; + order: 0; + } + } +} + +@media screen and (min-width:1500px){ + #chart-card { + flex-direction: row; + + .chart-top { + width:100%; + order: 0; + flex-wrap: nowrap; // 禁止换行 + + .top-left, .top-middle { + width:500px; + min-width: 460px; + order: 0; + } + .top-middle { + order: 1; + .middle-top, .middle-bottom { + display: flex; + width: 100%; + height: 50%; + flex-wrap: nowrap; // 禁止换行 + } + .middle-smaller { // 较小的区域 + width: 150px; + min-width: 150px; + } + .middle-larger { // 较大的区域 + width: 300px; + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + } + .top-right { + order: 2; + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + } + + .chart-bottom { + order: 1; + width:100%; + + flex-wrap: nowrap; + .bottom-right { + max-width: 500px; + min-width: 330px; + } + .bottom-left { + min-width: 900px; + flex-grow: 1; // 设置为1,存在剩余空间放大 + } + } + } +} \ No newline at end of file diff --git a/jeepay-ui-merchant/src/views/exception/403.vue b/jeepay-ui-merchant/src/views/exception/403.vue new file mode 100644 index 0000000..6df8f43 --- /dev/null +++ b/jeepay-ui-merchant/src/views/exception/403.vue @@ -0,0 +1,22 @@ + + + diff --git a/jeepay-ui-merchant/src/views/exception/404.vue b/jeepay-ui-merchant/src/views/exception/404.vue new file mode 100644 index 0000000..824644c --- /dev/null +++ b/jeepay-ui-merchant/src/views/exception/404.vue @@ -0,0 +1,22 @@ + + + diff --git a/jeepay-ui-merchant/src/views/exception/500.vue b/jeepay-ui-merchant/src/views/exception/500.vue new file mode 100644 index 0000000..08f2dc1 --- /dev/null +++ b/jeepay-ui-merchant/src/views/exception/500.vue @@ -0,0 +1,22 @@ + + + diff --git a/jeepay-ui-merchant/src/views/order/pay/PayOrderList.vue b/jeepay-ui-merchant/src/views/order/pay/PayOrderList.vue new file mode 100644 index 0000000..d99e6e9 --- /dev/null +++ b/jeepay-ui-merchant/src/views/order/pay/PayOrderList.vue @@ -0,0 +1,367 @@ + + diff --git a/jeepay-ui-merchant/src/views/order/refund/RefundOrderList.vue b/jeepay-ui-merchant/src/views/order/refund/RefundOrderList.vue new file mode 100644 index 0000000..8978871 --- /dev/null +++ b/jeepay-ui-merchant/src/views/order/refund/RefundOrderList.vue @@ -0,0 +1,375 @@ + + diff --git a/jeepay-ui-merchant/src/views/pay/MchPayPassageAddOrEdit.vue b/jeepay-ui-merchant/src/views/pay/MchPayPassageAddOrEdit.vue new file mode 100644 index 0000000..2410773 --- /dev/null +++ b/jeepay-ui-merchant/src/views/pay/MchPayPassageAddOrEdit.vue @@ -0,0 +1,194 @@ + + + + diff --git a/jeepay-ui-merchant/src/views/pay/PayConfigList.vue b/jeepay-ui-merchant/src/views/pay/PayConfigList.vue new file mode 100644 index 0000000..44ad50d --- /dev/null +++ b/jeepay-ui-merchant/src/views/pay/PayConfigList.vue @@ -0,0 +1,301 @@ + + + + + diff --git a/jeepay-ui-merchant/src/views/pay/PayPassageList.vue b/jeepay-ui-merchant/src/views/pay/PayPassageList.vue new file mode 100644 index 0000000..b9b3924 --- /dev/null +++ b/jeepay-ui-merchant/src/views/pay/PayPassageList.vue @@ -0,0 +1,95 @@ + + diff --git a/jeepay-ui-merchant/src/views/role/AddOrEdit.vue b/jeepay-ui-merchant/src/views/role/AddOrEdit.vue new file mode 100644 index 0000000..4153bc8 --- /dev/null +++ b/jeepay-ui-merchant/src/views/role/AddOrEdit.vue @@ -0,0 +1,105 @@ + + + diff --git a/jeepay-ui-merchant/src/views/role/RoleDist.vue b/jeepay-ui-merchant/src/views/role/RoleDist.vue new file mode 100644 index 0000000..529a860 --- /dev/null +++ b/jeepay-ui-merchant/src/views/role/RoleDist.vue @@ -0,0 +1,100 @@ + + + diff --git a/jeepay-ui-merchant/src/views/role/RolePage.vue b/jeepay-ui-merchant/src/views/role/RolePage.vue new file mode 100644 index 0000000..81514eb --- /dev/null +++ b/jeepay-ui-merchant/src/views/role/RolePage.vue @@ -0,0 +1,124 @@ + + diff --git a/jeepay-ui-merchant/src/views/sysuser/AddOrEdit.vue b/jeepay-ui-merchant/src/views/sysuser/AddOrEdit.vue new file mode 100644 index 0000000..9ee6482 --- /dev/null +++ b/jeepay-ui-merchant/src/views/sysuser/AddOrEdit.vue @@ -0,0 +1,158 @@ + + + diff --git a/jeepay-ui-merchant/src/views/sysuser/RoleDist.vue b/jeepay-ui-merchant/src/views/sysuser/RoleDist.vue new file mode 100644 index 0000000..518ab39 --- /dev/null +++ b/jeepay-ui-merchant/src/views/sysuser/RoleDist.vue @@ -0,0 +1,101 @@ + + + diff --git a/jeepay-ui-merchant/src/views/sysuser/SysUserPage.vue b/jeepay-ui-merchant/src/views/sysuser/SysUserPage.vue new file mode 100644 index 0000000..a591782 --- /dev/null +++ b/jeepay-ui-merchant/src/views/sysuser/SysUserPage.vue @@ -0,0 +1,146 @@ + + diff --git a/jeepay-ui-merchant/src/views/user/Login.vue b/jeepay-ui-merchant/src/views/user/Login.vue new file mode 100644 index 0000000..57652c2 --- /dev/null +++ b/jeepay-ui-merchant/src/views/user/Login.vue @@ -0,0 +1,224 @@ + + + + + diff --git a/jeepay-ui-merchant/tests/unit/.eslintrc.js b/jeepay-ui-merchant/tests/unit/.eslintrc.js new file mode 100644 index 0000000..958d51b --- /dev/null +++ b/jeepay-ui-merchant/tests/unit/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + env: { + jest: true + } +} diff --git a/jeepay-ui-merchant/vue.config.js b/jeepay-ui-merchant/vue.config.js new file mode 100644 index 0000000..3f97d9b --- /dev/null +++ b/jeepay-ui-merchant/vue.config.js @@ -0,0 +1,130 @@ +const path = require('path') +const webpack = require('webpack') +const GitRevisionPlugin = require('git-revision-webpack-plugin') +const GitRevision = new GitRevisionPlugin() +const buildDate = JSON.stringify(new Date().toLocaleString()) + +function resolve (dir) { + return path.join(__dirname, dir) +} + +// check Git +function getGitHash () { + try { + return GitRevision.version() + } catch (e) { } + 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' + ] +} + +// vue.config.js +const vueConfig = { + publicPath: process.env.VUE_APP_BASE_URL, // 前端资源访问根目录, 可配置到cdn目录下。 建议使用命令行环境变量进行替换。 + configureWebpack: { + // webpack plugins + plugins: [ + // Ignore all locale files of moment.js + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + new webpack.DefinePlugin({ + APP_VERSION: `"${require('./package.json').version}"`, + GIT_HASH: JSON.stringify(getGitHash()), + BUILD_DATE: buildDate + }) + ], + // 代码调试 + devtool: 'source-map', + // if prod, add externals + externals: isProd ? assetsCDN.externals : {} + }, + + chainWebpack: (config) => { + config.resolve.alias + .set('@$', resolve('src')) + + const svgRule = config.module.rule('svg') + svgRule.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/) + svgRule.uses.clear() + svgRule + .oneOf('inline') + .resourceQuery(/inline/) + .use('vue-svg-icon-loader') + .loader('vue-svg-icon-loader') + .end() + .end() + .oneOf('external') + .use('file-loader') + .loader('file-loader') + .options({ + 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: { + loaderOptions: { + less: { + modifyVars: { + 'primary-color': '#1a53ff', + 'link-color': '#1A79FF', + 'border-radius-base': '4px' + }, + javascriptEnabled: true + } + } + }, + + devServer: { + // development server port 8000 + port: 8000 + // If you want to turn on the proxy, please remove the mockjs /src/main.jsL11 + // proxy: { + // '/api': { + // target: 'https://mock.ihx.me/mock/5baf3052f7da7e07e04a5116/antd-pro', + // ws: false, + // changeOrigin: true + // } + // } + }, + + // disable source map in production + productionSourceMap: false, + lintOnSave: undefined, + // babel-loader no-ignore node_modules/* + transpileDependencies: [], + + pluginOptions: { // 第三方插件配置 + 'style-resources-loader': { + preProcessor: 'less', + patterns: [path.resolve(__dirname, 'src/assets/styles/color.less')] // less所在文件路径 + } + } +} + +module.exports = vueConfig